From 2501c41de939b61de6a8f1df7499ede79d29aa3f Mon Sep 17 00:00:00 2001 From: Giulio Troccoli-Allard Date: Sun, 29 Nov 2020 15:38:52 +0000 Subject: [PATCH 1/2] Added Laratrust package for roles and permissions --- app/Models/Permission.php | 10 + app/Models/Role.php | 10 + app/Models/User.php | 2 + composer.json | 3 +- composer.lock | 127 ++++++- config/laratrust.php | 324 ++++++++++++++++++ config/laratrust_seeder.php | 28 ++ ...20_11_29_153305_laratrust_setup_tables.php | 85 +++++ database/seeders/DatabaseSeeder.php | 1 + database/seeders/LaratrustSeeder.php | 103 ++++++ public/vendor/laratrust/img/logo.png | Bin 0 -> 3526 bytes public/vendor/laratrust/laratrust.css | 1 + public/vendor/laratrust/mix-manifest.json | 4 + 13 files changed, 696 insertions(+), 2 deletions(-) create mode 100644 app/Models/Permission.php create mode 100644 app/Models/Role.php create mode 100644 config/laratrust.php create mode 100644 config/laratrust_seeder.php create mode 100644 database/migrations/2020_11_29_153305_laratrust_setup_tables.php create mode 100644 database/seeders/LaratrustSeeder.php create mode 100644 public/vendor/laratrust/img/logo.png create mode 100644 public/vendor/laratrust/laratrust.css create mode 100644 public/vendor/laratrust/mix-manifest.json diff --git a/app/Models/Permission.php b/app/Models/Permission.php new file mode 100644 index 0000000..1a88ee8 --- /dev/null +++ b/app/Models/Permission.php @@ -0,0 +1,10 @@ +=5.4" + }, + "require-dev": { + "phpunit/phpunit": "~4.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Traitor\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kuba Szymanowski", + "email": "kuba.szymanowski@inf24.pl" + } + ], + "description": "Add a trait use statement to existing PHP class", + "keywords": [ + "add", + "php", + "trait" + ], + "support": { + "email": "kuba.szymanowski@inf24.pl", + "issues": "https://github.com/kkszymanowski/traitor/issues", + "source": "https://github.com/kkszymanowski/traitor" + }, + "time": "2018-04-19T12:24:36+00:00" + }, { "name": "laravel/fortify", "version": "v1.7.2", @@ -2980,6 +3030,81 @@ ], "time": "2020-08-18T17:17:46+00:00" }, + { + "name": "santigarcor/laratrust", + "version": "6.3.0", + "source": { + "type": "git", + "url": "https://github.com/santigarcor/laratrust.git", + "reference": "ca2a769326454ef81e5a0a3525fee2fb37dbfc13" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/santigarcor/laratrust/zipball/ca2a769326454ef81e5a0a3525fee2fb37dbfc13", + "reference": "ca2a769326454ef81e5a0a3525fee2fb37dbfc13", + "shasum": "" + }, + "require": { + "kkszymanowski/traitor": "^0.2.0", + "laravel/framework": "~6.0|~7.0|~8.0", + "php": "^7.2" + }, + "require-dev": { + "mockery/mockery": "^1.3.1", + "orchestra/testbench": "4.*|5.*|6.*", + "phpunit/phpunit": "^7.5.15|^8.4|^9.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Laratrust\\LaratrustServiceProvider" + ], + "aliases": { + "Laratrust": "Laratrust\\LaratrustFacade" + } + } + }, + "autoload": { + "psr-4": { + "Laratrust\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Santiago Garcia", + "homepage": "http://santigarcor.me" + } + ], + "description": "This package provides a flexible way to add Role-based Permissions to Laravel", + "keywords": [ + "Teams", + "acl", + "authorization", + "laratrust", + "laravel", + "multiusers", + "permissions", + "php", + "rbac", + "roles" + ], + "support": { + "issues": "https://github.com/santigarcor/laratrust/issues", + "source": "https://github.com/santigarcor/laratrust/tree/6.3.0" + }, + "funding": [ + { + "url": "https://github.com/santigarcor", + "type": "github" + } + ], + "time": "2020-10-17T17:37:41+00:00" + }, { "name": "swiftmailer/swiftmailer", "version": "v6.2.3", diff --git a/config/laratrust.php b/config/laratrust.php new file mode 100644 index 0000000..ea68e50 --- /dev/null +++ b/config/laratrust.php @@ -0,0 +1,324 @@ + false, + + /* + |-------------------------------------------------------------------------- + | Which permissions and role checker to use. + |-------------------------------------------------------------------------- + | + | Defines if you want to use the roles and permissions checker. + | Available: + | - default: Check for the roles and permissions using the method that Laratrust + has always used. + | - query: Check for the roles and permissions using direct queries to the database. + | This method doesn't support cache yet. + | + */ + 'checker' => 'default', + + /* + |-------------------------------------------------------------------------- + | Cache + |-------------------------------------------------------------------------- + | + | Manage Laratrust's cache configurations. It uses the driver defined in the + | config/cache.php file. + | + */ + 'cache' => [ + /* + |-------------------------------------------------------------------------- + | Use cache in the package + |-------------------------------------------------------------------------- + | + | Defines if Laratrust will use Laravel's Cache to cache the roles and permissions. + | NOTE: Currently the database check does not use cache. + | + */ + 'enabled' => env('LARATRUST_ENABLE_CACHE', true), + + /* + |-------------------------------------------------------------------------- + | Time to store in cache Laratrust's roles and permissions. + |-------------------------------------------------------------------------- + | + | Determines the time in SECONDS to store Laratrust's roles and permissions in the cache. + | + */ + 'expiration_time' => 3600, // 1 hour + ], + + /* + |-------------------------------------------------------------------------- + | Laratrust User Models + |-------------------------------------------------------------------------- + | + | This is the array that contains the information of the user models. + | This information is used in the add-trait command, for the roles and + | permissions relationships with the possible user models, and the + | administration panel to attach roles and permissions to the users. + | + | The key in the array is the name of the relationship inside the roles and permissions. + | + */ + 'user_models' => [ + 'users' => \App\Models\User::class, + ], + + /* + |-------------------------------------------------------------------------- + | Laratrust Models + |-------------------------------------------------------------------------- + | + | These are the models used by Laratrust to define the roles, permissions and teams. + | If you want the Laratrust models to be in a different namespace or + | to have a different name, you can do it here. + | + */ + 'models' => [ + + 'role' => \App\Models\Role::class, + + 'permission' => \App\Models\Permission::class, + + /** + * Will be used only if the teams functionality is enabled. + */ + 'team' => \App\Models\Team::class, + ], + + /* + |-------------------------------------------------------------------------- + | Laratrust Tables + |-------------------------------------------------------------------------- + | + | These are the tables used by Laratrust to store all the authorization data. + | + */ + 'tables' => [ + + 'roles' => 'roles', + + 'permissions' => 'permissions', + + /** + * Will be used only if the teams functionality is enabled. + */ + 'teams' => 'teams', + + 'role_user' => 'role_user', + + 'permission_user' => 'permission_user', + + 'permission_role' => 'permission_role', + ], + + /* + |-------------------------------------------------------------------------- + | Laratrust Foreign Keys + |-------------------------------------------------------------------------- + | + | These are the foreign keys used by laratrust in the intermediate tables. + | + */ + 'foreign_keys' => [ + /** + * User foreign key on Laratrust's role_user and permission_user tables. + */ + 'user' => 'user_id', + + /** + * Role foreign key on Laratrust's role_user and permission_role tables. + */ + 'role' => 'role_id', + + /** + * Role foreign key on Laratrust's permission_user and permission_role tables. + */ + 'permission' => 'permission_id', + + /** + * Role foreign key on Laratrust's role_user and permission_user tables. + */ + 'team' => 'team_id', + ], + + /* + |-------------------------------------------------------------------------- + | Laratrust Middleware + |-------------------------------------------------------------------------- + | + | This configuration helps to customize the Laratrust middleware behavior. + | + */ + 'middleware' => [ + /** + * Define if the laratrust middleware are registered automatically in the service provider + */ + 'register' => true, + + /** + * Method to be called in the middleware return case. + * Available: abort|redirect + */ + 'handling' => 'abort', + + /** + * Handlers for the unauthorized method in the middlewares. + * The name of the handler must be the same as the handling. + */ + 'handlers' => [ + /** + * Aborts the execution with a 403 code and allows you to provide the response text + */ + 'abort' => [ + 'code' => 403, + 'message' => 'User does not have any of the necessary access rights.' + ], + + /** + * Redirects the user to the given url. + * If you want to flash a key to the session, + * you can do it by setting the key and the content of the message + * If the message content is empty it won't be added to the redirection. + */ + 'redirect' => [ + 'url' => '/home', + 'message' => [ + 'key' => 'error', + 'content' => '' + ] + ] + ] + ], + + 'teams' => [ + /* + |-------------------------------------------------------------------------- + | Use teams feature in the package + |-------------------------------------------------------------------------- + | + | Defines if Laratrust will use the teams feature. + | Please check the docs to see what you need to do in case you have the package already configured. + | + */ + 'enabled' => false, + + /* + |-------------------------------------------------------------------------- + | Strict check for roles/permissions inside teams + |-------------------------------------------------------------------------- + | + | Determines if a strict check should be done when checking if a role or permission + | is attached inside a team. + | If it's false, when checking a role/permission without specifying the team, + | it will check only if the user has attached that role/permission ignoring the team. + | + */ + 'strict_check' => false, + ], + + /* + |-------------------------------------------------------------------------- + | Laratrust Magic 'isAbleTo' Method + |-------------------------------------------------------------------------- + | + | Supported cases for the magic is able to method (Refer to the docs). + | Available: camel_case|snake_case|kebab_case + | + */ + 'magic_is_able_to_method_case' => 'kebab_case', + + /* + |-------------------------------------------------------------------------- + | Laratrust Panel + |-------------------------------------------------------------------------- + | + | Section to manage everything related with the admin panel for the roles and permissions. + | + */ + 'panel' => [ + /* + |-------------------------------------------------------------------------- + | Laratrust Panel Register + |-------------------------------------------------------------------------- + | + | This manages if routes used for the admin panel should be registered. + | Turn this value to false if you don't want to use Laratrust admin panel + | + */ + 'register' => true, + + /* + |-------------------------------------------------------------------------- + | Laratrust Panel Path + |-------------------------------------------------------------------------- + | + | This is the URI path where Laratrust panel for roles and permissions + | will be accessible from. + | + */ + 'path' => 'laratrust', + + /* + |-------------------------------------------------------------------------- + | Laratrust Panel Path + |-------------------------------------------------------------------------- + | + | The route where the go back link should point + | + */ + 'go_back_route' => '/', + + /* + |-------------------------------------------------------------------------- + | Laratrust Panel Route Middleware + |-------------------------------------------------------------------------- + | + | These middleware will get attached onto each Laratrust panel route. + | + */ + 'middleware' => ['web'], + + /* + |-------------------------------------------------------------------------- + | Enable permissions assignment + |-------------------------------------------------------------------------- + | + | Enable/Disable the permissions assignment to the users. + | + */ + 'assign_permissions_to_user' => true, + + /* + |-------------------------------------------------------------------------- + | Add restriction to roles in the panel + |-------------------------------------------------------------------------- + | + | Configure which roles can not be editable, deletable and removable. + | To add a role to the restriction, use name of the role here. + | + */ + 'roles_restrictions' => [ + // The user won't be able to remove roles already assigned to users. + 'not_removable' => [], + + // The user won't be able to edit the role and the permissions assigned. + 'not_editable' => [], + + // The user won't be able to delete the role. + 'not_deletable' => [], + ], + ] +]; diff --git a/config/laratrust_seeder.php b/config/laratrust_seeder.php new file mode 100644 index 0000000..d49616f --- /dev/null +++ b/config/laratrust_seeder.php @@ -0,0 +1,28 @@ + false, + + /** + * Control if all the laratrust tables should be truncated before running the seeder. + */ + 'truncate_tables' => true, + + 'roles_structure' => [ + 'super-admin' => [ + 'users' => 'c,r,u,d', + ], + 'editor' => [ + ], + ], + + 'permissions_map' => [ + 'c' => 'create', + 'r' => 'read', + 'u' => 'update', + 'd' => 'delete' + ] +]; diff --git a/database/migrations/2020_11_29_153305_laratrust_setup_tables.php b/database/migrations/2020_11_29_153305_laratrust_setup_tables.php new file mode 100644 index 0000000..94ac743 --- /dev/null +++ b/database/migrations/2020_11_29_153305_laratrust_setup_tables.php @@ -0,0 +1,85 @@ +bigIncrements('id'); + $table->string('name')->unique(); + $table->string('display_name')->nullable(); + $table->string('description')->nullable(); + $table->timestamps(); + }); + + // Create table for storing permissions + Schema::create('permissions', function (Blueprint $table) { + $table->bigIncrements('id'); + $table->string('name')->unique(); + $table->string('display_name')->nullable(); + $table->string('description')->nullable(); + $table->timestamps(); + }); + + // Create table for associating roles to users and teams (Many To Many Polymorphic) + Schema::create('role_user', function (Blueprint $table) { + $table->unsignedBigInteger('role_id'); + $table->unsignedBigInteger('user_id'); + $table->string('user_type'); + + $table->foreign('role_id')->references('id')->on('roles') + ->onUpdate('cascade')->onDelete('cascade'); + + $table->primary(['user_id', 'role_id', 'user_type']); + }); + + // Create table for associating permissions to users (Many To Many Polymorphic) + Schema::create('permission_user', function (Blueprint $table) { + $table->unsignedBigInteger('permission_id'); + $table->unsignedBigInteger('user_id'); + $table->string('user_type'); + + $table->foreign('permission_id')->references('id')->on('permissions') + ->onUpdate('cascade')->onDelete('cascade'); + + $table->primary(['user_id', 'permission_id', 'user_type']); + }); + + // Create table for associating permissions to roles (Many-to-Many) + Schema::create('permission_role', function (Blueprint $table) { + $table->unsignedBigInteger('permission_id'); + $table->unsignedBigInteger('role_id'); + + $table->foreign('permission_id')->references('id')->on('permissions') + ->onUpdate('cascade')->onDelete('cascade'); + $table->foreign('role_id')->references('id')->on('roles') + ->onUpdate('cascade')->onDelete('cascade'); + + $table->primary(['permission_id', 'role_id']); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('permission_user'); + Schema::dropIfExists('permission_role'); + Schema::dropIfExists('permissions'); + Schema::dropIfExists('role_user'); + Schema::dropIfExists('roles'); + } +} diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 57b73b5..f759acc 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -14,5 +14,6 @@ class DatabaseSeeder extends Seeder public function run() { // \App\Models\User::factory(10)->create(); + $this->call(LaratrustSeeder::class); } } diff --git a/database/seeders/LaratrustSeeder.php b/database/seeders/LaratrustSeeder.php new file mode 100644 index 0000000..5b7d4c3 --- /dev/null +++ b/database/seeders/LaratrustSeeder.php @@ -0,0 +1,103 @@ +truncateLaratrustTables(); + + $config = Config::get('laratrust_seeder.roles_structure'); + + if ($config === null) { + $this->command->error("The configuration has not been published. Did you run `php artisan vendor:publish --tag=\"laratrust-seeder\"`"); + $this->command->line(''); + return false; + } + + $mapPermission = collect(config('laratrust_seeder.permissions_map')); + + foreach ($config as $key => $modules) { + + // Create a new role + $role = \App\Models\Role::firstOrCreate([ + 'name' => $key, + 'display_name' => ucwords(str_replace('-', ' ', $key)), + 'description' => ucwords(str_replace('-', ' ', $key)) + ]); + $permissions = []; + + $this->command->info('Creating Role '. strtoupper($key)); + + // Reading role permission modules + foreach ($modules as $module => $value) { + + foreach (explode(',', $value) as $p => $perm) { + + $permissionValue = $mapPermission->get($perm); + + $permissions[] = \App\Models\Permission::firstOrCreate([ + 'name' => $module . '-' . $permissionValue, + 'display_name' => ucfirst($permissionValue) . ' ' . ucfirst($module), + 'description' => ucfirst($permissionValue) . ' ' . ucfirst($module), + ])->id; + + $this->command->info('Creating Permission to '.$permissionValue.' for '. $module); + } + } + + // Attach all permissions to the role + $role->permissions()->sync($permissions); + + if (Config::get('laratrust_seeder.create_users')) { + $this->command->info("Creating '{$key}' user"); + // Create default user for each role + $user = \App\Models\User::create([ + 'name' => ucwords(str_replace('-', ' ', $key)), + 'email' => $key.'@example.com', + 'password' => bcrypt('password') + ]); + $user->attachRole($role); + } + + } + } + + /** + * Truncates all the laratrust tables and the users table + * + * @return void + */ + public function truncateLaratrustTables() + { + $this->command->info('Truncating User, Role and Permission tables'); + Schema::disableForeignKeyConstraints(); + + DB::table('permission_role')->truncate(); + DB::table('permission_user')->truncate(); + DB::table('role_user')->truncate(); + + if (Config::get('laratrust_seeder.truncate_tables')) { + DB::table('roles')->truncate(); + DB::table('permissions')->truncate(); + + if (Config::get('laratrust_seeder.create_users')) { + $usersTable = (new \App\Models\User)->getTable(); + DB::table($usersTable)->truncate(); + } + } + + Schema::enableForeignKeyConstraints(); + } +} diff --git a/public/vendor/laratrust/img/logo.png b/public/vendor/laratrust/img/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..59dffaf6c3c18b27cd56600dc81a0f6a9d905ca3 GIT binary patch literal 3526 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%0D#Kcq@=0Pmx%cuZ8)Zq9J{@26$>BWBWq%lb-;XXd zFToNQwgbGz=?t#jHFM^L`x)eDT=M0Y?i?-WS73S!gmJRvr|ITqFg+7y*WV77$M5CI zfc5()%wpcb`UOzxK;KrO@$%d!JGS8;~27sFB3Y?0B9Qeo^FZ&a)Wp{`aVOz z0K5Qo1MCIR3h?(J93hBWT@jxjm{~ex{~gBv0e^RjX!{)15&!@I07*qoM6N<$g5pqv AsQ>@~ literal 0 HcmV?d00001 diff --git a/public/vendor/laratrust/laratrust.css b/public/vendor/laratrust/laratrust.css new file mode 100644 index 0000000..e8bfbe3 --- /dev/null +++ b/public/vendor/laratrust/laratrust.css @@ -0,0 +1 @@ +/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}[hidden],template{display:none}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}button{background-color:transparent;background-image:none;padding:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}fieldset,ol,ul{margin:0;padding:0}ol,ul{list-style:none}html{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}*,:after,:before{box-sizing:border-box;border:0 solid #e2e8f0}hr{border-top-width:1px}img{border-style:solid}textarea{resize:vertical}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#a0aec0}input::-moz-placeholder,textarea::-moz-placeholder{color:#a0aec0}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#a0aec0}input::-ms-input-placeholder,textarea::-ms-input-placeholder{color:#a0aec0}input::placeholder,textarea::placeholder{color:#a0aec0}[role=button],button{cursor:pointer}table{border-collapse:collapse}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}button,input,optgroup,select,textarea{padding:0;line-height:inherit;color:inherit}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}.form-input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border-color:#e2e8f0;border-width:1px;border-radius:.25rem;padding:.5rem .75rem;font-size:1rem;line-height:1.5}.form-input::-webkit-input-placeholder{color:#a0aec0;opacity:1}.form-input::-moz-placeholder{color:#a0aec0;opacity:1}.form-input:-ms-input-placeholder{color:#a0aec0;opacity:1}.form-input::-ms-input-placeholder{color:#a0aec0;opacity:1}.form-input::placeholder{color:#a0aec0;opacity:1}.form-input:focus{outline:none;box-shadow:0 0 0 3px rgba(66,153,225,.5);border-color:#63b3ed}.form-textarea{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border-color:#e2e8f0;border-width:1px;border-radius:.25rem;padding:.5rem .75rem;font-size:1rem;line-height:1.5}.form-textarea::-webkit-input-placeholder{color:#a0aec0;opacity:1}.form-textarea::-moz-placeholder{color:#a0aec0;opacity:1}.form-textarea:-ms-input-placeholder{color:#a0aec0;opacity:1}.form-textarea::-ms-input-placeholder{color:#a0aec0;opacity:1}.form-textarea::placeholder{color:#a0aec0;opacity:1}.form-textarea:focus{outline:none;box-shadow:0 0 0 3px rgba(66,153,225,.5);border-color:#63b3ed}.form-multiselect{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border-color:#e2e8f0;border-width:1px;border-radius:.25rem;padding:.5rem .75rem;font-size:1rem;line-height:1.5}.form-multiselect:focus{outline:none;box-shadow:0 0 0 3px rgba(66,153,225,.5);border-color:#63b3ed}.form-select{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23a0aec0'%3E%3Cpath d='M15.3 9.3a1 1 0 011.4 1.4l-4 4a1 1 0 01-1.4 0l-4-4a1 1 0 011.4-1.4l3.3 3.29 3.3-3.3z'/%3E%3C/svg%3E");-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-print-color-adjust:exact;color-adjust:exact;background-repeat:no-repeat;background-color:#fff;border-color:#e2e8f0;border-width:1px;border-radius:.25rem;padding:.5rem 2.5rem .5rem .75rem;font-size:1rem;line-height:1.5;background-position:right .5rem center;background-size:1.5em 1.5em}.form-select::-ms-expand{color:#a0aec0;border:none}@media not print{.form-select::-ms-expand{display:none}}@media print and (-ms-high-contrast:active),print and (-ms-high-contrast:none){.form-select{padding-right:.75rem}}.form-select:focus{outline:none;box-shadow:0 0 0 3px rgba(66,153,225,.5);border-color:#63b3ed}.form-checkbox{-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-print-color-adjust:exact;color-adjust:exact;display:inline-block;vertical-align:middle;background-origin:border-box;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;flex-shrink:0;height:1em;width:1em;color:#4299e1;background-color:#fff;border-color:#e2e8f0;border-width:1px;border-radius:.25rem}.form-checkbox:checked{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 16 16' fill='%23fff' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M5.707 7.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4a1 1 0 00-1.414-1.414L7 8.586 5.707 7.293z'/%3E%3C/svg%3E");border-color:transparent;background-color:currentColor;background-size:100% 100%;background-position:50%;background-repeat:no-repeat}@media not print{.form-checkbox::-ms-check{border-width:1px;color:transparent;background:inherit;border-color:inherit;border-radius:inherit}}.form-checkbox:focus{outline:none;box-shadow:0 0 0 3px rgba(66,153,225,.5);border-color:#63b3ed}.form-radio{-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-print-color-adjust:exact;color-adjust:exact;display:inline-block;vertical-align:middle;background-origin:border-box;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;flex-shrink:0;border-radius:100%;height:1em;width:1em;color:#4299e1;background-color:#fff;border-color:#e2e8f0;border-width:1px}.form-radio:checked{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 16 16' fill='%23fff' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='8' cy='8' r='3'/%3E%3C/svg%3E");border-color:transparent;background-color:currentColor;background-size:100% 100%;background-position:50%;background-repeat:no-repeat}@media not print{.form-radio::-ms-check{border-width:1px;color:transparent;background:inherit;border-color:inherit;border-radius:inherit}}.form-radio:focus{outline:none;box-shadow:0 0 0 3px rgba(66,153,225,.5);border-color:#63b3ed}.nav-button,.nav-button-active{padding:.5rem .75rem;border-radius:.375rem;font-size:.875rem;font-weight:500;--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.nav-button-active{background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.nav-button-active,.nav-button-active:focus,.nav-button:focus{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity));--bg-opacity:1}.nav-button-active:focus,.nav-button:focus{outline:0}.nav-button-active:focus,.nav-button:focus,.nav-button:hover{background-color:#4a5568;background-color:rgba(74,85,104,var(--bg-opacity))}.nav-button:hover{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity));--bg-opacity:1}.th{padding:.75rem 1.5rem;--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity));text-align:left;font-size:.75rem;line-height:1rem;font-weight:500;--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity));text-transform:uppercase;letter-spacing:.05em}.td,.th{border-bottom-width:1px;--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.td{padding:1rem 1.5rem;white-space:nowrap}.btn{font-weight:700;padding:.5rem 1rem;border-radius:.25rem}.btn-blue{--bg-opacity:1;background-color:#4299e1;background-color:rgba(66,153,225,var(--bg-opacity));--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.btn-blue:hover{--bg-opacity:1;background-color:#2b6cb0;background-color:rgba(43,108,176,var(--bg-opacity))}.btn-red{--bg-opacity:1;background-color:#f56565;background-color:rgba(245,101,101,var(--bg-opacity));--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.btn-red:hover{--bg-opacity:1;background-color:#c53030;background-color:rgba(197,48,48,var(--bg-opacity))}.alert-warning{background-color:#fffaf0;background-color:rgba(255,250,240,var(--bg-opacity));border-left-width:4px;--border-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--border-opacity));color:#c05621;color:rgba(192,86,33,var(--text-opacity))}.alert-success,.alert-warning{--bg-opacity:1;--text-opacity:1;padding:1rem}.alert-success{background-color:#f0fff4;background-color:rgba(240,255,244,var(--bg-opacity));border-left-width:4px;--border-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--border-opacity));color:#2f855a;color:rgba(47,133,90,var(--text-opacity))}.alert-error{--bg-opacity:1;background-color:#fff5f5;background-color:rgba(255,245,245,var(--bg-opacity));border-left-width:4px;--border-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--border-opacity));--text-opacity:1;color:#c53030;color:rgba(197,48,48,var(--text-opacity));padding:1rem}.bg-transparent{background-color:transparent}.bg-white{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.bg-gray-200{--bg-opacity:1;background-color:#edf2f7;background-color:rgba(237,242,247,var(--bg-opacity))}.bg-gray-800{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.bg-gray-900{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.hover\:bg-gray-700:hover{--bg-opacity:1;background-color:#4a5568;background-color:rgba(74,85,104,var(--bg-opacity))}.hover\:bg-blue-500:hover{--bg-opacity:1;background-color:#4299e1;background-color:rgba(66,153,225,var(--bg-opacity))}.focus\:bg-gray-700:focus{--bg-opacity:1;background-color:#4a5568;background-color:rgba(74,85,104,var(--bg-opacity))}.border-gray-200{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.border-gray-300{--border-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--border-opacity))}.border-red-500{--border-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--border-opacity))}.border-blue-500{--border-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--border-opacity))}.focus\:border-transparent:focus,.hover\:border-transparent:hover{border-color:transparent}.focus\:border-blue-300:focus{--border-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--border-opacity))}.rounded{border-radius:.25rem}.rounded-md{border-radius:.375rem}.rounded-r-md{border-top-right-radius:.375rem;border-bottom-right-radius:.375rem}.rounded-l-md{border-top-left-radius:.375rem;border-bottom-left-radius:.375rem}.border{border-width:1px}.border-t{border-top-width:1px}.border-b{border-bottom-width:1px}.cursor-not-allowed{cursor:not-allowed}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-baseline{align-items:baseline}.self-end{align-self:flex-end}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.flex-1{flex:1 1 0%}.flex-shrink-0{flex-shrink:0}.font-medium{font-weight:500}.font-semibold{font-weight:600}.font-bold{font-weight:700}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-10{height:2.5rem}.h-16{height:4rem}.text-sm{font-size:.875rem}.text-base{font-size:1rem}.text-3xl{font-size:1.875rem}.leading-5{line-height:1.25rem}.leading-tight{line-height:1.25}.list-inside{list-style-position:inside}.list-disc{list-style-type:disc}.my-2{margin-top:.5rem;margin-bottom:.5rem}.my-4{margin-top:1rem;margin-bottom:1rem}.mx-auto{margin-left:auto;margin-right:auto}.-my-2{margin-top:-.5rem;margin-bottom:-.5rem}.mt-1{margin-top:.25rem}.ml-2{margin-left:.5rem}.mt-4{margin-top:1rem}.mr-4{margin-right:1rem}.mb-4{margin-bottom:1rem}.ml-4{margin-left:1rem}.mr-6{margin-right:1.5rem}.ml-10{margin-left:2.5rem}.-mr-2{margin-right:-.5rem}.-ml-px{margin-left:-1px}.max-w-6xl{max-width:72rem}.min-w-full{min-width:100%}.focus\:outline-none:focus{outline:0}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.p-2{padding:.5rem}.p-4{padding:1rem}.p-8{padding:2rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.px-2{padding-left:.5rem;padding-right:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.px-3{padding-left:.75rem;padding-right:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.px-4{padding-left:1rem;padding-right:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.pt-2{padding-top:.5rem}.pb-3{padding-bottom:.75rem}.relative{position:relative}.shadow-sm{box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.shadow{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.focus\:shadow-none:focus{box-shadow:none}.text-right{text-align:right}.text-white{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.text-gray-300{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.text-gray-400{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.text-gray-500{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.text-gray-600{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.text-gray-700{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.text-gray-800{--text-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--text-opacity))}.text-gray-900{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.text-red-500{--text-opacity:1;color:#f56565;color:rgba(245,101,101,var(--text-opacity))}.text-red-600{--text-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--text-opacity))}.text-blue-600{--text-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--text-opacity))}.text-blue-700{--text-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--text-opacity))}.hover\:text-white:hover{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.hover\:text-gray-400:hover{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.hover\:text-gray-700:hover{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.hover\:text-red-900:hover{--text-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--text-opacity))}.hover\:text-blue-900:hover{--text-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--text-opacity))}.focus\:text-white:focus{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.align-middle{vertical-align:middle}.truncate,.whitespace-no-wrap{white-space:nowrap}.truncate{overflow:hidden;text-overflow:ellipsis}.w-4{width:1rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-auto{width:auto}.w-3\/12{width:25%}.w-4\/12{width:33.333333%}.w-full{width:100%}.z-0{z-index:0}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.transition{transition-property:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-150{transition-duration:.15s}@media (min-width:640px){.sm\:rounded-lg{border-radius:.5rem}.sm\:flex{display:flex}.sm\:items-center{align-items:center}.sm\:justify-end{justify-content:flex-end}.sm\:-mx-6{margin-left:-1.5rem;margin-right:-1.5rem}.sm\:px-0{padding-left:0;padding-right:0}.sm\:px-3{padding-left:.75rem;padding-right:.75rem}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}}@media (min-width:768px){.md\:block{display:block}.md\:hidden{display:none}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}@media (min-width:1024px){.lg\:-mx-8{margin-left:-2rem;margin-right:-2rem}.lg\:px-8{padding-left:2rem;padding-right:2rem}.lg\:px-32{padding-left:8rem;padding-right:8rem}} \ No newline at end of file diff --git a/public/vendor/laratrust/mix-manifest.json b/public/vendor/laratrust/mix-manifest.json new file mode 100644 index 0000000..24e3a86 --- /dev/null +++ b/public/vendor/laratrust/mix-manifest.json @@ -0,0 +1,4 @@ +{ + "/laratrust.css": "/laratrust.css?id=41ea7a306eda21950d93", + "/img/logo.png": "/img/logo.png?id=b16a11382c0453bdb8a3" +} From e4a25b96f2f5b77b24701f775295b2472dc9ba8a Mon Sep 17 00:00:00 2001 From: Giulio Troccoli-Allard Date: Sun, 29 Nov 2020 16:23:33 +0000 Subject: [PATCH 2/2] Added seeder for test users --- .env.example | 1 + config/app.php | 2 +- database/factories/UserFactory.php | 2 ++ database/seeders/Testing/UserSeeder.php | 21 +++++++++++++++++++++ 4 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 database/seeders/Testing/UserSeeder.php diff --git a/.env.example b/.env.example index ac5529e..f248ff1 100644 --- a/.env.example +++ b/.env.example @@ -3,6 +3,7 @@ APP_ENV=local APP_KEY= APP_DEBUG=true APP_URL=http://localhost +FAKER_LOCALE=en_GB LOG_CHANNEL=stack LOG_LEVEL=debug diff --git a/config/app.php b/config/app.php index 26afdef..a52f316 100644 --- a/config/app.php +++ b/config/app.php @@ -106,7 +106,7 @@ | */ - 'faker_locale' => 'en_US', + 'faker_locale' => env('FAKER_LOCALE', 'en_US'), /* |-------------------------------------------------------------------------- diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php index bdea1a3..4789686 100644 --- a/database/factories/UserFactory.php +++ b/database/factories/UserFactory.php @@ -27,6 +27,8 @@ public function definition() 'email' => $this->faker->unique()->safeEmail, 'email_verified_at' => now(), 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password + 'two_factor_secret' => null, + 'two_factor_recovery_codes' => null, 'remember_token' => Str::random(10), ]; } diff --git a/database/seeders/Testing/UserSeeder.php b/database/seeders/Testing/UserSeeder.php new file mode 100644 index 0000000..fbbc2a4 --- /dev/null +++ b/database/seeders/Testing/UserSeeder.php @@ -0,0 +1,21 @@ +create([ + 'name' => 'Super Admin', + 'email' => 'super-admin@example.com', + ])->attachRole('super-admin'); + User::factory()->create([ + 'name' => 'Editor', + 'email' => 'editor@example.com', + ])->attachRole('editor'); + } +}