From c1ee30a25596fe5827745a455e0d69825874c5be Mon Sep 17 00:00:00 2001 From: Spitfire Date: Mon, 9 Sep 2024 15:08:41 -0600 Subject: [PATCH 1/3] Migrated Rules to ValidationRules --- app/Http/Requests/StoreEntityAsset.php | 4 +- app/Http/Requests/StoreEntityAssets.php | 4 +- app/Http/Requests/StoreEntityFile.php | 4 +- app/Rules/AccountEmail.php | 26 ++++------- app/Rules/AccountName.php | 35 ++++----------- app/Rules/CalendarFormat.php | 35 ++++----------- app/Rules/CalendarMoonOffset.php | 36 ++++------------ app/Rules/CampaignDelete.php | 36 ++++------------ app/Rules/EntityFileRule.php | 57 ++++++++----------------- app/Rules/EntityLink.php | 51 ++++++++-------------- app/Rules/FontAwesomeIcon.php | 35 ++++----------- app/Rules/GoodBye.php | 34 ++++----------- 12 files changed, 103 insertions(+), 254 deletions(-) diff --git a/app/Http/Requests/StoreEntityAsset.php b/app/Http/Requests/StoreEntityAsset.php index 21ac0ebec5..a5c214c193 100644 --- a/app/Http/Requests/StoreEntityAsset.php +++ b/app/Http/Requests/StoreEntityAsset.php @@ -4,7 +4,7 @@ use App\Facades\Limit; use App\Models\EntityAsset; -use App\Rules\EntityFileRule; +use App\Rules\EntityFile; use App\Rules\FontAwesomeIcon; use App\Traits\ApiRequest; use Illuminate\Foundation\Http\FormRequest; @@ -37,7 +37,7 @@ public function rules() 'required_if:type_id,' . EntityAsset::TYPE_FILE, 'file', 'max:' . Limit::upload(), - new EntityFileRule() + new EntityFile() ], 'metadata.url' => 'required_if:type_id,' . EntityAsset::TYPE_LINK . '|string|url', 'metadata.icon' => ['max:45', new FontAwesomeIcon()], diff --git a/app/Http/Requests/StoreEntityAssets.php b/app/Http/Requests/StoreEntityAssets.php index 038bab2886..57c56f1be6 100644 --- a/app/Http/Requests/StoreEntityAssets.php +++ b/app/Http/Requests/StoreEntityAssets.php @@ -4,7 +4,7 @@ use App\Facades\Limit; use App\Models\EntityAsset; -use App\Rules\EntityFileRule; +use App\Rules\EntityFile; use App\Rules\FontAwesomeIcon; use App\Traits\ApiRequest; use Illuminate\Foundation\Http\FormRequest; @@ -37,7 +37,7 @@ public function rules() 'required_if:type_id,' . EntityAsset::TYPE_FILE, 'file', 'max:' . Limit::upload(), - new EntityFileRule() + new EntityFile() ], 'metadata.url' => 'required_if:type_id,' . EntityAsset::TYPE_LINK . '|string|url', 'metadata.icon' => ['max:45', new FontAwesomeIcon()], diff --git a/app/Http/Requests/StoreEntityFile.php b/app/Http/Requests/StoreEntityFile.php index 020ca320cf..ca799f0fc4 100644 --- a/app/Http/Requests/StoreEntityFile.php +++ b/app/Http/Requests/StoreEntityFile.php @@ -3,7 +3,7 @@ namespace App\Http\Requests; use App\Facades\Limit; -use App\Rules\EntityFileRule; +use App\Rules\EntityFile; use Illuminate\Foundation\Http\FormRequest; class StoreEntityFile extends FormRequest @@ -30,7 +30,7 @@ public function rules() 'required', 'file', 'max:' . Limit::upload(), - new EntityFileRule() + new EntityFile() ], 'name' => 'nullable|string|max:45', 'visibility_id' => 'nullable|exists:visibilities,id' diff --git a/app/Rules/AccountEmail.php b/app/Rules/AccountEmail.php index 4036608e6f..73dc1123fe 100644 --- a/app/Rules/AccountEmail.php +++ b/app/Rules/AccountEmail.php @@ -2,29 +2,21 @@ namespace App\Rules; -use Illuminate\Contracts\Validation\Rule; +use Closure; +use Illuminate\Contracts\Validation\ValidationRule; use Illuminate\Support\Str; -class AccountEmail implements Rule +class AccountEmail implements ValidationRule { /** - * Determine if the validation rule passes. + * Run the validation rule. * - * @param string $attribute - * @return bool + * @param \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString $fail */ - public function passes($attribute, $value) + public function validate(string $attribute, mixed $value, Closure $fail): void { - return !Str::contains($value, ['@boxmail.lol', '@fireboxmail.lol']); - } - - /** - * Get the validation error message. - * - * @return string - */ - public function message() - { - return 'The validation error message.'; + if(Str::contains($value, ['@boxmail.lol', '@fireboxmail.lol'])) { + $fail('The validation error message.'); + } } } diff --git a/app/Rules/AccountName.php b/app/Rules/AccountName.php index dafc5fa648..0b1fdf2f15 100644 --- a/app/Rules/AccountName.php +++ b/app/Rules/AccountName.php @@ -2,38 +2,21 @@ namespace App\Rules; -use Illuminate\Contracts\Validation\Rule; +use Closure; +use Illuminate\Contracts\Validation\ValidationRule; use Illuminate\Support\Str; -class AccountName implements Rule +class AccountName implements ValidationRule { /** - * Create a new rule instance. + * Run the validation rule. * - * @return void + * @param \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString $fail */ - public function __construct() + public function validate(string $attribute, mixed $value, Closure $fail): void { - } - - /** - * Determine if the validation rule passes. - * - * @param string $attribute - * @return bool - */ - public function passes($attribute, $value) - { - return !Str::contains($value, ['<', '>', 'https', 'http://', 'www.', 'Ђ', ' Illuro']) && Str::length($value) < 31; - } - - /** - * Get the validation error message. - * - * @return string - */ - public function message() - { - return 'Invalid account name.'; + if (Str::contains($value, ['<', '>', 'https', 'http://', 'www.', 'Ђ', ' Illuro']) && Str::length($value) < 31) { + $fail('Invalid account name.'); + } } } diff --git a/app/Rules/CalendarFormat.php b/app/Rules/CalendarFormat.php index 1ffa893628..67ac1b3ad2 100644 --- a/app/Rules/CalendarFormat.php +++ b/app/Rules/CalendarFormat.php @@ -2,37 +2,20 @@ namespace App\Rules; -use Illuminate\Contracts\Validation\Rule; +use Closure; +use Illuminate\Contracts\Validation\ValidationRule; -class CalendarFormat implements Rule +class CalendarFormat implements ValidationRule { /** - * Create a new rule instance. + * Run the validation rule. * - * @return void + * @param \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString $fail */ - public function __construct() + public function validate(string $attribute, mixed $value, Closure $fail): void { - } - - /** - * Determine if the validation rule passes. - * - * @param string $attribute - * @return bool - */ - public function passes($attribute, $value) - { - return preg_match('/^[ymMds\s,-]+$/', $value); - } - - /** - * Get the validation error message. - * - * @return string - */ - public function message() - { - return __('calendars.validators.format'); + if(preg_match('/^[ymMds\s,-]+$/', $value)) { + $fail(__('calendars.validators.format')); + } } } diff --git a/app/Rules/CalendarMoonOffset.php b/app/Rules/CalendarMoonOffset.php index c7308c6864..2028d72c1c 100644 --- a/app/Rules/CalendarMoonOffset.php +++ b/app/Rules/CalendarMoonOffset.php @@ -2,50 +2,30 @@ namespace App\Rules; -use Illuminate\Contracts\Validation\Rule; +use Closure; +use Illuminate\Contracts\Validation\ValidationRule; -class CalendarMoonOffset implements Rule +class CalendarMoonOffset implements ValidationRule { /** - * Create a new rule instance. + * Run the validation rule. * - * @return void + * @param \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString $fail */ - public function __construct() - { - } - - /** - * Determine if the validation rule passes. - * - * @param string $attribute - * @return bool - */ - public function passes($attribute, $value) + public function validate(string $attribute, mixed $value, Closure $fail): void { // Max value $lengths = request()->get('month_length'); if (!is_array($lengths) || count($lengths) === 0) { - return false; + $fail(__('calendars.validators.moon_offset')); } $max = $lengths[0]; $min = 0 - $max; foreach ($value as $offset) { if ($offset > $max || $offset < $min) { - return false; + $fail(__('calendars.validators.moon_offset')); } } - return true; - } - - /** - * Get the validation error message. - * - * @return string - */ - public function message() - { - return __('calendars.validators.moon_offset'); } } diff --git a/app/Rules/CampaignDelete.php b/app/Rules/CampaignDelete.php index abf917c392..c5341371eb 100644 --- a/app/Rules/CampaignDelete.php +++ b/app/Rules/CampaignDelete.php @@ -2,39 +2,21 @@ namespace App\Rules; -use Illuminate\Contracts\Validation\Rule; +use Closure; +use Illuminate\Contracts\Validation\ValidationRule; use Illuminate\Support\Str; -class CampaignDelete implements Rule +class CampaignDelete implements ValidationRule { /** - * Create a new rule instance. + * Run the validation rule. * - * @return void + * @param \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString $fail */ - public function __construct() + public function validate(string $attribute, mixed $value, Closure $fail): void { - } - - /** - * Determine if the validation rule passes. - * - * @param string $attribute - * @param string $value - * @return bool - */ - public function passes($attribute, $value) - { - return Str::is(mb_strtolower($value), 'delete'); - } - - /** - * Get the validation error message. - * - * @return string - */ - public function message() - { - return (__('validation.delete_campaign', ['code' => 'delete'])); + if(!Str::is(mb_strtolower($value), 'delete')) { + $fail(__('validation.delete_campaign', ['code' => 'delete'])); + } } } diff --git a/app/Rules/EntityFileRule.php b/app/Rules/EntityFileRule.php index 56b1c26048..77db3367e3 100644 --- a/app/Rules/EntityFileRule.php +++ b/app/Rules/EntityFileRule.php @@ -2,67 +2,46 @@ namespace App\Rules; -use Illuminate\Contracts\Validation\Rule; +use Closure; +use Illuminate\Contracts\Validation\ValidationRule; use Symfony\Component\HttpFoundation\File\UploadedFile; -class EntityFileRule implements Rule +class EntityFile implements ValidationRule { /** - * Create a new rule instance. + * Run the validation rule. * - * @return void + * @param \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString $fail */ - public function __construct() - { - } - - /** - * Determine if the validation rule passes. - * - * @param string $attribute - * @return bool - */ - public function passes($attribute, $value) + public function validate(string $attribute, mixed $value, Closure $fail): void { // Not a valid file, don't go further if ($value instanceof UploadedFile && !$value->isValid()) { - return false; + $fail(__('validation.mimes', ['values' => 'jpg, jpeg, png, gif, webp, pdf, xls(x), csv, mp3, ogg, json'])); } - + // Block any hacking shenanigans if ($this->shouldBlockPhpUpload($value, [])) { - return false; + $fail(__('validation.mimes', ['values' => 'jpg, jpeg, png, gif, webp, pdf, xls(x), csv, mp3, ogg, json'])); } - + if (empty($value->getPath())) { - return false; + $fail(__('validation.mimes', ['values' => 'jpg, jpeg, png, gif, webp, pdf, xls(x), csv, mp3, ogg, json'])); } - + $validExtensions = explode(',', 'jpeg,png,jpg,gif,webp,pdf,xls,xlsx,mp3'); - if (in_array($value->guessExtension(), $validExtensions)) { - return true; + if (!in_array($value->guessExtension(), $validExtensions)) { + $fail(__('validation.mimes', ['values' => 'jpg, jpeg, png, gif, webp, pdf, xls(x), csv, mp3, ogg, json'])); } // It wasn't an image, maybe it's an audio file if (empty($value->getClientOriginalExtension())) { - return false; + $fail(__('validation.mimes', ['values' => 'jpg, jpeg, png, gif, webp, pdf, xls(x), csv, mp3, ogg, json'])); } - return !(!in_array($value->getClientOriginalExtension(), ['mp3', 'ogg', 'json', 'csv'])) - - - - ; - } - - /** - * Get the validation error message. - * - * @return string - */ - public function message() - { - return __('validation.mimes', ['values' => 'jpg, jpeg, png, gif, webp, pdf, xls(x), csv, mp3, ogg, json']); + if (in_array($value->getClientOriginalExtension(), ['mp3', 'ogg', 'json', 'csv'])) { + $fail(__('validation.mimes', ['values' => 'jpg, jpeg, png, gif, webp, pdf, xls(x), csv, mp3, ogg, json'])); + } } protected function shouldBlockPhpUpload($value, $parameters) diff --git a/app/Rules/EntityLink.php b/app/Rules/EntityLink.php index 3071ec14ae..d76b21bb8e 100644 --- a/app/Rules/EntityLink.php +++ b/app/Rules/EntityLink.php @@ -5,31 +5,22 @@ use App\Models\Campaign; use App\Models\CampaignPermission; use App\Models\Entity; -use Illuminate\Contracts\Validation\Rule; +use Closure; +use Illuminate\Contracts\Validation\ValidationRule; use Illuminate\Support\Str; -class EntityLink implements Rule +class EntityLink implements ValidationRule { /** - * Create a new rule instance. + * Run the validation rule. * - * @return void + * @param \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString $fail */ - public function __construct() - { - } - - /** - * Determine if the validation rule passes. - * - * @param string $attribute - * @return bool - */ - public function passes($attribute, $value) + public function validate(string $attribute, mixed $value, Closure $fail): void { // Validate that tue url is for Kanka if (!Str::startsWith($value, config('app.url'))) { - return false; + $fail(__('validation.entity_link')); } // Extract the campaign and entity @@ -43,17 +34,17 @@ public function passes($attribute, $value) // 3: character|entities // 4: id if (count($segments) < 3) { - return false; + $fail(__('validation.entity_link')); } if ($segments[1] !== 'campaign' || !is_numeric($segments[2])) { - return false; + $fail(__('validation.entity_link')); } // Check that the campaign is public $campaign = Campaign::where('id', $segments[2])->first(); if (empty($campaign) || !$campaign->isPublic()) { - return false; + $fail(__('validation.entity_link')); } // Are we targeting an entity or a misc? @@ -69,7 +60,7 @@ public function passes($attribute, $value) } else { $entityTypeID = config('entities.ids.' . Str::singular($segments[3])); if (empty($entityTypeID)) { - return false; + $fail(__('validation.entity_link')); } // @phpstan-ignore-next-line $entity = Entity::where('entity_id', (int) $segments[4]) @@ -80,13 +71,13 @@ public function passes($attribute, $value) ->first(); } if (empty($entity) || $entity->is_private) { - return false; + $fail(__('validation.entity_link')); } // Figuring out if the entity is visible to the public role is going to be tricky, so let's start doing some magic. $publicRole = $campaign->roles()->public()->first(); if (empty($publicRole)) { - return false; + $fail(__('validation.entity_link')); } $permission = $publicRole->permissions() @@ -98,18 +89,10 @@ public function passes($attribute, $value) ->where('access', 1) ->where('action', CampaignPermission::ACTION_READ) ->first(); - + // We don't check for the public role have deny as a permission, this is good enough - return !empty($permission); - } - - /** - * Get the validation error message. - * - * @return string - */ - public function message() - { - return __('validation.entity_link'); + if (empty($permission)) { + $fail( __('validation.entity_link')); + } } } diff --git a/app/Rules/FontAwesomeIcon.php b/app/Rules/FontAwesomeIcon.php index 2fa39093dd..5c8d24212d 100644 --- a/app/Rules/FontAwesomeIcon.php +++ b/app/Rules/FontAwesomeIcon.php @@ -2,38 +2,21 @@ namespace App\Rules; -use Illuminate\Contracts\Validation\Rule; +use Closure; +use Illuminate\Contracts\Validation\ValidationRule; use Illuminate\Support\Str; -class FontAwesomeIcon implements Rule +class FontAwesomeIcon implements ValidationRule { /** - * Create a new rule instance. + * Run the validation rule. * - * @return void + * @param \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString $fail */ - public function __construct() + public function validate(string $attribute, mixed $value, Closure $fail): void { - } - - /** - * Determine if the validation rule passes. - * - * @param string $attribute - * @return bool - */ - public function passes($attribute, $value) - { - return !Str::startsWith($value, ' 'fa-solid fa-skull']); + if (Str::startsWith($value, ' 'fa-solid fa-skull'])); + } } } diff --git a/app/Rules/GoodBye.php b/app/Rules/GoodBye.php index a78fb7bdd3..f2ec55f0aa 100644 --- a/app/Rules/GoodBye.php +++ b/app/Rules/GoodBye.php @@ -2,38 +2,22 @@ namespace App\Rules; -use Illuminate\Contracts\Validation\Rule; +use Closure; +use Illuminate\Contracts\Validation\ValidationRule; use Illuminate\Support\Str; -class GoodBye implements Rule +class GoodBye implements ValidationRule { /** - * Create a new rule instance. + * Run the validation rule. * - * @return void + * @param \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString $fail */ - public function __construct() + public function validate(string $attribute, mixed $value, Closure $fail): void { - } - /** - * Determine if the validation rule passes. - * - * @param string $attribute - * @return bool - */ - public function passes($attribute, $value) - { - return Str::is(mb_strtolower($value), 'goodbye'); - } - - /** - * Get the validation error message. - * - * @return string - */ - public function message() - { - return (__('validation.goodbye', ['code' => 'goodbye'])); + if (!Str::is(mb_strtolower($value), 'goodbye')) { + $fail(__('validation.goodbye', ['code' => 'goodbye'])); + } } } From 62035f07671659e8b7f48bf29dd51a59bfb60e71 Mon Sep 17 00:00:00 2001 From: spitfire305 Date: Mon, 9 Sep 2024 21:10:20 +0000 Subject: [PATCH 2/3] Fix styling --- app/Rules/AccountEmail.php | 2 +- app/Rules/AccountName.php | 2 +- app/Rules/CalendarFormat.php | 2 +- app/Rules/CampaignDelete.php | 2 +- app/Rules/EntityFileRule.php | 6 +++--- app/Rules/EntityLink.php | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/Rules/AccountEmail.php b/app/Rules/AccountEmail.php index 73dc1123fe..200321f9cd 100644 --- a/app/Rules/AccountEmail.php +++ b/app/Rules/AccountEmail.php @@ -15,7 +15,7 @@ class AccountEmail implements ValidationRule */ public function validate(string $attribute, mixed $value, Closure $fail): void { - if(Str::contains($value, ['@boxmail.lol', '@fireboxmail.lol'])) { + if (Str::contains($value, ['@boxmail.lol', '@fireboxmail.lol'])) { $fail('The validation error message.'); } } diff --git a/app/Rules/AccountName.php b/app/Rules/AccountName.php index 0b1fdf2f15..f0fc1d945b 100644 --- a/app/Rules/AccountName.php +++ b/app/Rules/AccountName.php @@ -15,7 +15,7 @@ class AccountName implements ValidationRule */ public function validate(string $attribute, mixed $value, Closure $fail): void { - if (Str::contains($value, ['<', '>', 'https', 'http://', 'www.', 'Ђ', ' Illuro']) && Str::length($value) < 31) { + if (Str::contains($value, ['<', '>', 'https', 'http://', 'www.', 'Ђ', ' Illuro']) && Str::length($value) < 31) { $fail('Invalid account name.'); } } diff --git a/app/Rules/CalendarFormat.php b/app/Rules/CalendarFormat.php index 67ac1b3ad2..a707fd5a71 100644 --- a/app/Rules/CalendarFormat.php +++ b/app/Rules/CalendarFormat.php @@ -14,7 +14,7 @@ class CalendarFormat implements ValidationRule */ public function validate(string $attribute, mixed $value, Closure $fail): void { - if(preg_match('/^[ymMds\s,-]+$/', $value)) { + if (preg_match('/^[ymMds\s,-]+$/', $value)) { $fail(__('calendars.validators.format')); } } diff --git a/app/Rules/CampaignDelete.php b/app/Rules/CampaignDelete.php index c5341371eb..55a68c01f8 100644 --- a/app/Rules/CampaignDelete.php +++ b/app/Rules/CampaignDelete.php @@ -15,7 +15,7 @@ class CampaignDelete implements ValidationRule */ public function validate(string $attribute, mixed $value, Closure $fail): void { - if(!Str::is(mb_strtolower($value), 'delete')) { + if (!Str::is(mb_strtolower($value), 'delete')) { $fail(__('validation.delete_campaign', ['code' => 'delete'])); } } diff --git a/app/Rules/EntityFileRule.php b/app/Rules/EntityFileRule.php index 77db3367e3..e24a55af76 100644 --- a/app/Rules/EntityFileRule.php +++ b/app/Rules/EntityFileRule.php @@ -19,16 +19,16 @@ public function validate(string $attribute, mixed $value, Closure $fail): void if ($value instanceof UploadedFile && !$value->isValid()) { $fail(__('validation.mimes', ['values' => 'jpg, jpeg, png, gif, webp, pdf, xls(x), csv, mp3, ogg, json'])); } - + // Block any hacking shenanigans if ($this->shouldBlockPhpUpload($value, [])) { $fail(__('validation.mimes', ['values' => 'jpg, jpeg, png, gif, webp, pdf, xls(x), csv, mp3, ogg, json'])); } - + if (empty($value->getPath())) { $fail(__('validation.mimes', ['values' => 'jpg, jpeg, png, gif, webp, pdf, xls(x), csv, mp3, ogg, json'])); } - + $validExtensions = explode(',', 'jpeg,png,jpg,gif,webp,pdf,xls,xlsx,mp3'); if (!in_array($value->guessExtension(), $validExtensions)) { $fail(__('validation.mimes', ['values' => 'jpg, jpeg, png, gif, webp, pdf, xls(x), csv, mp3, ogg, json'])); diff --git a/app/Rules/EntityLink.php b/app/Rules/EntityLink.php index d76b21bb8e..3389478af6 100644 --- a/app/Rules/EntityLink.php +++ b/app/Rules/EntityLink.php @@ -89,10 +89,10 @@ public function validate(string $attribute, mixed $value, Closure $fail): void ->where('access', 1) ->where('action', CampaignPermission::ACTION_READ) ->first(); - + // We don't check for the public role have deny as a permission, this is good enough if (empty($permission)) { - $fail( __('validation.entity_link')); + $fail(__('validation.entity_link')); } } } From 4b4ce5e15d97de24eef112d57a4f858c5db7c2f0 Mon Sep 17 00:00:00 2001 From: Spitfire Date: Mon, 9 Sep 2024 15:13:36 -0600 Subject: [PATCH 3/3] Phpstan fixes --- app/View/Components/Ad.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/View/Components/Ad.php b/app/View/Components/Ad.php index 10adbcc65c..c3a4e09465 100644 --- a/app/View/Components/Ad.php +++ b/app/View/Components/Ad.php @@ -57,11 +57,9 @@ protected function hasAd(): bool return false; } // Parameter to force ads to be displayed - return (bool) (request()->has('_showads')) - + return (bool) (request()->has('_showads')); // Temp workaround for venatus to fix their ads - ; if (isset($this->user)) { // Subscribed users don't have ads if ($this->user->isSubscriber()) {