Skip to content

Commit

Permalink
Merge pull request #382 from arneruy/issue_194
Browse files Browse the repository at this point in the history
[AdminBundle, GeneratorBundle, UserManagementBundle] Remove default hardcoded admin/admin
  • Loading branch information
Roderik van der Veer committed Jun 3, 2015
2 parents 0c7761a + ae81112 commit 30befa6
Show file tree
Hide file tree
Showing 18 changed files with 296 additions and 14 deletions.
17 changes: 17 additions & 0 deletions UPGRADE-3.2.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,20 @@ The FormHandler will pass the sequence to the adaptForm method of the FormSubmis
...
}

## Replace hardcoded admin/admin credentials by generated password for default admin user

The default admin user with username 'admin' now has a randomly generated, 8 characters long password.
To accomplish this, a new field password_changed has been added to the user entity. The user will be asked to change this password until he actually changes it.

#### HOW
Before generating this user, a placeholder for the generated password should be added to the app/resources/config.yml file.

kunstmaan_admin:
admin_password: -adminpwd-

The admin user is generated by running: ```app/console doctrine:fixtures:load```. The new password will be displayed on the console to the user
and the -adminpwd- placeholder will be replaced by the generated password.

Note that al Kunstmaan fixtures have been relocated from the AdminBundle to the GeneratorBundle. An extra 'AdminLoginFirstTime.feature' has been added
to the admintests.

3 changes: 2 additions & 1 deletion src/Kunstmaan/AdminBundle/Command/CreateUserCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,9 @@ protected function execute(InputInterface $input, OutputInterface $output)
}
}

// Set admin interface locale
// Set admin interface locale and enable password changed
$user->setAdminLocale($locale);
$user->setPasswordChanged(true);

// Persist
$em->persist($user);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public function getConfigTreeBuilder()
$rootNode
->fixXmlConfig('admin_locale')
->children()
->scalarNode('admin_password')->end()
->scalarNode('dashboard_route')->end()
->arrayNode('admin_locales')
->defaultValue(array('en'))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ public function load(array $configs, ContainerBuilder $container)
if (array_key_exists('dashboard_route', $config)) {
$container->setParameter('kunstmaan_admin.dashboard_route', $config['dashboard_route']);
}
if (array_key_exists('admin_password', $config)) {
$container->setParameter('kunstmaan_admin.admin_password', $config['admin_password']);
}
$container->setParameter('kunstmaan_admin.admin_locales', $config['admin_locales']);
$container->setParameter('kunstmaan_admin.default_admin_locale', $config['default_admin_locale']);

Expand Down
29 changes: 29 additions & 0 deletions src/Kunstmaan/AdminBundle/Entity/BaseUser.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ abstract class BaseUser extends AbstractUser
*/
protected $adminLocale;

/**
* @ORM\Column(type="boolean", name="password_changed", nullable=true)
*/
protected $passwordChanged;

/**
* Construct a new user
*/
Expand Down Expand Up @@ -117,6 +122,30 @@ public function setAdminLocale($adminLocale)
return $this;
}

/**
* is passwordChanged
*
* @return boolean
*/
public function isPasswordChanged()
{
return $this->passwordChanged;
}

/**
* Set passwordChanged
*
* @param boolean $passwordChanged
*
* @return User
*/
public function setPasswordChanged($passwordChanged)
{
$this->passwordChanged = $passwordChanged;

return $this;
}

/**
* @param ClassMetadata $metadata
*/
Expand Down
92 changes: 92 additions & 0 deletions src/Kunstmaan/AdminBundle/EventListener/PasswordCheckListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?php

namespace Kunstmaan\AdminBundle\EventListener;

use Symfony\Bundle\FrameworkBundle\Routing\Router;
use Symfony\Component\HttpKernel\Controller\ControllerResolver;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpFoundation\Session\Session;

