permissions refactoring
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Enums\Permission;
|
||||
use App\Models\PermissionAssignment;
|
||||
use App\Models\Project;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* @extends Factory<PermissionAssignment>
|
||||
*/
|
||||
class PermissionAssignmentFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'permission' => Permission::ProjectRead->value,
|
||||
'assignee_id' => User::factory(),
|
||||
'assignee_type' => (new User)->getMorphClass(),
|
||||
'scope_id' => Project::factory(),
|
||||
'scope_type' => (new Project)->getMorphClass(),
|
||||
];
|
||||
}
|
||||
|
||||
public function forAssignee(Model $assignee): static
|
||||
{
|
||||
return $this->state(fn (): array => [
|
||||
'assignee_id' => $assignee->getKey(),
|
||||
'assignee_type' => $assignee->getMorphClass(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function forScope(Model $scope): static
|
||||
{
|
||||
return $this->state(fn (): array => [
|
||||
'scope_id' => $scope->getKey(),
|
||||
'scope_type' => $scope->getMorphClass(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function global(): static
|
||||
{
|
||||
return $this->state(fn (): array => [
|
||||
'scope_id' => null,
|
||||
'scope_type' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
public function permission(Permission $permission): static
|
||||
{
|
||||
return $this->state(fn (): array => [
|
||||
'permission' => $permission->value,
|
||||
]);
|
||||
}
|
||||
|
||||
public function globalAdmin(): static
|
||||
{
|
||||
return $this->global()->permission(Permission::GlobalAdmin);
|
||||
}
|
||||
|
||||
public function projectAdmin(): static
|
||||
{
|
||||
return $this->permission(Permission::ProjectAdmin);
|
||||
}
|
||||
|
||||
public function projectRead(): static
|
||||
{
|
||||
return $this->permission(Permission::ProjectRead);
|
||||
}
|
||||
|
||||
public function projectWrite(): static
|
||||
{
|
||||
return $this->permission(Permission::ProjectWrite);
|
||||
}
|
||||
|
||||
public function teamAdmin(): static
|
||||
{
|
||||
return $this->permission(Permission::TeamAdmin);
|
||||
}
|
||||
|
||||
public function teamInvite(): static
|
||||
{
|
||||
return $this->permission(Permission::TeamInvite);
|
||||
}
|
||||
|
||||
public function teamManage(): static
|
||||
{
|
||||
return $this->permission(Permission::TeamManage);
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\PermissionAssignment;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
@@ -28,7 +29,6 @@ class UserFactory extends Factory
|
||||
'name' => fake()->name(),
|
||||
'email' => fake()->unique()->safeEmail(),
|
||||
'email_verified_at' => now(),
|
||||
'is_admin' => false,
|
||||
'password' => static::$password ??= Hash::make('password'),
|
||||
'remember_token' => Str::random(10),
|
||||
'two_factor_secret' => null,
|
||||
@@ -64,8 +64,11 @@ class UserFactory extends Factory
|
||||
*/
|
||||
public function admin(): static
|
||||
{
|
||||
return $this->state(fn (array $attributes) => [
|
||||
'is_admin' => true,
|
||||
]);
|
||||
return $this->afterCreating(function (User $user): void {
|
||||
PermissionAssignment::factory()
|
||||
->forAssignee($user)
|
||||
->globalAdmin()
|
||||
->create();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->boolean('is_admin')->default(false)->after('email_verified_at');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->dropColumn('is_admin');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -1,31 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('project_team_permissions', function (Blueprint $table) {
|
||||
$table->foreignId('project_id')->constrained()->cascadeOnDelete();
|
||||
$table->foreignId('team_id')->constrained()->cascadeOnDelete();
|
||||
$table->string('permission');
|
||||
$table->timestamps();
|
||||
|
||||
$table->primary(['project_id', 'team_id', 'permission']);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('project_team_permissions');
|
||||
}
|
||||
};
|
||||
@@ -1,31 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('project_user_permissions', function (Blueprint $table) {
|
||||
$table->foreignId('project_id')->constrained()->cascadeOnDelete();
|
||||
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
|
||||
$table->string('permission');
|
||||
$table->timestamps();
|
||||
|
||||
$table->primary(['project_id', 'user_id', 'permission']);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('project_user_permissions');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('permission_assignments', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->string('permission', 50);
|
||||
$table->string('assignee_type', 32);
|
||||
$table->unsignedBigInteger('assignee_id');
|
||||
$table->string('scope_type', 32)->nullable();
|
||||
$table->unsignedBigInteger('scope_id')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['assignee_type', 'assignee_id']);
|
||||
$table->index(['scope_type', 'scope_id']);
|
||||
$table->unique(['permission', 'assignee_type', 'assignee_id', 'scope_type', 'scope_id'], 'permission_assignments_unique');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('permission_assignments');
|
||||
}
|
||||
};
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Actions\ProjectPermissions\ProjectPermissionService;
|
||||
use App\Enums\Permission;
|
||||
use App\Models\PermissionAssignment;
|
||||
use App\Models\Project;
|
||||
use App\Models\Team;
|
||||
use App\Models\User;
|
||||
@@ -15,28 +16,33 @@ class ProjectAccessSeeder extends Seeder
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
$projectPermissionService = app(ProjectPermissionService::class);
|
||||
|
||||
$projects = Project::query()->get();
|
||||
$admins = User::query()
|
||||
->where('is_admin', true)
|
||||
->get();
|
||||
|
||||
foreach ($admins as $admin) {
|
||||
foreach ($projects as $project) {
|
||||
$projectPermissionService->grantAllProjectPermissions($project, $admin);
|
||||
}
|
||||
}
|
||||
|
||||
$coreProject = Project::query()->where('key', 'CORE')->first();
|
||||
$deliveryTeam = Team::query()->where('name', 'Delivery Team')->first();
|
||||
$platformTeam = Team::query()->where('name', 'Platform Team')->first();
|
||||
$testUser = User::query()->where('email', 'test@example.com')->first();
|
||||
|
||||
if ($coreProject !== null && $platformTeam !== null) {
|
||||
$projectPermissionService->syncTeamPermissions($coreProject, $platformTeam, [
|
||||
'create',
|
||||
'edit',
|
||||
'view',
|
||||
]);
|
||||
PermissionAssignment::factory()
|
||||
->forAssignee($platformTeam)
|
||||
->forScope($coreProject)
|
||||
->projectWrite()
|
||||
->create();
|
||||
}
|
||||
|
||||
if ($platformTeam !== null && $testUser !== null) {
|
||||
PermissionAssignment::factory()
|
||||
->forAssignee($testUser)
|
||||
->forScope($platformTeam)
|
||||
->teamManage()
|
||||
->create();
|
||||
}
|
||||
|
||||
if ($deliveryTeam !== null && $testUser !== null) {
|
||||
PermissionAssignment::factory()
|
||||
->forAssignee($testUser)
|
||||
->forScope($deliveryTeam)
|
||||
->permission(Permission::TeamInvite)
|
||||
->create();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Enums\Permission;
|
||||
use App\Models\PermissionAssignment;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
@@ -12,16 +14,27 @@ class UserSeeder extends Seeder
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
User::factory()->admin()->create([
|
||||
$admin = User::factory()->create([
|
||||
'name' => 'Admin User',
|
||||
'email' => 'admin@kanbangit.test',
|
||||
]);
|
||||
|
||||
User::factory()->create([
|
||||
PermissionAssignment::factory()
|
||||
->forAssignee($admin)
|
||||
->globalAdmin()
|
||||
->create();
|
||||
|
||||
$testUser = User::factory()->create([
|
||||
'name' => 'Test User',
|
||||
'email' => 'test@example.com',
|
||||
]);
|
||||
|
||||
PermissionAssignment::factory()
|
||||
->forAssignee($testUser)
|
||||
->global()
|
||||
->permission(Permission::ProjectCreate)
|
||||
->create();
|
||||
|
||||
User::factory(8)->create();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user