Removed InternalEvent, simplified SecurityContext

This commit is contained in:
franck
2013-08-28 17:52:32 +02:00
parent 253a0b76d8
commit 0361cd1ff2
26 changed files with 630 additions and 610 deletions

View File

@@ -35,27 +35,8 @@ use Thelia\Form\BaseForm;
*/
abstract class ActionEvent extends Event
{
/**
*
* @var Symfony\Component\HttpFoundation\Request
*/
protected $request;
protected $errorForm = null;
protected $parameters = array();
/**
*
* @param \Symfony\Component\HttpFoundation\Request $request
* @param string $action
*/
public function __construct(Request $request)
{
$this->request = $request;
}
public function __set($name, $value)
{
$this->parameters[$name] = $value;
@@ -69,30 +50,4 @@ abstract class ActionEvent extends Event
return null;
}
/**
*
* @return \Symfony\Component\HttpFoundation\Request
*/
public function getRequest()
{
return $this->request;
}
public function setErrorForm(BaseForm $form)
{
$this->errorForm = $form;
if ($form != null) $this->stopPropagation();
}
public function getErrorForm()
{
return $this->errorForm;
}
public function hasErrorForm()
{
return $this->errorForm != null ? true : false;
}
}
}

View File

@@ -25,7 +25,7 @@ namespace Thelia\Core\Event;
use Thelia\Model\CartItem;
class CartItemEvent extends InternalEvent
class CartItemEvent extends ActionEvent
{
protected $cartItem;

View File

@@ -21,34 +21,64 @@
/* */
/*************************************************************************************/
namespace Thelia\Core;
namespace Thelia\Core\Event;
use Thelia\Model\Category;
class Context
class CategoryChangePositionEvent extends ActionEvent
{
const CONTEXT_FRONT_OFFICE = 'front';
const CONTEXT_BACK_OFFICE = 'admin';
const POSITION_UP = 1;
const POSITION_DOWN = 2;
const POSITION_ABSOLUTE = 3;
protected $defineContext = array(
self::CONTEXT_BACK_OFFICE,
self::CONTEXT_FRONT_OFFICE
);
protected $id;
protected $mode;
protected $position;
protected $category;
protected $currentContext = self::CONTEXT_FRONT_OFFICE;
public function isValidContext($context)
public function __construct($id, $mode, $position = null)
{
return in_array($context, $this->defineContext);
$this->id = $id;
$this->mode = $mode;
$this->position = $position;
}
public function setContext($context)
public function getId()
{
if ($this->isValidContext($context)) {
$this->currentContext = $context;
}
return $this->id;
}
public function getContext()
public function setId($id)
{
return $this->currentContext;
$this->id = $id;
}
}
public function getMode()
{
return $this->mode;
}
public function setMode($mode)
{
$this->mode = $mode;
}
public function getPosition()
{
return $this->position;
}
public function setPosition($position)
{
$this->position = $position;
}
public function getCategory()
{
return $this->category;
}
public function setCategory($category)
{
$this->category = $category;
}
}

View File

@@ -21,16 +21,62 @@
/* */
/*************************************************************************************/
namespace Thelia\Core\Event\Internal;
namespace Thelia\Core\Event;
use Symfony\Component\EventDispatcher\Event;
use Thelia\Model\Category;
/**
* Base class used for internal event like creating new Customer, adding item to cart, etc
*
* Class InternalEvent
* @package Thelia\Core\Event
*/
abstract class InternalEvent extends Event
class CategoryCreateEvent extends ActionEvent
{
protected $title;
protected $parent;
protected $locale;
protected $created_category;
public function __construct($title, $parent, $locale)
{
$this->title = $title;
$this->parent = $parent;
$this->locale = $locale;
}
public function getTitle()
{
return $this->title;
}
public function setTitle($title)
{
$this->title = $title;
}
public function getParent()
{
return $this->parent;
}
public function setParent($parent)
{
$this->parent = $parent;
}
public function getLocale()
{
return $this->locale;
}
public function setLocale($locale)
{
$this->locale = $locale;
}
public function getCreatedCategory()
{
return $this->created_category;
}
public function setCreatedCategory(Category $created_category)
{
$this->created_category = $created_category;
var_dump($this->created_category);
}
}

View File

@@ -21,17 +21,36 @@
/* */
/*************************************************************************************/
namespace Thelia\Core\Event\Internal;
namespace Thelia\Core\Event;
use Thelia\Model\Category;
use Thelia\Model\Cart;
class CartEvent extends InternalEvent
class CategoryDeleteEvent extends ActionEvent
{
public $cart;
protected $id;
protected $deleted_category;
public function __construct(Cart $cart)
public function __construct($id)
{
$this->cart = $cart;
$this->id = $id;
}
public function getId()
{
return $this->id;
}
public function setId($id)
{
$this->id = $id;
}
public function getDeletedCategory()
{
return $this->deleted_category;
}
public function setDeletedCategory(Category $deleted_category)
{
$this->deleted_category = $deleted_category;
}
}

View File

