diff --git a/app/DoctrineMigrations/Version20160720094920.php b/app/DoctrineMigrations/Version20160720094920.php index d9a8242..9344b26 100644 --- a/app/DoctrineMigrations/Version20160720094920.php +++ b/app/DoctrineMigrations/Version20160720094920.php @@ -19,6 +19,7 @@ public function up(Schema $schema) $this->abortIf($this->connection->getDatabasePlatform()->getName() != 'mysql', 'Migration can only be executed safely on \'mysql\'.'); $this->addSql('RENAME TABLE `user` TO `user_table`'); + $this->addSql('ALTER TABLE user_table RENAME INDEX uniq_8d93d649f85e0677 TO UNIQ_14EB741EF85E0677'); } /** @@ -30,5 +31,6 @@ public function down(Schema $schema) $this->abortIf($this->connection->getDatabasePlatform()->getName() != 'mysql', 'Migration can only be executed safely on \'mysql\'.'); $this->addSql('RENAME TABLE `user_table` TO `user`'); + $this->addSql('ALTER TABLE user_table RENAME INDEX UNIQ_14EB741EF85E0677 TO uniq_8d93d649f85e0677'); } } diff --git a/app/DoctrineMigrations/Version20160720100543.php b/app/DoctrineMigrations/Version20160720100543.php new file mode 100644 index 0000000..a01b2cc --- /dev/null +++ b/app/DoctrineMigrations/Version20160720100543.php @@ -0,0 +1,34 @@ +abortIf($this->connection->getDatabasePlatform()->getName() != 'mysql', 'Migration can only be executed safely on \'mysql\'.'); + + $this->addSql('ALTER TABLE user_table ADD password VARCHAR(255) NOT NULL'); + } + + /** + * @param Schema $schema + */ + public function down(Schema $schema) + { + // this down() migration is auto-generated, please modify it to your needs + $this->abortIf($this->connection->getDatabasePlatform()->getName() != 'mysql', 'Migration can only be executed safely on \'mysql\'.'); + + $this->addSql('ALTER TABLE user_table DROP password'); + } +} diff --git a/app/Resources/views/base.html.twig b/app/Resources/views/base.html.twig index 5470d59..6d4ea51 100644 --- a/app/Resources/views/base.html.twig +++ b/app/Resources/views/base.html.twig @@ -45,6 +45,23 @@
+ {% if app.session.started and app.session.flashBag.peekAll is not empty %} +
+ {% for type, messages in app.session.flashBag.all %} + {% for message in messages %} + {# Bootstrap alert, see http://getbootstrap.com/components/#alerts #} + + {% endfor %} + {% endfor %} +
+ {% endif %} + {% block content %} {% endblock %}
diff --git a/app/config/security.yml b/app/config/security.yml index 4b75384..117ef22 100644 --- a/app/config/security.yml +++ b/app/config/security.yml @@ -1,6 +1,8 @@ # To get started with security, check out the documentation: # http://symfony.com/doc/current/book/security.html security: + encoders: + AppBundle\Entity\User: bcrypt # http://symfony.com/doc/current/book/security.html#where-do-users-come-from-user-providers providers: diff --git a/app/config/services.yml b/app/config/services.yml index 527e021..5e0b3c7 100644 --- a/app/config/services.yml +++ b/app/config/services.yml @@ -10,4 +10,10 @@ services: app.form_login_authenticator: class: AppBundle\Security\FormLoginAuthenticator - arguments: ['@doctrine.orm.entity_manager'] + arguments: ['@doctrine.orm.entity_manager', '@security.password_encoder', '@router'] + + app.user_password_listener: + class: AppBundle\Doctrine\UserPasswordListener + arguments: ['@security.password_encoder'] + tags: + - { name: doctrine.event_listener, event: prePersist } diff --git a/src/AppBundle/Controller/Admin/BlogController.php b/src/AppBundle/Controller/Admin/BlogController.php index f186be7..b667736 100644 --- a/src/AppBundle/Controller/Admin/BlogController.php +++ b/src/AppBundle/Controller/Admin/BlogController.php @@ -53,6 +53,8 @@ public function updateBlogPostAction(Request $request, $id) if ($form->isValid()) { $this->getDoctrine()->getManager()->flush(); + $this->addFlash('success', 'Blog post successfully saved!'); + return $this->redirectToRoute('admin_blog_show'); } diff --git a/src/AppBundle/Controller/SecurityController.php b/src/AppBundle/Controller/SecurityController.php index f5f194c..32e72a6 100644 --- a/src/AppBundle/Controller/SecurityController.php +++ b/src/AppBundle/Controller/SecurityController.php @@ -13,6 +13,10 @@ class SecurityController extends Controller */ public function loginAction() { + if ($this->getUser()) { + $this->addFlash('warning', 'You\'re already logged in.'); + } + $form = $this->createForm(UserLoginType::class, null, [ 'action' => $this->generateUrl('security_check'), ]); diff --git a/src/AppBundle/DataFixtures/ORM/LoadUserData.php b/src/AppBundle/DataFixtures/ORM/LoadUserData.php index fa37f7d..2ab80d1 100644 --- a/src/AppBundle/DataFixtures/ORM/LoadUserData.php +++ b/src/AppBundle/DataFixtures/ORM/LoadUserData.php @@ -12,6 +12,7 @@ public function load(ObjectManager $manager) { $user = new User(); $user->setUsername('victor'); + $user->setPlainPassword('victorpass'); $manager->persist($user); $manager->flush(); diff --git a/src/AppBundle/Doctrine/UserPasswordListener.php b/src/AppBundle/Doctrine/UserPasswordListener.php new file mode 100644 index 0000000..cc1c236 --- /dev/null +++ b/src/AppBundle/Doctrine/UserPasswordListener.php @@ -0,0 +1,30 @@ +encoder = $encoder; + } + + public function prePersist(LifecycleEventArgs $event) + { + $user = $event->getEntity(); + if (!$user instanceof User) { + return null; + } + if ($user->getPlainPassword()) { + // encode password + $encodedPassword = $this->encoder->encodePassword($user, $user->getPlainPassword()); + $user->setPassword($encodedPassword); + } + } +} diff --git a/src/AppBundle/Entity/User.php b/src/AppBundle/Entity/User.php index ff449b5..51cd897 100644 --- a/src/AppBundle/Entity/User.php +++ b/src/AppBundle/Entity/User.php @@ -27,6 +27,18 @@ class User implements UserInterface */ private $username; + /** + * @var string + * + * @ORM\Column(type="string") + */ + private $password; + + /** + * @var string + */ + private $plainPassword; + /** * @return int */ @@ -53,9 +65,36 @@ public function getRoles() return ['ROLE_USER']; } + /** + * @param string $password + */ + public function setPassword($password) + { + $this->password = $password; + } + + /** + * @return string + */ public function getPassword() { - // TODO: Implement getPassword() method. + return $this->password; + } + + /** + * @return string + */ + public function getPlainPassword() + { + return $this->plainPassword; + } + + /** + * @param string $plainPassword + */ + public function setPlainPassword($plainPassword) + { + $this->plainPassword = $plainPassword; } public function getSalt() diff --git a/src/AppBundle/Form/UserLoginType.php b/src/AppBundle/Form/UserLoginType.php index ce5051f..b49029a 100644 --- a/src/AppBundle/Form/UserLoginType.php +++ b/src/AppBundle/Form/UserLoginType.php @@ -4,6 +4,7 @@ use AppBundle\Entity\User; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Extension\Core\Type\PasswordType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; @@ -13,6 +14,9 @@ public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('username') + ->add('plain_password', PasswordType::class, [ + 'label' => 'Password', + ]) ; } diff --git a/src/AppBundle/Security/FormLoginAuthenticator.php b/src/AppBundle/Security/FormLoginAuthenticator.php index 1ff7b90..2eb134e 100644 --- a/src/AppBundle/Security/FormLoginAuthenticator.php +++ b/src/AppBundle/Security/FormLoginAuthenticator.php @@ -4,8 +4,11 @@ use AppBundle\Entity\User; use Doctrine\ORM\EntityManager; +use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Routing\RouterInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; +use Symfony\Component\Security\Core\Encoder\UserPasswordEncoder; use Symfony\Component\Security\Core\Exception\AuthenticationException; use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserProviderInterface; @@ -14,10 +17,14 @@ class FormLoginAuthenticator extends AbstractGuardAuthenticator { private $em; + private $encoder; + private $router; - public function __construct(EntityManager $em) + public function __construct(EntityManager $em, UserPasswordEncoder $encoder, RouterInterface $router) { $this->em = $em; + $this->encoder = $encoder; + $this->router = $router; } public function getCredentials(Request $request) @@ -26,6 +33,7 @@ public function getCredentials(Request $request) if ($request->request->has('username')) { return [ 'username' => $request->request->get('username'), + 'password' => $request->request->get('plain_password'), ]; } } @@ -42,7 +50,7 @@ public function getUser($credentials, UserProviderInterface $userProvider) public function checkCredentials($credentials, UserInterface $user) { - return true; + return $this->encoder->isPasswordValid($user, $credentials['password']); } public function onAuthenticationFailure(Request $request, AuthenticationException $exception) @@ -52,7 +60,9 @@ public function onAuthenticationFailure(Request $request, AuthenticationExceptio public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey) { - return null; + $url = $this->router->generate('admin_blog_show'); + + return new RedirectResponse($url); } public function supportsRememberMe()