-
-
Notifications
You must be signed in to change notification settings - Fork 75
fix: relax over-strict validation_rules() so abilities accept minimal input #755
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -228,10 +228,29 @@ function wu_create_site($site_data) { | |
|
|
||
| $current_site = get_current_site(); | ||
|
|
||
| $network_domain = $current_site->domain; | ||
|
|
||
| // Mode-aware domain/path normalisation. When the caller passes a path | ||
| // but no explicit domain (or only the network root domain) on a | ||
| // subdomain multisite install, the path is meaningless — WordPress | ||
| // won't route to it. Convert the supplied path into a subdomain | ||
| // prefix instead so the site is reachable. Callers that pass an | ||
| // explicit non-root domain are respected as-is so subdomain/subdir | ||
| // mixing still works. | ||
| $path_supplied = isset($site_data['path']) && '' !== $site_data['path'] && '/' !== $site_data['path']; | ||
| $domain_supplied = isset($site_data['domain']) && '' !== $site_data['domain'] && $site_data['domain'] !== $network_domain; | ||
|
|
||
| if (is_multisite() && is_subdomain_install() && $path_supplied && ! $domain_supplied) { | ||
| $slug = trim((string) $site_data['path'], '/'); | ||
| $bare_network_domain = preg_replace('/^www\./i', '', (string) $network_domain); | ||
| $site_data['domain'] = "{$slug}.{$bare_network_domain}"; | ||
| $site_data['path'] = '/'; | ||
|
Comment on lines
+244
to
+247
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sanitize and validate the derived subdomain slug before building Line 244 currently trims slashes only, then interpolates directly into a hostname on Line 246. Invalid characters or malformed path values can generate invalid domains. Sanitize the slug and return Suggested patch if (is_multisite() && is_subdomain_install() && $path_supplied && ! $domain_supplied) {
- $slug = trim((string) $site_data['path'], '/');
+ $raw_slug = trim((string) $site_data['path'], '/');
+ $slug = sanitize_title_with_dashes(wu_clean($raw_slug));
+ if ('' === $slug) {
+ return new \WP_Error(
+ 'invalid_site_path',
+ __('Invalid site path for subdomain creation.', 'ultimate-multisite')
+ );
+ }
$bare_network_domain = preg_replace('/^www\./i', '', (string) $network_domain);
$site_data['domain'] = "{$slug}.{$bare_network_domain}";
$site_data['path'] = '/';
}As per coding guidelines, "Use wu_clean() or WordPress sanitization functions for input sanitization" and "Use WP_Error for validation/operation failures instead of exceptions". 🤖 Prompt for AI Agents |
||
| } | ||
|
|
||
| $site_data = wp_parse_args( | ||
| $site_data, | ||
| [ | ||
| 'domain' => $current_site->domain, | ||
| 'domain' => $network_domain, | ||
| 'path' => '/', | ||
| 'title' => false, | ||
| 'type' => false, | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -331,10 +331,15 @@ public function validation_rules() { | |||||||||||||
| return [ | ||||||||||||||
| 'categories' => 'default:', | ||||||||||||||
| 'featured_image_id' => 'integer|default:', | ||||||||||||||
| 'site_id' => 'required|integer', | ||||||||||||||
| // site_id is the network id; defaults to 1 (the main network) in | ||||||||||||||
| // the model, so it's optional for a regular WordPress subsite. | ||||||||||||||
| 'site_id' => 'integer|default:1', | ||||||||||||||
|
Comment on lines
+334
to
+336
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Defaulting Line 336 hard-defaults to Suggested fix- 'site_id' => 'integer|default:1',
+ 'site_id' => 'integer|default:',- protected $site_id = 1;
+ protected $site_id = 0;📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||
| 'title' => 'required', | ||||||||||||||
| 'name' => 'required', | ||||||||||||||
| 'description' => 'required|min:2', | ||||||||||||||
| // description is optional metadata. A regular WordPress subsite | ||||||||||||||
| // doesn't have one at the network level — it lives in | ||||||||||||||
| // blogdescription per blog and can be set later. | ||||||||||||||
| 'description' => 'default:', | ||||||||||||||
| 'domain' => 'domain', | ||||||||||||||
| 'path' => 'required|default:', | ||||||||||||||
| 'registered' => "default:{$date}", | ||||||||||||||
|
|
@@ -346,8 +351,12 @@ public function validation_rules() { | |||||||||||||
| 'deleted' => 'boolean|default:0', | ||||||||||||||
| 'is_publishing' => 'boolean|default:0', | ||||||||||||||
| 'land_id' => 'integer|default:', | ||||||||||||||
| 'customer_id' => 'required|integer|exists:\WP_Ultimo\Models\Customer,id', | ||||||||||||||
| 'membership_id' => 'required|integer|exists:\WP_Ultimo\Models\Membership,id', | ||||||||||||||
| // customer_id and membership_id are WaaS-specific. A vanilla | ||||||||||||||
| // WordPress subsite (type=default) does not need a paying | ||||||||||||||
| // customer or a membership. Keep the foreign-key existence | ||||||||||||||
| // check so customer-owned sites still validate when supplied. | ||||||||||||||
| 'customer_id' => 'integer|default:|exists:\WP_Ultimo\Models\Customer,id', | ||||||||||||||
| 'membership_id' => 'integer|default:|exists:\WP_Ultimo\Models\Membership,id', | ||||||||||||||
| 'template_id' => 'integer|default:', | ||||||||||||||
| 'type' => "required|in:{$site_types}", | ||||||||||||||
| 'signup_options' => 'default:', | ||||||||||||||
|
|
@@ -631,7 +640,7 @@ public function get_domain() { | |||||||||||||
| * Set domain name used by this site.. | ||||||||||||||
| * | ||||||||||||||
| * @since 2.0.0 | ||||||||||||||
| * @param string $domain The site domain. You don't need to put http or https in front of your domain in this field. e.g: example.com. | ||||||||||||||
| * @param string $domain Full hostname for the site, no protocol. On a subdomain multisite install supply the full subdomain you want (e.g. "blog.example.com"). On a subdirectory install leave empty to inherit the network root domain. wu_create_site() will auto-derive this from `path` on subdomain installs when you only supply a slug. | ||||||||||||||
| * @return void | ||||||||||||||
| */ | ||||||||||||||
| public function set_domain($domain): void { | ||||||||||||||
|
|
@@ -653,7 +662,7 @@ public function get_path(): string { | |||||||||||||
| * Set path of the site. Used when in sub-directory mode.. | ||||||||||||||
| * | ||||||||||||||
| * @since 2.0.0 | ||||||||||||||
| * @param string $path Path of the site. Used when in sub-directory mode. | ||||||||||||||
| * @param string $path URL path for the site. On a subdirectory multisite install this is the URL prefix (e.g. "/blog/"). On a subdomain install supply just the slug (e.g. "blog") and wu_create_site() will convert it into the full subdomain "blog.<network-domain>" automatically. | ||||||||||||||
| * @return void | ||||||||||||||
| */ | ||||||||||||||
| public function set_path($path): void { | ||||||||||||||
|
|
||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Normalize root-domain comparison before setting
domain_suppliedLine 241 can misclassify a root domain as “explicit non-root” when forms differ (
www.example.comvsexample.com, or case differences), which skips the subdomain conversion path unexpectedly.Suggested patch
📝 Committable suggestion
🤖 Prompt for AI Agents