diff options
| author | nsfisis <nsfisis@gmail.com> | 2024-01-17 02:11:31 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2024-01-17 02:11:31 +0900 |
| commit | deacd0dfc195bca41af631114804d29937337cd8 (patch) | |
| tree | f1f83580e5bc892c0794ac41632bc0cce3498f65 /services/app/src/Forms/LoginForm.php | |
| parent | 38ddeb28ec846ee966d0fe6873585d697a9ef373 (diff) | |
| download | phperkaigi-2024-albatross-deacd0dfc195bca41af631114804d29937337cd8.tar.gz phperkaigi-2024-albatross-deacd0dfc195bca41af631114804d29937337cd8.tar.zst phperkaigi-2024-albatross-deacd0dfc195bca41af631114804d29937337cd8.zip | |
.
Diffstat (limited to 'services/app/src/Forms/LoginForm.php')
| -rw-r--r-- | services/app/src/Forms/LoginForm.php | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/services/app/src/Forms/LoginForm.php b/services/app/src/Forms/LoginForm.php new file mode 100644 index 0000000..26f6ad1 --- /dev/null +++ b/services/app/src/Forms/LoginForm.php @@ -0,0 +1,116 @@ +<?php + +declare(strict_types=1); + +namespace Nsfisis\Albatross\Forms; + +use Nsfisis\Albatross\Auth\AuthenticationResult; +use Nsfisis\Albatross\Auth\AuthProviderInterface; +use Nsfisis\Albatross\Exceptions\EntityValidationException; +use Nsfisis\Albatross\Form\FormBase; +use Nsfisis\Albatross\Form\FormItem; +use Nsfisis\Albatross\Form\FormState; +use Nsfisis\Albatross\Form\FormSubmissionFailureException; +use Nsfisis\Albatross\Repositories\UserRepository; +use Slim\Interfaces\RouteParserInterface; + +final class LoginForm extends FormBase +{ + public function __construct( + ?FormState $state, + private readonly ?string $destination, + private readonly RouteParserInterface $routeParser, + private readonly UserRepository $userRepo, + private readonly AuthProviderInterface $authProvider, + ) { + if (!isset($state)) { + $state = new FormState(); + } + parent::__construct($state); + } + + public function pageTitle(): string + { + return 'ログイン'; + } + + public function redirectUrl(): string + { + return $this->destination ?? $this->routeParser->urlFor('quiz_list'); + } + + protected function submitLabel(): string + { + return 'ログイン'; + } + + /** + * @return list<FormItem> + */ + protected function items(): array + { + return [ + new FormItem( + name: 'username', + type: 'text', + label: 'ユーザ名', + isRequired: true, + ), + new FormItem( + name: 'password', + type: 'password', + label: 'パスワード', + isRequired: true, + ), + ]; + } + + public function submit(): void + { + $username = $this->state->get('username') ?? ''; + $password = $this->state->get('password') ?? ''; + + $this->validate($username, $password); + + $authResult = $this->authProvider->login($username, $password); + if ($authResult === AuthenticationResult::InvalidCredentials) { + $this->state->setErrors(['general' => 'ユーザ名またはパスワードが異なります']); + throw new FormSubmissionFailureException(code: 403); + } elseif ($authResult === AuthenticationResult::InvalidJson || $authResult === AuthenticationResult::UnknownError) { + throw new FormSubmissionFailureException(code: 500); + } else { + $user = $this->userRepo->findByUsername($username); + if ($user === null) { + try { + $user_id = $this->userRepo->create( + $username, + is_admin: true, // TODO + ); + } catch (EntityValidationException $e) { + $this->state->setErrors($e->toFormErrors()); + throw new FormSubmissionFailureException(previous: $e); + } + $_SESSION['user_id'] = $user_id; + } else { + $_SESSION['user_id'] = $user->user_id; + } + } + } + + private function validate(string $username, string $password): void + { + $errors = []; + if (strlen($username) < 1) { + $errors['username'] = 'ユーザ名は必須です'; + } + + if (strlen($password) < 1) { + $errors['password'] = 'パスワードは必須です'; + } + + if (count($errors) > 0) { + $this->state->setErrors($errors); + throw new FormSubmissionFailureException(code: 400); + } + } +} |
