From dbac0f7f897a0b2e5ea3c6ff015af7950a32c061 Mon Sep 17 00:00:00 2001 From: apsky Date: Tue, 15 Sep 2020 17:38:50 +0300 Subject: [PATCH 01/11] add grant and grant_user pivot tables --- app/Grant.php | 16 ++++++++ app/Grant_user.php | 11 ++++++ app/User.php | 4 ++ .../2020_09_15_141642_create_grants_table.php | 31 +++++++++++++++ ..._09_15_142223_create_grant_users_table.php | 34 ++++++++++++++++ database/seeds/DatabaseSeeder.php | 39 ++++++++++++++++++- 6 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 app/Grant.php create mode 100644 app/Grant_user.php create mode 100644 database/migrations/2020_09_15_141642_create_grants_table.php create mode 100644 database/migrations/2020_09_15_142223_create_grant_users_table.php diff --git a/app/Grant.php b/app/Grant.php new file mode 100644 index 0000000..339e3de --- /dev/null +++ b/app/Grant.php @@ -0,0 +1,16 @@ +belongsToMany(User::class); + } +} diff --git a/app/Grant_user.php b/app/Grant_user.php new file mode 100644 index 0000000..0fa3f60 --- /dev/null +++ b/app/Grant_user.php @@ -0,0 +1,11 @@ +hasMany(Post::class, 'owner_id'); } + + public function grants() { + return $this->belongsToMany(Grant::class); + } } diff --git a/database/migrations/2020_09_15_141642_create_grants_table.php b/database/migrations/2020_09_15_141642_create_grants_table.php new file mode 100644 index 0000000..c84a391 --- /dev/null +++ b/database/migrations/2020_09_15_141642_create_grants_table.php @@ -0,0 +1,31 @@ +id(); + $table->string('name'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('grants'); + } +} diff --git a/database/migrations/2020_09_15_142223_create_grant_users_table.php b/database/migrations/2020_09_15_142223_create_grant_users_table.php new file mode 100644 index 0000000..61f3a30 --- /dev/null +++ b/database/migrations/2020_09_15_142223_create_grant_users_table.php @@ -0,0 +1,34 @@ +unsignedBigInteger('grant_id'); + $table->unsignedBigInteger('user_id'); + $table->primary(['grant_id', 'user_id']); + $table->foreign('grant_id')->references('id')->on('grants')->onDelete('cascade'); + $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('grant_user'); + } +} diff --git a/database/seeds/DatabaseSeeder.php b/database/seeds/DatabaseSeeder.php index 237dfc5..cc26d02 100644 --- a/database/seeds/DatabaseSeeder.php +++ b/database/seeds/DatabaseSeeder.php @@ -1,6 +1,10 @@ call(UserSeeder::class); + $users = [ + [ + 'id' => 1, + 'name' => 'Pavel', + 'email' => 'admin@mail.ru', + 'password' => bcrypt('1'), + 'remember_token' => Str::random(10), + 'created_at' => Carbon::now()->format('Y-m-d H:i:s'), + 'updated_at' => Carbon::now()->format('Y-m-d H:i:s'), + ], + [ + 'id' => 2, + 'name' => 'user', + 'email' => 'user@mail.ru', + 'password' => Hash::make('1'), + 'remember_token' => Str::random(10), + 'created_at' => Carbon::now()->format('Y-m-d H:i:s'), + 'updated_at' => Carbon::now()->format('Y-m-d H:i:s'), + ], + ]; + + $grants = [ + ['id' => 1, 'name' => 'admin'], + ['id' => 2, 'name' => 'registered'], + ]; + + $grant_user = [ + ['grant_id' => 1, 'user_id' => 1], + ['grant_id' => 2, 'user_id' => 2], + ]; + + DB::table('users')->insert($users); + DB::table('grants')->insert($grants); + DB::table('grant_user')->insert($grant_user); } } From b309e1206d9139e438da05d4deb118cf204338b3 Mon Sep 17 00:00:00 2001 From: apsky Date: Fri, 18 Sep 2020 16:31:03 +0300 Subject: [PATCH 02/11] create tables for users roles and permissions --- app/Grant_user.php | 11 ---- .../Controllers/Auth/RegisterController.php | 2 +- app/{Grant.php => Permission.php} | 10 ++-- app/Role.php | 20 +++++++ app/User.php | 21 ++------ composer.lock | 53 +++++++++---------- database/factories/PermissionFactory.php | 19 +++++++ database/factories/RoleFactory.php | 19 +++++++ database/factories/UserFactory.php | 38 ++++++------- ..._09_15_142223_create_grant_users_table.php | 34 ------------ ... 2020_09_18_134638_create_roles_table.php} | 6 +-- ..._09_18_134809_create_permissions_table.php | 31 +++++++++++ ...18_141922_create_permission_role_table.php | 33 ++++++++++++ ...20_09_18_151207_create_role_user_table.php | 33 ++++++++++++ database/seeds/DatabaseSeeder.php | 37 ++----------- database/seeds/PermissionsTableSeeder.php | 27 ++++++++++ database/seeds/RolesTableSeeder.php | 27 ++++++++++ database/seeds/UsersTableSeeder.php | 21 ++++++++ resources/views/auth/login.blade.php | 4 +- 19 files changed, 293 insertions(+), 153 deletions(-) delete mode 100644 app/Grant_user.php rename app/{Grant.php => Permission.php} (50%) create mode 100644 app/Role.php create mode 100644 database/factories/PermissionFactory.php create mode 100644 database/factories/RoleFactory.php delete mode 100644 database/migrations/2020_09_15_142223_create_grant_users_table.php rename database/migrations/{2020_09_15_141642_create_grants_table.php => 2020_09_18_134638_create_roles_table.php} (74%) create mode 100644 database/migrations/2020_09_18_134809_create_permissions_table.php create mode 100644 database/migrations/2020_09_18_141922_create_permission_role_table.php create mode 100644 database/migrations/2020_09_18_151207_create_role_user_table.php create mode 100644 database/seeds/PermissionsTableSeeder.php create mode 100644 database/seeds/RolesTableSeeder.php create mode 100644 database/seeds/UsersTableSeeder.php diff --git a/app/Grant_user.php b/app/Grant_user.php deleted file mode 100644 index 0fa3f60..0000000 --- a/app/Grant_user.php +++ /dev/null @@ -1,11 +0,0 @@ - ['required', 'string', 'max:255'], 'email' => ['required', 'string', 'email', 'max:255', 'unique:users'], - 'password' => ['required', 'string', 'min:1', 'confirmed'], + 'password' => ['required', 'string', 'min:8', 'confirmed'], ]); } diff --git a/app/Grant.php b/app/Permission.php similarity index 50% rename from app/Grant.php rename to app/Permission.php index 339e3de..d8dd422 100644 --- a/app/Grant.php +++ b/app/Permission.php @@ -5,12 +5,16 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; -class Grant extends Model +class Permission extends Model { + use HasFactory; + protected $guarded = []; - public function users() + public $timestamps = false; + + public function roles() { - return $this->belongsToMany(User::class); + return $this->belongsToMany(Role::class); } } diff --git a/app/Role.php b/app/Role.php new file mode 100644 index 0000000..20c63c7 --- /dev/null +++ b/app/Role.php @@ -0,0 +1,20 @@ +belongsToMany(Permission::class); + } +} diff --git a/app/User.php b/app/User.php index 5ede169..21b1cf5 100644 --- a/app/User.php +++ b/app/User.php @@ -3,36 +3,23 @@ namespace App; use Illuminate\Contracts\Auth\MustVerifyEmail; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; class User extends Authenticatable { use Notifiable; + use HasFactory; - /** - * The attributes that are mass assignable. - * - * @var array - */ protected $fillable = [ 'name', 'email', 'password', ]; - /** - * The attributes that should be hidden for arrays. - * - * @var array - */ protected $hidden = [ 'password', 'remember_token', ]; - /** - * The attributes that should be cast to native types. - * - * @var array - */ protected $casts = [ 'email_verified_at' => 'datetime', ]; @@ -42,7 +29,7 @@ public function posts() return $this->hasMany(Post::class, 'owner_id'); } - public function grants() { - return $this->belongsToMany(Grant::class); + public function roles() { + return $this->belongsToMany(Role::class); } } diff --git a/composer.lock b/composer.lock index c7b1a37..6725f08 100644 --- a/composer.lock +++ b/composer.lock @@ -802,16 +802,16 @@ }, { "name": "laravel/framework", - "version": "v8.2.0", + "version": "v8.4.0", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "846d4dad13ed8cb535bf4058d53b2770647f9301" + "reference": "1c57ab5e375d0a897c22b29e8352453be514131e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/846d4dad13ed8cb535bf4058d53b2770647f9301", - "reference": "846d4dad13ed8cb535bf4058d53b2770647f9301", + "url": "https://api.github.com/repos/laravel/framework/zipball/1c57ab5e375d0a897c22b29e8352453be514131e", + "reference": "1c57ab5e375d0a897c22b29e8352453be514131e", "shasum": "" }, "require": { @@ -841,7 +841,7 @@ "symfony/routing": "^5.1", "symfony/var-dumper": "^5.1", "tijsverkoyen/css-to-inline-styles": "^2.2.2", - "vlucas/phpdotenv": "^5.0", + "vlucas/phpdotenv": "^5.2", "voku/portable-ascii": "^1.4.8" }, "conflict": { @@ -961,7 +961,7 @@ "framework", "laravel" ], - "time": "2020-09-14T13:36:13+00:00" + "time": "2020-09-16T16:13:13+00:00" }, { "name": "laravel/helpers", @@ -1524,16 +1524,16 @@ }, { "name": "nesbot/carbon", - "version": "2.39.2", + "version": "2.40.0", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "326efde1bc09077a26cb77f6e2e32e13f06c27f2" + "reference": "6c7646154181013ecd55e80c201b9fd873c6ee5d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/326efde1bc09077a26cb77f6e2e32e13f06c27f2", - "reference": "326efde1bc09077a26cb77f6e2e32e13f06c27f2", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/6c7646154181013ecd55e80c201b9fd873c6ee5d", + "reference": "6c7646154181013ecd55e80c201b9fd873c6ee5d", "shasum": "" }, "require": { @@ -1609,7 +1609,7 @@ "type": "tidelift" } ], - "time": "2020-09-10T12:16:42+00:00" + "time": "2020-09-11T19:00:58+00:00" }, { "name": "nikic/php-parser", @@ -4812,16 +4812,16 @@ }, { "name": "facade/flare-client-php", - "version": "1.3.5", + "version": "1.3.6", "source": { "type": "git", "url": "https://github.com/facade/flare-client-php.git", - "reference": "25907a113bfc212a38d458ae365bfb902b4e7fb8" + "reference": "451fadf38e9f635e7f8e1f5b3cf5c9eb82f11799" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/facade/flare-client-php/zipball/25907a113bfc212a38d458ae365bfb902b4e7fb8", - "reference": "25907a113bfc212a38d458ae365bfb902b4e7fb8", + "url": "https://api.github.com/repos/facade/flare-client-php/zipball/451fadf38e9f635e7f8e1f5b3cf5c9eb82f11799", + "reference": "451fadf38e9f635e7f8e1f5b3cf5c9eb82f11799", "shasum": "" }, "require": { @@ -4834,7 +4834,6 @@ }, "require-dev": { "friendsofphp/php-cs-fixer": "^2.14", - "larapack/dd": "^1.1", "phpunit/phpunit": "^7.5.16", "spatie/phpunit-snapshot-assertions": "^2.0" }, @@ -4870,7 +4869,7 @@ "type": "github" } ], - "time": "2020-08-26T18:06:23+00:00" + "time": "2020-09-18T06:35:11+00:00" }, { "name": "facade/ignition", @@ -5510,16 +5509,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.2.1", + "version": "5.2.2", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "d870572532cd70bc3fab58f2e23ad423c8404c44" + "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d870572532cd70bc3fab58f2e23ad423c8404c44", - "reference": "d870572532cd70bc3fab58f2e23ad423c8404c44", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/069a785b2141f5bcf49f3e353548dc1cce6df556", + "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556", "shasum": "" }, "require": { @@ -5558,20 +5557,20 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2020-08-15T11:14:08+00:00" + "time": "2020-09-03T19:13:55+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "1.3.0", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "e878a14a65245fbe78f8080eba03b47c3b705651" + "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e878a14a65245fbe78f8080eba03b47c3b705651", - "reference": "e878a14a65245fbe78f8080eba03b47c3b705651", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", + "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", "shasum": "" }, "require": { @@ -5603,7 +5602,7 @@ } ], "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "time": "2020-06-27T10:12:23+00:00" + "time": "2020-09-17T18:55:26+00:00" }, { "name": "phpspec/prophecy", diff --git a/database/factories/PermissionFactory.php b/database/factories/PermissionFactory.php new file mode 100644 index 0000000..01ae47b --- /dev/null +++ b/database/factories/PermissionFactory.php @@ -0,0 +1,19 @@ +define(User::class, function (Faker $faker) { - return [ - 'name' => $faker->name, - 'email' => $faker->unique()->safeEmail, - 'email_verified_at' => now(), - 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password - 'remember_token' => Str::random(10), - ]; -}); + public function definition() + { + return [ + 'name' => $this->faker->name, + 'email' => $this->faker->unique()->safeEmail, + 'email_verified_at' => now(), + 'password' => Hash::make(1), + 'remember_token' => Str::random(10), + ]; + } +} diff --git a/database/migrations/2020_09_15_142223_create_grant_users_table.php b/database/migrations/2020_09_15_142223_create_grant_users_table.php deleted file mode 100644 index 61f3a30..0000000 --- a/database/migrations/2020_09_15_142223_create_grant_users_table.php +++ /dev/null @@ -1,34 +0,0 @@ -unsignedBigInteger('grant_id'); - $table->unsignedBigInteger('user_id'); - $table->primary(['grant_id', 'user_id']); - $table->foreign('grant_id')->references('id')->on('grants')->onDelete('cascade'); - $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); - }); - } - - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::dropIfExists('grant_user'); - } -} diff --git a/database/migrations/2020_09_15_141642_create_grants_table.php b/database/migrations/2020_09_18_134638_create_roles_table.php similarity index 74% rename from database/migrations/2020_09_15_141642_create_grants_table.php rename to database/migrations/2020_09_18_134638_create_roles_table.php index c84a391..4c1b24c 100644 --- a/database/migrations/2020_09_15_141642_create_grants_table.php +++ b/database/migrations/2020_09_18_134638_create_roles_table.php @@ -4,7 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class CreateGrantsTable extends Migration +class CreateRolesTable extends Migration { /** * Run the migrations. @@ -13,7 +13,7 @@ class CreateGrantsTable extends Migration */ public function up() { - Schema::create('grants', function (Blueprint $table) { + Schema::create('roles', function (Blueprint $table) { $table->id(); $table->string('name'); }); @@ -26,6 +26,6 @@ public function up() */ public function down() { - Schema::dropIfExists('grants'); + Schema::dropIfExists('roles'); } } diff --git a/database/migrations/2020_09_18_134809_create_permissions_table.php b/database/migrations/2020_09_18_134809_create_permissions_table.php new file mode 100644 index 0000000..f05b6f8 --- /dev/null +++ b/database/migrations/2020_09_18_134809_create_permissions_table.php @@ -0,0 +1,31 @@ +id(); + $table->string('name'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('permissions'); + } +} diff --git a/database/migrations/2020_09_18_141922_create_permission_role_table.php b/database/migrations/2020_09_18_141922_create_permission_role_table.php new file mode 100644 index 0000000..a170483 --- /dev/null +++ b/database/migrations/2020_09_18_141922_create_permission_role_table.php @@ -0,0 +1,33 @@ +primary(['permission_id', 'role_id']); + + $table->foreignId('permission_id')->constrained('permissions')->onDelete('Cascade'); + $table->foreignId('role_id')->constrained('roles')->onDelete('Cascade'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('permission_role'); + } +} diff --git a/database/migrations/2020_09_18_151207_create_role_user_table.php b/database/migrations/2020_09_18_151207_create_role_user_table.php new file mode 100644 index 0000000..09cbd9d --- /dev/null +++ b/database/migrations/2020_09_18_151207_create_role_user_table.php @@ -0,0 +1,33 @@ +primary(['role_id', 'user_id']); + + $table->foreignId('role_id')->constrained('roles')->onDelete('Cascade'); + $table->foreignId('user_id')->constrained('users')->onDelete('Cascade'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('role_user'); + } +} diff --git a/database/seeds/DatabaseSeeder.php b/database/seeds/DatabaseSeeder.php index cc26d02..3057054 100644 --- a/database/seeds/DatabaseSeeder.php +++ b/database/seeds/DatabaseSeeder.php @@ -15,39 +15,8 @@ class DatabaseSeeder extends Seeder */ public function run() { - $users = [ - [ - 'id' => 1, - 'name' => 'Pavel', - 'email' => 'admin@mail.ru', - 'password' => bcrypt('1'), - 'remember_token' => Str::random(10), - 'created_at' => Carbon::now()->format('Y-m-d H:i:s'), - 'updated_at' => Carbon::now()->format('Y-m-d H:i:s'), - ], - [ - 'id' => 2, - 'name' => 'user', - 'email' => 'user@mail.ru', - 'password' => Hash::make('1'), - 'remember_token' => Str::random(10), - 'created_at' => Carbon::now()->format('Y-m-d H:i:s'), - 'updated_at' => Carbon::now()->format('Y-m-d H:i:s'), - ], - ]; - - $grants = [ - ['id' => 1, 'name' => 'admin'], - ['id' => 2, 'name' => 'registered'], - ]; - - $grant_user = [ - ['grant_id' => 1, 'user_id' => 1], - ['grant_id' => 2, 'user_id' => 2], - ]; - - DB::table('users')->insert($users); - DB::table('grants')->insert($grants); - DB::table('grant_user')->insert($grant_user); + $this->call(\Database\Seeders\UsersTableSeeder::class); + $this->call(\Database\Seeders\PermissionsTableSeeder::class); + $this->call(\Database\Seeders\RolesTableSeeder::class); } } diff --git a/database/seeds/PermissionsTableSeeder.php b/database/seeds/PermissionsTableSeeder.php new file mode 100644 index 0000000..9168179 --- /dev/null +++ b/database/seeds/PermissionsTableSeeder.php @@ -0,0 +1,27 @@ +count(3) + ->state(new Sequence( + ['name' => 'user.create'], + ['name' => 'user.update'], + ['name' => 'user.delete'], + )) + ->create(); + } +} diff --git a/database/seeds/RolesTableSeeder.php b/database/seeds/RolesTableSeeder.php new file mode 100644 index 0000000..dc76f4c --- /dev/null +++ b/database/seeds/RolesTableSeeder.php @@ -0,0 +1,27 @@ +count(3) + ->state(new Sequence( + ['name' => 'admin'], + ['name' => 'moderator'], + ['name' => 'registered'] + )) + ->create(); + } +} diff --git a/database/seeds/UsersTableSeeder.php b/database/seeds/UsersTableSeeder.php new file mode 100644 index 0000000..c9971cf --- /dev/null +++ b/database/seeds/UsersTableSeeder.php @@ -0,0 +1,21 @@ +create([ + 'name' => 'Pavel', + 'email' => 'admin@mail.ru', + 'password' => Hash::make('1') + ]); + + User::factory()->count(3)->create(); + } +} diff --git a/resources/views/auth/login.blade.php b/resources/views/auth/login.blade.php index 80108b6..b6a1409 100644 --- a/resources/views/auth/login.blade.php +++ b/resources/views/auth/login.blade.php @@ -5,8 +5,8 @@ @endsection @section('content') -
-
+
+
{{ __('Login') }}
From acd8622bab8c75b85af4be5f10490bb58032a067 Mon Sep 17 00:00:00 2001 From: apsky Date: Tue, 22 Sep 2020 17:41:29 +0300 Subject: [PATCH 03/11] add PostFactory with some changes --- app/Post.php | 3 +++ database/factories/PostFactory.php | 32 +++++++++++++++++++++++ database/seeds/PermissionsTableSeeder.php | 10 ++++--- database/seeds/PostsTableSeeder.php | 19 ++++++++++++++ database/seeds/UsersTableSeeder.php | 5 ++-- 5 files changed, 63 insertions(+), 6 deletions(-) create mode 100644 database/factories/PostFactory.php create mode 100644 database/seeds/PostsTableSeeder.php diff --git a/app/Post.php b/app/Post.php index a8c2092..90c29ac 100644 --- a/app/Post.php +++ b/app/Post.php @@ -3,10 +3,13 @@ namespace App; use App\Events\PostCreated; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Post extends Model { + use HasFactory; + protected $table = 'posts'; protected $guarded = []; diff --git a/database/factories/PostFactory.php b/database/factories/PostFactory.php new file mode 100644 index 0000000..923bc02 --- /dev/null +++ b/database/factories/PostFactory.php @@ -0,0 +1,32 @@ + $this->faker->unique()->regexify('[a-zA-Z0-9_-]+'), + 'name' => $this->faker->words(2, true), + 'description' => $this->faker->words(3, true), + 'text' => $this->faker->text + ]; + } +} diff --git a/database/seeds/PermissionsTableSeeder.php b/database/seeds/PermissionsTableSeeder.php index 9168179..d791c43 100644 --- a/database/seeds/PermissionsTableSeeder.php +++ b/database/seeds/PermissionsTableSeeder.php @@ -16,11 +16,13 @@ class PermissionsTableSeeder extends Seeder public function run() { Permission::factory() - ->count(3) + ->count(5) ->state(new Sequence( - ['name' => 'user.create'], - ['name' => 'user.update'], - ['name' => 'user.delete'], + ['name' => 'viewAny'], + ['name' => 'view'], + ['name' => 'create'], + ['name' => 'update'], + ['name' => 'delete'], )) ->create(); } diff --git a/database/seeds/PostsTableSeeder.php b/database/seeds/PostsTableSeeder.php new file mode 100644 index 0000000..1ce19a4 --- /dev/null +++ b/database/seeds/PostsTableSeeder.php @@ -0,0 +1,19 @@ +count(3)->create(); + } +} diff --git a/database/seeds/UsersTableSeeder.php b/database/seeds/UsersTableSeeder.php index c9971cf..fe14428 100644 --- a/database/seeds/UsersTableSeeder.php +++ b/database/seeds/UsersTableSeeder.php @@ -2,6 +2,7 @@ namespace Database\Seeders; +use App\Post; use App\User; use Illuminate\Database\Seeder; use Illuminate\Support\Facades\Hash; @@ -10,12 +11,12 @@ class UsersTableSeeder extends Seeder { public function run() { - User::factory()->create([ + User::factory()->has(Post::factory()->count(2))->create([ 'name' => 'Pavel', 'email' => 'admin@mail.ru', 'password' => Hash::make('1') ]); - User::factory()->count(3)->create(); + User::factory()->has(Post::factory()->count(2))->count(3)->create(); } } From 9e9adaa9d3fd01cf045c19c2d19b5325521276e2 Mon Sep 17 00:00:00 2001 From: pashaapsky Date: Tue, 22 Sep 2020 22:16:18 +0300 Subject: [PATCH 04/11] work with users, roles and permisions factories and seeders --- app/Role.php | 5 +++ app/Tag.php | 3 ++ database/factories/TagFactory.php | 19 +++++++++ .../2020_09_18_134638_create_roles_table.php | 3 +- ..._09_18_134809_create_permissions_table.php | 3 +- database/seeds/DatabaseSeeder.php | 2 +- database/seeds/PermissionsTableSeeder.php | 40 ++++++++++++------- database/seeds/RolesTableSeeder.php | 34 ++++++++++------ database/seeds/UsersTableSeeder.php | 32 ++++++++++++--- 9 files changed, 104 insertions(+), 37 deletions(-) create mode 100644 database/factories/TagFactory.php diff --git a/app/Role.php b/app/Role.php index 20c63c7..6b52b31 100644 --- a/app/Role.php +++ b/app/Role.php @@ -17,4 +17,9 @@ public function permissions() { return $this->belongsToMany(Permission::class); } + + public function users() + { + return $this->belongsToMany(User::class); + } } diff --git a/app/Tag.php b/app/Tag.php index aee6777..8df7266 100644 --- a/app/Tag.php +++ b/app/Tag.php @@ -2,10 +2,13 @@ namespace App; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Tag extends Model { + use HasFactory; + protected $table = 'tags'; protected $guarded = []; diff --git a/database/factories/TagFactory.php b/database/factories/TagFactory.php new file mode 100644 index 0000000..ea6a3c1 --- /dev/null +++ b/database/factories/TagFactory.php @@ -0,0 +1,19 @@ + $this->faker->unique()->word + ]; + } +} diff --git a/database/migrations/2020_09_18_134638_create_roles_table.php b/database/migrations/2020_09_18_134638_create_roles_table.php index 4c1b24c..56cd593 100644 --- a/database/migrations/2020_09_18_134638_create_roles_table.php +++ b/database/migrations/2020_09_18_134638_create_roles_table.php @@ -15,7 +15,8 @@ public function up() { Schema::create('roles', function (Blueprint $table) { $table->id(); - $table->string('name'); + $table->string('name')->unique(); + $table->string('slug')->unique(); }); } diff --git a/database/migrations/2020_09_18_134809_create_permissions_table.php b/database/migrations/2020_09_18_134809_create_permissions_table.php index f05b6f8..c60db6b 100644 --- a/database/migrations/2020_09_18_134809_create_permissions_table.php +++ b/database/migrations/2020_09_18_134809_create_permissions_table.php @@ -15,7 +15,8 @@ public function up() { Schema::create('permissions', function (Blueprint $table) { $table->id(); - $table->string('name'); + $table->string('name')->unique(); + $table->string('slug')->unique();; }); } diff --git a/database/seeds/DatabaseSeeder.php b/database/seeds/DatabaseSeeder.php index 3057054..504ce7f 100644 --- a/database/seeds/DatabaseSeeder.php +++ b/database/seeds/DatabaseSeeder.php @@ -15,8 +15,8 @@ class DatabaseSeeder extends Seeder */ public function run() { - $this->call(\Database\Seeders\UsersTableSeeder::class); $this->call(\Database\Seeders\PermissionsTableSeeder::class); $this->call(\Database\Seeders\RolesTableSeeder::class); + $this->call(\Database\Seeders\UsersTableSeeder::class); } } diff --git a/database/seeds/PermissionsTableSeeder.php b/database/seeds/PermissionsTableSeeder.php index d791c43..f7e7b09 100644 --- a/database/seeds/PermissionsTableSeeder.php +++ b/database/seeds/PermissionsTableSeeder.php @@ -8,22 +8,32 @@ class PermissionsTableSeeder extends Seeder { - /** - * Run the database seeds. - * - * @return void - */ public function run() { - Permission::factory() - ->count(5) - ->state(new Sequence( - ['name' => 'viewAny'], - ['name' => 'view'], - ['name' => 'create'], - ['name' => 'update'], - ['name' => 'delete'], - )) - ->create(); + $permissions = [ + [ + 'name' => 'view posts', + 'slug' => 'view-posts' + ], + [ + 'name' => 'create posts', + 'slug' => 'create-posts' + ], + [ + 'name' => 'update posts', + 'slug' => 'update-posts' + ], + [ + 'name' => 'delete posts', + 'slug' => 'delete-posts' + ], + ]; + + foreach ($permissions as $permission) { + Permission::factory()->create([ + 'name' => $permission['name'], + 'slug' => $permission['slug'] + ]); + } } } diff --git a/database/seeds/RolesTableSeeder.php b/database/seeds/RolesTableSeeder.php index dc76f4c..d437fe7 100644 --- a/database/seeds/RolesTableSeeder.php +++ b/database/seeds/RolesTableSeeder.php @@ -8,20 +8,28 @@ class RolesTableSeeder extends Seeder { - /** - * Run the database seeds. - * - * @return void - */ public function run() { - Role::factory() - ->count(3) - ->state(new Sequence( - ['name' => 'admin'], - ['name' => 'moderator'], - ['name' => 'registered'] - )) - ->create(); + $roles = [ + [ + 'name' => 'admin', + 'slug' => 'admin' + ], + [ + 'name' => 'site manager', + 'slug' => 'site-manager' + ], + [ + 'name' => 'registered', + 'slug' => 'registered' + ] + ]; + + foreach ($roles as $role) { + Role::factory()->create([ + 'name' => $role['name'], + 'slug' => $role['slug'] + ]); + } } } diff --git a/database/seeds/UsersTableSeeder.php b/database/seeds/UsersTableSeeder.php index fe14428..15db940 100644 --- a/database/seeds/UsersTableSeeder.php +++ b/database/seeds/UsersTableSeeder.php @@ -3,6 +3,8 @@ namespace Database\Seeders; use App\Post; +use App\Role; +use App\Tag; use App\User; use Illuminate\Database\Seeder; use Illuminate\Support\Facades\Hash; @@ -11,12 +13,30 @@ class UsersTableSeeder extends Seeder { public function run() { - User::factory()->has(Post::factory()->count(2))->create([ - 'name' => 'Pavel', - 'email' => 'admin@mail.ru', - 'password' => Hash::make('1') - ]); + $adminRole = Role::where('slug', 'admin')->first(); + $registeredRole = Role::where('slug', 'registered')->first(); - User::factory()->has(Post::factory()->count(2))->count(3)->create(); + User::factory() + ->has(Post::factory() + ->has(Tag::factory()->count(random_int(1,2))) + ->count(2)) + ->create([ + 'name' => 'Pavel', + 'email' => 'admin@mail.ru', + 'password' => Hash::make('1') + ]) + ->roles()->attach($adminRole) + ; + + User::factory() + ->has(Post::factory() + ->has(Tag::factory()->count(random_int(1,2))) + ->count(9)) + ->count(2) + ->create() + ->each(function ($user) use ($registeredRole) { + $user->roles()->attach($registeredRole); + }) + ; } } From fec38446b457f44275090c83e72671e3ea216933 Mon Sep 17 00:00:00 2001 From: apsky Date: Wed, 23 Sep 2020 17:40:46 +0300 Subject: [PATCH 05/11] edit database seeders --- database/factories/PostFactory.php | 18 ++++++++---------- database/seeds/UsersTableSeeder.php | 10 +++++++--- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/database/factories/PostFactory.php b/database/factories/PostFactory.php index 923bc02..8e6d0aa 100644 --- a/database/factories/PostFactory.php +++ b/database/factories/PostFactory.php @@ -3,27 +3,25 @@ namespace Database\Factories; use App\Post; +use App\User; use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Support\Str; class PostFactory extends Factory { - /** - * The name of the factory's corresponding model. - * - * @var string - */ protected $model = Post::class; - /** - * Define the model's default state. - * - * @return array - */ public function definition() { + $activeUsers = User::all(); + + if ($activeUsers->isEmpty()) { + $activeUsers = collect([User::factory()->create()]); + } + return [ 'code' => $this->faker->unique()->regexify('[a-zA-Z0-9_-]+'), + 'owner_id' => $activeUsers->random(1)->first(), 'name' => $this->faker->words(2, true), 'description' => $this->faker->words(3, true), 'text' => $this->faker->text diff --git a/database/seeds/UsersTableSeeder.php b/database/seeds/UsersTableSeeder.php index 15db940..f7f5294 100644 --- a/database/seeds/UsersTableSeeder.php +++ b/database/seeds/UsersTableSeeder.php @@ -2,6 +2,7 @@ namespace Database\Seeders; +use App\Permission; use App\Post; use App\Role; use App\Tag; @@ -18,7 +19,7 @@ public function run() User::factory() ->has(Post::factory() - ->has(Tag::factory()->count(random_int(1,2))) + ->has(Tag::factory()->count(random_int(0,2))) ->count(2)) ->create([ 'name' => 'Pavel', @@ -30,13 +31,16 @@ public function run() User::factory() ->has(Post::factory() - ->has(Tag::factory()->count(random_int(1,2))) + ->has(Tag::factory()->count(random_int(0,2))) ->count(9)) ->count(2) ->create() - ->each(function ($user) use ($registeredRole) { + ->each(function (User $user) use ($registeredRole) { $user->roles()->attach($registeredRole); }) ; + + $adminRole->permissions()->attach(Permission::all()); + $registeredRole->permissions()->attach(Permission::all()); } } From e6a54c5abe13d01cbee34aed07043e4272f57aeb Mon Sep 17 00:00:00 2001 From: pashaapsky Date: Wed, 23 Sep 2020 23:28:28 +0300 Subject: [PATCH 06/11] make RolesAndPermission Middleware. Edit PostsController policies. Edit Seeders --- app/Http/Controllers/PostsController.php | 9 ++- app/Http/Kernel.php | 1 + app/Http/Middleware/RoleMiddleware.php | 22 +++++ app/Permission.php | 5 ++ app/Policies/PostPolicy.php | 10 +++ app/Providers/AuthServiceProvider.php | 5 +- app/Traits/HasRolesAndPermissions.php | 81 +++++++++++++++++++ app/User.php | 6 +- ...23_202223_create_permission_user_table.php | 33 ++++++++ database/seeds/PostsTableSeeder.php | 19 ----- database/seeds/UsersTableSeeder.php | 31 ++++--- 11 files changed, 188 insertions(+), 34 deletions(-) create mode 100644 app/Http/Middleware/RoleMiddleware.php create mode 100644 app/Traits/HasRolesAndPermissions.php create mode 100644 database/migrations/2020_09_23_202223_create_permission_user_table.php delete mode 100644 database/seeds/PostsTableSeeder.php diff --git a/app/Http/Controllers/PostsController.php b/app/Http/Controllers/PostsController.php index 723ecbf..4c74e39 100644 --- a/app/Http/Controllers/PostsController.php +++ b/app/Http/Controllers/PostsController.php @@ -16,7 +16,6 @@ class PostsController extends Controller public function __construct() { $this->middleware('auth'); - $this->middleware('can:update,post')->except(['index', 'userPosts', 'adminIndex', 'create', 'store']); } public function validateRequest($request, $post) @@ -79,16 +78,22 @@ public function store(Request $request) public function show(Post $post) { + $this->authorize('view', $post); + return view('/posts.show', compact('post')); } public function edit(Post $post) { + $this->authorize('update', $post); + return view('/posts.edit', compact('post')); } public function update(Request $request, Post $post) { + $this->authorize('update', $post); + $values = $this->validateRequest($request, $post); $post->update($values); @@ -127,6 +132,8 @@ public function update(Request $request, Post $post) public function destroy(Post $post) { + $this->authorize('delete', $post); + $post->delete(); sendMailNotifyToAdmin(new PostDeleted($post)); diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 36ced13..b704d04 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -63,5 +63,6 @@ class Kernel extends HttpKernel 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, + 'role' => \App\Http\Middleware\RoleMiddleware::class, ]; } diff --git a/app/Http/Middleware/RoleMiddleware.php b/app/Http/Middleware/RoleMiddleware.php new file mode 100644 index 0000000..e256600 --- /dev/null +++ b/app/Http/Middleware/RoleMiddleware.php @@ -0,0 +1,22 @@ +user()->hasRole($role)) { + abort(403, 'THIS ACTION IS UNAUTHORIZED.'); + } + + if ($permission !== null && !auth()->user()->hasPermissionTo($permission)) { + abort(403, 'THIS ACTION IS UNAUTHORIZED.'); + } + + return $next($request); + } +} diff --git a/app/Permission.php b/app/Permission.php index d8dd422..1dc414c 100644 --- a/app/Permission.php +++ b/app/Permission.php @@ -17,4 +17,9 @@ public function roles() { return $this->belongsToMany(Role::class); } + + public function users() + { + return $this->belongsToMany(User::class); + } } diff --git a/app/Policies/PostPolicy.php b/app/Policies/PostPolicy.php index 6275d0d..f2be6fe 100644 --- a/app/Policies/PostPolicy.php +++ b/app/Policies/PostPolicy.php @@ -10,8 +10,18 @@ class PostPolicy { use HandlesAuthorization; + public function view(User $user, Post $post) + { + return $post->owner_id == $user->id; + } + public function update(User $user, Post $post) { return $post->owner_id == $user->id; } + + public function delete(User $user, Post $post) + { + return $post->owner_id == $user->id; + } } diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php index 4671263..e6f9098 100644 --- a/app/Providers/AuthServiceProvider.php +++ b/app/Providers/AuthServiceProvider.php @@ -2,6 +2,8 @@ namespace App\Providers; +use App\Policies\PostPolicy; +use App\Post; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; use Illuminate\Contracts\Auth\Access\Gate; @@ -14,7 +16,8 @@ class AuthServiceProvider extends ServiceProvider */ protected $policies = [ // 'App\Model' => 'App\Policies\ModelPolicy', - 'App\Post' => 'App\Policies\PostPolicy', + Post::class => PostPolicy::class + //'App\Post' => 'App\Policies\PostPolicy', ]; /** diff --git a/app/Traits/HasRolesAndPermissions.php b/app/Traits/HasRolesAndPermissions.php new file mode 100644 index 0000000..54e40b6 --- /dev/null +++ b/app/Traits/HasRolesAndPermissions.php @@ -0,0 +1,81 @@ +belongsToMany(Role::class); + } + + public function permissions() + { + return $this->belongsToMany(Permission::class); + } + + public function hasRole(... $roles) + { + foreach ($roles as $role) { + if ($this->roles->contains('slug', $role)) { + return true; + } + } + return false; + } + + public function hasPermission($permission) + { + return (bool) $this->permissions->where('slug', $permission)->count(); + } + + public function hasPermissionThroughRole($permission) + { + foreach ($permission->roles as $role){ + if($this->roles->contains($role)) { + return true; + } + } + return false; + } + + public function hasPermissionTo($permission) + { + return $this->hasPermissionThroughRole($permission) || $this->hasPermission($permission->slug); + } + + public function getAllPermissions(array $permissions) + { + return Permission::whereIn('slug', $permissions)->get(); + } + + public function givePermissionsTo(... $permissions) + { + $permissions = $this->getAllPermissions($permissions); + + if ($permissions === null) { + return $this; + } + + $this->permissions()->saveMany($permissions); + return $this; + } + + public function deletePermissions(... $permissions ) + { + $permissions = $this->getAllPermissions($permissions); + + $this->permissions()->detach($permissions); + return $this; + } + + public function refreshPermissions(... $permissions ) + { + $this->permissions()->detach(); + + return $this->givePermissionsTo($permissions); + } +} diff --git a/app/User.php b/app/User.php index 21b1cf5..26ee71b 100644 --- a/app/User.php +++ b/app/User.php @@ -2,6 +2,7 @@ namespace App; +use App\Traits\HasRolesAndPermissions; use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Foundation\Auth\User as Authenticatable; @@ -11,6 +12,7 @@ class User extends Authenticatable { use Notifiable; use HasFactory; + use HasRolesAndPermissions; protected $fillable = [ 'name', 'email', 'password', @@ -28,8 +30,4 @@ public function posts() { return $this->hasMany(Post::class, 'owner_id'); } - - public function roles() { - return $this->belongsToMany(Role::class); - } } diff --git a/database/migrations/2020_09_23_202223_create_permission_user_table.php b/database/migrations/2020_09_23_202223_create_permission_user_table.php new file mode 100644 index 0000000..ce5c8fa --- /dev/null +++ b/database/migrations/2020_09_23_202223_create_permission_user_table.php @@ -0,0 +1,33 @@ +primary(['permission_id', 'user_id']); + + $table->foreignId('permission_id')->constrained('permissions')->onDelete('Cascade'); + $table->foreignId('user_id')->constrained('users')->onDelete('Cascade'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('permission_user'); + } +} diff --git a/database/seeds/PostsTableSeeder.php b/database/seeds/PostsTableSeeder.php deleted file mode 100644 index 1ce19a4..0000000 --- a/database/seeds/PostsTableSeeder.php +++ /dev/null @@ -1,19 +0,0 @@ -count(3)->create(); - } -} diff --git a/database/seeds/UsersTableSeeder.php b/database/seeds/UsersTableSeeder.php index f7f5294..8f11443 100644 --- a/database/seeds/UsersTableSeeder.php +++ b/database/seeds/UsersTableSeeder.php @@ -15,28 +15,41 @@ class UsersTableSeeder extends Seeder public function run() { $adminRole = Role::where('slug', 'admin')->first(); + $adminPermissions = Permission::all(); + + $registeredPermissions = ['view-posts', 'create-posts', 'update-posts', 'delete-posts']; + $registeredPermissions = Permission::whereIn('slug', $registeredPermissions)->get(); $registeredRole = Role::where('slug', 'registered')->first(); - User::factory() + $tags = Tag::factory()->count(10)->create(); + + $admin = User::factory() ->has(Post::factory() - ->has(Tag::factory()->count(random_int(0,2))) - ->count(2)) - ->create([ + ->count(2) + )->create([ 'name' => 'Pavel', 'email' => 'admin@mail.ru', 'password' => Hash::make('1') - ]) - ->roles()->attach($adminRole) - ; + ]); + + $admin->posts()->each(function ($post) use ($tags) { + $post->tags()->attach($tags->random(random_int(0, 2))); + }); + + $admin->roles()->attach($adminRole); + $admin->permissions()->attach($adminPermissions); User::factory() ->has(Post::factory() - ->has(Tag::factory()->count(random_int(0,2))) ->count(9)) ->count(2) ->create() - ->each(function (User $user) use ($registeredRole) { + ->each(function (User $user) use ($registeredRole, $registeredPermissions, $tags) { $user->roles()->attach($registeredRole); + $user->permissions()->attach($registeredPermissions); + $user->posts()->each(function ($post) use ($tags) { + $post->tags()->attach($tags->random(random_int(1, 2))); + }); }) ; From 75889c7b7c526477aed6754afd6d1565ba31cb8f Mon Sep 17 00:00:00 2001 From: apsky Date: Thu, 24 Sep 2020 17:45:07 +0300 Subject: [PATCH 07/11] work with controllers --- .../Controllers/AdministrationController.php | 23 +++++++++++++++++++ app/Http/Controllers/FeedbacksController.php | 2 +- app/Http/Controllers/PostsController.php | 5 ---- app/Providers/AuthServiceProvider.php | 3 +-- app/Providers/TelescopeServiceProvider.php | 4 ++-- .../layouts/admin/admin-header.blade.php | 2 +- resources/views/posts/admin-index.blade.php | 2 +- resources/views/posts/index.blade.php | 2 +- routes/web.php | 7 ++---- 9 files changed, 32 insertions(+), 18 deletions(-) create mode 100644 app/Http/Controllers/AdministrationController.php diff --git a/app/Http/Controllers/AdministrationController.php b/app/Http/Controllers/AdministrationController.php new file mode 100644 index 0000000..2756c82 --- /dev/null +++ b/app/Http/Controllers/AdministrationController.php @@ -0,0 +1,23 @@ +middleware('role:admin'); + } + + public function index() { + return view('admin.index'); + } + + public function posts() { + $posts = Post::with('tags')->latest()->get(); + return view('/posts.admin-index', compact('posts')); + } +} diff --git a/app/Http/Controllers/FeedbacksController.php b/app/Http/Controllers/FeedbacksController.php index f2ba7c5..2482d35 100644 --- a/app/Http/Controllers/FeedbacksController.php +++ b/app/Http/Controllers/FeedbacksController.php @@ -9,7 +9,7 @@ class FeedbacksController extends Controller { public function __construct() { - $this->middleware('auth'); + $this->middleware('role:admin'); } public function index() diff --git a/app/Http/Controllers/PostsController.php b/app/Http/Controllers/PostsController.php index 4c74e39..e658273 100644 --- a/app/Http/Controllers/PostsController.php +++ b/app/Http/Controllers/PostsController.php @@ -40,11 +40,6 @@ public function userPosts() return view('/posts.index', compact('posts')); } - public function adminIndex() { - $posts = Post::with('tags')->latest()->get(); - return view('/posts.admin-index', compact('posts')); - } - public function create() { return view('/posts.create'); diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php index e6f9098..e4f261f 100644 --- a/app/Providers/AuthServiceProvider.php +++ b/app/Providers/AuthServiceProvider.php @@ -17,7 +17,6 @@ class AuthServiceProvider extends ServiceProvider protected $policies = [ // 'App\Model' => 'App\Policies\ModelPolicy', Post::class => PostPolicy::class - //'App\Post' => 'App\Policies\PostPolicy', ]; /** @@ -31,7 +30,7 @@ public function boot(Gate $gate) $this->registerPolicies(); $gate->before(function ($user) { - if ($user->email == 'admin@mail.ru') { + if ($user->email == env('ADMIN_EMAIL_FOR_NOTIFICATIONS')) { return true; } }); diff --git a/app/Providers/TelescopeServiceProvider.php b/app/Providers/TelescopeServiceProvider.php index 75f53ee..3ed290a 100644 --- a/app/Providers/TelescopeServiceProvider.php +++ b/app/Providers/TelescopeServiceProvider.php @@ -16,7 +16,7 @@ class TelescopeServiceProvider extends TelescopeApplicationServiceProvider */ public function register() { - // Telescope::night(); +// Telescope::night(); $this->hideSensitiveRequestDetails(); @@ -64,7 +64,7 @@ protected function gate() { Gate::define('viewTelescope', function ($user) { return in_array($user->email, [ - 'ap.sky@yandex.ru' + env('ADMIN_EMAIL_FOR_NOTIFICATIONS') ]); }); } diff --git a/resources/views/layouts/admin/admin-header.blade.php b/resources/views/layouts/admin/admin-header.blade.php index c9776df..066dd62 100644 --- a/resources/views/layouts/admin/admin-header.blade.php +++ b/resources/views/layouts/admin/admin-header.blade.php @@ -25,7 +25,7 @@ diff --git a/resources/views/posts/admin-index.blade.php b/resources/views/posts/admin-index.blade.php index 3cb7e40..0b1ca96 100644 --- a/resources/views/posts/admin-index.blade.php +++ b/resources/views/posts/admin-index.blade.php @@ -38,7 +38,7 @@
Edit -
+ @csrf @method('DELETE') diff --git a/resources/views/posts/index.blade.php b/resources/views/posts/index.blade.php index 782a690..2d9cb38 100644 --- a/resources/views/posts/index.blade.php +++ b/resources/views/posts/index.blade.php @@ -46,7 +46,7 @@
Edit - + @csrf @method('DELETE') diff --git a/routes/web.php b/routes/web.php index d89879f..f342db4 100644 --- a/routes/web.php +++ b/routes/web.php @@ -8,15 +8,12 @@ Route::get('/posts', 'PostsController@userPosts')->name('user.posts'); Route::resource('posts', PostsController::class)->except(['index']); -Route::get('/admin/posts', 'PostsController@adminIndex')->name('admin-post-index'); - Route::get('/about', 'StaticPagesController@aboutIndex')->name('about'); Route::get('/contacts', 'StaticPagesController@contactsIndex')->name('contacts'); -Route::get('/admin', function () { - return view('admin.index'); -})->name('admin'); +Route::get('/admin', 'AdministrationController@index')->name('admin'); +Route::get('/admin/posts', 'AdministrationController@posts')->name('admin.posts.index'); Route::get('/admin/feedbacks', 'FeedbacksController@index')->name('feedback');; Route::post('/admin/feedbacks', 'FeedbacksController@store'); From 339055a6fe51d0b8413afb92ee6aa978bf59ece8 Mon Sep 17 00:00:00 2001 From: apsky Date: Fri, 25 Sep 2020 16:42:38 +0300 Subject: [PATCH 08/11] add send email command every week --- app/Console/Commands/SendNewPosts.php | 47 +++++++++++++++++++ app/Console/Kernel.php | 6 ++- .../Controllers/AdministrationController.php | 2 +- app/Http/Controllers/PostsController.php | 4 +- app/Http/Middleware/RoleMiddleware.php | 14 ++++-- app/Notifications/PostsForPeriod.php | 37 +++++++++++++++ database/factories/PostFactory.php | 3 +- .../posts.blade.php} | 0 .../layouts/admin/admin-header.blade.php | 2 +- resources/views/layouts/base/header.blade.php | 30 +++++++----- .../views/mail/posts-for-period.blade.php | 17 +++++++ resources/views/static/contacts.blade.php | 8 ++-- routes/web.php | 2 +- 13 files changed, 145 insertions(+), 27 deletions(-) create mode 100644 app/Console/Commands/SendNewPosts.php create mode 100644 app/Notifications/PostsForPeriod.php rename resources/views/{posts/admin-index.blade.php => admin/posts.blade.php} (100%) create mode 100644 resources/views/mail/posts-for-period.blade.php diff --git a/app/Console/Commands/SendNewPosts.php b/app/Console/Commands/SendNewPosts.php new file mode 100644 index 0000000..4ba6e9f --- /dev/null +++ b/app/Console/Commands/SendNewPosts.php @@ -0,0 +1,47 @@ +=', $this->argument('since'))->latest()->take(5)->get(); + + if ($posts->isNotEmpty() && $users->isNotEmpty()) { + $this->alert('Письма отправляются...'); + + $bar = $this->output->createProgressBar(count($users)); + + $bar->start(); + + foreach ($users as $user) { + $user->notify(new PostsForPeriod($posts)); + + $bar->advance(); + } + + $bar->finish(); + $this->info(PHP_EOL . 'Письма успешно отправленны'); + } else { + $this->info(PHP_EOL . 'Письма не были отправлены. Проверьте введенные параметры.'); + } + + return 0; + } +} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 69914e9..944dba0 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -2,6 +2,8 @@ namespace App\Console; +use App\Console\Commands\SendNewPosts; +use Carbon\Carbon; use Illuminate\Console\Scheduling\Schedule; use Illuminate\Foundation\Console\Kernel as ConsoleKernel; @@ -24,7 +26,9 @@ class Kernel extends ConsoleKernel */ protected function schedule(Schedule $schedule) { - // $schedule->command('inspire')->hourly(); + $now = Carbon::now()->format('Y-m-d'); + + $schedule->command(SendNewPosts::class, [$now])->weekly()->mondays()->at('09:00'); } /** diff --git a/app/Http/Controllers/AdministrationController.php b/app/Http/Controllers/AdministrationController.php index 2756c82..c796560 100644 --- a/app/Http/Controllers/AdministrationController.php +++ b/app/Http/Controllers/AdministrationController.php @@ -18,6 +18,6 @@ public function index() { public function posts() { $posts = Post::with('tags')->latest()->get(); - return view('/posts.admin-index', compact('posts')); + return view('/admin.posts', compact('posts')); } } diff --git a/app/Http/Controllers/PostsController.php b/app/Http/Controllers/PostsController.php index e658273..49a0492 100644 --- a/app/Http/Controllers/PostsController.php +++ b/app/Http/Controllers/PostsController.php @@ -30,7 +30,7 @@ public function validateRequest($request, $post) public function index() { - $posts = Post::with('tags')->latest()->get(); + $posts = Post::with('tags')->where('published', 1)->latest()->get(); return view('/index', compact('posts')); } @@ -91,6 +91,8 @@ public function update(Request $request, Post $post) $values = $this->validateRequest($request, $post); + $request->has('published') ? $values['published'] = 1 : $values['published'] = 0; + $post->update($values); $postTags = $post->tags->keyBy('name'); diff --git a/app/Http/Middleware/RoleMiddleware.php b/app/Http/Middleware/RoleMiddleware.php index e256600..0764c0f 100644 --- a/app/Http/Middleware/RoleMiddleware.php +++ b/app/Http/Middleware/RoleMiddleware.php @@ -9,12 +9,16 @@ class RoleMiddleware { public function handle(Request $request, Closure $next, $role, $permission = null) { - if (!auth()->user()->hasRole($role)) { - abort(403, 'THIS ACTION IS UNAUTHORIZED.'); - } + if (auth()->user()) { + if (!auth()->user()->hasRole($role)) { + abort(403, 'THIS ACTION IS UNAUTHORIZED.'); + } - if ($permission !== null && !auth()->user()->hasPermissionTo($permission)) { - abort(403, 'THIS ACTION IS UNAUTHORIZED.'); + if ($permission !== null && !auth()->user()->hasPermissionTo($permission)) { + abort(403, 'THIS ACTION IS UNAUTHORIZED.'); + } + } else { + return redirect('/'); } return $next($request); diff --git a/app/Notifications/PostsForPeriod.php b/app/Notifications/PostsForPeriod.php new file mode 100644 index 0000000..4f73b32 --- /dev/null +++ b/app/Notifications/PostsForPeriod.php @@ -0,0 +1,37 @@ +posts = $posts; + } + + public function via($notifiable) + { + return ['mail']; + } + + public function toMail($notifiable) + { + return (new MailMessage)->markdown('mail.posts-for-period', ['posts' => $this->posts]); + } + + public function toArray($notifiable) + { + return [ + // + ]; + } +} diff --git a/database/factories/PostFactory.php b/database/factories/PostFactory.php index 8e6d0aa..07b639f 100644 --- a/database/factories/PostFactory.php +++ b/database/factories/PostFactory.php @@ -24,7 +24,8 @@ public function definition() 'owner_id' => $activeUsers->random(1)->first(), 'name' => $this->faker->words(2, true), 'description' => $this->faker->words(3, true), - 'text' => $this->faker->text + 'text' => $this->faker->text, + 'published' => boolval(rand(0,1)) ]; } } diff --git a/resources/views/posts/admin-index.blade.php b/resources/views/admin/posts.blade.php similarity index 100% rename from resources/views/posts/admin-index.blade.php rename to resources/views/admin/posts.blade.php diff --git a/resources/views/layouts/admin/admin-header.blade.php b/resources/views/layouts/admin/admin-header.blade.php index 066dd62..2d84ef7 100644 --- a/resources/views/layouts/admin/admin-header.blade.php +++ b/resources/views/layouts/admin/admin-header.blade.php @@ -25,7 +25,7 @@ diff --git a/resources/views/layouts/base/header.blade.php b/resources/views/layouts/base/header.blade.php index 5fe9989..8dca032 100644 --- a/resources/views/layouts/base/header.blade.php +++ b/resources/views/layouts/base/header.blade.php @@ -11,21 +11,27 @@
@@ -38,7 +38,7 @@
@@ -54,7 +54,7 @@
@@ -70,7 +70,7 @@
diff --git a/routes/web.php b/routes/web.php index f342db4..a96340d 100644 --- a/routes/web.php +++ b/routes/web.php @@ -13,7 +13,7 @@ Route::get('/contacts', 'StaticPagesController@contactsIndex')->name('contacts'); Route::get('/admin', 'AdministrationController@index')->name('admin'); -Route::get('/admin/posts', 'AdministrationController@posts')->name('admin.posts.index'); +Route::get('/admin/posts', 'AdministrationController@posts')->name('admin.posts'); Route::get('/admin/feedbacks', 'FeedbacksController@index')->name('feedback');; Route::post('/admin/feedbacks', 'FeedbacksController@store'); From b4302d9c578b3029294b52a635dd3c4d2e615e17 Mon Sep 17 00:00:00 2001 From: pashaapsky Date: Sun, 27 Sep 2020 11:49:36 +0300 Subject: [PATCH 09/11] add push notifications to PostController actions --- .env.example | 5 ++++- app/Http/Controllers/PostsController.php | 7 +++++-- app/helpers.php | 23 +++++++++++++++++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/.env.example b/.env.example index 8a5ad36..a4b04fd 100644 --- a/.env.example +++ b/.env.example @@ -45,4 +45,7 @@ PUSHER_APP_CLUSTER=mt1 MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" -ADMIN_EMAIL_FOR_NOTIFICATIONS = 'example@mail.ru' +ADMIN_EMAIL_FOR_NOTIFICATIONS=example@mail.ru + +PUSH_ALL_API_KEY= +PUSH_ALL_API_ID= diff --git a/app/Http/Controllers/PostsController.php b/app/Http/Controllers/PostsController.php index 49a0492..d6e1724 100644 --- a/app/Http/Controllers/PostsController.php +++ b/app/Http/Controllers/PostsController.php @@ -67,6 +67,7 @@ public function store(Request $request) sendMailNotifyToAdmin(new PostCreated($post)); flash( 'Post created successfully'); + pushNotification('Post created successfully'); return redirect('/'); } @@ -123,6 +124,7 @@ public function update(Request $request, Post $post) sendMailNotifyToAdmin(new PostEdited($post)); flash( 'Post edited successfully'); + pushNotification('Post edited successfully'); return back(); } @@ -134,8 +136,9 @@ public function destroy(Post $post) $post->delete(); sendMailNotifyToAdmin(new PostDeleted($post)); - flash( 'Post delete successfully'); + flash( 'Post deleted successfully'); + pushNotification('Post deleted successfully'); - return redirect('/posts'); + return back(); } } diff --git a/app/helpers.php b/app/helpers.php index 927b22b..753ce33 100644 --- a/app/helpers.php +++ b/app/helpers.php @@ -1,5 +1,7 @@ flash('message', $message); session()->flash('message_type', $type); @@ -12,3 +14,24 @@ function sendMailNotifyToAdmin($mailView) { $admin->notify($mailView); } } + +function pushNotification($text, $title = 'Уведомление') { + $id = env('PUSH_ALL_API_ID'); + $key = env('PUSH_ALL_API_KEY'); + + $data = [ + 'type' => 'self', + 'id' => $id, + 'key' => $key, + 'text' => $text, + 'title' => $title + ]; + + $client = new Client([ + 'base_uri' => 'https://pushall.ru/api.php', + ]); + + $response = $client->request('POST', '', [ + 'form_params' => $data + ]); +} From a6374ec459976896f79579ca6386e46ddb6e5126 Mon Sep 17 00:00:00 2001 From: pashaapsky Date: Mon, 28 Sep 2020 21:19:30 +0300 Subject: [PATCH 10/11] add PushNotificationServiceProvider with booting PushNotificationService, correct PR --- app/Http/Controllers/PostsController.php | 8 +-- .../PushNotificationServiceProvider.php | 21 ++++++ app/Services/PushNotificationsService.php | 38 +++++++++++ app/helpers.php | 64 +++++++++++-------- config/app.php | 2 +- 5 files changed, 100 insertions(+), 33 deletions(-) create mode 100644 app/Providers/PushNotificationServiceProvider.php create mode 100644 app/Services/PushNotificationsService.php diff --git a/app/Http/Controllers/PostsController.php b/app/Http/Controllers/PostsController.php index d6e1724..2d183d2 100644 --- a/app/Http/Controllers/PostsController.php +++ b/app/Http/Controllers/PostsController.php @@ -67,7 +67,7 @@ public function store(Request $request) sendMailNotifyToAdmin(new PostCreated($post)); flash( 'Post created successfully'); - pushNotification('Post created successfully'); + pushNotification('Post created successfully', 'New Notification'); return redirect('/'); } @@ -92,7 +92,7 @@ public function update(Request $request, Post $post) $values = $this->validateRequest($request, $post); - $request->has('published') ? $values['published'] = 1 : $values['published'] = 0; + $values['published'] = $request->has('published'); $post->update($values); @@ -124,7 +124,7 @@ public function update(Request $request, Post $post) sendMailNotifyToAdmin(new PostEdited($post)); flash( 'Post edited successfully'); - pushNotification('Post edited successfully'); + pushNotification('Post edited successfully', 'New Notification'); return back(); } @@ -137,7 +137,7 @@ public function destroy(Post $post) sendMailNotifyToAdmin(new PostDeleted($post)); flash( 'Post deleted successfully'); - pushNotification('Post deleted successfully'); + pushNotification('Post deleted successfully', 'New Notification'); return back(); } diff --git a/app/Providers/PushNotificationServiceProvider.php b/app/Providers/PushNotificationServiceProvider.php new file mode 100644 index 0000000..470fd14 --- /dev/null +++ b/app/Providers/PushNotificationServiceProvider.php @@ -0,0 +1,21 @@ +app->singleton(PushNotificationsService::class, function() { + return new PushNotificationsService(env('PUSH_ALL_API_ID'), env('PUSH_ALL_API_KEY')); + }); + } +} diff --git a/app/Services/PushNotificationsService.php b/app/Services/PushNotificationsService.php new file mode 100644 index 0000000..6a4f6b5 --- /dev/null +++ b/app/Services/PushNotificationsService.php @@ -0,0 +1,38 @@ +apiID = $api_id; + $this->apiKey= $api_key; + } + + public function send($text, $title) + { + $data = [ + 'type' => 'self', + 'id' => $this->apiID, + 'key' => $this->apiKey, + 'text' => $text, + 'title' => $title + ]; + + $client = new Client([ + 'base_uri' => 'https://pushall.ru/api.php', + ]); + + $response = $client->request('POST', '', [ + 'form_params' => $data + ]); + + return $response; + } +} diff --git a/app/helpers.php b/app/helpers.php index 753ce33..b7f9ca0 100644 --- a/app/helpers.php +++ b/app/helpers.php @@ -1,37 +1,45 @@ flash('message', $message); - session()->flash('message_type', $type); +if (! function_exists('flash')) { + /** + * @param $message + * @param string $type + */ + function flash($message, $type = 'success') { + session()->flash('message', $message); + session()->flash('message_type', $type); + } } -function sendMailNotifyToAdmin($mailView) { - $admin = \App\User::where('email', env('ADMIN_EMAIL_FOR_NOTIFICATIONS'))->first(); - if ($admin) { - $admin->notify($mailView); +if (! function_exists('sendMailNotifyToAdmin')) { + + /** + * @param $mailView + */ + + function sendMailNotifyToAdmin($mailView) { + $admin = \App\User::where('email', env('ADMIN_EMAIL_FOR_NOTIFICATIONS'))->first(); + + if ($admin) { + $admin->notify($mailView); + } } } -function pushNotification($text, $title = 'Уведомление') { - $id = env('PUSH_ALL_API_ID'); - $key = env('PUSH_ALL_API_KEY'); - - $data = [ - 'type' => 'self', - 'id' => $id, - 'key' => $key, - 'text' => $text, - 'title' => $title - ]; - - $client = new Client([ - 'base_uri' => 'https://pushall.ru/api.php', - ]); - - $response = $client->request('POST', '', [ - 'form_params' => $data - ]); + +if (! function_exists('pushNotification')) { + + /** + * @param null $text + * @param null $title + * @return \App\Services\PushNotificationsService|mixed + */ + function pushNotification($text = null, $title = null) { + if (is_null($text) || is_null($title)) { + return app(\App\Services\PushNotificationsService::class); + } + + return app(\App\Services\PushNotificationsService::class)->send($text, $title); + } } diff --git a/config/app.php b/config/app.php index 79f1db5..37a68bb 100644 --- a/config/app.php +++ b/config/app.php @@ -175,7 +175,7 @@ App\Providers\EventServiceProvider::class, App\Providers\RouteServiceProvider::class, App\Providers\TelescopeServiceProvider::class, - + App\Providers\PushNotificationServiceProvider::class, ], /* From 813d6c9dfb056d46fafe988f6671d409902a3d73 Mon Sep 17 00:00:00 2001 From: pashaapsky Date: Tue, 29 Sep 2020 20:56:20 +0300 Subject: [PATCH 11/11] create admin migration and edit db seeders --- .../2020_09_29_201917_create_user_admin.php | 40 +++++++++++++++++++ database/seeds/DatabaseSeeder.php | 2 - database/seeds/UsersTableSeeder.php | 22 +++------- 3 files changed, 45 insertions(+), 19 deletions(-) create mode 100644 database/migrations/2020_09_29_201917_create_user_admin.php diff --git a/database/migrations/2020_09_29_201917_create_user_admin.php b/database/migrations/2020_09_29_201917_create_user_admin.php new file mode 100644 index 0000000..0a599b7 --- /dev/null +++ b/database/migrations/2020_09_29_201917_create_user_admin.php @@ -0,0 +1,40 @@ +run(); + + $rolesSeeder = new RolesTableSeeder(); + $rolesSeeder->run(); + + $adminRole = Role::where('slug', 'admin')->first(); + $adminPermissions = Permission::all(); + $adminRole->permissions()->attach($adminPermissions); + + $admin = User::factory() + ->create([ + 'name' => 'Pavel', + 'email' => 'admin@mail.ru', + 'password' => Hash::make('1') + ]); + + $admin->roles()->attach($adminRole); + $admin->permissions()->attach($adminPermissions); + } + + public function down() + { + + } +} diff --git a/database/seeds/DatabaseSeeder.php b/database/seeds/DatabaseSeeder.php index 504ce7f..0b25e0f 100644 --- a/database/seeds/DatabaseSeeder.php +++ b/database/seeds/DatabaseSeeder.php @@ -15,8 +15,6 @@ class DatabaseSeeder extends Seeder */ public function run() { - $this->call(\Database\Seeders\PermissionsTableSeeder::class); - $this->call(\Database\Seeders\RolesTableSeeder::class); $this->call(\Database\Seeders\UsersTableSeeder::class); } } diff --git a/database/seeds/UsersTableSeeder.php b/database/seeds/UsersTableSeeder.php index 8f11443..2f4ab8a 100644 --- a/database/seeds/UsersTableSeeder.php +++ b/database/seeds/UsersTableSeeder.php @@ -14,31 +14,22 @@ class UsersTableSeeder extends Seeder { public function run() { - $adminRole = Role::where('slug', 'admin')->first(); - $adminPermissions = Permission::all(); - $registeredPermissions = ['view-posts', 'create-posts', 'update-posts', 'delete-posts']; $registeredPermissions = Permission::whereIn('slug', $registeredPermissions)->get(); + $registeredRole = Role::where('slug', 'registered')->first(); + $registeredRole->permissions()->attach(Permission::all()); $tags = Tag::factory()->count(10)->create(); - $admin = User::factory() - ->has(Post::factory() - ->count(2) - )->create([ - 'name' => 'Pavel', - 'email' => 'admin@mail.ru', - 'password' => Hash::make('1') - ]); + $admin = User::where('email', env('ADMIN_EMAIL_FOR_NOTIFICATIONS'))->first(); + + $admin->posts()->saveMany(Post::factory()->count(2)->create()); $admin->posts()->each(function ($post) use ($tags) { $post->tags()->attach($tags->random(random_int(0, 2))); }); - $admin->roles()->attach($adminRole); - $admin->permissions()->attach($adminPermissions); - User::factory() ->has(Post::factory() ->count(9)) @@ -52,8 +43,5 @@ public function run() }); }) ; - - $adminRole->permissions()->attach(Permission::all()); - $registeredRole->permissions()->attach(Permission::all()); } }