denyAccessUnlessGranted('ROLE_ADMIN'); return $this->render('admin/users.html.twig', [ 'users' => $this->users->all(), 'roles' => UserDirectory::ROLES, 'roleHelp' => UserDirectory::ROLE_HELP, 'minPassword' => UserDirectory::MIN_PASSWORD, 'maxPassword' => UserDirectory::MAX_PASSWORD, 'me' => $this->cmsUser()->id, ]); } #[Route('/%kant.admin_path%/benutzer/neu', name: 'admin_user_create', methods: ['POST'])] public function create(Request $request): Response { if (null !== $refusal = $this->guard($request)) { return $refusal; } try { $this->users->create( $request->request->getString('username'), $request->request->getString('password'), $request->request->getString('role'), ); } catch (InvalidAccount $e) { return $this->back($e->getMessage()); } return $this->back('Das Konto wurde angelegt.', 'success'); } #[Route('/%kant.admin_path%/benutzer/{id}/rolle', name: 'admin_user_role', requirements: ['id' => '[a-zA-Z0-9_-]{1,64}'], methods: ['POST'])] public function role(Request $request, string $id): Response { if (null !== $refusal = $this->guard($request)) { return $refusal; } try { $this->users->changeRole($id, $request->request->getString('role'), $this->cmsUser()); } catch (InvalidAccount $e) { return $this->back($e->getMessage()); } return $this->back('Die Rolle wurde geändert. Offene Sitzungen dieses Kontos sind damit abgemeldet.', 'success'); } #[Route('/%kant.admin_path%/benutzer/{id}/passwort', name: 'admin_user_password', requirements: ['id' => '[a-zA-Z0-9_-]{1,64}'], methods: ['POST'])] public function password(Request $request, string $id): Response { if (null !== $refusal = $this->guard($request)) { return $refusal; } try { $this->users->setPassword($id, $request->request->getString('password')); } catch (InvalidAccount $e) { return $this->back($e->getMessage()); } return $this->back('Das Passwort wurde gesetzt. Offene Sitzungen dieses Kontos sind damit abgemeldet.', 'success'); } #[Route('/%kant.admin_path%/benutzer/{id}/loeschen', name: 'admin_user_delete', requirements: ['id' => '[a-zA-Z0-9_-]{1,64}'], methods: ['POST'])] public function delete(Request $request, string $id): Response { if (null !== $refusal = $this->guard($request)) { return $refusal; } try { $this->users->delete($id, $this->cmsUser()); } catch (InvalidAccount $e) { return $this->back($e->getMessage()); } return $this->back('Das Konto wurde gelöscht.', 'success'); } #[Route('/%kant.admin_path%/konto', name: 'admin_account', methods: ['GET'])] public function account(): Response { $this->denyAccessUnlessGranted('ROLE_EDITOR'); $me = $this->cmsUser(); $mine = null; foreach ($this->users->all() as $account) { if ($account['id'] === $me->id) { $mine = $account; } } return $this->render('admin/account.html.twig', [ 'account' => $mine, 'roles' => UserDirectory::ROLES, 'roleHelp' => UserDirectory::ROLE_HELP, 'minPassword' => UserDirectory::MIN_PASSWORD, 'maxPassword' => UserDirectory::MAX_PASSWORD, ]); } #[Route('/%kant.admin_path%/konto/passwort', name: 'admin_account_password', methods: ['POST'])] public function ownPassword(Request $request): Response { $this->denyAccessUnlessGranted('ROLE_EDITOR'); if (!$this->isCsrfTokenValid('account', $request->request->getString('_csrf_token'))) { return $this->back('Deine Sitzung ist abgelaufen. Bitte melde dich erneut an.', 'error', 'admin_account'); } $me = $this->cmsUser(); try { $fresh = $this->users->changeOwnPassword( $me, $request->request->getString('current'), $request->request->getString('password'), ); } catch (InvalidAccount $e) { return $this->back($e->getMessage(), 'error', 'admin_account'); } // Keep this session signed in with the new hash. Every other session of the account fails // its next refresh against the database and is logged out - which is the point. $this->tokens->setToken(new UsernamePasswordToken($fresh, 'admin', $fresh->getRoles())); return $this->back('Das Passwort wurde geändert. Andere offene Sitzungen dieses Kontos sind abgemeldet.', 'success', 'admin_account'); } /** Every write needs the administrator role and a valid token; the check is the same each time. */ private function guard(Request $request): ?Response { $this->denyAccessUnlessGranted('ROLE_ADMIN'); if (!$this->isCsrfTokenValid('users', $request->request->getString('_csrf_token'))) { return $this->back('Deine Sitzung ist abgelaufen. Bitte melde dich erneut an.'); } return null; } private function cmsUser(): CmsUser { $user = $this->getUser(); if (!$user instanceof CmsUser) { throw $this->createAccessDeniedException(); } return $user; } private function back(string $message, string $type = 'error', string $route = 'admin_users'): Response { $this->addFlash($type, $message); return $this->redirectToRoute($route); } }