@@ -22,15 +22,35 @@
/*************************************************************************************/
namespace Thelia\Core\Event;
use Thelia\Model\Category;
class CategoryEvent extends InternalEvent
class CategoryToggleVisibilityEvent extends ActionEvent
{
public $category;
protected $id;
protected $category;
public function __construct(Category $category)
public function __construct($id)
{
$this->id = $id;
}
public function getId()
{
return $this->id;
}
public function setId($id)
{
$this->id = $id;
}
public function getCategory()
{
return $this->category;
}
public function setCategory(Category $category)
{
$this->category = $category;
}
}
}

View File

@@ -21,11 +21,12 @@
/* */
/*************************************************************************************/
namespace Thelia\Core\Event\Internal;
namespace Thelia\Core\Event;
use Thelia\Model\Customer;
use Thelia\Core\Event\ActionEvent;
class CustomerEvent extends InternalEvent
class CustomerEvent extends ActionEvent
{
public $customer;

View File

@@ -94,11 +94,29 @@ final class TheliaEvents
*/
const AFTER_CHANGECUSTOMER = "action.after_changecustomer";
/**
* Sent once the category creation form has been successfully validated, and before category insertion in the database.
*/
const BEFORE_CREATECATEGORY = "action.before_createcategory";
/**
* Create, change or delete a category
*/
const CATEGORY_CREATE = "action.createCategory";
const CATEGORY_MODIFY = "action.modifyCategory";
const CATEGORY_DELETE = "action.deleteCategory";
/**
* Toggle category visibility
*/
const CATEGORY_TOGGLE_VISIBILITY = "action.toggleCategoryVisibility";
/**
* Change category position
*/
const CATEGORY_CHANGE_POSITION = "action.changeCategoryPosition";
/**
* Sent just after a successful insert of a new category in the database.
*/
@@ -113,6 +131,11 @@ final class TheliaEvents
*/
const AFTER_DELETECATEGORY = "action.after_deletecategory";
/**
* Sent just before a successful change of a category in the database.
*/
const BEFORE_CHANGECATEGORY = "action.before_changecategory";
/**
* Sent just after a successful change of a category in the database.
*/
@@ -154,5 +177,4 @@ final class TheliaEvents
* Sent on cimage cache clear request
*/
const IMAGE_CLEAR_CACHE = "action.clearImageCache";
}

View File

