Finalized admin security

This commit is contained in:
franck
2013-07-12 14:22:08 +02:00
parent 257de6fba4
commit 385a83f896
35 changed files with 386 additions and 896 deletions

View File

@@ -27,11 +27,13 @@ use Symfony\Component\DependencyInjection\ContainerAware;
use Symfony\Component\HttpFoundation\Response;
use Thelia\Form\BaseForm;
use Thelia\Model\ConfigQuery;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Thelia\Core\Security\Exception\AuthenticationTokenNotFoundException;
use Thelia\Model\ConfigQuery;
use Thelia\Core\Security\Exception\AuthenticationException;
use Thelia\Core\Security\SecurityContext;
/**
*
@@ -44,14 +46,14 @@ use Thelia\Core\Security\Exception\AuthenticationTokenNotFoundException;
class BaseAdminController extends ContainerAware
{
const TEMPLATE_404 = "404.html";
public function notFoundAction()
protected function undefinedAction()
{
return new Response($this->renderRaw(self::TEMPLATE_404), 404);
}
/**
* Render the givent template, and returns the result as an Http Response.
*
@@ -59,7 +61,7 @@ class BaseAdminController extends ContainerAware
* @param array $args the template arguments
* @return \Symfony\Component\HttpFoundation\Response
*/
public function render($templateName, $args = array())
protected function render($templateName, $args = array())
{
$response = new Response();
@@ -67,46 +69,78 @@ class BaseAdminController extends ContainerAware
}
/**
* Render the givent template, and returns the result as a string.
* Render the given template, and returns the result as a string.
*
* @param $templateName the complete template name, with extension
* @param array $args the template arguments
* @return \Symfony\Component\HttpFoundation\Response
*/
public function renderRaw($templateName, $args = array())
protected function renderRaw($templateName, $args = array())
{
$args = array_merge($args, array('lang' => 'fr')); // FIXME
$session = $this->getSession();
$args = array_merge($args, array(
'locale' => $session->getLocale(),
'lang' => $session->getLang()
));
try {
$data = $this->getParser()->render($templateName, $args);
}
catch (AuthenticationTokenNotFoundException $ex) {
// No auth token -> perform login
return new RedirectResponse($this->generateUrl('admin/login'));
return $data;
}
catch (AuthenticationException $ex) {
return $data;
// User is not authenticated, and templates requires authentication -> redirect to login page
// (see Thelia\Core\Template\Smarty\Plugins\Security)
return new RedirectResponse($this->generateUrl('admin/login')); // FIXME shoud be a parameter
}
}
/**
* Return the security context, by default in admin mode.
*
* @return Thelia\Core\Security\SecurityContext
*/
protected function getSecurityContext($context = false)
{
$securityContext = $this->container->get('thelia.securityContext');
$securityContext->setContext($context === false ? SecurityContext::CONTEXT_BACK_OFFICE : $context);
return $securityContext;
}
/**
* @return \Symfony\Component\HttpFoundation\Request
*/
public function getRequest()
protected function getRequest()
{
return $this->container->get('request');
}
/**
* Returns the session from the current request
*
* @return Ambigous <NULL, \Symfony\Component\HttpFoundation\Session\SessionInterface>
*/
protected function getSession() {
$request = $this->getRequest();
return $request->getSession();
}
/**
*
* @return a ParserInterface instance parser, as configured.
*/
public function getParser()
protected function getParser()
{
$parser = $this->container->get("thelia.parser");
// FIXME: should be read from config
$parser->setTemplate('admin/default');
// Define the template thant shoud be used
$parser->setTemplate(ConfigQuery::read('base_admin_template', 'admin/default'));
return $parser;
}
@@ -132,11 +166,19 @@ class BaseAdminController extends ContainerAware
*
* @see UrlGeneratorInterface
*/
public function generateUrl($route, $parameters = array(), $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH)
protected function generateUrl($path, array $parameters = array())
{
return "thelia2/$route"; //FIXME
$base = ConfigQuery::read("base_url", "/").$path; //FIXME
//return $this->container->get('router')->generate($route, $parameters, $referenceType);
$queryString = '';
foreach($parameters as $name => $value) {
$queryString = sprintf("%s=%s&", urlencode($name), urlencode($value));
}
if ('' !== $queryString = rtrim($queryString, "&")) $queryString = '?' . $queryString;
return $base . $queryString;
}
/**
@@ -148,7 +190,7 @@ class BaseAdminController extends ContainerAware
*
* @return Response A Response instance
*/
public function forward($controller, array $path = array(), array $query = array())
protected function forward($controller, array $path = array(), array $query = array())
{
$path['_controller'] = $controller;
$subRequest = $this->container->get('request')->duplicate($query, null, $path);
@@ -164,7 +206,7 @@ class BaseAdminController extends ContainerAware
*
* @return RedirectResponse
*/
public function redirect($url, $status = 302)
protected function redirect($url, $status = 302)
{
return new RedirectResponse($url, $status);
}

View File

@@ -25,33 +25,66 @@ namespace Thelia\Admin\Controller;
use Symfony\Component\HttpFoundation\Response;
use Thelia\Form\AdminLogin;
use Thelia\Core\Security\Token\UsernamePasswordToken;
use Thelia\Core\Security\Authentication\UsernamePasswordAuthenticator;
use Thelia\Core\Security\Encoder\PasswordPhpCompatEncoder;
use Thelia\Core\Security\Token\TokenInterface;
use Thelia\Core\Security\Authentication\AdminUsernamePasswordFormAuthenticator;
use Thelia\Model\AdminLog;
use Thelia\Core\Security\Exception\AuthenticationException;
class SessionController extends BaseAdminController {
public function loginAction()
public function showLoginAction()
{
$form = $this->getLoginForm();
return $this->render("login.html", array(
"form" => $form->createView()
));
}
public function checkLogoutAction()
{
$this->getSecurityContext()->clear();
// Go back to login page.
return $this->redirect($this->generateUrl('admin/login'));
}
public function checkLoginAction()
{
$form = $this->getLoginForm();
$form = $this->getLoginForm();
$request = $this->getRequest();
$request = $this->getRequest();
if($request->isMethod("POST")) {
$authenticator = new AdminUsernamePasswordFormAuthenticator($request, $form);
$form->bind($request);
try {
$user = $authenticator->getAuthentifiedUser();
if ($form->isValid()) {
// Success -> store user in security context
$this->getSecurityContext()->setUser($user);
$this->container->get('request')->authenticate(
$form->get('username')->getData(),
$form->get('password')->getData()
);
// Log authentication success
AdminLog::append("Authentication successufull", $request, $user);
echo "valid"; exit;
}
}
// Redirect to home page - FIXME: requested URL, if we come from another page ?
return $this->redirect($this->generateUrl('admin'));
}
catch (AuthenticationException $ex) {
return $this->render("login.html", array(
"form" => $form->createView()
));
// Log authentication failure
AdminLog::append(sprintf("Authentication failure for username '%s'", $authenticator->getUsername()), $request);
$message = "Login failed. Please check your username and password.";
}
// Display the login form again
return $this->render("login.html", array(
"form" => $authenticator->getLoginForm()->createView(),
"message" => $message
));
}
protected function getLoginForm()