diff --git a/db/migrations/2024_04_20_000000_refactor_permissions_and_groups.php b/db/migrations/2024_04_20_000000_refactor_permissions_and_groups.php new file mode 100644 index 00000000..1c6be487 --- /dev/null +++ b/db/migrations/2024_04_20_000000_refactor_permissions_and_groups.php @@ -0,0 +1,205 @@ +db = $this->schema->getConnection(); + + $this->active = $this->getPrivilegeId('admin_active'); + $this->driveEdit = $this->getPrivilegeId('user.drive.edit'); + $this->eventConfig = $this->getPrivilegeId('admin_event_config'); + $this->goodieEdit = $this->getPrivilegeId('user.goodie.edit'); + $this->ifsgEdit = $this->getPrivilegeId('user.ifsg.edit'); + $this->log = $this->getPrivilegeId('admin_log'); + $this->news = $this->getPrivilegeId('admin_news'); + $this->register = $this->getPrivilegeId('register'); + $this->scheduleImport = $this->getPrivilegeId('schedule.import'); + $this->shifts = $this->getPrivilegeId('admin_shifts'); + $this->user = $this->getPrivilegeId('admin_user'); + $this->userAngeltypes = $this->getPrivilegeId('admin_user_angeltypes'); + $this->userShifts = $this->getPrivilegeId('user_shifts_admin'); + } + + /** + * Run the migration + */ + public function up(): void + { + $this->deletePermission($this->shiftentry); + $this->deletePermission($this->language); + + $this->movePermission($this->active, $this->bureaucrat, $this->shiCo); + $this->movePermission($this->userAngeltypes, $this->bureaucrat, $this->shiCo); + $this->movePermission($this->eventConfig, $this->shiCo, $this->developer); + $this->movePermission($this->goodieEdit, $this->bureaucrat, $this->shiCo); + + $this->insertGroupPermission($this->log, $this->bureaucrat); + + $this->deleteGroupPermission($this->news, $this->bureaucrat); + $this->deleteGroupPermission($this->shifts, $this->bureaucrat); + $this->deleteGroupPermission($this->user, $this->bureaucrat); + $this->deleteGroupPermission($this->register, $this->bureaucrat); + $this->deleteGroupPermission($this->scheduleImport, $this->developer); + + $this->updatePermission($this->shifttypes, $this->shifttypesView, 'View shift types'); + $this->updatePermission($this->userEdit, $this->userNickEdit, 'Edit user nick'); + + $this->deleteGroup($this->newsAdmin); + $this->deleteGroup($this->teamCoordinator); + } + + /** + * Reverse the migration + */ + public function down(): void + { + $this->insertPermission( + $this->shiftentry, + 'If user with this privilege is angeltype supporter, he can put users in shifts for their angeltype', + $this->angel + ); + $this->insertPermission( + $this->language, + 'Translate the system', + $this->developer + ); + + $this->movePermission($this->active, $this->shiCo, $this->bureaucrat); + $this->movePermission($this->userAngeltypes, $this->shiCo, $this->bureaucrat); + $this->movePermission($this->eventConfig, $this->developer, $this->shiCo); + $this->movePermission($this->goodieEdit, $this->shiCo, $this->bureaucrat); + + $this->deleteGroupPermission($this->log, $this->bureaucrat); + + $this->insertGroupPermission($this->news, $this->bureaucrat); + $this->insertGroupPermission($this->shifts, $this->bureaucrat); + $this->insertGroupPermission($this->user, $this->bureaucrat); + $this->insertGroupPermission($this->register, $this->bureaucrat); + $this->insertGroupPermission($this->scheduleImport, $this->developer); + + $this->updatePermission($this->shifttypesView, $this->shifttypes, 'Administrate shift types'); + $this->updatePermission($this->userNickEdit, $this->userEdit, 'Edit user'); + + $this->insertGroup($this->newsAdmin, 'News Admin', [$this->news]); + $this->insertGroup($this->teamCoordinator, 'Team Coordinator', [ + $this->news, + $this->userAngeltypes, + $this->driveEdit, + $this->ifsgEdit, + $this->userShifts, + ]); + } + + protected function getPrivilegeId(string $privilege): int + { + return $this->db->table('privileges') + ->where('name', $privilege) + ->get(['id']) + ->first()->id; + } + + protected function deleteGroup(int $group): void + { + $this->db->table('groups') + ->where(['id' => $group]) + ->delete(); + } + + protected function insertGroup(int $id, string $name, array $privileges): void + { + $this->db->table('groups') + ->insertOrIgnore([ + 'name' => $name, + 'id' => $id, + ]); + foreach ($privileges as $privilege) { + $this->insertGroupPermission($privilege, $id); + } + } + + protected function deleteGroupPermission(int $privilege, int $group): void + { + $this->db->table('group_privileges') + ->where(['group_id' => $group, 'privilege_id' => $privilege]) + ->delete(); + } + + protected function insertGroupPermission(int $privilege, int $group): void + { + $this->db->table('group_privileges') + ->insertOrIgnore([ + ['group_id' => $group, 'privilege_id' => $privilege], + ]); + } + + protected function movePermission(int $privilege, int $oldGroup, int $newGroup): void + { + $this->insertGroupPermission($privilege, $newGroup); + $this->deleteGroupPermission($privilege, $oldGroup); + } + + protected function insertPermission(string $name, string $description, int $group): void + { + $this->db->table('privileges') + ->insertOrIgnore([ + 'name' => $name, 'description' => $description, + ]); + $permission = $this->getPrivilegeId($name); + $this->insertGroupPermission($permission, $group); + } + + protected function deletePermission(string $privilege): void + { + $this->db->table('privileges') + ->where(['name' => $privilege]) + ->delete(); + } + + protected function updatePermission(string $oldName, string $newName, string $description): void + { + $this->db->table('privileges')->where('name', $oldName)->update([ + 'name' => $newName, + 'description' => $description, + ]); + } +} diff --git a/includes/model/Shifts_model.php b/includes/model/Shifts_model.php index 5c6041c1..2457b026 100644 --- a/includes/model/Shifts_model.php +++ b/includes/model/Shifts_model.php @@ -548,8 +548,7 @@ function Shift_signout_allowed(Shift $shift, AngelType $angeltype, $signout_user // angeltype supporter can sign out any user at any time from their supported angeltype if ( - auth()->can('shiftentry_edit_angeltype_supporter') - && ($user->isAngelTypeSupporter($angeltype) || auth()->can('admin_user_angeltypes')) + $user->isAngelTypeSupporter($angeltype) || auth()->can('admin_user_angeltypes') ) { return true; } @@ -587,8 +586,7 @@ function Shift_signup_allowed( } if ( - auth()->can('shiftentry_edit_angeltype_supporter') - && (auth()->user()->isAngelTypeSupporter($angeltype) || auth()->can('admin_user_angeltypes')) + auth()->user()->isAngelTypeSupporter($angeltype) || auth()->can('admin_user_angeltypes') ) { return Shift_signup_allowed_angeltype_supporter($needed_angeltype, $shift_entries); } diff --git a/includes/pages/admin_user.php b/includes/pages/admin_user.php index 9e09e45b..dd359252 100644 --- a/includes/pages/admin_user.php +++ b/includes/pages/admin_user.php @@ -29,7 +29,7 @@ function admin_user() $goodie_tshirt = $goodie === GoodieType::Tshirt; $user_info_edit = auth()->can('user.info.edit'); $user_goodie_edit = auth()->can('user.goodie.edit'); - $user_edit = auth()->can('user.edit'); + $user_nick_edit = auth()->can('user.nick.edit'); $admin_arrive = auth()->can('admin_arrive'); if (!$request->has('id')) { @@ -63,7 +63,7 @@ function admin_user() $html .= '' . "\n"; $html .= ' ' . "\n"; $html .= '
' . __('general.nick') . '' . '' + . '" class="form-control" maxlength="24" ' . ($user_nick_edit ? '' : 'disabled') . '>' . '
' . __('Last login') . '

' . ($user_source->last_login_at ? $user_source->last_login_at->format(__('general.datetime')) : '-') @@ -307,7 +307,7 @@ function admin_user() break; } $old_nick = $user_source->name; - if ($nickValid && $user_edit) { + if ($nickValid && $user_nick_edit) { $changed_nick = ($user_source->name !== $nick) || User::whereName($nick)->exists(); $user_source->name = $nick; }