editing users in user list now works

This commit is contained in:
overflowerror 2021-01-18 16:35:11 +01:00
parent 9dfa558399
commit 995c2eadb6
11 changed files with 166 additions and 12 deletions

View file

@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20210117225723 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->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');
}
}

View file

@ -53,6 +53,11 @@
color: red; color: red;
} }
.deleteToggle:disabled { .btn:disabled {
}
a.btn.disabled {
color: dimgrey; color: dimgrey;
pointer-events: none;
cursor: pointer;
} }

View file

@ -152,4 +152,55 @@ class UserController extends AbstractController
"form" => $form->createView() "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()
]);
}
} }

View file

@ -49,6 +49,7 @@ class User implements UserInterface
* @ORM\Column(type="string") * @ORM\Column(type="string")
*/ */
private $password; private $password;
private $newPassword;
/** /**
* @ORM\OneToMany(targetEntity=Video::class, mappedBy="uploader", orphanRemoval=true) * @ORM\OneToMany(targetEntity=Video::class, mappedBy="uploader", orphanRemoval=true)
@ -144,8 +145,7 @@ class User implements UserInterface
*/ */
public function eraseCredentials() public function eraseCredentials()
{ {
// If you store any temporary, sensitive data on the user, clear it here $this->newPassword = null;
// $this->plainPassword = null;
} }
/** /**
@ -239,4 +239,15 @@ class User implements UserInterface
$this->created = new DateTimeImmutable(); $this->created = new DateTimeImmutable();
return $this; return $this;
} }
public function getNewPassword(): ?string
{
return $this->newPassword;
}
public function setNewPassword(string $newPassword): self
{
$this->newPassword = $newPassword;
return $this;
}
} }

View file

@ -28,8 +28,9 @@ class UserType extends AbstractType
"multiple" => true, "multiple" => true,
"expanded" => true, "expanded" => true,
]) ])
->add("password", PasswordType::class, [ ->add("newPassword", PasswordType::class, [
"always_empty" => true "always_empty" => true,
"required" => !$options["password_optional"]
]) ])
->add("submit", SubmitType::class); ->add("submit", SubmitType::class);
} }
@ -37,7 +38,8 @@ class UserType extends AbstractType
public function configureOptions(OptionsResolver $resolver): void public function configureOptions(OptionsResolver $resolver): void
{ {
$resolver->setDefaults([ $resolver->setDefaults([
"data_class" => User::class "data_class" => User::class,
"password_optional" => false
]); ]);
} }

View file

@ -73,4 +73,9 @@ class UserRepository extends ServiceEntityRepository implements PasswordUpgrader
$this->_em->persist($user); $this->_em->persist($user);
$this->_em->flush(); $this->_em->flush();
} }
public function update($user)
{
$this->_em->flush();
}
} }

View file

@ -7,6 +7,7 @@ namespace App\Service;
use App\Entity\User; use App\Entity\User;
use App\Repository\UserRepository; use App\Repository\UserRepository;
use Ramsey\Uuid\UuidInterface; use Ramsey\Uuid\UuidInterface;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Core\Security; use Symfony\Component\Security\Core\Security;
class UserService class UserService
@ -14,11 +15,17 @@ class UserService
private $security; private $security;
private $userRepository; private $userRepository;
private $passwordEncoder;
public function __construct(Security $security, UserRepository $userRepository) public function __construct(
Security $security,
UserRepository $userRepository,
UserPasswordEncoderInterface $passwordEncoder
)
{ {
$this->security = $security; $this->security = $security;
$this->userRepository = $userRepository; $this->userRepository = $userRepository;
$this->passwordEncoder = $passwordEncoder;
} }
public function getLoggedInUser(): ?User public function getLoggedInUser(): ?User
@ -55,7 +62,17 @@ class UserService
{ {
$user->setCreated(); $user->setCreated();
$user->setCreator($this->getLoggedInUser()); $user->setCreator($this->getLoggedInUser());
$user->setPassword($this->passwordEncoder->encodePassword($user, $user->getNewPassword()));
$this->userRepository->save($user); $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);
}
} }

View file

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>{% block title %}Welcome!{% endblock %}</title> <title>MyTube - {% block title %}Welcome{% endblock %}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.11.2/css/all.css"/> <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.11.2/css/all.css"/>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons"> <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons">

View file

@ -1,6 +1,6 @@
{% extends 'base.html.twig' %} {% extends 'base.html.twig' %}
{% block title %}Log in!{% endblock %} {% block title %}Login{% endblock %}
{% block body %} {% block body %}
<form method="post"> <form method="post">
@ -15,7 +15,7 @@
{% endif %} {% endif %}
<h1 class="h3 mb-3 font-weight-normal">Please sign in</h1> <h1 class="h3 mb-3 font-weight-normal">Please sign in</h1>
<label for="inputName">Name</label> <label for="inputName">E-Mail</label>
<input type="text" value="{{ last_username }}" name="email" id="inputName" class="form-control" required <input type="text" value="{{ last_username }}" name="email" id="inputName" class="form-control" required
autofocus> autofocus>
<label for="inputPassword">Password</label> <label for="inputPassword">Password</label>

View file

@ -0,0 +1,20 @@
{% extends 'base.html.twig' %}
{% block title %}Users{% endblock %}
{% block stylesheets %}
<link rel="stylesheet" href="{{ asset("css/admin.css") }}">
{% endblock %}
{% block javascripts %}
{% if ok %}
<script>
window.setTimeout(function () {
toast("Saved");
}, 0);
</script>
{% endif %}
{% endblock %}
{% block body %}
{{ form(form) }}
{% endblock %}

View file

@ -28,6 +28,7 @@
</th> </th>
</tr> </tr>
{% for user in users %} {% for user in users %}
{% set canEdit = (user.id == current.id) or (user.isSuperAdmin()) %}
<tr> <tr>
<td> <td>
<input type="checkbox"> <input type="checkbox">
@ -52,7 +53,8 @@
</td> </td>
<td> <td>
<div class="btn-group" role="group"> <div class="btn-group" role="group">
<a class="btn btn-link" href=""> <a class="btn btn-link {% if canEdit %}disabled{% endif %}"
href="{{ path("app_user_edit") }}?user={{ user.customId }}">
<i class="fas fa-cog"></i> <i class="fas fa-cog"></i>
</a> </a>
<form action="{{ path("app_user_delete") }}" method="POST"> <form action="{{ path("app_user_delete") }}" method="POST">
@ -63,7 +65,7 @@
data-mdb-toggle="dropdown" data-mdb-toggle="dropdown"
aria-expanded="false" aria-expanded="false"
onclick="" onclick=""
{% if (user.id == current.id) or (user.isSuperAdmin()) %} {% if canEdit %}
disabled disabled
{% endif %} {% endif %}
> >