@@ -33,36 +33,11 @@ use Thelia\Core\HttpFoundation\Request;
*/
class SecurityContext
{
const CONTEXT_FRONT_OFFICE = 'front';
const CONTEXT_BACK_OFFICE = 'admin';
private $request;
private $context;
public function __construct(Request $request)
{
$this->request = $request;
$this->context = null;
}
public function setContext($context)
{
if ($context !== self::CONTEXT_FRONT_OFFICE && $context !== self::CONTEXT_BACK_OFFICE) {
throw new \InvalidArgumentException(sprintf("Invalid or empty context identifier '%s'", $context));
}
$this->context = $context;
return $this;
}
public function getContext($exception_if_context_undefined = false)
{
if (null === $this->context && $exception_if_context_undefined === true)
throw new \LogicException("No context defined. Please use setContext() first.");
return $this->context;
}
private function getSession()
@@ -76,28 +51,47 @@ class SecurityContext
}
/**
* Gets the currently authenticated user in the current context, or null if none is defined
* Gets the currently authenticated user in the admin, or null if none is defined
*
* @return UserInterface|null A UserInterface instance or null if no user is available
*/
public function getUser()
public function getAdminUser()
{
$context = $this->getContext(true);
if ($context === self::CONTEXT_FRONT_OFFICE)
$user = $this->getSession()->getCustomerUser();
else if ($context == self::CONTEXT_BACK_OFFICE)
$user = $this->getSession()->getAdminUser();
else
$user = null;
return $user;
return $this->getSession()->getAdminUser();
}
final public function isAuthenticated()
/**
* Gets the currently authenticated customer, or null if none is defined
*
* @return UserInterface|null A UserInterface instance or null if no user is available
*/
public function getCustomerUser()
{
if (null !== $this->getUser()) {
return true;
return $this->getSession()->getCustomerUser();
}
/**
* Check if a user has at least one of the required roles
*
* @param UserInterface $user the user
* @param array $roles the roles
* @return boolean true if the user has the required role, false otherwise
*/
final public function hasRequiredRole($user, array $roles) {
if ($user != null) {
// Check if user's roles matches required roles
$userRoles = $user->getRoles();
$roleFound = false;
foreach ($userRoles as $role) {
if (in_array($role, $roles)) {
$roleFound = true;
return true;
}
}
}
return false;
@@ -110,85 +104,88 @@ class SecurityContext
*/
final public function isGranted(array $roles, array $permissions)
{
if ($this->isAuthenticated() === true) {
// Find a user which matches the required roles.
$user = $this->getCustomerUser();
$user = $this->getUser();
if (! $this->hasRequiredRole($user, $roles)) {
$user = $this->getAdminUser();
// Check if user's roles matches required roles
$userRoles = $user->getRoles();
if (! $this->hasRequiredRole($user, $roles)) {
$user = null;
}
}
$roleFound = false;
if ($user != null) {
foreach ($userRoles as $role) {
if (in_array($role, $roles)) {
$roleFound = true;
break;
}
if (empty($permissions)) {
return true;
}
if ($roleFound) {
// Get permissions from profile
// $userPermissions = $user->getPermissions(); FIXME
if (empty($permissions)) {
return true;
}
// TODO: Finalize permissions system !;
// Get permissions from profile
// $userPermissions = $user->getPermissions(); FIXME
$userPermissions = array('*'); // FIXME !
// TODO: Finalize permissions system !;
$permissionsFound = true;
$userPermissions = array('*'); // FIXME !
// User have all permissions ?
if (in_array('*', $userPermissions))
return true;
$permissionsFound = true;
// Check that user's permissions matches required permissions
foreach ($permissions as $permission) {
if (! in_array($permission, $userPermissions)) {
$permissionsFound = false;
// User have all permissions ?
if (in_array('*', $userPermissions))
return true;
// Check that user's permissions matches required permissions
foreach ($permissions as $permission) {
if (! in_array($permission, $userPermissions)) {
$permissionsFound = false;
break;
}
}
return $permissionsFound;
break;
}
}
return $permissionsFound;
}
return false;
}
/**
* Sets the authenticated user.
* Sets the authenticated admin user.
*
* @param UserInterface $user A UserInterface, or null if no further user should be stored
*/
public function setUser(UserInterface $user)
public function setAdminUser(UserInterface $user)
{
$context = $this->getContext(true);
$user->eraseCredentials();
if ($context === self::CONTEXT_FRONT_OFFICE)
$this->getSession()->setCustomerUser($user);
else if ($context == self::CONTEXT_BACK_OFFICE)
$this->getSession()->setAdminUser($user);
$this->getSession()->setAdminUser($user);
}
/**
* Clear the user from the security context
* Sets the authenticated customer user.
*
* @param UserInterface $user A UserInterface, or null if no further user should be stored
*/
public function clear()
public function setCustomerUser(UserInterface $user)
{
$context = $this->getContext(true);
$user->eraseCredentials();
if ($context === self::CONTEXT_FRONT_OFFICE)
$this->getSession()->clearCustomerUser();
else if ($context == self::CONTEXT_BACK_OFFICE)
$this->getSession()->clearAdminUser();
$this->getSession()->setCustomerUser($user);
}
}
/**
* Clear the customer from the security context
*/
public function clearCustomerUser()
{
$this->getSession()->clearCustomerUser();
}
/**
* Clear the admin from the security context
*/
public function clearAdminUser()
{
$this->getSession()->clearAdminUser();
}
}

View File

@@ -68,15 +68,12 @@ class Auth extends BaseLoop
*/
public function exec(&$pagination)
{
$context = $this->getContext();
$roles = $this->_explode($this->getRoles());
$permissions = $this->_explode($this->getPermissions());
$loopResult = new LoopResult();
try {
$this->securityContext->setContext($context);
if (true === $this->securityContext->isGranted($roles, $permissions == null ? array() : $permissions)) {
// Create an empty row: loop is no longer empty :)

View File

@@ -52,7 +52,7 @@ class DataAccessFunctions extends AbstractSmartyPlugin
*/
public function adminDataAccess($params, &$smarty)
{
return $this->userDataAccess("Admin User", SecurityContext::CONTEXT_BACK_OFFICE, $params);
return $this->userDataAccess("Admin User", $this->securityContext->getAdminUser(), $params);
}
/**
@@ -64,7 +64,7 @@ class DataAccessFunctions extends AbstractSmartyPlugin
*/
public function customerDataAccess($params, &$smarty)
{
return $this->userDataAccess("Customer User", SecurityContext::CONTEXT_FRONT_OFFICE, $params);
return $this->userDataAccess("Customer User", $this->securityContext->getCustomerUser(), $params);
}
/**
@@ -75,12 +75,11 @@ class DataAccessFunctions extends AbstractSmartyPlugin
* @return string the value of the requested attribute
* @throws InvalidArgumentException if the object does not have the requested attribute.
*/
protected function userDataAccess($objectLabel, $context, $params)
protected function userDataAccess($objectLabel, $user, $params)
{
$attribute = $this->getNormalizedParam($params, array('attribute', 'attrib', 'attr'));
if (! empty($attribute)) {
$user = $this->securityContext->setContext($context)->getUser();
if (null != $user) {
$getter = sprintf("get%s", ucfirst($attribute));

View File

@@ -46,11 +46,6 @@ class Security extends AbstractSmartyPlugin
*/
public function checkAuthFunction($params, &$smarty)
{
// Context: 'front' or 'admin'
$context = $this->getNormalizedParam($params, 'context');
$this->securityContext->setContext($context);
$roles = $this->_explode($this->getParam($params, 'roles'));
$permissions = $this->_explode($this->getParam($params, 'permissions'));