]> BookStack Code Mirror - bookstack/blob - database/migrations/2022_10_08_104202_drop_entity_restricted_field.php
063f924f255846d15b84d053d8518d51572d1250
[bookstack] / database / migrations / 2022_10_08_104202_drop_entity_restricted_field.php
1 <?php
2
3 use Illuminate\Database\Migrations\Migration;
4 use Illuminate\Database\Query\Builder;
5 use Illuminate\Database\Query\JoinClause;
6 use Illuminate\Database\Schema\Blueprint;
7 use Illuminate\Support\Facades\DB;
8 use Illuminate\Support\Facades\Schema;
9
10 class DropEntityRestrictedField extends Migration
11 {
12     /**
13      * Run the migrations.
14      *
15      * @return void
16      */
17     public function up()
18     {
19         // Remove entity-permissions on non-restricted entities
20         $deleteInactiveEntityPermissions = function (string $table, string $morphClass) {
21             $permissionIds = DB::table('entity_permissions')->select('entity_permissions.id as id')
22                 ->join($table, function (JoinClause $join) use ($table, $morphClass) {
23                     return $join->where($table . '.restricted', '=', 0)
24                         ->on($table . '.id', '=', 'entity_permissions.entity_id');
25                 })->where('entity_type', '=', $morphClass)
26                 ->pluck('id');
27             DB::table('entity_permissions')->whereIn('id', $permissionIds)->delete();
28         };
29         $deleteInactiveEntityPermissions('pages', 'page');
30         $deleteInactiveEntityPermissions('chapters', 'chapter');
31         $deleteInactiveEntityPermissions('books', 'book');
32         $deleteInactiveEntityPermissions('bookshelves', 'bookshelf');
33
34         // Migrate restricted=1 entries to new entity_permissions (role_id=0) entries
35         $defaultEntityPermissionGenQuery = function (Builder $query, string $table, string $morphClass) {
36             return $query->select(['id as entity_id'])
37                 ->selectRaw('? as entity_type', [$morphClass])
38                 ->selectRaw('? as `role_id`', [0])
39                 ->selectRaw('? as `view`', [0])
40                 ->selectRaw('? as `create`', [0])
41                 ->selectRaw('? as `update`', [0])
42                 ->selectRaw('? as `delete`', [0])
43                 ->from($table)
44                 ->where('restricted', '=', 1);
45         };
46
47         $query = $defaultEntityPermissionGenQuery(DB::query(), 'pages', 'page')
48             ->union(fn(Builder $query) => $defaultEntityPermissionGenQuery($query, 'books', 'book'))
49             ->union(fn(Builder $query) => $defaultEntityPermissionGenQuery($query, 'chapters', 'chapter'))
50             ->union(fn(Builder $query) => $defaultEntityPermissionGenQuery($query, 'bookshelves', 'bookshelf'));
51
52         DB::table('entity_permissions')->insertUsing(['entity_id', 'entity_type', 'role_id', 'view', 'create', 'update', 'delete'], $query);
53
54         // Drop restricted columns
55         $dropRestrictedColumn = fn(Blueprint $table) => $table->dropColumn('restricted');
56         Schema::table('pages', $dropRestrictedColumn);
57         Schema::table('chapters', $dropRestrictedColumn);
58         Schema::table('books', $dropRestrictedColumn);
59         Schema::table('bookshelves', $dropRestrictedColumn);
60     }
61
62     /**
63      * Reverse the migrations.
64      *
65      * @return void
66      */
67     public function down()
68     {
69         // Create restricted columns
70         $createRestrictedColumn = fn(Blueprint $table) => $table->boolean('restricted')->index()->default(0);
71         Schema::table('pages', $createRestrictedColumn);
72         Schema::table('chapters', $createRestrictedColumn);
73         Schema::table('books', $createRestrictedColumn);
74         Schema::table('bookshelves', $createRestrictedColumn);
75
76         // Set restrictions for entities that have a default entity permission assigned
77         // Note: Possible loss of data where default entity permissions have been configured
78         $restrictEntities = function (string $table, string $morphClass) {
79             $toRestrictIds = DB::table('entity_permissions')
80                 ->where('role_id', '=', 0)
81                 ->where('entity_type', '=', $morphClass)
82                 ->pluck('entity_id');
83             DB::table($table)->whereIn('id', $toRestrictIds)->update(['restricted' => true]);
84         };
85         $restrictEntities('pages', 'page');
86         $restrictEntities('chapters', 'chapter');
87         $restrictEntities('books', 'book');
88         $restrictEntities('bookshelves', 'bookshelf');
89
90         // Delete default entity permissions
91         DB::table('entity_permissions')->where('role_id', '=', 0)->delete();
92     }
93 }