diff --git a/README-abac.md b/README-abac.md index 9d6995c..680e904 100644 --- a/README-abac.md +++ b/README-abac.md @@ -17,6 +17,7 @@ backlog - config e aranacak model klasörü eklenecek ?? AStart a mı eklemek lazım? - abac rule'u eloquent'a - dönüştüren builder ?? şimdilik scope içinden yapıldı +- model'in rule'larını alan servis veya util ? ----- diff --git a/README.md b/README.md index 8b57218..87b3085 100644 --- a/README.md +++ b/README.md @@ -5,15 +5,17 @@ [![GitHub Code Style Action Status](https://img.shields.io/github/workflow/status/aurorawebsoftware/aauth/Check%20&%20fix%20styling?label=code%20style)](https://github.com/aurorawebsoftware/aauth/actions?query=workflow%3A"Check+%26+fix+styling"+branch%3Amain) [![Total Downloads](https://img.shields.io/packagist/dt/aurorawebsoftware/aauth.svg?style=flat-square)](https://packagist.org/packages/aurora/aauth) -Hierarchical Rol-Permission Based **Laravel Auth Package** with Limitless Hierarchical Level of Organizations +Organization Based (OrBAC) , Attibute Based (ABAC) , Rol-Permission (RBAC) Based Authentication Methods Combined **Laravel Auth Package** with Limitless Hierarchical Level of Organizations and Limitless Attribute Conditions # Features - Organization Based Access Controllable (OrBAC) Eloquent Models +- Attribute Based Access Controllable (ABAC) Eloquent Models - Role Based Access Control (RoBAC) - Permissions Based Access Control - Lean & Non-Complex Architecture - PolyMorphic Relationships of Model & Organization Node +- DB Row Level Filtering for the Role with ABAC - Built-in Blade Directives for permission control inside **Blade** files - Mysql, MariaDB, Postgres Support - Community Driven and Open Source Forever @@ -21,7 +23,7 @@ Hierarchical Rol-Permission Based **Laravel Auth Package** with Limitless Hierar --- -[](https://github.com/AuroraWebSoftware/AAuth) +[](https://github.com/AuroraWebSoftware/AAuth) # Installation @@ -88,7 +90,7 @@ return [ ]; ``` -# Main Philosophy +# Main Philosophy of AAuth OrBAC In computer system security, there are several approaches to restrict system access to authorized users. @@ -139,6 +141,12 @@ Principal dynamically *without writing one line of code?* - Canada - ..... +# Main Philosophy of AAuth ABAC + +// todo coming soon .... + + +--- **AAuth may be your first class assistant package.** --- @@ -187,6 +195,9 @@ file's permission['system'] array. an Organization Role. Organization Permissions should be added inside `aauth.php` config file's permission['organization'] array. +## ABAC +// todo coming soon + ## Role Roles are assigned to users. Each User can have multiple roles. @@ -226,6 +237,10 @@ be an organization node and can be access controllable. It means that; Only Authorized User Role can be access the relating model, or in other words, Each role only can access the models which is on Authenticated Sub-Organization Tree of User's Role. +### Model - ABAC rules +// todo coming soon + + # Usage Before using this, please make sure that you published the config files. @@ -283,10 +298,10 @@ $organizationService->createOrganizationScope($data); ``` ### Updating an Organization Scope -the contributors' space +// todo help wanted ### Deleting an Organization Scope -the contributors' space +// todo help wanted ### Creating an Organization Node without Model Relationship @@ -304,10 +319,10 @@ $organizationService->createOrganizationNode($data); ``` ### Updating an Organization Node -the contributors' space +// todo help wanted ### Deleting an Organization Node -the contributors' space +// todo help wanted ## Role Permission Service @@ -341,10 +356,10 @@ $createdRole = $rolePermissionService->createRole($data); ``` ### Updating a Role -... +// todo help wanted ### Deleting a Role -.... +// todo help wanted ### Attaching a Role to a User ```php @@ -389,7 +404,7 @@ $rolePermissionService->attachOrganizationRoleToUser($organizationNode->id, $cre ``` ### Creating a System Role and Attaching to a User -.... +// todo help wanted ## Using AAuth Interface and Trait with Eloquent Models @@ -411,7 +426,11 @@ class ExampleModel extends Model implements AAuthOrganizationNodeInterface } ``` +## Using ABAC Interface and Trait with Eloquent Models +// todo + ## AAuth Service and Facade Methods +// todo ### Current Roles All Permissions current user's selected roles permissions with **AAuth Facade** @@ -444,8 +463,7 @@ $organizationNodes = AAuth::organizationNodes(); ``` ### Get one specified organization node -..... - +// todo help wanted ### Descendant nodes can be checked with this method you can check is a organization node is descendant of another organization node. @@ -469,16 +487,22 @@ $exampleModel = ExampleModel::find(1); $relatedOrganizationModel = $exampleModel->relatedAAuthOrganizationNode() ``` -## Getting allowed Organization Nodes Only. +## Getting authorized Models only. (OrBAC) after adding `AAuthOrganizationNode` trait to your model, you are adding a global scope which filters the permitted data. -Thus you can simply use any eloquent model method without adding anything +Thus, you can simply use any eloquent model method without adding anything ```php ExampleModel::all(); ``` +## Creating Role - ABAC Rules +// todo + +## Getting authorized Models only. (ABAC) +// todo + ## Getting All Model Collection without any access control ```php ExampleModel::withoutGlobalScopes()->all() diff --git a/Readme-todo.md b/Readme-todo.md index fdb5b8a..3bb2735 100644 --- a/Readme-todo.md +++ b/Readme-todo.md @@ -2,10 +2,10 @@ - Facade yerine sadece service provide kullanılabilir mi? aliass? - singleton içinde facade yerine service class olabilir - phpStan problemleri -- pint +- pint, github actions - can fonkisyonlarında yetki 1 kez çekilebilir - Readme contribution - +- ABAC ## Done @@ -35,17 +35,19 @@ - role perm. service validation ve excepiton unit testleri, validation excepitonarlını testti - org. service validation ve excepiton unit testleri, validation excepitonarlını testti - test with coverage -- ABAC - translations - request's ve validations -- github pages ? - test'lerin publish edilmesi ve namespacelerin replace edilmesi - postgress testleri için github actions - laravel gates register policy ## Dökümantasyon - - config'ler - migr. ve seeder'ların çalıştırılması - github pages docs +- ABAC docs + + +## backlog +- github pages ? diff --git a/composer.json b/composer.json index 4718407..78b46d5 100644 --- a/composer.json +++ b/composer.json @@ -18,6 +18,7 @@ "require": { "php": "^8.1", "illuminate/contracts": "^9.0", + "laravel/pint": "^1.2", "spatie/laravel-package-tools": "^1.9.2" }, "require-dev": { diff --git a/config/aauth.php b/config/aauth.php index 8206509..998f714 100644 --- a/config/aauth.php +++ b/config/aauth.php @@ -1,17 +1,18 @@ [ - 'system' => [ - // example system permission - // key => translation - 'edit_something_for_system' => 'aauth/system.edit_something_for_system', - 'create_something_for_system' => 'aauth/system.create_something_for_system', - ], - 'organization' => [ - // example organization permission - 'edit_something_for_organization' => 'aauth/organization.edit_something_for_organization', - 'create_something_for_organization' => 'aauth/organization.create_something_for_organization', - ], + 'system' => [ + // example system permission + // key => translation + 'edit_something_for_system' => 'aauth/system.edit_something_for_system', + 'create_something_for_system' => 'aauth/system.create_something_for_system', ], + 'organization' => [ + // example organization permission + 'edit_something_for_organization' => 'aauth/organization.edit_something_for_organization', + 'create_something_for_organization' => 'aauth/organization.create_something_for_organization', + ], + ], ]; diff --git a/database/migrations/2021_10_18_142336_seed_initial_data.php b/database/migrations/2021_10_18_142336_seed_initial_data.php index 8daeeba..05ec114 100644 --- a/database/migrations/2021_10_18_142336_seed_initial_data.php +++ b/database/migrations/2021_10_18_142336_seed_initial_data.php @@ -1,6 +1,5 @@ id = 1; - $organizationScope->name = "Root Scope"; + $organizationScope->name = 'Root Scope'; $organizationScope->level = 1; - $organizationScope->status = "active"; + $organizationScope->status = 'active'; $organizationScope->save(); - if (config('database.default') == 'pgsql') { DB::select(" SELECT setval(pg_get_serial_sequence('organization_scopes', 'id'), coalesce(max(id)+1, 1), false) @@ -35,8 +31,8 @@ public function up() $on = new OrganizationNode(); $on->id = 1; $on->organization_scope_id = 1; - $on->name = "Root Node"; - $on->path = "1"; + $on->name = 'Root Node'; + $on->path = '1'; $on->save(); if (config('database.default') == 'pgsql') { @@ -52,7 +48,6 @@ public function up() * * @return void */ - public function down() { OrganizationScope::whereId(1)->delete(); diff --git a/database/seeders/SampleDataSeeder.php b/database/seeders/SampleDataSeeder.php index 9a807b6..913bcbb 100644 --- a/database/seeders/SampleDataSeeder.php +++ b/database/seeders/SampleDataSeeder.php @@ -69,7 +69,7 @@ public function run() 'parent_id' => $organizationNode1->id, ] ); - $organizationNode2->path = $organizationNode1->id . '/' . $organizationNode2->id; + $organizationNode2->path = $organizationNode1->id.'/'.$organizationNode2->id; $organizationNode2->save(); $organizationNode3 = OrganizationNode::create( @@ -82,7 +82,7 @@ public function run() 'parent_id' => $organizationNode1->id, ] ); - $organizationNode3->path = $organizationNode1->id . '/' . $organizationNode3->id; + $organizationNode3->path = $organizationNode1->id.'/'.$organizationNode3->id; $organizationNode3->save(); $organizationNode4 = OrganizationNode::create( @@ -95,10 +95,9 @@ public function run() 'parent_id' => $organizationNode2->id, ] ); - $organizationNode4->path = $organizationNode2->path . '/' . $organizationNode4->id; + $organizationNode4->path = $organizationNode2->path.'/'.$organizationNode4->id; $organizationNode4->save(); - $role1 = Role::create([ 'type' => 'system', 'name' => 'System Role 1', @@ -174,7 +173,6 @@ public function run() 'organization_node_id' => $organizationNode4->id, ]); - $systemPermissions = config('aauth.permissions.system'); foreach ($systemPermissions as $key => $val) { @@ -236,14 +234,13 @@ public function run() //loop through the tables foreach ($tables as $table) { - // if the table is not to be ignored then: if (! in_array($table->table_name, $ignores)) { //Get the max id from that table and add 1 to it $seq = DB::table($table->table_name)->max('id') + 1; // alter the sequence to now RESTART WITH the new sequence index from above - DB::select('ALTER SEQUENCE ' . $table->table_name . '_id_seq RESTART WITH ' . $seq); + DB::select('ALTER SEQUENCE '.$table->table_name.'_id_seq RESTART WITH '.$seq); } } } diff --git a/src/AAuth.php b/src/AAuth.php index 7af6f73..e1a5712 100755 --- a/src/AAuth.php +++ b/src/AAuth.php @@ -83,7 +83,7 @@ public function switchableRoles(): array|Collection|\Illuminate\Support\Collecti } /** - * @param int $userId + * @param int $userId * @return array|Collection|\Illuminate\Support\Collection */ public static function switchableRolesStatic(int $userId): array|Collection|\Illuminate\Support\Collection @@ -97,6 +97,7 @@ public static function switchableRolesStatic(int $userId): array|Collection|\Ill /** * Role's all permissions + * * @return array */ public function permissions(): array @@ -130,7 +131,8 @@ public function systemPermissions(): array /** * check if user can - * @param string $permission + * + * @param string $permission * @return bool */ public function can(string $permission): bool @@ -142,8 +144,8 @@ public function can(string $permission): bool } /** - * @param string $permission - * @param string $message + * @param string $permission + * @param string $message * @return void */ public function passOrAbort(string $permission, string $message = 'No Permission'): void @@ -157,9 +159,11 @@ public function passOrAbort(string $permission, string $message = 'No Permission /** * Returns user's current role's authorized organization nodes * if model type is given, returns only this model typed nodes. - * @param bool $includeRootNode - * @param string|null $modelType + * + * @param bool $includeRootNode + * @param string|null $modelType * @return \Illuminate\Support\Collection + * * @throws Throwable */ public function organizationNodes(bool $includeRootNode = false, ?string $modelType = null): \Illuminate\Support\Collection @@ -173,7 +177,7 @@ public function organizationNodes(bool $includeRootNode = false, ?string $modelT throw_unless($rootNode, new InvalidOrganizationNodeException()); $rootNodeChar = $includeRootNode ? '' : '/'; - $query->orWhere('path', 'like', $rootNode->path . $rootNodeChar . '%'); + $query->orWhere('path', 'like', $rootNode->path.$rootNodeChar.'%'); } }) ->when($modelType !== null, function ($query) use ($modelType) { @@ -183,9 +187,11 @@ public function organizationNodes(bool $includeRootNode = false, ?string $modelT /** * checks if current role authorized to access given node id - * @param int $nodeId - * @param string|null $modelType + * + * @param int $nodeId + * @param string|null $modelType * @return OrganizationNode + * * @throws InvalidOrganizationNodeException|Throwable */ public function organizationNode(int $nodeId, ?string $modelType = null): OrganizationNode @@ -208,9 +214,11 @@ public function organizationNode(int $nodeId, ?string $modelType = null): Organi /** * Checks if tree has given child * No permission check. - * @param int $rootNodeId - * @param int $childNodeId + * + * @param int $rootNodeId + * @param int $childNodeId * @return bool + * * @throws Throwable */ public function descendant(int $rootNodeId, int $childNodeId): bool @@ -218,12 +226,12 @@ public function descendant(int $rootNodeId, int $childNodeId): bool $subTreeRootNode = OrganizationNode::find($rootNodeId); throw_unless($subTreeRootNode, new InvalidOrganizationNodeException()); - return OrganizationNode::where('path', 'like', $subTreeRootNode->path . '%') + return OrganizationNode::where('path', 'like', $subTreeRootNode->path.'%') ->where('id', '=', $childNodeId)->exists(); } /** - * @param string $modelType + * @param string $modelType * @return array|null */ public function ABACRules(string $modelType): ?array diff --git a/src/AAuthServiceProvider.php b/src/AAuthServiceProvider.php index 968607a..347d0f5 100644 --- a/src/AAuthServiceProvider.php +++ b/src/AAuthServiceProvider.php @@ -12,7 +12,7 @@ class AAuthServiceProvider extends PackageServiceProvider { /** - * @param Package $package + * @param Package $package * @return void */ public function configurePackage(Package $package): void @@ -23,7 +23,7 @@ public function configurePackage(Package $package): void // ->hasViews() // ->hasMigration() // ->hasCommand(AAuthCommand::class) - ; +; } /** @@ -34,14 +34,14 @@ public function boot(): void parent::boot(); // load packages migrations - $this->loadMigrationsFrom(__DIR__ . '/../database/migrations'); + $this->loadMigrationsFrom(__DIR__.'/../database/migrations'); $this->publishes([ - __DIR__ . '/../database/seeders' => resource_path('../database/seeders'), + __DIR__.'/../database/seeders' => resource_path('../database/seeders'), ], 'aauth-seeders'); $this->publishes([ - __DIR__ . '/../config' => config_path(), + __DIR__.'/../config' => config_path(), ], 'aauth-config'); // todo singleton bind ?? @@ -56,7 +56,7 @@ public function boot(): void return ""; }); Blade::directive('endaauth', function () { - return ""; + return ''; }); } } diff --git a/src/Exceptions/AuthorizationException.php b/src/Exceptions/AuthorizationException.php index cc3b9cb..944f608 100644 --- a/src/Exceptions/AuthorizationException.php +++ b/src/Exceptions/AuthorizationException.php @@ -23,7 +23,7 @@ class AuthorizationException extends Exception /** * Create a new authentication exception. * - * @param string $message + * @param string $message * @param array $guards * @param string|null $redirectTo * @return void diff --git a/src/Exceptions/InvalidLocationScopesException.php b/src/Exceptions/InvalidLocationScopesException.php index c898643..c9d5059 100644 --- a/src/Exceptions/InvalidLocationScopesException.php +++ b/src/Exceptions/InvalidLocationScopesException.php @@ -21,7 +21,7 @@ public function report() /** * Render the exception into an HTTP response. * - * @param Request $request + * @param Request $request * @return Response */ public function render(Request $request): Response|bool diff --git a/src/Exceptions/InvalidOrganizationNodeException.php b/src/Exceptions/InvalidOrganizationNodeException.php index be3a3e0..9416954 100644 --- a/src/Exceptions/InvalidOrganizationNodeException.php +++ b/src/Exceptions/InvalidOrganizationNodeException.php @@ -21,7 +21,7 @@ public function report() /** * Render the exception into an HTTP response. * - * @param Request $request + * @param Request $request * @return Response */ public function render(Request $request): Response|bool diff --git a/src/Exceptions/InvalidOrganizationScopeException.php b/src/Exceptions/InvalidOrganizationScopeException.php index 56ccc5f..873ba1e 100644 --- a/src/Exceptions/InvalidOrganizationScopeException.php +++ b/src/Exceptions/InvalidOrganizationScopeException.php @@ -21,7 +21,7 @@ public function report() /** * Render the exception into an HTTP response. * - * @param Request $request + * @param Request $request * @return Response|bool */ public function render(Request $request): Response|bool diff --git a/src/Exceptions/InvalidRoleException.php b/src/Exceptions/InvalidRoleException.php index f262953..a2309af 100644 --- a/src/Exceptions/InvalidRoleException.php +++ b/src/Exceptions/InvalidRoleException.php @@ -21,7 +21,7 @@ public function report() /** * Render the exception into an HTTP response. * - * @param Request $request + * @param Request $request * @return Response|bool */ public function render(Request $request): Response|bool diff --git a/src/Exceptions/InvalidRoleTypeException.php b/src/Exceptions/InvalidRoleTypeException.php index 3d133bb..490f071 100644 --- a/src/Exceptions/InvalidRoleTypeException.php +++ b/src/Exceptions/InvalidRoleTypeException.php @@ -21,7 +21,7 @@ public function report() /** * Render the exception into an HTTP response. * - * @param Request $request + * @param Request $request * @return Response|bool */ public function render(Request $request): Response|bool diff --git a/src/Exceptions/InvalidUserException.php b/src/Exceptions/InvalidUserException.php index 39254f3..353ced9 100644 --- a/src/Exceptions/InvalidUserException.php +++ b/src/Exceptions/InvalidUserException.php @@ -21,7 +21,7 @@ public function report() /** * Render the exception into an HTTP response. * - * @param Request $request + * @param Request $request * @return Response|bool */ public function render(Request $request): Response|bool diff --git a/src/Exceptions/OrganizationNodeAuthException.php b/src/Exceptions/OrganizationNodeAuthException.php index 0c694a8..276294c 100644 --- a/src/Exceptions/OrganizationNodeAuthException.php +++ b/src/Exceptions/OrganizationNodeAuthException.php @@ -21,7 +21,7 @@ public function report(): void /** * Render the exception into an HTTP response. * - * @param Request $request + * @param Request $request * @return Response|bool */ public function render(Request $request): Response|bool diff --git a/src/Exceptions/OrganizationScopesMismatchException.php b/src/Exceptions/OrganizationScopesMismatchException.php index b834558..e1d8f1c 100644 --- a/src/Exceptions/OrganizationScopesMismatchException.php +++ b/src/Exceptions/OrganizationScopesMismatchException.php @@ -21,7 +21,7 @@ public function report() /** * Render the exception into an HTTP response. * - * @param Request $request + * @param Request $request * @return Response */ public function render(Request $request): Response|bool diff --git a/src/Exceptions/UserHasNoAssignedRoleException.php b/src/Exceptions/UserHasNoAssignedRoleException.php index 1aa0b8c..9b81948 100644 --- a/src/Exceptions/UserHasNoAssignedRoleException.php +++ b/src/Exceptions/UserHasNoAssignedRoleException.php @@ -21,7 +21,7 @@ public function report() /** * Render the exception into an HTTP response. * - * @param Request $request + * @param Request $request * @return Response|bool */ public function render(Request $request): Response|bool diff --git a/src/Facades/AAuth.php b/src/Facades/AAuth.php index 800b246..e987e03 100644 --- a/src/Facades/AAuth.php +++ b/src/Facades/AAuth.php @@ -6,6 +6,7 @@ /** * AAuth Facade + * * @see AuroraWebSoftware * @static switchableRoles(): array|Collection|\Illuminate\Support\Collection * @static permissions(): \Illuminate\Support\Collection|array @@ -13,15 +14,15 @@ * @static systemPermissions(): array|\Illuminate\Support\Collection * @static can(string $string) * @static passOrAbort(string $string, string $message = 'No Permission') + * * @method static organizationNodes(bool $includeRootNode = false, ?string $modelType = null): \Illuminate\Support\Collection * @static organizationNode(int $nodeId, ?string $modelType = null): OrganizationNode|array|Collection|Model * @static descendant(int $rootNodeId, int $childNodeId): bool * @static switchableRolesStatic(int $userId): array|Collection|\Illuminate\Support\Collection + * * @method static currentRole() \AuroraWebSoftware\AAuth\Models\Role|null * @method static ABACRules() array|null - * */ - class AAuth extends Facade { protected static function getFacadeAccessor() diff --git a/src/Http/Requests/UpdateRoleRequest.php b/src/Http/Requests/UpdateRoleRequest.php index ba0c12a..061f12b 100644 --- a/src/Http/Requests/UpdateRoleRequest.php +++ b/src/Http/Requests/UpdateRoleRequest.php @@ -7,12 +7,11 @@ class UpdateRoleRequest extends FormRequest { public static array $rules = [ - 'name' => - [ - 'required', - 'min:5', - 'unique:permissions', - ], + 'name' => [ + 'required', + 'min:5', + 'unique:permissions', + ], ]; /** diff --git a/src/Models/OrganizationNode.php b/src/Models/OrganizationNode.php index b2036fb..a358b0c 100644 --- a/src/Models/OrganizationNode.php +++ b/src/Models/OrganizationNode.php @@ -25,6 +25,7 @@ * @property-read int $assigned_node_count * @property-read bool $deletable * @property-read OrganizationScope $organization_scope + * * @method static Builder|OrganizationNode newModelQuery() * @method static Builder|OrganizationNode newQuery() * @method static Builder|OrganizationNode query() @@ -64,7 +65,6 @@ public function getAssignedNodeCountAttribute(): int /** * @return bool - * */ public function getDeletableAttribute(): bool { diff --git a/src/Models/OrganizationScope.php b/src/Models/OrganizationScope.php index ebe9022..8a9a3f8 100644 --- a/src/Models/OrganizationScope.php +++ b/src/Models/OrganizationScope.php @@ -20,7 +20,9 @@ * @property Carbon|null $created_at * @property Carbon|null $updated_at * @mixin \Eloquent + * * @method static Builder|OrganizationScope whereLevel($value) + * * @property-read bool $deletable * @property-read bool $is_active * @property-read int $node_count @@ -33,6 +35,7 @@ class OrganizationScope extends Model use HasFactory; protected $primaryKey = 'id'; + protected $fillable = ['name', 'level', 'status']; /** diff --git a/src/Models/Role.php b/src/Models/Role.php index 8687112..05b2aec 100644 --- a/src/Models/Role.php +++ b/src/Models/Role.php @@ -20,11 +20,13 @@ * @property Carbon|null $created_at * @property Carbon|null $updated_at * @property int|null $organization_scope_id + * * @method static find($role_id) : Role */ class Role extends Model { use HasFactory; + protected $fillable = ['organization_scope_id', 'type', 'name', 'status']; /** diff --git a/src/Models/RoleModelAbacRule.php b/src/Models/RoleModelAbacRule.php index 73be01d..cf908ee 100644 --- a/src/Models/RoleModelAbacRule.php +++ b/src/Models/RoleModelAbacRule.php @@ -16,14 +16,17 @@ * @property int $role_id * @property Carbon|null $created_at * @property Carbon|null $updated_at + * * @method static find($role_id) : RoleModelAbacRule * @method static where(string $string, string $string1, int $id) */ class RoleModelAbacRule extends Model { use HasFactory; + protected $casts = [ 'rules_json' => 'array', ]; + protected $fillable = ['role_id', 'model_type', 'rules_json']; } diff --git a/src/Models/User.php b/src/Models/User.php index b4c67d1..98f3f23 100644 --- a/src/Models/User.php +++ b/src/Models/User.php @@ -24,6 +24,7 @@ * @property Carbon|null $created_at * @property Carbon|null $updated_at * @mixin Eloquent + * * @property-read \Illuminate\Database\Eloquent\Collection|Role[] $roles * @property-read int|null $roles_count * @property-read \Illuminate\Database\Eloquent\Collection|Role[] $organizational_roles @@ -46,7 +47,6 @@ class User extends Authenticatable implements AAuthUserContract * * @var string[] */ - protected $fillable = [ 'name', 'email', diff --git a/src/Scopes/AAuthABACModelScope.php b/src/Scopes/AAuthABACModelScope.php index d2f1331..9d2cc49 100644 --- a/src/Scopes/AAuthABACModelScope.php +++ b/src/Scopes/AAuthABACModelScope.php @@ -75,7 +75,6 @@ function ($query) use ($rule, $model) { } } - // todo refactor gerekebilir /* foreach ($rules as $key => $rule) { diff --git a/src/Scopes/AAuthOrganizationNodeScope.php b/src/Scopes/AAuthOrganizationNodeScope.php index 59415b3..8c12afd 100644 --- a/src/Scopes/AAuthOrganizationNodeScope.php +++ b/src/Scopes/AAuthOrganizationNodeScope.php @@ -9,8 +9,8 @@ class AAuthOrganizationNodeScope implements \Illuminate\Database\Eloquent\Scope { /** - * @param Builder $builder - * @param Model $model + * @param Builder $builder + * @param Model $model * @return void */ public function apply(Builder $builder, Model $model): void diff --git a/src/Services/OrganizationService.php b/src/Services/OrganizationService.php index ee204c4..727dee9 100644 --- a/src/Services/OrganizationService.php +++ b/src/Services/OrganizationService.php @@ -21,9 +21,11 @@ class OrganizationService { /** * Creates an org. scope with given array - * @param array $organizationScope - * @param bool $withValidation + * + * @param array $organizationScope + * @param bool $withValidation * @return OrganizationScope + * * @throws ValidationException */ public function createOrganizationScope(array $organizationScope, bool $withValidation = true): OrganizationScope @@ -42,10 +44,12 @@ public function createOrganizationScope(array $organizationScope, bool $withVali /** * Updates a Perm. - * @param array $organizationScope - * @param int $id - * @param bool $withValidation + * + * @param array $organizationScope + * @param int $id + * @param bool $withValidation * @return ?OrganizationScope + * * @throws ValidationException */ public function updateOrganizationScope(array $organizationScope, int $id, bool $withValidation = true): ?OrganizationScope @@ -66,7 +70,8 @@ public function updateOrganizationScope(array $organizationScope, int $id, bool /** * deletes perm. - * @param int $id + * + * @param int $id * @return bool|null */ public function deleteOrganizationScope(int $id): ?bool @@ -76,9 +81,11 @@ public function deleteOrganizationScope(int $id): ?bool /** * Creates an org. node with given array - * @param array $organizationNode - * @param bool $withValidation + * + * @param array $organizationNode + * @param bool $withValidation * @return OrganizationNode + * * @throws ValidationException */ public function createOrganizationNode(array $organizationNode, bool $withValidation = true): OrganizationNode @@ -96,19 +103,19 @@ public function createOrganizationNode(array $organizationNode, bool $withValida $parentPath = $this->getPath($organizationNode['parent_id'] ?? null); // add temp path before determine actual path - $organizationNode['path'] = $parentPath . '/?'; + $organizationNode['path'] = $parentPath.'/?'; $organizationNode = OrganizationNode::create($organizationNode); // todo , can be add inside model's created event - $organizationNode->path = $parentPath . $organizationNode->id; + $organizationNode->path = $parentPath.$organizationNode->id; $organizationNode->save(); return $organizationNode; } /** - * @param Model $model - * @param int $parentOrganizationId + * @param Model $model + * @param int $parentOrganizationId * @return OrganizationNode|null */ public function createOrganizationNodeForModel(Model $model, int $parentOrganizationId): ?OrganizationNode @@ -117,7 +124,7 @@ public function createOrganizationNodeForModel(Model $model, int $parentOrganiza } /** - * @param int|null $organizationNodeId + * @param int|null $organizationNodeId * @return string|null */ public function getPath(?int $organizationNodeId): ?string @@ -126,11 +133,11 @@ public function getPath(?int $organizationNodeId): ?string return ''; } - return OrganizationNode::find($organizationNodeId)?->path . '/'; + return OrganizationNode::find($organizationNodeId)?->path.'/'; } /** - * @param int $organizationNodeId + * @param int $organizationNodeId */ public function calculatePath(int $organizationNodeId): void { @@ -138,10 +145,11 @@ public function calculatePath(int $organizationNodeId): void } /** - * @param array $organizationNode - * @param int $id - * @param bool $withValidation + * @param array $organizationNode + * @param int $id + * @param bool $withValidation * @return OrganizationNode|false + * * @throws ValidationException */ public function updateOrganizationNode(array $organizationNode, int $id, bool $withValidation = true): OrganizationNode|bool @@ -158,13 +166,13 @@ public function updateOrganizationNode(array $organizationNode, int $id, bool $w $organizationNodeModel = OrganizationNode::find($id); - $organizationNodeModel->path = $this->getPath($organizationNodeModel->parent_id) . $organizationNodeModel->id; + $organizationNodeModel->path = $this->getPath($organizationNodeModel->parent_id).$organizationNodeModel->id; return $organizationNodeModel->update($organizationNode) ? $organizationNodeModel : false; } /** - * @param int $id + * @param int $id * @return bool */ public function deleteOrganizationNode(int $id): bool diff --git a/src/Services/RolePermissionService.php b/src/Services/RolePermissionService.php index 8840a75..4bc881f 100644 --- a/src/Services/RolePermissionService.php +++ b/src/Services/RolePermissionService.php @@ -23,9 +23,11 @@ class RolePermissionService { /** * Creates a Perm. with given array - * @param array $role - * @param bool $withValidation + * + * @param array $role + * @param bool $withValidation * @return Role + * * @throws ValidationException */ public function createRole(array $role, bool $withValidation = true): Role @@ -45,9 +47,10 @@ public function createRole(array $role, bool $withValidation = true): Role /** * Updates a Perm. - * @param array $role - * @param int $id - * @param bool $withValidation + * + * @param array $role + * @param int $id + * @param bool $withValidation * @return Role|null */ public function updateRole(array $role, int $id, bool $withValidation = true): ?Role @@ -58,7 +61,7 @@ public function updateRole(array $role, int $id, bool $withValidation = true): ? if ($validator->fails()) { $message = implode(' , ', $validator->getMessageBag()->all()); - abort(422, 'Invalid Update Role Request, ' . $message); + abort(422, 'Invalid Update Role Request, '.$message); } } $roleModel = Role::find($id); @@ -68,7 +71,8 @@ public function updateRole(array $role, int $id, bool $withValidation = true): ? /** * deletes the role. - * @param int $id + * + * @param int $id * @return bool|null */ public function deleteRole(int $id): ?bool @@ -78,7 +82,8 @@ public function deleteRole(int $id): ?bool /** * activates the roles - * @param int $roleId + * + * @param int $roleId * @return bool */ public function activateRole(int $roleId): bool @@ -91,7 +96,8 @@ public function activateRole(int $roleId): bool /** * deactivates the roles - * @param int $roleId + * + * @param int $roleId * @return bool */ public function deactivateRole(int $roleId): bool @@ -103,8 +109,8 @@ public function deactivateRole(int $roleId): bool } /** - * @param string|array $permissionOrPermissions - * @param int $roleId + * @param string|array $permissionOrPermissions + * @param int $roleId * @return bool */ public function attachPermissionToRole(string|array $permissionOrPermissions, int $roleId): bool @@ -132,8 +138,8 @@ public function attachPermissionToRole(string|array $permissionOrPermissions, in } /** - * @param string|array $permissions - * @param int $roleId + * @param string|array $permissions + * @param int $roleId * @return bool */ public function detachPermissionFromRole(string|array $permissions, int $roleId): bool @@ -155,7 +161,7 @@ public function detachPermissionFromRole(string|array $permissions, int $roleId) } /** - * @param int $roleId + * @param int $roleId * @return bool */ public function detachAllPermissionsFromRole(int $roleId): bool @@ -170,9 +176,10 @@ public function detachAllPermissionsFromRole(int $roleId): bool } /** - * @param array $permissions - * @param int $roleId + * @param array $permissions + * @param int $roleId * @return bool + * * @throws Throwable */ public function syncPermissionsOfRole(array $permissions, int $roleId): bool @@ -184,13 +191,14 @@ public function syncPermissionsOfRole(array $permissions, int $roleId): bool $detached = $this->detachAllPermissionsFromRole($roleId); $attached = $this->attachPermissionToRole($permissions, $roleId); - return ($attached && $detached); + return $attached && $detached; } /** - * @param int $userId - * @param array $roleIdOrIds + * @param int $userId + * @param array $roleIdOrIds * @return array + * * @throws Throwable */ public function attachSystemRoleToUser(array|int $roleIdOrIds, int $userId): array @@ -213,9 +221,10 @@ public function attachSystemRoleToUser(array|int $roleIdOrIds, int $userId): arr } /** - * @param int $userId - * @param int $roleIdOrIds + * @param int $userId + * @param int $roleIdOrIds * @return int + * * @throws Throwable */ public function detachSystemRoleFromUser(array|int $roleIdOrIds, int $userId): int @@ -236,8 +245,8 @@ public function detachSystemRoleFromUser(array|int $roleIdOrIds, int $userId): i } /** - * @param int $userId - * @param array $roleIds + * @param int $userId + * @param array $roleIds * @return array */ public function syncUserSystemRoles(int $userId, array $roleIds): array @@ -249,10 +258,12 @@ public function syncUserSystemRoles(int $userId, array $roleIds): array /** * it makes organization insert and return the pivot table id's - * @param int $userId - * @param int $roleId - * @param int $organizationNodeId + * + * @param int $userId + * @param int $roleId + * @param int $organizationNodeId * @return bool + * * @throws Throwable */ public function attachOrganizationRoleToUser(int $organizationNodeId, int $roleId, int $userId): bool @@ -277,10 +288,11 @@ public function attachOrganizationRoleToUser(int $organizationNodeId, int $roleI } /** - * @param int $userId - * @param int $roleId - * @param int $organizationNodeId + * @param int $userId + * @param int $roleId + * @param int $organizationNodeId * @return int + * * @throws Throwable */ public function detachOrganizationRoleFromUser(int $userId, int $roleId, int $organizationNodeId): int @@ -300,7 +312,7 @@ public function detachOrganizationRoleFromUser(int $userId, int $roleId, int $or ->where([ 'user_id' => $userId, 'role_id' => $roleId, - 'organization_node_id' => $organizationNodeId,]) + 'organization_node_id' => $organizationNodeId, ]) ->delete(); // todo attach ve sync ile olmayacak gibi direk db query yazmank lazım } diff --git a/src/Utils/ABACUtil.php b/src/Utils/ABACUtil.php index 58b0e81..bdce8e3 100644 --- a/src/Utils/ABACUtil.php +++ b/src/Utils/ABACUtil.php @@ -9,8 +9,9 @@ class ABACUtil { /** - * @param array $abacRules + * @param array $abacRules * @return void + * * @throws Exception */ public static function validateAbacRuleArray(array $abacRules): void @@ -25,8 +26,8 @@ public static function validateAbacRuleArray(array $abacRules): void foreach (ABACCondition::cases() as $condition) { $validationRules[$condition->value] = ['array']; if (array_key_exists($condition->value, $abacRules)) { - $validationRules[$condition->value . '.attribute'] = ['string', 'required']; - $validationRules[$condition->value . '.value'] = ['string', 'required']; + $validationRules[$condition->value.'.attribute'] = ['string', 'required']; + $validationRules[$condition->value.'.value'] = ['string', 'required']; } } @@ -44,8 +45,9 @@ public static function validateAbacRuleArray(array $abacRules): void } /** - * @param string $ruleJson + * @param string $ruleJson * @return void + * * @throws Exception */ public static function validateAbacRuleJson(string $ruleJson): void diff --git a/tests/Pest.php b/tests/Pest.php index a90668a..91e2e6c 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -4,7 +4,6 @@ uses(TestCase::class)->in(__DIR__); - // arrange // act // assert diff --git a/tests/TestCase.php b/tests/TestCase.php index ee81868..97ea314 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -13,7 +13,7 @@ protected function setUp(): void parent::setUp(); Factory::guessFactoryNamesUsing( - fn (string $modelName) => 'AuroraWebSoftware\\AAuth\\Database\\Factories\\' . class_basename($modelName) . 'Factory' + fn (string $modelName) => 'AuroraWebSoftware\\AAuth\\Database\\Factories\\'.class_basename($modelName).'Factory' ); } diff --git a/tests/Unit/AAuthTest.php b/tests/Unit/AAuthTest.php index b743d9a..0efbe6e 100644 --- a/tests/Unit/AAuthTest.php +++ b/tests/Unit/AAuthTest.php @@ -42,7 +42,6 @@ $this->assertEquals($switchableRolesCount, $srCount); }); - test('role can get all permissions', function () { $permissionsCount = count(AAuth::permissions()); @@ -58,12 +57,11 @@ ->and(AAuth::can('create_something_for_organization_k'))->toBeFalse(); }); - test('passOrAbort', function () { + // todo expect(1)->toBeTruthy(); }); - test('can get all permitted organization nodes', function () { $organizationNodeCount = AAuth::organizationNodes()->count(); $actualOrganizationNodeCount = OrganizationNode::where('parent_id', '!=', null)->get()->count(); @@ -82,7 +80,6 @@ expect(1)->toBeTruthy(); }); - test('descendant nodes can be checked', function () { expect(AAuth::descendant(1, 3))->toBeTrue() ->and(AAuth::descendant(1, 2))->toBeTrue() diff --git a/tests/Unit/ABACTest.php b/tests/Unit/ABACTest.php index fab71ca..2be0d3d 100644 --- a/tests/Unit/ABACTest.php +++ b/tests/Unit/ABACTest.php @@ -31,25 +31,24 @@ }); }); - test('can validate abac rule array', function () { $rules1 = [ - "&&" => [ - ["=" => ["attribute" => "name", "value" => "Test Organization Nodeable 2.2"]], - ["=" => ["attribute" => "age", "value" => "19"]], + '&&' => [ + ['=' => ['attribute' => 'name', 'value' => 'Test Organization Nodeable 2.2']], + ['=' => ['attribute' => 'age', 'value' => '19']], ], ]; $rules2 = [ - "&&" => [ - ["=" => ["attribute" => "name", "value" => "Test Organization Nodeable 2.2"]], - ["=" => ["attribute" => "age", "value" => "19"]], + '&&' => [ + ['=' => ['attribute' => 'name', 'value' => 'Test Organization Nodeable 2.2']], + ['=' => ['attribute' => 'age', 'value' => '19']], [ - "&&" => [ - ["=" => ["attribute" => "name", "value" => "Test Organization Nodeable 2.2"]], - ["=" => ["attribute" => "age", "value" => "19"]], + '&&' => [ + ['=' => ['attribute' => 'name', 'value' => 'Test Organization Nodeable 2.2']], + ['=' => ['attribute' => 'age', 'value' => '19']], ], ], ], @@ -124,21 +123,19 @@ 2 ); - // 1 - 2 equals $rules1 = [ - "&&" => [ - ["=" => ["attribute" => "name", "value" => "Test Organization Nodeable 2.2"]], - ["=" => ["attribute" => "age", "value" => "19"]], + '&&' => [ + ['=' => ['attribute' => 'name', 'value' => 'Test Organization Nodeable 2.2']], + ['=' => ['attribute' => 'age', 'value' => '19']], ], ]; - $dataRule = [ 'role_id' => 3, 'model_type' => OrganizationNodeable::getModelType(), - "rules_json" => $rules1, + 'rules_json' => $rules1, ]; $roleModelAbacRuleModelInstance = RoleModelAbacRule::create($dataRule); @@ -147,12 +144,11 @@ // 1 end - // 2 - greater then $rules2 = [ - "&&" => [ - [">" => ["attribute" => "age", "value" => "19"]], + '&&' => [ + ['>' => ['attribute' => 'age', 'value' => '19']], ], ]; @@ -162,12 +158,11 @@ $this->assertEquals(3, OrganizationNodeable::count()); // 2 end - // 3 - greater than and equals to $rules3 = [ - "&&" => [ - [">=" => ["attribute" => "age", "value" => "19"]], + '&&' => [ + ['>=' => ['attribute' => 'age', 'value' => '19']], ], ]; @@ -177,12 +172,11 @@ $this->assertEquals(5, OrganizationNodeable::count()); // 3 end - // 3 - like $rules3 = [ - "&&" => [ - ["like" => ["attribute" => "name", "value" => "%2.%"]], + '&&' => [ + ['like' => ['attribute' => 'name', 'value' => '%2.%']], ], ]; @@ -192,13 +186,12 @@ $this->assertEquals(5, OrganizationNodeable::count()); // 3 end - // 4 - 2 like $rules4 = [ - "&&" => [ - ["like" => ["attribute" => "name", "value" => "%2.%"]], - ["like" => ["attribute" => "name", "value" => "%3.%"]], + '&&' => [ + ['like' => ['attribute' => 'name', 'value' => '%2.%']], + ['like' => ['attribute' => 'name', 'value' => '%3.%']], ], ]; @@ -211,9 +204,9 @@ // 5 - like and equal $rules5 = [ - "&&" => [ - ["like" => ["attribute" => "name", "value" => "%2.%"]], - ["=" => ["attribute" => "age", "value" => "19"]], + '&&' => [ + ['like' => ['attribute' => 'name', 'value' => '%2.%']], + ['=' => ['attribute' => 'age', 'value' => '19']], ], ]; @@ -225,30 +218,27 @@ // todo not_equal,nested and - // 20 - like or equal $rules20 = [ - "||" => [ - ["like" => ["attribute" => "name", "value" => "%3.%"]], - ["=" => ["attribute" => "age", "value" => "21"]], + '||' => [ + ['like' => ['attribute' => 'name', 'value' => '%3.%']], + ['=' => ['attribute' => 'age', 'value' => '21']], ], ]; $roleModelAbacRuleModelInstance->rules_json = $rules20; $roleModelAbacRuleModelInstance->save(); - $this->assertEquals(2, OrganizationNodeable::count()); // 20 end - // 21 - greater or equal $rules21 = [ - "||" => [ - [">" => ["attribute" => "age", "value" => "21"]], - ["=" => ["attribute" => "age", "value" => "19"]], + '||' => [ + ['>' => ['attribute' => 'age', 'value' => '21']], + ['=' => ['attribute' => 'age', 'value' => '19']], ], ]; @@ -261,11 +251,11 @@ // 22 - nested (or) and (and) $rules22 = [ - "||" => [ - ["like" => ["attribute" => "name", "value" => "%3.%"]], - "&&" => [ - [">=" => ["attribute" => "age", "value" => "20"]], - ["<=" => ["attribute" => "age", "value" => "21"]], + '||' => [ + ['like' => ['attribute' => 'name', 'value' => '%3.%']], + '&&' => [ + ['>=' => ['attribute' => 'age', 'value' => '20']], + ['<=' => ['attribute' => 'age', 'value' => '21']], ], ], ]; diff --git a/tests/Unit/OrganizationServiceTest.php b/tests/Unit/OrganizationServiceTest.php index 44a23dd..fced745 100644 --- a/tests/Unit/OrganizationServiceTest.php +++ b/tests/Unit/OrganizationServiceTest.php @@ -109,7 +109,6 @@ $createdCount = OrganizationNode::whereName($data['name'])->count(); $this->assertEquals(1, $createdCount); - $data = [ 'name' => 'Updated Org Node 2', 'organization_scope_id' => $os->id, diff --git a/tests/Unit/RolePermissionServiceTest.php b/tests/Unit/RolePermissionServiceTest.php index 4eedbc9..f04b9cc 100644 --- a/tests/Unit/RolePermissionServiceTest.php +++ b/tests/Unit/RolePermissionServiceTest.php @@ -33,7 +33,6 @@ $createdCount = Role::whereName($data['name'])->count(); $this->assertEquals(1, $createdCount); - $data = [ 'organization_scope_id' => $organizationScope->id, 'type' => 'organization', @@ -83,12 +82,10 @@ $this->service->attachPermissionToRole($permissionName, $role->id); expect(AAuth::can($permissionName))->toBeTrue(); - $this->service->detachPermissionFromRole($permissionName, $role->id, ); + $this->service->detachPermissionFromRole($permissionName, $role->id); expect(AAuth::can($permissionName))->toBeFalse(); }); - - test('can sync permission of role', function () { $role = Role::whereName('System Role 1')->first(); $permissionName1 = 'test_permission1'; @@ -139,7 +136,6 @@ expect($contains)->toBeFalse(); }); - test('can attach organization role to user and detach from user', function () { $organizationScope = OrganizationScope::whereName('Root Scope')->first(); $organizationNode = OrganizationNode::whereName('Root Node')->first();