feat(auth): assign default roles on verification (#508)

This commit is contained in:
paranarimasu authored and GitHub committed 2023-01-22 22:26:58 -06:00
1 parent 3d239a624a
commit a97a1663d4
18 files changed
+461 -183

No files matched your search

@@ -0,0 +1,35 @@
<?php
declare(strict_types=1);
use App\Models\Auth\Role;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up(): void
{
Schema::table(Role::TABLE, function (Blueprint $table) {
$table->boolean(Role::ATTRIBUTE_DEFAULT)->default(false);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down(): void
{
Schema::table(Role::TABLE, function (Blueprint $table) {
$table->dropColumn(Role::ATTRIBUTE_DEFAULT);
});
}
};
@@ -2,7 +2,7 @@
declare(strict_types=1);
namespace Database\Seeders;
namespace Database\Seeders\Admin\Setting;
use App\Constants\Config\FlagConstants;
use App\Constants\Config\VideoConstants;
@@ -0,0 +1,77 @@
<?php
declare(strict_types=1);
namespace Database\Seeders\Auth\Role;
use App\Models\Auth\Role;
/**
* Class AdminSeeder.
*/
class AdminSeeder extends RoleSeeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run(): void
{
/** @var Role $role */
$role = Role::findOrCreate('Admin');
// Admin Resources
$this->configureResource($role, 'announcement', $this->extendedCrudAbilities());
$this->configureResource($role, 'dump', $this->extendedCrudAbilities());
$this->configureResource($role, 'setting', $this->crudAbilities());
// Auth Resources
$this->configureResource($role, 'permission', ['view']);
$this->configureResource($role, 'role', $this->crudAbilities());
$this->configureResource($role, 'user', $this->extendedCrudAbilities());
// Billing Resources
$this->configureResource($role, 'balance', $this->extendedCrudAbilities());
$this->configureResource($role, 'transaction', $this->extendedCrudAbilities());
// List Resources
$this->configureResource($role, 'playlist', $this->extendedCrudAbilities());
$this->configureResource($role, 'playlist track', $this->extendedCrudAbilities());
// Wiki Resources
$this->configureResource($role, 'anime', $this->extendedCrudAbilities());
$this->configureResource($role, 'anime synonym', $this->extendedCrudAbilities());
$this->configureResource($role, 'anime theme', $this->extendedCrudAbilities());
$this->configureResource($role, 'anime theme entry', $this->extendedCrudAbilities());
$this->configureResource($role, 'artist', $this->extendedCrudAbilities());
$this->configureResource($role, 'audio', $this->extendedCrudAbilities());
$this->configureResource($role, 'external resource', $this->extendedCrudAbilities());
$this->configureResource($role, 'image', $this->extendedCrudAbilities());
$this->configureResource($role, 'page', $this->extendedCrudAbilities());
$this->configureResource($role, 'series', $this->extendedCrudAbilities());
$this->configureResource($role, 'song', $this->extendedCrudAbilities());
$this->configureResource($role, 'studio', $this->extendedCrudAbilities());
$this->configureResource($role, 'video', $this->extendedCrudAbilities());
$this->configureResource($role, 'video script', $this->extendedCrudAbilities());
// Special Permissions
$this->configureAbilities($role, ['view nova', 'view telescope', 'view horizon', 'bypass api rate limiter']);
}
/**
* Get extended CRUD abilities for soft-delete resource.
*
* @return array<int, string>
*/
protected function extendedCrudAbilities(): array
{
return array_merge(
$this->crudAbilities(),
[
'restore',
'force delete',
],
);
}
}
@@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
namespace Database\Seeders\Auth\Role;
use App\Models\Auth\Role;
/**
* Class PlaylistUserRoleSeeder.
*/
class PlaylistUserRoleSeeder extends RoleSeeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run(): void
{
/** @var Role $role */
$role = Role::findOrCreate('Playlist User');
// List Resources
$this->configureResource($role, 'playlist', $this->extendedCrudAbilities());
$this->configureResource($role, 'playlist track', $this->extendedCrudAbilities());
$role->default = true;
if ($role->isDirty()) {
$role->save();
}
}
}
+88
View File
@@ -0,0 +1,88 @@
<?php
declare(strict_types=1);
namespace Database\Seeders\Auth\Role;
use App\Models\Auth\Permission;
use App\Models\Auth\Role;
use Illuminate\Database\Seeder;
use Illuminate\Support\Arr;
/**
* Class RoleSeeder.
*/
class RoleSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run(): void
{
$this->call(AdminSeeder::class);
$this->call(WikiEditorRoleSeeder::class);
$this->call(WikiViewerRoleSeeder::class);
$this->call(PlaylistUserRoleSeeder::class);
}
/**
* Configure role with resource abilities.
*
* @param Role $role
* @param string $resource
* @param array<int, string> $abilities
* @return void
*/
protected function configureResource(Role $role, string $resource, array $abilities): void
{
$permissions = Arr::map($abilities, fn (string $ability) => Permission::findOrCreate("$ability $resource"));
$role->givePermissionTo($permissions);
}
/**
* Configure role with abilities.
*
* @param Role $role
* @param array<int, string> $abilities
* @return void
*/
protected function configureAbilities(Role $role, array $abilities): void
{
$permissions = Arr::map($abilities, fn (string $ability) => Permission::findOrCreate($ability));
$role->givePermissionTo($permissions);
}
/**
* Get CRUD abilities for resource.
*
* @return array<int, string>
*/
protected function crudAbilities(): array
{
return [
'view',
'create',
'update',
'delete',
];
}
/**
* Get extended CRUD abilities for soft-delete resource.
*
* @return array<int, string>
*/
protected function extendedCrudAbilities(): array
{
return array_merge(
$this->crudAbilities(),
[
'restore',
],
);
}
}
@@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
namespace Database\Seeders\Auth\Role;
use App\Models\Auth\Role;
/**
* Class WikiEditorRoleSeeder.
*/
class WikiEditorRoleSeeder extends RoleSeeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run(): void
{
/** @var Role $role */
$role = Role::findOrCreate('Wiki Editor');
// List Resources
$this->configureResource($role, 'playlist', $this->extendedCrudAbilities());
$this->configureResource($role, 'playlist track', $this->extendedCrudAbilities());
// Wiki Resources
$this->configureResource($role, 'anime', $this->extendedCrudAbilities());
$this->configureResource($role, 'anime synonym', $this->extendedCrudAbilities());
$this->configureResource($role, 'anime theme', $this->extendedCrudAbilities());
$this->configureResource($role, 'anime theme entry', $this->extendedCrudAbilities());
$this->configureResource($role, 'artist', $this->extendedCrudAbilities());
$this->configureResource($role, 'audio', ['view', 'update']);
$this->configureResource($role, 'external resource', $this->extendedCrudAbilities());
$this->configureResource($role, 'image', $this->extendedCrudAbilities());
$this->configureResource($role, 'page', $this->extendedCrudAbilities());
$this->configureResource($role, 'series', $this->extendedCrudAbilities());
$this->configureResource($role, 'song', $this->extendedCrudAbilities());
$this->configureResource($role, 'studio', $this->extendedCrudAbilities());
$this->configureResource($role, 'video', ['view', 'update']);
$this->configureResource($role, 'video script', ['view']);
// Special Permissions
$this->configureAbilities($role, ['view nova']);
}
}
@@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
namespace Database\Seeders\Auth\Role;
use App\Models\Auth\Role;
/**
* Class WikiViewerRoleSeeder.
*/
class WikiViewerRoleSeeder extends RoleSeeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run(): void
{
/** @var Role $role */
$role = Role::findOrCreate('Wiki Viewer');
// List Resources
$this->configureResource($role, 'playlist', $this->extendedCrudAbilities());
$this->configureResource($role, 'playlist track', $this->extendedCrudAbilities());
// Wiki Resources
$this->configureResource($role, 'anime', ['view']);
$this->configureResource($role, 'anime synonym', ['view']);
$this->configureResource($role, 'anime theme', ['view']);
$this->configureResource($role, 'anime theme entry', ['view']);
$this->configureResource($role, 'artist', ['view']);
$this->configureResource($role, 'audio', ['view']);
$this->configureResource($role, 'external resource', ['view']);
$this->configureResource($role, 'image', ['view']);
$this->configureResource($role, 'page', ['view']);
$this->configureResource($role, 'series', ['view']);
$this->configureResource($role, 'song', ['view']);
$this->configureResource($role, 'studio', ['view']);
$this->configureResource($role, 'video', ['view']);
$this->configureResource($role, 'video script', ['view']);
// Special Permissions
$this->configureAbilities($role, ['view nova']);
}
}
@@ -2,7 +2,7 @@
declare(strict_types=1);
namespace Database\Seeders;
namespace Database\Seeders\Billing\Transaction;
use App\Actions\Repositories\Billing\Transaction\ReconcileTransactionRepositoriesAction;
use App\Repositories\DigitalOcean\Billing\DigitalOceanTransactionRepository as DigitalOceanSourceRepository;
+5 -1
View File
@@ -4,6 +4,10 @@ declare(strict_types=1);
namespace Database\Seeders;
use Database\Seeders\Auth\Role\RoleSeeder;
use Database\Seeders\Billing\Transaction\DigitalOceanTransactionSeeder;
use Database\Seeders\Wiki\Audio\AudioSeeder;
use Database\Seeders\Wiki\Video\VideoSeeder;
use Illuminate\Database\Seeder;
/**
@@ -19,7 +23,7 @@ class DatabaseSeeder extends Seeder
public function run(): void
{
$this->call(DigitalOceanTransactionSeeder::class);
$this->call(PermissionSeeder::class);
$this->call(RoleSeeder::class);
$this->call(VideoSeeder::class);
$this->call(AudioSeeder::class);
}
-177
View File
@@ -1,177 +0,0 @@
<?php
declare(strict_types=1);
namespace Database\Seeders;
use App\Models\Auth\Permission;
use App\Models\Auth\Role;
use Illuminate\Database\Seeder;
/**
* Class PermissionSeeder.
*/
class PermissionSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run(): void
{
/** @var Role $admin */
$admin = Role::findOrCreate('Admin');
/** @var Role $wikiEditor */
$wikiEditor = Role::findOrCreate('Wiki Editor');
/** @var Role $wikiViewer */
$wikiViewer = Role::findOrCreate('Wiki Viewer');
// Admin Resources
$this->configureAdminResourcePermissions($admin, 'announcement', true);
$this->configureAdminResourcePermissions($admin, 'balance', true);
$this->configureAdminResourcePermissions($admin, 'dump', true);
$this->configureAdminResourcePermissions($admin, 'permission', false);
$this->configureAdminResourcePermissions($admin, 'role', false);
$this->configureAdminResourcePermissions($admin, 'setting', false);
$this->configureAdminResourcePermissions($admin, 'transaction', true);
$this->configureAdminResourcePermissions($admin, 'user', true);
// Wiki Resources
$this->configureWikiResourcePermissions($admin, $wikiEditor, $wikiViewer, 'anime');
$this->configureWikiResourcePermissions($admin, $wikiEditor, $wikiViewer, 'anime synonym');
$this->configureWikiResourcePermissions($admin, $wikiEditor, $wikiViewer, 'anime theme');
$this->configureWikiResourcePermissions($admin, $wikiEditor, $wikiViewer, 'anime theme entry');
$this->configureWikiResourcePermissions($admin, $wikiEditor, $wikiViewer, 'artist');
$this->configureWikiResourcePermissions($admin, $wikiEditor, $wikiViewer, 'audio');
$this->configureWikiResourcePermissions($admin, $wikiEditor, $wikiViewer, 'external resource');
$this->configureWikiResourcePermissions($admin, $wikiEditor, $wikiViewer, 'image');
$this->configureWikiResourcePermissions($admin, $wikiEditor, $wikiViewer, 'page');
$this->configureWikiResourcePermissions($admin, $wikiEditor, $wikiViewer, 'series');
$this->configureWikiResourcePermissions($admin, $wikiEditor, $wikiViewer, 'song');
$this->configureWikiResourcePermissions($admin, $wikiEditor, $wikiViewer, 'studio');
$this->configureWikiResourcePermissions($admin, $wikiEditor, $wikiViewer, 'video');
$this->configureWikiResourcePermissions($admin, $wikiEditor, $wikiViewer, 'video script');
// List Resources
$this->configureWikiResourcePermissions($admin, $wikiEditor, $wikiViewer, 'playlist');
$this->configureWikiResourcePermissions($admin, $wikiEditor, $wikiViewer, 'playlist track');
// Special Permissions
$this->configureSpecialPermissions($admin, $wikiEditor, $wikiViewer);
}
/**
* Assign permissions for admin resources.
*
* @param Role $admin
* @param string $adminResource
* @param bool $includeSoftDeletion
* @return void
*/
protected function configureAdminResourcePermissions(Role $admin, string $adminResource, bool $includeSoftDeletion): void
{
$permissions = [];
$permissions[] = Permission::findOrCreate("view $adminResource");
if ($adminResource !== 'permission') {
$permissions[] = Permission::findOrCreate("create $adminResource");
$permissions[] = Permission::findOrCreate("update $adminResource");
$permissions[] = Permission::findOrCreate("delete $adminResource");
}
if ($includeSoftDeletion) {
$permissions[] = Permission::findOrCreate("restore $adminResource");
$permissions[] = Permission::findOrCreate("force delete $adminResource");
}
$admin->givePermissionTo($permissions);
}
/**
* Assign permissions for wiki resources.
*
* @param Role $admin
* @param Role $editor
* @param Role $viewer
* @param string $wikiResource
* @return void
*/
protected function configureWikiResourcePermissions(Role $admin, Role $editor, Role $viewer, string $wikiResource): void
{
$adminPermissions = [];
$editorPermissions = [];
$viewerPermissions = [];
$view = Permission::findOrCreate("view $wikiResource");
$adminPermissions[] = $view;
$editorPermissions[] = $view;
$viewerPermissions[] = $view;
$create = Permission::findOrCreate("create $wikiResource");
$adminPermissions[] = $create;
if ($wikiResource !== 'video' && $wikiResource !== 'audio' && $wikiResource !== 'video script') {
$editorPermissions[] = $create;
}
$update = Permission::findOrCreate("update $wikiResource");
$adminPermissions[] = $update;
if ($wikiResource !== 'video script') {
$editorPermissions[] = $update;
}
$delete = Permission::findOrCreate("delete $wikiResource");
$adminPermissions[] = $delete;
if ($wikiResource !== 'video' && $wikiResource !== 'audio' && $wikiResource !== 'video script') {
$editorPermissions[] = $delete;
}
$restore = Permission::findOrCreate("restore $wikiResource");
$adminPermissions[] = $restore;
if ($wikiResource !== 'video' && $wikiResource !== 'audio') {
$editorPermissions[] = $restore;
}
$forceDelete = Permission::findOrCreate("force delete $wikiResource");
$adminPermissions[] = $forceDelete;
$admin->givePermissionTo($adminPermissions);
$editor->givePermissionTo($editorPermissions);
$viewer->givePermissionTo($viewerPermissions);
}
/**
* Configure special permissions.
*
* @param Role $admin
* @param Role $editor
* @param Role $viewer
* @return void
*/
protected function configureSpecialPermissions(Role $admin, Role $editor, Role $viewer): void
{
$adminPermissions = [];
$editorPermissions = [];
$viewerPermissions = [];
$viewNova = Permission::findOrCreate('view nova');
$adminPermissions[] = $viewNova;
$editorPermissions[] = $viewNova;
$viewerPermissions[] = $viewNova;
$viewTelescope = Permission::findOrCreate('view telescope');
$adminPermissions[] = $viewTelescope;
$viewHorizon = Permission::findOrCreate('view horizon');
$adminPermissions[] = $viewHorizon;
$bypassApiRateLimiter = Permission::findOrCreate('bypass api rate limiter');
$adminPermissions[] = $bypassApiRateLimiter;
$admin->givePermissionTo($adminPermissions);
$editor->givePermissionTo($editorPermissions);
$viewer->givePermissionTo($viewerPermissions);
}
}
@@ -2,7 +2,7 @@
declare(strict_types=1);
namespace Database\Seeders;
namespace Database\Seeders\Wiki\Audio;
use App\Actions\Repositories\Wiki\Audio\ReconcileAudioRepositoriesAction;
use App\Repositories\Eloquent\Wiki\AudioRepository as AudioDestinationRepository;
@@ -2,7 +2,7 @@
declare(strict_types=1);
namespace Database\Seeders;
namespace Database\Seeders\Wiki\Audio;
use App\Actions\Models\Wiki\Video\Audio\BackfillAudioAction;
use App\Models\Wiki\Video;
@@ -2,7 +2,7 @@
declare(strict_types=1);
namespace Database\Seeders;
namespace Database\Seeders\Wiki\Video;
use App\Actions\Repositories\Wiki\Video\ReconcileVideoRepositoriesAction;
use App\Repositories\Eloquent\Wiki\VideoRepository as VideoDestinationRepository;