From 5d5d66bd79189fc49ce71d9ed1ce972b97f23db6 Mon Sep 17 00:00:00 2001 From: Brock H Caldwell Date: Thu, 15 May 2025 23:25:12 -0500 Subject: [PATCH] wip-feat: reduces env vars, adds getting-started page --- .env | 5 +- .env.dev => .env.dev.dist | 1 + .env.dist | 4 +- .env.example.dist | 52 +++++++++ config/dist/ldap.security.yaml | 1 + config/dist/local.security.yaml | 1 + config/packages/mercure.yaml | 4 +- config/packages/security.yaml | 7 +- config/services.yaml | 4 + example.compose.yml | 102 ++++++++++++++++++ .../Command/RegisterLdapUserCommand.php | 16 +++ .../Action/Command/RegisterUserCommand.php | 16 +++ .../Handler/RegisterLdapUserHandler.php | 57 ++++++++++ .../Action/Handler/RegisterUserHandler.php | 53 +++++++++ .../Action/Result/RegisterLdapUserResult.php | 14 +++ src/User/Action/Result/RegisterUserResult.php | 14 +++ .../Controller/Web/LoginController.php | 41 ++++++- .../Controller/Web/RegistrationController.php | 41 +++---- .../Framework/Form/RegistrationFormType.php | 1 + .../Framework/Security/LdapUserProvider.php | 26 +++-- templates/user/getting-started.html.twig | 79 ++++++++++++++ templates/user/login.html.twig | 23 ++-- 22 files changed, 500 insertions(+), 62 deletions(-) rename .env.dev => .env.dev.dist (90%) create mode 100644 .env.example.dist create mode 100644 example.compose.yml create mode 100644 src/User/Action/Command/RegisterLdapUserCommand.php create mode 100644 src/User/Action/Command/RegisterUserCommand.php create mode 100644 src/User/Action/Handler/RegisterLdapUserHandler.php create mode 100644 src/User/Action/Handler/RegisterUserHandler.php create mode 100644 src/User/Action/Result/RegisterLdapUserResult.php create mode 100644 src/User/Action/Result/RegisterUserResult.php create mode 100644 templates/user/getting-started.html.twig diff --git a/.env b/.env index 729a6ae..884c7a8 100644 --- a/.env +++ b/.env @@ -15,7 +15,7 @@ # https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration ###> symfony/framework-bundle ### -APP_ENV=dev +APP_ENV=prod APP_SECRET= ###< symfony/framework-bundle ### @@ -26,7 +26,8 @@ APP_SECRET= # DATABASE_URL="sqlite:///%kernel.project_dir%/var/data.db" # DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=8.0.32&charset=utf8mb4" # DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=10.11.2-MariaDB&charset=utf8mb4" -DATABASE_URL="postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=16&charset=utf8" +# DATABASE_URL="postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=16&charset=utf8" + ###< doctrine/doctrine-bundle ### ###> symfony/messenger ### diff --git a/.env.dev b/.env.dev.dist similarity index 90% rename from .env.dev rename to .env.dev.dist index a65b9e2..19dc9e2 100644 --- a/.env.dev +++ b/.env.dev.dist @@ -1,3 +1,4 @@ +APP_URL="https://dev.caldwell.digital" DATABASE_URL="mysql://root:password@database:3306/app?serverVersion=10.6.19.2-MariaDB&charset=utf8mb4" APP_SECRET=70169beadfbc8101c393cbfbba27a313 diff --git a/.env.dist b/.env.dist index f28828a..ed8f1cc 100644 --- a/.env.dist +++ b/.env.dist @@ -7,8 +7,6 @@ TMDB_API=%%tmdb_api%% MERCURE_URL=%%mercure_url%% MERCURE_PUBLIC_URL=%%mercure_public_url%% MERCURE_JWT_SECRET="%%mercure_jwt_secret%%" -JELLYFIN_URL=%%jellyfin_url%% -JELLYFIN_TOKEN=%%jellyfin_token%% REDIS_HOST="%%redis_host%%" @@ -25,7 +23,7 @@ LDAP_UID_KEY="uid" # LDAP group that identifies an Admin # Users with this LDAP group will automatically # get the admin role in this system. -LDAP_ADMIN_ROLE_DN="cn=admins,cn=groups,cn=accounts,dc=caldwell,dc=local" +LDAP_ADMIN_ROLE_DN="" LDAP_EMAIL_ATTRIBUTE=mail LDAP_USERNAME_ATTRIBUTE=uid LDAP_NAME_ATTRIBUTE=displayname diff --git a/.env.example.dist b/.env.example.dist new file mode 100644 index 0000000..ba97059 --- /dev/null +++ b/.env.example.dist @@ -0,0 +1,52 @@ +# App must be served over HTTPS (requirement of Mercure) +# Either serve behind an SSL terminating reverse proxy +# or pass your certificates into the 'app' container. +# Please omit any trailing slashes. The APP_URL is passed +# used to generate the Mercure URL behind the scenes. +APP_URL="https://dev.caldwell.digital" +APP_SECRET="70169beadfbc8101c393cbfbba27a313" + +# Use the DATABASE_URL below to use the MariaDB container +# provided in the example.compose.yml file, or remove this +# line and fill in the details of your own MySQL/MariaDB server +DATABASE_URL="mysql://root:password@database:3306/app?serverVersion=10.6.19.2-MariaDB&charset=utf8mb4" + +# Fill in your MySQL/MariaDB connection details +#DATABASE_URL="mysql://:@:3306/?serverVersion=10.6.19.2-MariaDB&charset=utf8mb4" + +# Enter you Real Debrid API key +# This key is never saved anywhere +# else and is passed to Torrentio +# to retrieve download options +REAL_DEBRID_KEY="QYYBR7OSQ4VEFKWASDEZ2B4VO67KHUJY6IWOT7HHA7ATXO7QCYDQ" + +# Enter you TMDB API key +# This is used to provide rich search results +# when searching for media and rendering the +# Popular Movies and TV Shows section. +TMDB_API="eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiI0ZTJjYjJhOGUzOGJhNjdiNjVhOGU1NGM0ZWI1MzhmOCIsIm5iZiI6MTczNzkyNjA0NC41NjQsInN1YiI6IjY3OTZhNTljYzdiMDFiNzJjNzIzZWM5YiIsInNjb3BlcyI6WyJhcGlfcmVhZCJdLCJ2ZXJzaW9uIjoxfQ.e8DbNe9qrSBC1y-ANRv-VWBAtls-ZS2r7aNCiI68mpw" + +MERCURE_JWT_SECRET="!ChangeThisMercureHubJWTSecretKey!" + +# Use your own Redis instance to use the +# below value to use the container included +# in the example.compose.yml file. +REDIS_HOST="redis://redis" + +# LDAP Config: To use LDAP, enter the below fields +# and run 'php bin/console config:set auth.method ldap' +LDAP_HOST= +LDAP_PORT= +LDAP_ENCRYPTION= +LDAP_BASE_DN= +LDAP_BIND_USER= +LDAP_BIND_PASS= +LDAP_DN_STRING= +LDAP_UID_KEY="uid" +# LDAP group that identifies an Admin +# Users with this LDAP group will automatically +# get the admin role in this system. +LDAP_ADMIN_ROLE_DN="" +LDAP_EMAIL_ATTRIBUTE=mail +LDAP_USERNAME_ATTRIBUTE=uid +LDAP_NAME_ATTRIBUTE=displayname diff --git a/config/dist/ldap.security.yaml b/config/dist/ldap.security.yaml index 4f6dbaf..880d113 100644 --- a/config/dist/ldap.security.yaml +++ b/config/dist/ldap.security.yaml @@ -38,6 +38,7 @@ security: # Easy way to control access for large sections of your site # Note: Only the *first* access control that matches will be used access_control: + - { path: ^/getting-started, roles: PUBLIC_ACCESS } - { path: ^/register, roles: PUBLIC_ACCESS } - { path: ^/login, roles: PUBLIC_ACCESS } - { path: ^/, roles: ROLE_USER } # Or ROLE_ADMIN, ROLE_SUPER_ADMIN, diff --git a/config/dist/local.security.yaml b/config/dist/local.security.yaml index b71b57c..7a31233 100644 --- a/config/dist/local.security.yaml +++ b/config/dist/local.security.yaml @@ -36,6 +36,7 @@ security: # Easy way to control access for large sections of your site # Note: Only the *first* access control that matches will be used access_control: + - { path: ^/getting-started, roles: PUBLIC_ACCESS } - { path: ^/register, roles: PUBLIC_ACCESS } - { path: ^/login, roles: PUBLIC_ACCESS } - { path: ^/, roles: ROLE_USER } # Or ROLE_ADMIN, ROLE_SUPER_ADMIN, diff --git a/config/packages/mercure.yaml b/config/packages/mercure.yaml index f2a7395..482c500 100644 --- a/config/packages/mercure.yaml +++ b/config/packages/mercure.yaml @@ -1,8 +1,8 @@ mercure: hubs: default: - url: '%env(MERCURE_URL)%' - public_url: '%env(MERCURE_PUBLIC_URL)%' + url: '%app.mercure.url%' + public_url: '%app.mercure.public_url%' jwt: secret: '%env(MERCURE_JWT_SECRET)%' publish: '*' diff --git a/config/packages/security.yaml b/config/packages/security.yaml index 4f6dbaf..7a31233 100644 --- a/config/packages/security.yaml +++ b/config/packages/security.yaml @@ -19,13 +19,11 @@ security: security: false main: lazy: true - provider: app_ldap - form_login_ldap: + provider: app_local + form_login: login_path: app_login check_path: app_login enable_csrf: true - service: Symfony\Component\Ldap\Ldap - dn_string: '%env(LDAP_DN_STRING)%' logout: path: app_logout @@ -38,6 +36,7 @@ security: # Easy way to control access for large sections of your site # Note: Only the *first* access control that matches will be used access_control: + - { path: ^/getting-started, roles: PUBLIC_ACCESS } - { path: ^/register, roles: PUBLIC_ACCESS } - { path: ^/login, roles: PUBLIC_ACCESS } - { path: ^/, roles: ROLE_USER } # Or ROLE_ADMIN, ROLE_SUPER_ADMIN, diff --git a/config/services.yaml b/config/services.yaml index ec7bdf0..2b97e31 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -9,6 +9,9 @@ parameters: media.movies_path: '/var/download/%env(default:media.default_movies_dir:MOVIES_PATH)%' media.tvshows_path: '/var/download/%env(default:media.default_tvshows_dir:TVSHOWS_PATH)%' + app.mercure.url: 'http://mercure/.well-known/mercure' + app.mercure.public_url: '%env(APP_URL)%/hub/.well-known/mercure' + services: # default configuration for services in *this* file _defaults: @@ -36,6 +39,7 @@ services: # LDAP App\User\Framework\Security\LdapUserProvider: arguments: + $registerLdapUserHandler: '@App\User\Action\Handler\RegisterLdapUserHandler' $userRepository: '@App\User\Framework\Repository\UserRepository' $ldap: '@Symfony\Component\Ldap\LdapInterface' $baseDn: '%env(LDAP_BASE_DN)%' diff --git a/example.compose.yml b/example.compose.yml new file mode 100644 index 0000000..2146096 --- /dev/null +++ b/example.compose.yml @@ -0,0 +1,102 @@ +services: + caddy: + image: caddy:2.9.1 + restart: unless-stopped + cap_add: + - NET_ADMIN + ports: + - "80:80" + - "443:443" + - "443:443/udp" + volumes: + - $PWD/bash/caddy:/etc/caddy + - $PWD/bash/certs:/etc/ssl + + app: + image: torsearch_test + ports: + - "8001:80" + environment: + APP_ENV: dev + APP_URL: ${APP_URL} + APP_SECRET: ${APP_SECRET} + DATABASE_URL: ${DATABASE_URL} + READ_DEBRID_KEY: ${REAL_DEBRID_KEY} + TMDB_API: ${TMDB_API} + MERCURE_JWT_SECRET: ${MERCURE_JWT_SECRET} + REDIS_HOST: ${REDIS_HOST} + + LDAP_HOST: directory.caldwell.local + LDAP_PORT: 389 + LDAP_ENCRYPTION: none + LDAP_BASE_DN: "dc=caldwell,dc=local" + LDAP_BIND_USER: "uid=admin,cn=users,cn=accounts,dc=caldwell,dc=local" + LDAP_BIND_PASS: "Caldwell.24272911" + LDAP_DN_STRING: "uid={user_identifier},cn=users,cn=accounts,dc=caldwell,dc=local" + LDAP_UID_KEY: "uid" + LDAP_ADMIN_ROLE_DN: "" + LDAP_EMAIL_ATTRIBUTE: mail + LDAP_USERNAME_ATTRIBUTE: uid + LDAP_NAME_ATTRIBUTE: displayname + + worker: + image: torsearch_test + volumes: + - ./downloads/:/var/download + command: php ./bin/console messenger:consume async -v --time-limit=3600 --limit=10 + environment: + APP_URL: ${APP_URL} + APP_SECRET: ${APP_SECRET} + DATABASE_URL: ${DATABASE_URL} + READ_DEBRID_KEY: ${REAL_DEBRID_KEY} + TMDB_API: ${TMDB_API} + MERCURE_JWT_SECRET: ${MERCURE_JWT_SECRET} + REDIS_HOST: ${REDIS_HOST} + + scheduler: + image: torsearch_test + volumes: + - ./downloads:/var/download + command: php ./bin/console messenger:consume scheduler_monitor -vv --time-limit=3600 + environment: + APP_URL: ${APP_URL} + APP_SECRET: ${APP_SECRET} + DATABASE_URL: ${DATABASE_URL} + READ_DEBRID_KEY: ${REAL_DEBRID_KEY} + TMDB_API: ${TMDB_API} + MERCURE_JWT_SECRET: ${MERCURE_JWT_SECRET} + REDIS_HOST: ${REDIS_HOST} + + mercure: + image: dunglas/mercure + restart: unless-stopped + ports: + - "3000:80" + environment: + SERVER_NAME: ':80' + MERCURE_PUBLISHER_JWT_KEY: ${MERCURE_JWT_SECRET} + MERCURE_SUBSCRIBER_JWT_KEY: ${MERCURE_JWT_SECRET} + MERCURE_EXTRA_DIRECTIVES: | + cors_origins * + anonymous + command: /usr/bin/caddy run --config /etc/caddy/dev.Caddyfile + volumes: + - mercure_data:/data + - mercure_config:/config + + database: + image: mariadb:10.11.2 + ports: + - "3306:3306" + volumes: + - mysql:/var/lib/mysql + environment: + MYSQL_DATABASE: app + MYSQL_USERNAME: app + MYSQL_PASSWORD: password + MYSQL_ROOT_PASSWORD: password + +volumes: + mysql: + mercure_config: + mercure_data: diff --git a/src/User/Action/Command/RegisterLdapUserCommand.php b/src/User/Action/Command/RegisterLdapUserCommand.php new file mode 100644 index 0000000..ee4961e --- /dev/null +++ b/src/User/Action/Command/RegisterLdapUserCommand.php @@ -0,0 +1,16 @@ + */ +class RegisterLdapUserCommand implements CommandInterface +{ + public function __construct( + public string $name, + public string $email, + public string $username, + public string $password, + ) {} +} \ No newline at end of file diff --git a/src/User/Action/Command/RegisterUserCommand.php b/src/User/Action/Command/RegisterUserCommand.php new file mode 100644 index 0000000..327a35a --- /dev/null +++ b/src/User/Action/Command/RegisterUserCommand.php @@ -0,0 +1,16 @@ + */ +class RegisterUserCommand implements CommandInterface +{ + public function __construct( + public string $name, + public string $email, + public string $username, + public string $password, + ) {} +} \ No newline at end of file diff --git a/src/User/Action/Handler/RegisterLdapUserHandler.php b/src/User/Action/Handler/RegisterLdapUserHandler.php new file mode 100644 index 0000000..0a24ba0 --- /dev/null +++ b/src/User/Action/Handler/RegisterLdapUserHandler.php @@ -0,0 +1,57 @@ + */ +class RegisterLdapUserHandler implements HandlerInterface +{ + public function __construct( + private readonly EntityManagerInterface $entityManager, + private readonly PreferencesRepository $preferenceRepository, + private readonly UserPasswordHasherInterface $userPasswordHasher, + private readonly UserRepository $userRepository, + ) {} + + public function handle(C $command): R + { + $user = $this->userRepository->findOneBy(['username' => $command->username]); + if (null === $user) { + $user = new User(); + $user->setPassword($this->userPasswordHasher->hashPassword($user, $command->password)); + } + + $user->setUsername($command->username); + $user->setEmail($command->email); + $user->setName($command->name); + $this->entityManager->persist($user); + $this->entityManager->flush(); + + $this->setUserPreferences($user, $this->preferenceRepository->findEnabled()); + $this->entityManager->flush(); + + return new RegisterLdapUserResult($user); + } + + private function setUserPreferences(User $user, array $preferences): void + { + foreach ($preferences as $preference) { + $user->addUserPreference((new UserPreference()) + ->setUser($user) + ->setPreference($preference) + ->setPreferenceValue(null) + ); + } + } +} diff --git a/src/User/Action/Handler/RegisterUserHandler.php b/src/User/Action/Handler/RegisterUserHandler.php new file mode 100644 index 0000000..966b0f7 --- /dev/null +++ b/src/User/Action/Handler/RegisterUserHandler.php @@ -0,0 +1,53 @@ + */ +class RegisterUserHandler implements HandlerInterface +{ + public function __construct( + private readonly EntityManagerInterface $entityManager, + private readonly PreferencesRepository $preferenceRepository, + private readonly UserPasswordHasherInterface $userPasswordHasher, + ) {} + + public function handle(C $command): R + { + $user = new User(); + + $user->setUsername($command->username); + $user->setEmail($command->email); + $user->setPassword($this->userPasswordHasher->hashPassword($user, $command->password)); + $user->setName($command->name); + $this->entityManager->persist($user); + $this->entityManager->flush(); + + $this->setUserPreferences($user, $this->preferenceRepository->findEnabled()); + $this->entityManager->flush(); + + return new RegisterUserResult($user); + } + + private function setUserPreferences(User $user, array $preferences): void + { + foreach ($preferences as $preference) { + $user->addUserPreference((new UserPreference()) + ->setUser($user) + ->setPreference($preference) + ->setPreferenceValue(null) + ); + } + } +} diff --git a/src/User/Action/Result/RegisterLdapUserResult.php b/src/User/Action/Result/RegisterLdapUserResult.php new file mode 100644 index 0000000..d333d03 --- /dev/null +++ b/src/User/Action/Result/RegisterLdapUserResult.php @@ -0,0 +1,14 @@ +findAll()))->count() === 0) { + return $this->redirectToRoute('app_getting_started'); + } + // get the login error if there is one $error = $authenticationUtils->getLastAuthenticationError(); @@ -29,4 +44,26 @@ class LoginController extends AbstractController { throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.'); } + + #[Route(path: '/getting-started', name: 'app_getting_started')] + public function gettingStarted(Request $request): Response + { + $form = $this->createForm(RegistrationFormType::class, new User()); + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $this->registerUserHandler->handle(new RegisterUserCommand( + name: $form->get('name')->getData(), + email: $form->get('email')->getData(), + username: $form->get('username')->getData(), + password: $form->get('plainPassword')->getData(), + )); + + return $this->redirectToRoute('app_index'); + } + + return $this->render('user/getting-started.html.twig', [ + 'registrationForm' => $form, + ]); + } } diff --git a/src/User/Framework/Controller/Web/RegistrationController.php b/src/User/Framework/Controller/Web/RegistrationController.php index 5cadc2b..494304a 100644 --- a/src/User/Framework/Controller/Web/RegistrationController.php +++ b/src/User/Framework/Controller/Web/RegistrationController.php @@ -2,6 +2,8 @@ namespace App\User\Framework\Controller\Web; +use App\User\Action\Command\RegisterUserCommand; +use App\User\Action\Handler\RegisterUserHandler; use App\User\Framework\Entity\User; use App\User\Framework\Entity\UserPreference; use App\User\Framework\Form\RegistrationFormType; @@ -15,30 +17,24 @@ use Symfony\Component\Routing\Attribute\Route; class RegistrationController extends AbstractController { + public function __construct(private readonly RegisterUserHandler $registerUserHandler) + { + } + #[Route('/register', name: 'app_register')] public function register( Request $request, - UserPasswordHasherInterface $userPasswordHasher, - EntityManagerInterface $entityManager, - PreferencesRepository $preferencesRepository, ): Response { - $user = new User(); - $form = $this->createForm(RegistrationFormType::class, $user); + $form = $this->createForm(RegistrationFormType::class, new User()); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { - /** @var string $plainPassword */ - $plainPassword = $form->get('plainPassword')->getData(); - - // encode the plain password - $user->setPassword($userPasswordHasher->hashPassword($user, $plainPassword)); - - $entityManager->persist($user); - $entityManager->flush(); - - $this->setUserPreferences($user, $preferencesRepository->findEnabled()); - - $preferencesRepository->getEntityManager()->flush(); + $this->registerUserHandler->handle(new RegisterUserCommand( + name: $form->get('name')->getData(), + email: $form->get('email')->getData(), + username: $form->get('username')->getData(), + password: $form->get('plainPassword')->getData(), + )); return $this->redirectToRoute('app_index'); } @@ -47,15 +43,4 @@ class RegistrationController extends AbstractController 'registrationForm' => $form, ]); } - - private function setUserPreferences(User $user, array $preferences): void - { - foreach ($preferences as $preference) { - $user->addUserPreference((new UserPreference()) - ->setUser($user) - ->setPreference($preference) - ->setPreferenceValue(null) - ); - } - } } diff --git a/src/User/Framework/Form/RegistrationFormType.php b/src/User/Framework/Form/RegistrationFormType.php index 8ce1a34..9019a96 100644 --- a/src/User/Framework/Form/RegistrationFormType.php +++ b/src/User/Framework/Form/RegistrationFormType.php @@ -16,6 +16,7 @@ class RegistrationFormType extends AbstractType { $builder ->add('email') + ->add('username') ->add('name') ->add('plainPassword', PasswordType::class, [ // instead of being set onto the object directly, diff --git a/src/User/Framework/Security/LdapUserProvider.php b/src/User/Framework/Security/LdapUserProvider.php index 6164e42..8023551 100644 --- a/src/User/Framework/Security/LdapUserProvider.php +++ b/src/User/Framework/Security/LdapUserProvider.php @@ -11,6 +11,8 @@ namespace App\User\Framework\Security; +use App\User\Action\Command\RegisterLdapUserCommand; +use App\User\Action\Handler\RegisterLdapUserHandler; use App\User\Framework\Entity\User; use App\User\Framework\Repository\UserRepository; use Symfony\Component\Ldap\Entry; @@ -45,6 +47,7 @@ class LdapUserProvider implements UserProviderInterface, PasswordUpgraderInterfa private string $displayNameAttribute; public function __construct( + private RegisterLdapUserHandler $registerLdapUserHandler, private UserRepository $userRepository, private LdapInterface $ldap, private string $baseDn, @@ -159,21 +162,24 @@ class LdapUserProvider implements UserProviderInterface, PasswordUpgraderInterfa $dbUser = $this->getDbUser($identifier, $entry); if (null === $dbUser) { - $dbUser = new User(); - $dbUser->setPassword("test"); + return $this->registerLdapUserHandler->handle(new RegisterLdapUserCommand( + name:$this->getAttributeValue($entry, $this->displayNameAttribute)[0] ?? null, + email:$this->getAttributeValue($entry, $this->emailAttribute)[0] ?? null, + username:$this->getAttributeValue($entry, $this->usernameAttribute) ?? null, + password: uniqid(), + ))->user; + } else { + $dbUser + ->setName($this->getAttributeValue($entry, $this->displayNameAttribute)[0] ?? null) + ->setEmail($this->getAttributeValue($entry, $this->emailAttribute)[0] ?? null) + ->setUsername($this->getAttributeValue($entry, $this->usernameAttribute) ?? null); + $this->userRepository->getEntityManager()->flush(); } - $dbUser - ->setName( $this->getAttributeValue($entry, $this->displayNameAttribute)[0] ?? null) - ->setEmail($this->getAttributeValue($entry, $this->emailAttribute)[0] ?? null) - ->setUsername($this->getAttributeValue($entry, $this->usernameAttribute) ?? null); - - $this->userRepository->getEntityManager()->persist($dbUser); - $this->userRepository->getEntityManager()->flush(); - return $dbUser; } + /** @return User */ private function getDbUser(string $identifier, Entry $entry): ?UserInterface { if (in_array($this->uidKey, ['mail', 'email'])) { diff --git a/templates/user/getting-started.html.twig b/templates/user/getting-started.html.twig new file mode 100644 index 0000000..96e7130 --- /dev/null +++ b/templates/user/getting-started.html.twig @@ -0,0 +1,79 @@ +{% extends 'bare.html.twig' %} + +{% block title %}Getting Started — Torsearch{% endblock %} + +{% block body %} +
+

Getting Started

+

Let's get started by creating your first User.

+ + {{ form_start(registrationForm) }} + + + + + + + + + + + {{ form_end(registrationForm) }} +
+{% endblock %} diff --git a/templates/user/login.html.twig b/templates/user/login.html.twig index 4089753..05d852a 100644 --- a/templates/user/login.html.twig +++ b/templates/user/login.html.twig @@ -3,11 +3,13 @@ {% block title %}Log in — Torsearch{% endblock %} {% block body %} -
+

Login

{% if error %} -
{{ error.messageKey|trans(error.messageData, 'security') }}
+
+ {{ error.messageKey|trans(error.messageData, 'security') }} +
{% endif %} {% if app.user %} @@ -16,15 +18,15 @@
{% endif %} -
- -