diff --git a/app-modules/service-management/database/factories/ServiceRequestStatusFactory.php b/app-modules/service-management/database/factories/ServiceRequestStatusFactory.php index 89123744b..f32419ae5 100644 --- a/app-modules/service-management/database/factories/ServiceRequestStatusFactory.php +++ b/app-modules/service-management/database/factories/ServiceRequestStatusFactory.php @@ -52,9 +52,15 @@ public function definition(): array 'classification' => $this->faker->randomElement(SystemServiceRequestClassification::cases()), 'name' => $this->faker->word, 'color' => $this->faker->randomElement(ColumnColorOptions::cases()), + 'is_system_protected' => false, ]; } + public function systemProtected(): self + { + return $this->state(fn (): array => ['is_system_protected' => true]); + } + public function open(): Factory { return $this->state(function (array $attributes) { diff --git a/app-modules/service-management/database/migrations/2024_10_07_175810_add_is_system_protected_column_to_service_request_statuses_table.php b/app-modules/service-management/database/migrations/2024_10_07_175810_add_is_system_protected_column_to_service_request_statuses_table.php new file mode 100644 index 000000000..21fd9bb6d --- /dev/null +++ b/app-modules/service-management/database/migrations/2024_10_07_175810_add_is_system_protected_column_to_service_request_statuses_table.php @@ -0,0 +1,55 @@ + + + Copyright © 2016-2024, Canyon GBS LLC. All rights reserved. + + Aiding App™ is licensed under the Elastic License 2.0. For more details, + see + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Aiding App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + or contact us via email at legal@canyongbs.com. + + +*/ + +use Illuminate\Support\Facades\Schema; +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Database\Migrations\Migration; + +return new class () extends Migration { + public function up(): void + { + Schema::table('service_request_statuses', function (Blueprint $table) { + $table->boolean('is_system_protected')->default(false); + }); + } + + public function down(): void + { + Schema::table('service_request_statuses', function (Blueprint $table) { + $table->dropColumn('is_system_protected'); + }); + } +}; diff --git a/app-modules/service-management/database/migrations/2024_10_07_180708_data_seed_system_protected_new_status_for_service_request_statuses.php b/app-modules/service-management/database/migrations/2024_10_07_180708_data_seed_system_protected_new_status_for_service_request_statuses.php new file mode 100644 index 000000000..22e73e797 --- /dev/null +++ b/app-modules/service-management/database/migrations/2024_10_07_180708_data_seed_system_protected_new_status_for_service_request_statuses.php @@ -0,0 +1,83 @@ + + + Copyright © 2016-2024, Canyon GBS LLC. All rights reserved. + + Aiding App™ is licensed under the Elastic License 2.0. For more details, + see + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Aiding App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + or contact us via email at legal@canyongbs.com. + + +*/ + +use Illuminate\Support\Str; +use Illuminate\Support\Facades\DB; +use Illuminate\Database\Migrations\Migration; + +return new class () extends Migration { + public function up(): void + { + $status = DB::table('service_request_statuses')->where([ + 'name' => 'New', + 'classification' => 'open', + ])->first(); + + if ($status && $status->is_system_protected) { + return; + } + + if ($status) { + DB::table('service_request_statuses') + ->where('name', 'New') + ->where('classification', 'open') + ->update([ + 'is_system_protected' => true, + ]); + + return; + } + + DB::table('service_request_statuses')->insert([ + 'id' => Str::orderedUuid(), + 'classification' => 'open', + 'name' => 'New', + 'color' => 'info', + 'is_system_protected' => true, + 'created_at' => now(), + ]); + } + + public function down(): void + { + DB::table('service_request_statuses') + ->where('name', 'New') + ->where('classification', 'open') + ->update([ + 'is_system_protected' => false, + ]); + } +}; diff --git a/app-modules/service-management/database/seeders/ServiceRequestStatusSeeder.php b/app-modules/service-management/database/seeders/ServiceRequestStatusSeeder.php index 977e2e932..d2d73eb6b 100644 --- a/app-modules/service-management/database/seeders/ServiceRequestStatusSeeder.php +++ b/app-modules/service-management/database/seeders/ServiceRequestStatusSeeder.php @@ -45,14 +45,16 @@ class ServiceRequestStatusSeeder extends Seeder { public function run(): void { + ServiceRequestStatus::query()->createOrFirst([ + 'classification' => SystemServiceRequestClassification::Open, + 'name' => 'New', + 'color' => ColumnColorOptions::Info, + 'is_system_protected' => true, + ]); + ServiceRequestStatus::factory() ->createMany( [ - [ - 'classification' => SystemServiceRequestClassification::Open, - 'name' => 'New', - 'color' => ColumnColorOptions::Info, - ], [ 'classification' => SystemServiceRequestClassification::InProgress, 'name' => 'In-Progress', diff --git a/app-modules/service-management/resources/views/filament/pages/service-request-type-lock-icon.blade.php b/app-modules/service-management/resources/views/filament/pages/service-request-type-lock-icon.blade.php new file mode 100644 index 000000000..513d4a205 --- /dev/null +++ b/app-modules/service-management/resources/views/filament/pages/service-request-type-lock-icon.blade.php @@ -0,0 +1,46 @@ +{{-- + + + Copyright © 2016-2024, Canyon GBS LLC. All rights reserved. + + Aiding App™ is licensed under the Elastic License 2.0. For more details, + see + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Aiding App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + or contact us via email at legal@canyongbs.com. + + +--}} +@php + use App\Features\ServiceRequestStatusSystemProtection; +@endphp + +@if (ServiceRequestStatusSystemProtection::active() && $this->getRecord()?->is_system_protected) + +@endif diff --git a/app-modules/service-management/src/Filament/Resources/ServiceRequestStatusResource/Pages/ListServiceRequestStatuses.php b/app-modules/service-management/src/Filament/Resources/ServiceRequestStatusResource/Pages/ListServiceRequestStatuses.php index 23eaf5b3a..41f7e79e6 100644 --- a/app-modules/service-management/src/Filament/Resources/ServiceRequestStatusResource/Pages/ListServiceRequestStatuses.php +++ b/app-modules/service-management/src/Filament/Resources/ServiceRequestStatusResource/Pages/ListServiceRequestStatuses.php @@ -38,9 +38,13 @@ use Filament\Tables\Table; use Filament\Actions\CreateAction; +use Illuminate\Support\Collection; use Filament\Tables\Actions\EditAction; use Filament\Tables\Actions\ViewAction; use Filament\Tables\Columns\TextColumn; +use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\QueryException; +use Filament\Notifications\Notification; use App\Filament\Tables\Columns\IdColumn; use Filament\Resources\Pages\ListRecords; use Filament\Tables\Filters\TrashedFilter; @@ -83,7 +87,49 @@ public function table(Table $table): Table ]) ->bulkActions([ BulkActionGroup::make([ - DeleteBulkAction::make(), + DeleteBulkAction::make() + ->action(function (DeleteBulkAction $component): void { + $total = 0; + $totalDeleted = 0; + + $component->process(static function (Collection $records) use (&$total, &$totalDeleted) { + $total = $records->count(); + + $records->each(function (Model $record) use (&$totalDeleted) { + try { + $record->delete(); + + $totalDeleted++; + } catch (QueryException $e) { + if (str_contains($e->getMessage(), 'Cannot modify system protected rows')) { + Notification::make() + ->title('Cannot Delete System Protected record') + ->body('A system protected record cannot be deleted.') + ->danger() + ->send(); + } + } + }); + }); + + $notification = Notification::make() + ->title('Service Request Statuses Deleted') + ->body("{$totalDeleted} of {$total} selected service request statuses have been deleted."); + + if ($totalDeleted > 0) { + $notification->success(); + } else { + $notification->danger(); + } + + $notification->send(); + + if ($totalDeleted > 0) { + $component->dispatchSuccessRedirect(); + } else { + $component->dispatchFailureRedirect(); + } + }), ]), ]) ->filters([ diff --git a/app-modules/service-management/src/Filament/Resources/ServiceRequestStatusResource/Pages/ViewServiceRequestStatus.php b/app-modules/service-management/src/Filament/Resources/ServiceRequestStatusResource/Pages/ViewServiceRequestStatus.php index 96aee64d9..d0eb33409 100644 --- a/app-modules/service-management/src/Filament/Resources/ServiceRequestStatusResource/Pages/ViewServiceRequestStatus.php +++ b/app-modules/service-management/src/Filament/Resources/ServiceRequestStatusResource/Pages/ViewServiceRequestStatus.php @@ -38,8 +38,11 @@ use Filament\Actions\EditAction; use Filament\Infolists\Infolist; +use Filament\View\PanelsRenderHook; +use Illuminate\Contracts\View\View; use Filament\Resources\Pages\ViewRecord; use Filament\Infolists\Components\Section; +use Filament\Support\Facades\FilamentView; use Filament\Infolists\Components\TextEntry; use AidingApp\ServiceManagement\Models\ServiceRequestStatus; use AidingApp\ServiceManagement\Filament\Resources\ServiceRequestStatusResource; @@ -48,6 +51,15 @@ class ViewServiceRequestStatus extends ViewRecord { protected static string $resource = ServiceRequestStatusResource::class; + public function boot(): void + { + FilamentView::registerRenderHook( + PanelsRenderHook::PAGE_HEADER_ACTIONS_AFTER, + fn (): View => view('service-management::filament.pages.service-request-type-lock-icon'), + scopes: static::class, + ); + } + public function infolist(Infolist $infolist): Infolist { return $infolist diff --git a/app-modules/service-management/src/Models/ServiceRequestStatus.php b/app-modules/service-management/src/Models/ServiceRequestStatus.php index a36854e9e..e2f7d7cfe 100644 --- a/app-modules/service-management/src/Models/ServiceRequestStatus.php +++ b/app-modules/service-management/src/Models/ServiceRequestStatus.php @@ -57,11 +57,13 @@ class ServiceRequestStatus extends BaseModel implements Auditable 'classification', 'name', 'color', + 'is_system_protected', ]; protected $casts = [ 'classification' => SystemServiceRequestClassification::class, 'color' => ColumnColorOptions::class, + 'is_system_protected' => 'boolean', ]; public function serviceRequests(): HasMany diff --git a/app-modules/service-management/src/Policies/ServiceRequestStatusPolicy.php b/app-modules/service-management/src/Policies/ServiceRequestStatusPolicy.php index eb4562e7a..0480c8f2d 100644 --- a/app-modules/service-management/src/Policies/ServiceRequestStatusPolicy.php +++ b/app-modules/service-management/src/Policies/ServiceRequestStatusPolicy.php @@ -42,6 +42,7 @@ use Illuminate\Support\Facades\Gate; use AidingApp\Contact\Models\Contact; use App\Support\FeatureAccessResponse; +use App\Features\ServiceRequestStatusSystemProtection; use AidingApp\ServiceManagement\Models\ServiceRequestStatus; class ServiceRequestStatusPolicy @@ -87,6 +88,10 @@ public function create(Authenticatable $authenticatable): Response public function update(Authenticatable $authenticatable, ServiceRequestStatus $serviceRequestStatus): Response { + if (ServiceRequestStatusSystemProtection::active() && $serviceRequestStatus->is_system_protected) { + return Response::deny('You cannot update this service request status because it is system protected.'); + } + return $authenticatable->canOrElse( abilities: ['service_request_status.*.update', "service_request_status.{$serviceRequestStatus->id}.update"], denyResponse: 'You do not have permissions to update this service request status.' @@ -95,6 +100,10 @@ public function update(Authenticatable $authenticatable, ServiceRequestStatus $s public function delete(Authenticatable $authenticatable, ServiceRequestStatus $serviceRequestStatus): Response { + if (ServiceRequestStatusSystemProtection::active() && $serviceRequestStatus->is_system_protected) { + return Response::deny('You cannot delete this service request status because it is system protected.'); + } + return $authenticatable->canOrElse( abilities: ['service_request_status.*.delete', "service_request_status.{$serviceRequestStatus->id}.delete"], denyResponse: 'You do not have permissions to delete this service request status.' @@ -111,6 +120,10 @@ public function restore(Authenticatable $authenticatable, ServiceRequestStatus $ public function forceDelete(Authenticatable $authenticatable, ServiceRequestStatus $serviceRequestStatus): Response { + if (ServiceRequestStatusSystemProtection::active() && $serviceRequestStatus->is_system_protected) { + return Response::deny('You cannot delete this service request status because it is system protected.'); + } + if ($serviceRequestStatus->serviceRequests()->exists()) { return Response::deny('You cannot force delete this service request status because it has associated service requests.'); } diff --git a/app-modules/service-management/tests/ServiceRequestStatus/CreateServiceRequestStatusTest.php b/app-modules/service-management/tests/ServiceRequestStatus/CreateServiceRequestStatusTest.php index 9c1f04199..33147913b 100644 --- a/app-modules/service-management/tests/ServiceRequestStatus/CreateServiceRequestStatusTest.php +++ b/app-modules/service-management/tests/ServiceRequestStatus/CreateServiceRequestStatusTest.php @@ -47,8 +47,8 @@ use Illuminate\Validation\Rules\Enum; use function PHPUnit\Framework\assertCount; -use function PHPUnit\Framework\assertEmpty; use function Pest\Laravel\assertDatabaseHas; +use function Pest\Laravel\assertDatabaseMissing; use AidingApp\ServiceManagement\Models\ServiceRequestStatus; use AidingApp\ServiceManagement\Filament\Resources\ServiceRequestStatusResource; @@ -69,7 +69,7 @@ ->call('create') ->assertHasNoFormErrors(); - assertCount(1, ServiceRequestStatus::all()); + assertCount(2, ServiceRequestStatus::all()); assertDatabaseHas(ServiceRequestStatus::class, $request); }); @@ -82,7 +82,7 @@ ->call('create') ->assertHasFormErrors($errors); - assertEmpty(ServiceRequestStatus::all()); + assertDatabaseMissing((new ServiceRequestStatus())->getTable(), CreateServiceRequestStatusRequestFactory::new($data)->create()); })->with( [ 'name missing' => [CreateServiceRequestStatusRequestFactory::new()->without('name'), ['name' => 'required']], @@ -120,7 +120,7 @@ ->call('create') ->assertHasNoFormErrors(); - assertCount(1, ServiceRequestStatus::all()); + assertCount(2, ServiceRequestStatus::all()); assertDatabaseHas(ServiceRequestStatus::class, $request->toArray()); }); @@ -161,7 +161,7 @@ ->call('create') ->assertHasNoFormErrors(); - assertCount(1, ServiceRequestStatus::all()); + assertCount(2, ServiceRequestStatus::all()); assertDatabaseHas(ServiceRequestStatus::class, $request->toArray()); }); diff --git a/app-modules/service-management/tests/ServiceRequestStatus/EditServiceRequestStatusTest.php b/app-modules/service-management/tests/ServiceRequestStatus/EditServiceRequestStatusTest.php index 8030f1727..5a100eee2 100644 --- a/app-modules/service-management/tests/ServiceRequestStatus/EditServiceRequestStatusTest.php +++ b/app-modules/service-management/tests/ServiceRequestStatus/EditServiceRequestStatusTest.php @@ -200,3 +200,43 @@ assertEquals($request['name'], $serviceRequestStatus->fresh()->name); }); + +test('EditServiceRequestStatus is gated with proper system protection access control', function () { + /** @var ServiceRequestStatus $serviceRequestStatus */ + $serviceRequestStatus = ServiceRequestStatus::factory() + ->systemProtected() + ->create(); + + asSuperAdmin() + ->get( + ServiceRequestStatusResource::getUrl('edit', [ + 'record' => $serviceRequestStatus, + ]) + )->assertForbidden(); + + livewire(EditServiceRequestStatus::class, [ + 'record' => $serviceRequestStatus->getRouteKey(), + ]) + ->assertForbidden(); + + $serviceRequestStatus = ServiceRequestStatus::factory() + ->create(); + + asSuperAdmin() + ->get( + ServiceRequestStatusResource::getUrl('edit', [ + 'record' => $serviceRequestStatus, + ]) + )->assertSuccessful(); + + $request = collect(EditServiceRequestStatusRequestFactory::new()->create()); + + livewire(EditServiceRequestStatus::class, [ + 'record' => $serviceRequestStatus->getRouteKey(), + ]) + ->fillForm($request->toArray()) + ->call('save') + ->assertHasNoFormErrors(); + + assertEquals($request['name'], $serviceRequestStatus->fresh()->name); +}); diff --git a/app-modules/service-management/tests/ServiceRequestStatus/ListServiceRequestStatusesTest.php b/app-modules/service-management/tests/ServiceRequestStatus/ListServiceRequestStatusesTest.php index afeda393b..a38311982 100644 --- a/app-modules/service-management/tests/ServiceRequestStatus/ListServiceRequestStatusesTest.php +++ b/app-modules/service-management/tests/ServiceRequestStatus/ListServiceRequestStatusesTest.php @@ -49,6 +49,8 @@ use AidingApp\ServiceManagement\Filament\Resources\ServiceRequestStatusResource; test('The correct details are displayed on the ListServiceRequestStatuses page', function () { + ServiceRequestStatus::query()->truncate(); + $serviceRequestStatuses = ServiceRequestStatus::factory() ->has(ServiceRequest::factory()->count(fake()->randomNumber(1)), 'serviceRequests') ->count(10) diff --git a/app-modules/service-management/tests/ServiceRequestStatus/ViewServiceRequestStatusTest.php b/app-modules/service-management/tests/ServiceRequestStatus/ViewServiceRequestStatusTest.php index 9ae602cea..8727ffdd2 100644 --- a/app-modules/service-management/tests/ServiceRequestStatus/ViewServiceRequestStatusTest.php +++ b/app-modules/service-management/tests/ServiceRequestStatus/ViewServiceRequestStatusTest.php @@ -41,10 +41,12 @@ use App\Settings\LicenseSettings; use function Pest\Laravel\actingAs; +use function Pest\Livewire\livewire; use AidingApp\Contact\Models\Contact; use AidingApp\ServiceManagement\Models\ServiceRequestStatus; use AidingApp\ServiceManagement\Filament\Resources\ServiceRequestStatusResource; +use AidingApp\ServiceManagement\Filament\Resources\ServiceRequestStatusResource\Pages\ViewServiceRequestStatus; test('The correct details are displayed on the ViewServiceRequestStatus page', function () { $serviceRequestStatus = ServiceRequestStatus::factory()->create(); @@ -123,3 +125,31 @@ ]) )->assertSuccessful(); }); + +it('displays the edit action and not the lock when the service request status is not system protected', function () { + $serviceRequestStatus = ServiceRequestStatus::factory()->create(); + + asSuperAdmin(); + + livewire(ViewServiceRequestStatus::class, [ + 'record' => $serviceRequestStatus->getRouteKey(), + ]) + ->assertDontSeeHtml('data-identifier="service_request_type_system_protected"') + ->assertActionVisible('edit') + ->assertActionEnabled('edit'); +}); + +it('displays the lock icon rather than the edit action when the service request status is system protected', function () { + $serviceRequestStatus = ServiceRequestStatus::factory()->create([ + 'is_system_protected' => true, + ]); + + asSuperAdmin(); + + livewire(ViewServiceRequestStatus::class, [ + 'record' => $serviceRequestStatus->getRouteKey(), + ]) + ->assertSeeHtml('data-identifier="service_request_type_system_protected"') + ->assertActionHidden('edit') + ->assertActionDisabled('edit'); +}); diff --git a/app/Features/ServiceRequestStatusSystemProtection.php b/app/Features/ServiceRequestStatusSystemProtection.php new file mode 100644 index 000000000..3a1a3d156 --- /dev/null +++ b/app/Features/ServiceRequestStatusSystemProtection.php @@ -0,0 +1,47 @@ + + + Copyright © 2016-2024, Canyon GBS LLC. All rights reserved. + + Aiding App™ is licensed under the Elastic License 2.0. For more details, + see + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Aiding App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + or contact us via email at legal@canyongbs.com. + + +*/ + +namespace App\Features; + +use App\Support\AbstractFeatureFlag; + +class ServiceRequestStatusSystemProtection extends AbstractFeatureFlag +{ + public function resolve(mixed $scope): mixed + { + return false; + } +} diff --git a/database/migrations/2024_10_07_185927_data_activate_feature_flag_service_request_status_system_protection.php b/database/migrations/2024_10_07_185927_data_activate_feature_flag_service_request_status_system_protection.php new file mode 100644 index 000000000..146c7e681 --- /dev/null +++ b/database/migrations/2024_10_07_185927_data_activate_feature_flag_service_request_status_system_protection.php @@ -0,0 +1,50 @@ + + + Copyright © 2016-2024, Canyon GBS LLC. All rights reserved. + + Aiding App™ is licensed under the Elastic License 2.0. For more details, + see + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Aiding App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + or contact us via email at legal@canyongbs.com. + + +*/ + +use Illuminate\Database\Migrations\Migration; +use App\Features\ServiceRequestStatusSystemProtection; + +return new class () extends Migration { + public function up(): void + { + ServiceRequestStatusSystemProtection::activate(); + } + + public function down(): void + { + ServiceRequestStatusSystemProtection::deactivate(); + } +}; diff --git a/database/migrations/2024_10_07_203357_create_function_to_prevent_modification_of_system_protected_rows.php b/database/migrations/2024_10_07_203357_create_function_to_prevent_modification_of_system_protected_rows.php new file mode 100644 index 000000000..bc98c2b72 --- /dev/null +++ b/database/migrations/2024_10_07_203357_create_function_to_prevent_modification_of_system_protected_rows.php @@ -0,0 +1,68 @@ + + + Copyright © 2016-2024, Canyon GBS LLC. All rights reserved. + + Aiding App™ is licensed under the Elastic License 2.0. For more details, + see + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Aiding App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + or contact us via email at legal@canyongbs.com. + + +*/ + +use Illuminate\Database\Migrations\Migration; +use Tpetry\PostgresqlEnhanced\Support\Facades\Schema; + +return new class () extends Migration { + public function up(): void + { + Schema::createFunctionOrReplace( + name: 'prevent_modification_of_system_protected_rows', + parameters: [], + return: 'TRIGGER', + language: 'plpgsql', + body: << 'invoker', + 'volatility' => 'immutable', + 'parallel' => 'safe', + ] + ); + } + + public function down(): void + { + Schema::dropFunctionIfExists('prevent_modification_of_system_protected_rows'); + } +}; diff --git a/database/migrations/2024_10_07_204633_create_trigger_to_apply_modification_prevention_for_system_protected_service_request_statuses.php b/database/migrations/2024_10_07_204633_create_trigger_to_apply_modification_prevention_for_system_protected_service_request_statuses.php new file mode 100644 index 000000000..74481a374 --- /dev/null +++ b/database/migrations/2024_10_07_204633_create_trigger_to_apply_modification_prevention_for_system_protected_service_request_statuses.php @@ -0,0 +1,61 @@ + + + Copyright © 2016-2024, Canyon GBS LLC. All rights reserved. + + Aiding App™ is licensed under the Elastic License 2.0. For more details, + see + + Notice: + + - You may not provide the software to third parties as a hosted or managed + service, where the service provides users with access to any substantial set of + the features or functionality of the software. + - You may not move, change, disable, or circumvent the license key functionality + in the software, and you may not remove or obscure any functionality in the + software that is protected by the license key. + - You may not alter, remove, or obscure any licensing, copyright, or other notices + of the licensor in the software. Any use of the licensor’s trademarks is subject + to applicable law. + - Canyon GBS LLC respects the intellectual property rights of others and expects the + same in return. Canyon GBS™ and Aiding App™ are registered trademarks of + Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks + vigorously. + - The software solution, including services, infrastructure, and code, is offered as a + Software as a Service (SaaS) by Canyon GBS LLC. + - Use of this software implies agreement to the license terms and conditions as stated + in the Elastic License 2.0. + + For more information or inquiries please visit our website at + or contact us via email at legal@canyongbs.com. + + +*/ + +use Illuminate\Database\Migrations\Migration; +use Tpetry\PostgresqlEnhanced\Schema\Blueprint; +use Tpetry\PostgresqlEnhanced\Support\Facades\Schema; + +return new class () extends Migration { + public function up(): void + { + Schema::table('service_request_statuses', function (Blueprint $table) { + $table->trigger( + name: 'prevent_modification_of_system_protected_rows', + action: 'prevent_modification_of_system_protected_rows()', + fire: 'BEFORE UPDATE OR DELETE', + ) + ->forEachRow() + ->replace(true); + }); + } + + public function down(): void + { + Schema::table('service_request_statuses', function (Blueprint $table) { + $table->dropTriggerIfExists('prevent_modification_of_system_protected_rows'); + }); + } +};