/**
* PasswordCheckListener to check if the user has to change his password
*/
class PasswordCheckListener
{
/**
* @var $authorizationChecker
*/
private $authorizationChecker;

/**
* @var $tokenStorage
*/
private $tokenStorage;

/**
* @var $router
*/
private $router;

/**
* @var $session
*/
private $session;

/**
* @param AuthorizationChecker $authorizationChecker
* @param TokenStorage $tokenStorage
* @param Router $router
* @param Session $session
*/
function __construct(AuthorizationChecker $authorizationChecker, TokenStorage $tokenStorage, Router $router, Session $session)
{
$this->authorizationChecker = $authorizationChecker;
$this->tokenStorage = $tokenStorage;
$this->router = $router;
$this->session = $session;
}

/**
* @param GetResponseEvent $event
**/
public function onKernelRequest(GetResponseEvent $event)
{
$url = $event->getRequest()->getRequestUri();
if($this->isAdminRoute($url)) {
$route = $event->getRequest()->get('_route');
if($this->authorizationChecker->isGranted('IS_AUTHENTICATED_REMEMBERED') && $route != 'fos_user_change_password'){
$user = $this->tokenStorage->getToken()->getUser();
if($user->isPasswordChanged() == false) {
$response = new RedirectResponse($this->router->generate('fos_user_change_password'));
$this->session->getFlashBag()->add('error', 'Your password has not yet been changed');
$event->setResponse($response);
}
}
}
}

/**
* @param string $url
*
* @return bool
*/
private function isAdminRoute($url)
{
preg_match('/^\/(app_(.*)\.php\/)?([a-zA-Z_-]{2,5}\/)?admin\/(.*)/', $url, $matches);

// Check if path is part of admin area
if (count($matches) === 0) {
return false;
}

if (strpos($url, '/admin/preview') !== false) {
return false;
}

return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

namespace Kunstmaan\AdminBundle\EventListener;

use FOS\UserBundle\Event\FilterUserResponseEvent;
use FOS\UserBundle\Model\UserManager;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;

/**
* Set password_changed property to 1 after changing the password
*/
class PasswordResettingListener
{

/**
* @var UserManager
*/
private $userManager;

/**
* @param UserManager $userManager
*/
function __construct(UserManager $userManager)
{
$this->userManager = $userManager;
}

/**
* @param FilterUserResponseEvent $event
*/
public function onPasswordResettingSuccess(FilterUserResponseEvent $event)
{
$user = $event->getUser();
$user->setPasswordChanged(true);
$this->userManager->updateUser($user);
}
}
14 changes: 14 additions & 0 deletions src/Kunstmaan/AdminBundle/Resources/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ parameters:
kunstmaan_admin.acl.native.helper.class: 'Kunstmaan\AdminBundle\Helper\Security\Acl\AclNativeHelper'
kunstmaan_admin.clone.listener.class: 'Kunstmaan\AdminBundle\EventListener\CloneListener'
kunstmaan_admin.session_security.class: 'Kunstmaan\AdminBundle\EventListener\SessionSecurityListener'
kunstmaan_admin.password_resetting.listener.class: 'Kunstmaan\AdminBundle\EventListener\PasswordResettingListener'
kunstmaan_admin.password_check.listener.class: 'Kunstmaan\AdminBundle\EventListener\PasswordCheckListener'
kunstmaan_admin.firewall.provider_key: 'main'

services:
Expand Down Expand Up @@ -149,3 +151,15 @@ services:
class: Kunstmaan\AdminBundle\Form\WysiwygType
tags:
- { name: form.type, alias: wysiwyg }

kunstmaan_admin.password_resetting.listener:
class: "%kunstmaan_admin.password_resetting.listener.class%"
arguments: ['@fos_user.user_manager']
tags:
- { name: kernel.event_listener, event: fos_user.change_password.edit.completed, method: onPasswordResettingSuccess }

kunstmaan_admin.password_check.listener:
class: "%kunstmaan_admin.password_check.listener.class%"
arguments: ['@security.authorization_checker', '@security.token_storage', '@router.default', '@session']
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: 1 }
8 changes: 8 additions & 0 deletions src/Kunstmaan/AdminBundle/Resources/views/layout.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@

{% block fos_user_content %}{% endblock fos_user_content %}

{% block admin_link %}
{% if 'profile' in app.request.pathInfo and 'change-password' not in app.request.pathInfo %}
<a href="{{ path('KunstmaanAdminBundle_homepage') }}" class="btn btn-brand btn-block btn--raise-on-hover">
OK
</a>
{% endif %}
{% endblock %}

{% block forgot_password_link %}
{% if 'resetting' not in app.request.pathInfo and 'profile' not in app.request.pathInfo %}
<a href="{{ path('fos_user_resetting_request') }}" class="login__form__forgot-pw">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,6 @@ protected function interact(InputInterface $input, OutputInterface $output)

protected function createGenerator()
{
return new AdminTestsGenerator($this->getContainer()->get('filesystem'), '/admintests');
return new AdminTestsGenerator($this->getContainer(), $this->getContainer()->get('filesystem'), '/admintests');
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Kunstmaan\AdminBundle\DataFixtures\ORM;
namespace Kunstmaan\GeneratorBundle\DataFixtures\ORM;

use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\DataFixtures\AbstractFixture;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Kunstmaan\AdminBundle\DataFixtures\ORM;
namespace Kunstmaan\GeneratorBundle\DataFixtures\ORM;

use Kunstmaan\AdminBundle\Entity\Role;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
<?php

namespace Kunstmaan\AdminBundle\DataFixtures\ORM;
namespace Kunstmaan\GeneratorBundle\DataFixtures\ORM;

use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Kunstmaan\AdminBundle\Entity\User;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Console\Output\ConsoleOutput;

/**
* Fixture for creating the admin and guest user
Expand Down Expand Up @@ -36,18 +37,32 @@ public function setContainer(ContainerInterface $container = null)
*/
public function load(ObjectManager $manager)
{
$tokenGenerator = $this->container->get('fos_user.util.token_generator');
$password = substr($tokenGenerator->generateToken(), 0, 8);

$user1 = $this->createUser(
$manager,
'admin',
'admin',
$password,
'admin@domain.com',
$this->container->getParameter('kunstmaan_admin.default_admin_locale'),
array('ROLE_SUPER_ADMIN'),
array($manager->merge($this->getReference('superadmins-group'))),
true
true,
false
);
$manager->flush();

$output = new ConsoleOutput();
$output->writeln(array(
"<comment> > User 'admin' created with password '$password'</comment>",
));

$file = $this->container->get('kernel')->getRootDir().'/config/config.yml';
$contents = file_get_contents($file);
$contents = str_replace('-adminpwd-', $password, $contents);
file_put_contents($file, $contents);

$this->setReference('adminuser', $user1);
}

Expand All @@ -62,6 +77,7 @@ public function load(ObjectManager $manager)
* @param array $roles The roles the user has
* @param array $groups The groups the user belongs to
* @param bool $enabled Enable login for the user
* @param bool $changed Disable password changed for the user
*
* @return User
*/
Expand All @@ -73,7 +89,8 @@ private function createUser(
$locale,
array $roles = array(),
array $groups = array(),
$enabled = false
$enabled = false,
$changed = false
) {
$user = new User();
$user->setUsername($username);
Expand All @@ -82,6 +99,7 @@ private function createUser(
$user->setEmail($email);
$user->setEnabled($enabled);
$user->setAdminLocale($locale);
$user->setPasswordChanged($changed);
foreach ($groups as $group) {
$user->addGroup($group);
}
Expand Down
Loading

0 comments on commit 30befa6

Please sign in to comment.