diff --git a/migrations/Version20210117225723.php b/migrations/Version20210117225723.php new file mode 100644 index 0000000..e6a8456 --- /dev/null +++ b/migrations/Version20210117225723.php @@ -0,0 +1,41 @@ +addSql('ALTER TABLE user ADD creator_id BINARY(16) DEFAULT NULL, ADD created DATETIME NOT NULL COMMENT \'(DC2Type:datetime_immutable)\', CHANGE id id BINARY(16) NOT NULL'); + $this->addSql('ALTER TABLE user ADD CONSTRAINT FK_8D93D64961220EA6 FOREIGN KEY (creator_id) REFERENCES user (id)'); + $this->addSql('CREATE INDEX IDX_8D93D64961220EA6 ON user (creator_id)'); + $this->addSql('ALTER TABLE video CHANGE id id BINARY(16) NOT NULL, CHANGE uploader_id uploader_id BINARY(16) NOT NULL'); + $this->addSql('ALTER TABLE video_link CHANGE id id BINARY(16) NOT NULL, CHANGE video_id video_id BINARY(16) NOT NULL, CHANGE creator_id creator_id BINARY(16) NOT NULL'); + $this->addSql('ALTER TABLE view CHANGE id id BINARY(16) NOT NULL, CHANGE video_id video_id BINARY(16) NOT NULL, CHANGE link_id link_id BINARY(16) NOT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE user DROP FOREIGN KEY FK_8D93D64961220EA6'); + $this->addSql('DROP INDEX IDX_8D93D64961220EA6 ON user'); + $this->addSql('ALTER TABLE user DROP creator_id, DROP created, CHANGE id id BINARY(16) NOT NULL'); + $this->addSql('ALTER TABLE video CHANGE id id BINARY(16) NOT NULL, CHANGE uploader_id uploader_id BINARY(16) NOT NULL'); + $this->addSql('ALTER TABLE video_link CHANGE id id BINARY(16) NOT NULL, CHANGE video_id video_id BINARY(16) NOT NULL, CHANGE creator_id creator_id BINARY(16) NOT NULL'); + $this->addSql('ALTER TABLE `view` CHANGE id id BINARY(16) NOT NULL, CHANGE video_id video_id BINARY(16) NOT NULL, CHANGE link_id link_id BINARY(16) NOT NULL'); + } +} diff --git a/public/css/base.css b/public/css/base.css index ed02d02..467aafb 100644 --- a/public/css/base.css +++ b/public/css/base.css @@ -53,6 +53,11 @@ color: red; } -.deleteToggle:disabled { +.btn:disabled { +} + +a.btn.disabled { color: dimgrey; + pointer-events: none; + cursor: pointer; } \ No newline at end of file diff --git a/src/Controller/UserController.php b/src/Controller/UserController.php index d9522d7..1bcbcb6 100644 --- a/src/Controller/UserController.php +++ b/src/Controller/UserController.php @@ -152,4 +152,55 @@ class UserController extends AbstractController "form" => $form->createView() ]); } + + /** + * @Route("/admin/users/edit", name="app_user_edit") + */ + public function userEdit(Request $request): Response + { + if (!$this->isGranted(User::ROLE_ADMIN)) { + throw new AccessDeniedHttpException(); + } + + $userId = $request->query->get("user"); + + if (!$userId) { + throw new BadRequestHttpException(); + } + + try { + $userId = $this->uuidMapper->fromString($userId); + } catch (ConversionException $e) { + throw new BadRequestHttpException(); + } + + $user = $this->userService->get($userId); + if ($user == null) { + throw new NotFoundHttpException(); + } + + $form = $this->createForm(UserType::class, $user, [ + "password_optional" => true + ]); + + $okay = false; + + $form->handleRequest($request); + if ($form->isSubmitted() && $form->isValid()) { + $user = $form->getData(); + + if ($user->isSuperAdmin()) { + throw new BadRequestHttpException(); + } + + $this->userService->update($user); + + $okay = true; + } + + return $this->render("user/user-new.html.twig", [ + "ok" => $okay, + "form" => $form->createView() + ]); + } } \ No newline at end of file diff --git a/src/Entity/User.php b/src/Entity/User.php index 86b67a6..302f310 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -49,6 +49,7 @@ class User implements UserInterface * @ORM\Column(type="string") */ private $password; + private $newPassword; /** * @ORM\OneToMany(targetEntity=Video::class, mappedBy="uploader", orphanRemoval=true) @@ -144,8 +145,7 @@ class User implements UserInterface */ public function eraseCredentials() { - // If you store any temporary, sensitive data on the user, clear it here - // $this->plainPassword = null; + $this->newPassword = null; } /** @@ -239,4 +239,15 @@ class User implements UserInterface $this->created = new DateTimeImmutable(); return $this; } + + public function getNewPassword(): ?string + { + return $this->newPassword; + } + + public function setNewPassword(string $newPassword): self + { + $this->newPassword = $newPassword; + return $this; + } } diff --git a/src/Form/UserType.php b/src/Form/UserType.php index 442a9d7..a8af7b1 100644 --- a/src/Form/UserType.php +++ b/src/Form/UserType.php @@ -28,8 +28,9 @@ class UserType extends AbstractType "multiple" => true, "expanded" => true, ]) - ->add("password", PasswordType::class, [ - "always_empty" => true + ->add("newPassword", PasswordType::class, [ + "always_empty" => true, + "required" => !$options["password_optional"] ]) ->add("submit", SubmitType::class); } @@ -37,7 +38,8 @@ class UserType extends AbstractType public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ - "data_class" => User::class + "data_class" => User::class, + "password_optional" => false ]); } diff --git a/src/Repository/UserRepository.php b/src/Repository/UserRepository.php index 8ac161b..756364c 100644 --- a/src/Repository/UserRepository.php +++ b/src/Repository/UserRepository.php @@ -73,4 +73,9 @@ class UserRepository extends ServiceEntityRepository implements PasswordUpgrader $this->_em->persist($user); $this->_em->flush(); } + + public function update($user) + { + $this->_em->flush(); + } } diff --git a/src/Service/UserService.php b/src/Service/UserService.php index 71c1460..b9aed41 100644 --- a/src/Service/UserService.php +++ b/src/Service/UserService.php @@ -7,6 +7,7 @@ namespace App\Service; use App\Entity\User; use App\Repository\UserRepository; use Ramsey\Uuid\UuidInterface; +use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface; use Symfony\Component\Security\Core\Security; class UserService @@ -14,11 +15,17 @@ class UserService private $security; private $userRepository; + private $passwordEncoder; - public function __construct(Security $security, UserRepository $userRepository) + public function __construct( + Security $security, + UserRepository $userRepository, + UserPasswordEncoderInterface $passwordEncoder + ) { $this->security = $security; $this->userRepository = $userRepository; + $this->passwordEncoder = $passwordEncoder; } public function getLoggedInUser(): ?User @@ -55,7 +62,17 @@ class UserService { $user->setCreated(); $user->setCreator($this->getLoggedInUser()); + $user->setPassword($this->passwordEncoder->encodePassword($user, $user->getNewPassword())); $this->userRepository->save($user); } + + public function update(User $user) + { + if ($user->getNewPassword() != null && $user->getNewPassword() != "") { + $user->setPassword($this->passwordEncoder->encodePassword($user, $user->getNewPassword())); + } + + $this->userRepository->update($user); + } } \ No newline at end of file diff --git a/templates/base.html.twig b/templates/base.html.twig index 6f05442..991249d 100644 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -2,7 +2,7 @@
-