From ac4fd86ab30d724e2bcc7bd19c7d966a181cdaa2 Mon Sep 17 00:00:00 2001 From: denisdulici Date: Thu, 6 Feb 2020 17:08:20 +0300 Subject: [PATCH] improved permissions trait --- app/Listeners/Update/V20/Version200.php | 5 +- app/Traits/Permissions.php | 279 +++++++++++++++--- app/Utilities/Installer.php | 4 +- app/Utilities/Reports.php | 7 +- app/Utilities/Widgets.php | 7 +- database/seeds/{Roles.php => Permissions.php} | 8 +- .../module/Commands/InstallCommand.php | 83 +----- 7 files changed, 262 insertions(+), 131 deletions(-) rename database/seeds/{Roles.php => Permissions.php} (97%) diff --git a/app/Listeners/Update/V20/Version200.php b/app/Listeners/Update/V20/Version200.php index 05cd55efa..ec4c428a0 100644 --- a/app/Listeners/Update/V20/Version200.php +++ b/app/Listeners/Update/V20/Version200.php @@ -774,7 +774,7 @@ class Version200 extends Listener public function updatePermissions() { - $this->attachPermissions([ + $this->attachPermissionsByRoleNames([ 'admin' => [ 'common-dashboards' => 'c,r,u,d', 'common-reports' => 'c,r,u,d', @@ -833,7 +833,7 @@ class Version200 extends Listener ], ]); - $this->detachPermissions([ + $this->detachPermissionsByRoleNames([ 'admin' => [ 'read-modules-token', 'update-modules-token', @@ -970,6 +970,7 @@ class Version200 extends Listener 'config/menus.php', 'config/modules.php', 'docker-compose.yml', + 'database/seeds/Roles.php', 'Dockerfile', 'modules/PaypalStandard/Http/Controllers/PaypalStandard.php', 'modules/PaypalStandard/Http/routes.php', diff --git a/app/Traits/Permissions.php b/app/Traits/Permissions.php index 554ae5893..02a68a4ac 100644 --- a/app/Traits/Permissions.php +++ b/app/Traits/Permissions.php @@ -4,6 +4,8 @@ namespace App\Traits; use App\Models\Auth\Permission; use App\Models\Auth\Role; +use App\Utilities\Reports; +use App\Utilities\Widgets; use Illuminate\Support\Str; trait Permissions @@ -18,46 +20,41 @@ trait Permissions ]; } - public function attachPermissions($roles) + public function attachPermissionsByRoleNames($roles) { - $actions_map = collect($this->getActionsMap()); - foreach ($roles as $role_name => $permissions) { - $role_display_name = Str::title($role_name); + $role = $this->createRole($role_name); - $role = Role::firstOrCreate([ - 'name' => $role_name, - ], [ - 'display_name' => $role_display_name, - 'description' => $role_display_name, - ]); - - foreach ($permissions as $page => $action_list) { - $actions = explode(',', $action_list); - - foreach ($actions as $short_action) { - $action = $actions_map->get($short_action); - - $display_name = Str::title($action . ' ' . str_replace('-', ' ', $page)); - - $permission = Permission::firstOrCreate([ - 'name' => $action . '-' . $page, - ], [ - 'display_name' => $display_name, - 'description' => $display_name, - ]); - - if ($role->hasPermission($permission->name)) { - continue; - } - - $role->attachPermission($permission); - } + foreach ($permissions as $id => $permission) { + $this->attachPermissionsByAction($role, $id, $permission); } } } - public function detachPermissions($roles) + public function attachPermissionsToAdminRoles($permissions) + { + $this->attachPermissionsToAllRoles($permissions, 'read-admin-panel'); + } + + public function attachPermissionsToPortalRoles($permissions) + { + $this->attachPermissionsToAllRoles($permissions, 'read-client-portal'); + } + + public function attachPermissionsToAllRoles($permissions, $require = 'read-admin-panel') + { + $roles = Role::all()->filter(function ($r) use ($require) { + return $require ? $r->hasPermission($require) : true; + }); + + foreach ($roles as $role) { + foreach ($permissions as $permission) { + $this->attachPermission($role, $permission); + } + } + } + + public function detachPermissionsByRoleNames($roles) { foreach ($roles as $role_name => $permissions) { $role = Role::where('name', $role_name)->first(); @@ -67,14 +64,7 @@ trait Permissions } foreach ($permissions as $permission_name) { - $permission = Permission::where('name', $permission_name)->first(); - - if (empty($permission)) { - continue; - } - - $role->detachPermission($permission); - $permission->delete(); + $this->detachPermission($role, $permission_name); } } } @@ -94,7 +84,7 @@ trait Permissions } $new_name = $action . '-' . $new; - $new_display_name = Str::title(str_replace('-', ' ', $new_name)); + $new_display_name = $this->getPermissionDisplayName($new_name); $permission->update([ 'name' => $new_name, @@ -103,4 +93,209 @@ trait Permissions } } } + + public function attachDefaultModulePermissions($module, $require = 'read-admin-panel') + { + $this->attachModuleReportPermissions($module, $require); + + $this->attachModuleWidgetPermissions($module, $require); + + $this->attachModuleSettingPermissions($module, $require); + } + + public function attachModuleReportPermissions($module, $require = 'read-admin-panel') + { + if (is_string($module)) { + $module = module($module); + } + + if (empty($module->get('reports'))) { + return; + } + + $permissions = []; + + foreach ($module->get('reports') as $class) { + if (!class_exists($class)) { + continue; + } + + $permissions[] = $this->createModuleReportPermission($module, $class); + } + + $this->attachPermissionsToAllRoles($permissions, $require); + } + + public function attachModuleWidgetPermissions($module, $require = 'read-admin-panel') + { + if (is_string($module)) { + $module = module($module); + } + + if (empty($module->get('widgets'))) { + return; + } + + $permissions = []; + + foreach ($module->get('widgets') as $class) { + if (!class_exists($class)) { + continue; + } + + $permissions[] = $this->createModuleWidgetPermission($module, $class); + } + + $this->attachPermissionsToAllRoles($permissions, $require); + } + + public function attachModuleSettingPermissions($module, $require = 'read-admin-panel') + { + if (is_string($module)) { + $module = module($module); + } + + if (empty($module->get('settings'))) { + return; + } + + $permissions = []; + + $permissions[] = $this->createModuleSettingPermission($module, 'read'); + $permissions[] = $this->createModuleSettingPermission($module, 'update'); + + $this->attachPermissionsToAllRoles($permissions, $require); + } + + public function createModuleReportPermission($module, $class) + { + if (is_string($module)) { + $module = module($module); + } + + if (!class_exists($class)) { + return; + } + + $name = Reports::getPermission($class); + $display_name = 'Read ' . $module->getName() . ' Reports ' . Reports::getDefaultName($class); + + return $this->createPermission($name, $display_name); + } + + public function createModuleWidgetPermission($module, $class) + { + if (is_string($module)) { + $module = module($module); + } + + if (!class_exists($class)) { + return; + } + + $name = Widgets::getPermission($class); + $display_name = 'Read ' . $module->getName() . ' Widgets ' . Widgets::getDefaultName($class); + + return $this->createPermission($name, $display_name); + } + + public function createModuleSettingPermission($module, $action) + { + if (is_string($module)) { + $module = module($module); + } + + $name = $action . '-' . $module->getAlias() . '-settings'; + $display_name = Str::title($action) . ' ' . $module->getName() . ' Settings'; + + return $this->createPermission($name, $display_name); + } + + public function createRole($name, $display_name = null, $description = null) + { + $display_name = $display_name ?? Str::title($name); + + return Role::firstOrCreate([ + 'name' => $name, + ], [ + 'display_name' => $display_name, + 'description' => $description ?? $display_name, + ]); + } + + public function createPermission($name, $display_name = null, $description = null) + { + $display_name = $display_name ?? $this->getPermissionDisplayName($name); + + return Permission::firstOrCreate([ + 'name' => $name, + ], [ + 'display_name' => $display_name, + 'description' => $description ?? $display_name, + ]); + } + + public function attachPermission($role, $permission) + { + if (is_string($permission)) { + $permission = $this->createPermission($permission); + } + + if ($role->hasPermission($permission->name)) { + return; + } + + $role->attachPermission($permission); + } + + public function detachPermission($role, $permission) + { + if (is_string($role)) { + $role = Role::where('name', $role)->first(); + } + + if (empty($role)) { + return; + } + + if (is_string($permission)) { + $permission = Permission::where('name', $permission)->first(); + } + + if (empty($permission)) { + return; + } + + $role->detachPermission($permission); + $permission->delete(); + } + + public function isActionList($permission) + { + if (!is_string($permission)) { + return false; + } + + return (strlen($permission) == '1') || Str::contains($permission, ','); + } + + public function attachPermissionsByAction($role, $page, $action_list) + { + $actions_map = collect($this->getActionsMap()); + + $actions = explode(',', $action_list); + + foreach ($actions as $short_action) { + $action = $actions_map->get($short_action); + + $name = $action . '-' . $page; + + $this->attachPermission($role, $name); + } + } + + public function getPermissionDisplayName($name) + { + return Str::title(str_replace('-', ' ', $name)); + } } diff --git a/app/Utilities/Installer.php b/app/Utilities/Installer.php index 40c12794c..6956e150f 100644 --- a/app/Utilities/Installer.php +++ b/app/Utilities/Installer.php @@ -151,8 +151,8 @@ class Installer // Create tables Artisan::call('migrate', ['--force' => true]); - // Create Roles - Artisan::call('db:seed', ['--class' => 'Database\Seeds\Roles', '--force' => true]); + // Create Permissions + Artisan::call('db:seed', ['--class' => 'Database\Seeds\Permissions', '--force' => true]); return true; } diff --git a/app/Utilities/Reports.php b/app/Utilities/Reports.php index 67124872c..8e6b26727 100644 --- a/app/Utilities/Reports.php +++ b/app/Utilities/Reports.php @@ -35,7 +35,7 @@ class Reports continue; } - $classes[$class] = (new $class())->getDefaultName(); + $classes[$class] = static::getDefaultName($class); } return $classes; @@ -80,4 +80,9 @@ class Reports return str_replace('--', '-', $permission); } + + public static function getDefaultName($class) + { + return (new $class())->getDefaultName(); + } } diff --git a/app/Utilities/Widgets.php b/app/Utilities/Widgets.php index 6a023d410..2038e114f 100644 --- a/app/Utilities/Widgets.php +++ b/app/Utilities/Widgets.php @@ -39,7 +39,7 @@ class Widgets continue; } - $classes[$class] = (new $class())->getDefaultName(); + $classes[$class] = static::getDefaultName($class); } return $classes; @@ -112,4 +112,9 @@ class Widgets return str_replace('--', '-', $permission); } + + public static function getDefaultName($class) + { + return (new $class())->getDefaultName(); + } } diff --git a/database/seeds/Roles.php b/database/seeds/Permissions.php similarity index 97% rename from database/seeds/Roles.php rename to database/seeds/Permissions.php index 3283809fe..0225d6811 100644 --- a/database/seeds/Roles.php +++ b/database/seeds/Permissions.php @@ -2,12 +2,12 @@ namespace Database\Seeds; use App\Abstracts\Model; -use App\Traits\Permissions; +use App\Traits\Permissions as Helper; use Illuminate\Database\Seeder; -class Roles extends Seeder +class Permissions extends Seeder { - use Permissions; + use Helper; /** * Run the database seeds. @@ -144,6 +144,6 @@ class Roles extends Seeder ] ]; - $this->attachPermissions($rows); + $this->attachPermissionsByRoleNames($rows); } } diff --git a/overrides/akaunting/module/Commands/InstallCommand.php b/overrides/akaunting/module/Commands/InstallCommand.php index 0257108db..f252762df 100644 --- a/overrides/akaunting/module/Commands/InstallCommand.php +++ b/overrides/akaunting/module/Commands/InstallCommand.php @@ -2,18 +2,17 @@ namespace Akaunting\Module\Commands; -use App\Models\Auth\Permission; -use App\Models\Auth\Role; use App\Models\Module\Module; use App\Models\Module\ModuleHistory; -use App\Utilities\Reports; -use App\Utilities\Widgets; +use App\Traits\Permissions; use Illuminate\Console\Command; use Illuminate\Support\Str; use Symfony\Component\Console\Input\InputArgument; class InstallCommand extends Command { + use Permissions; + /** * The name and signature of the console command. * @@ -68,9 +67,7 @@ class InstallCommand extends Command event(new \App\Events\Module\Installed($alias, $company_id)); - if (!empty($module->get('reports')) || !empty($module->get('widgets')) || !empty($module->get('settings'))) { - $this->updatePermissions($module); - } + $this->attachDefaultModulePermissions($module); session()->forget('company_id'); @@ -93,76 +90,4 @@ class InstallCommand extends Command array('company_id', InputArgument::REQUIRED, 'Company ID.'), ); } - - protected function updatePermissions($module) - { - $permissions = []; - - if (!empty($module->get('reports'))) { - foreach ($module->get('reports') as $class) { - if (!class_exists($class)) { - continue; - } - - $name = Reports::getPermission($class); - $display_name = (new $class())->getDefaultName(); - - $permissions[] = Permission::firstOrCreate([ - 'name' => $name - ], [ - 'display_name' => 'Read ' . $module->getName() . ' Reports ' . $display_name, - 'description' => 'Read ' . $module->getName() . ' Reports ' . $display_name, - ]); - } - } - - if (!empty($module->get('widgets'))) { - foreach ($module->get('widgets') as $class) { - if (!class_exists($class)) { - continue; - } - - $name = Widgets::getPermission($class); - $display_name = (new $class())->getDefaultName(); - - $permissions[] = Permission::firstOrCreate([ - 'name' => $name - ], [ - 'display_name' => 'Read ' . $module->getName() . ' Widgets ' . $display_name, - 'description' => 'Read ' . $module->getName() . ' Widgets ' . $display_name, - ]); - } - } - - if (!empty($module->get('settings'))) { - $permissions[] = Permission::firstOrCreate([ - 'name' => 'read-' . $module->getAlias() . '-settings' - ], [ - 'display_name' => 'Read ' . $module->getName() . ' Settings', - 'description' => 'Read ' . $module->getName() . ' Settings', - ]); - - $permissions[] = Permission::firstOrCreate([ - 'name' => 'update-' . $module->getAlias() . '-settings' - ], [ - 'display_name' => 'Update ' . $module->getName() . ' Settings', - 'description' => 'Update ' . $module->getName() . ' Settings', - ]); - } - - // Attach permission to roles - $roles = Role::all()->filter(function ($r) { - return $r->hasPermission('read-admin-panel'); - }); - - foreach ($roles as $role) { - foreach ($permissions as $permission) { - if ($role->hasPermission($permission->name)) { - continue; - } - - $role->attachPermission($permission); - } - } - } }