Created
December 27, 2009 19:45
-
-
Save savannah/264376 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Base auth presenter, provides support for annotation based authorization checks. | |
* | |
* @author Ondrej Skalicka | |
*/ | |
abstract class BaseAuthPresenter extends Presenter { | |
public $oldLayoutMode = FALSE; | |
protected function startup() { | |
$this->authCheck(); | |
parent::startup(); | |
} | |
/** | |
* Search for annotations on presenter render/action and performs auth check if necessary. | |
* | |
* If user fails to authorize, redirects to login page. | |
* | |
* Recognized annotations are: | |
* <ul> | |
* <li>@loginRequired - only requires user to be logged in (eg. not a guest). Accepts | |
* optional loginUrl attribute (default 'Auth:login') where to redirect if user fails | |
* to authorize | |
* </li> | |
* <li>@permissionRequired - requires user to has access to certain resource/privilege and/or | |
* to be member of a role. Accepts optional arguments (however at least one of 'role', | |
* 'resource' and 'privilege' should be present): | |
* <ul> | |
* <li>'role' if supplied, user must pass $user->isInRole($role) to be authorized</li> | |
* <li>'resource' if supplied, user must pass either $user->isAllowed($resource) | |
* (if 'privilege' is not set) or $user->isAllowed($resource, $privilege) (if both | |
* 'resource' and 'privilege' is set) | |
* </li> | |
* <li>'privilege' if supplied, user must pass either $user->isAllowed(null, $privilege) | |
* (if 'resource' is not set) or $user->isAllowed($resource, $privilege) (if both | |
* 'resource' and 'privilege' is set)</li> | |
* <li>'loginUrl' (defaults to 'Auth:login')if user don't authorize, redirect there</li> | |
* </ul> | |
* </ul> | |
* | |
* Annotations could be set both on Presenter level and Render/Action level. If both are | |
* present, Render overrides Presenter. | |
* | |
* | |
* @return void | |
*/ | |
protected function authCheck() { | |
$loginRequired = false; | |
$roleRequired = null; | |
$resourceRequired = false; | |
$privilegeRequired = false; | |
$loginUrl = 'Auth:login'; | |
// check view level for annotations | |
if ($an = $this -> getAnnotation('permissionRequired')) { | |
if ($an->offsetExists('role')) $roleRequired = $an['role']; | |
if ($an->offsetExists('resource')) $resourceRequired = $an['resource']; | |
if ($an->offsetExists('privilege')) $privilegeRequired = $an['privilege']; | |
if ($an->offsetExists('loginUrl')) $loginUrl = $an['loginUrl']; | |
} elseif ($an = $this -> getAnnotation('loginRequired')) { | |
if ($an->offsetExists('loginUrl')) $loginUrl = $an['loginUrl']; | |
$loginRequired = true; | |
} | |
// check signal for annotations | |
/** | |
* @todo buggy as of now, won't get signalMethodName correctly | |
*/ | |
/*if ($this -> signal !== NULL) { | |
$signalMethod = $this->formatSignalMethod($this->signal); | |
var_dump($this->signal); | |
if ($an = $this -> getMethodAnnotation($signalMethod, 'permissionRequired')) { | |
var_dump($an); | |
if ($an->offsetExists('role')) $roleRequired = $an['role']; | |
if ($an->offsetExists('resource')) $resourceRequired = $an['resource']; | |
if ($an->offsetExists('privilege')) $privilegeRequired = $an['privilege']; | |
if ($an->offsetExists('loginUrl')) $loginUrl = $an['loginUrl']; | |
} elseif ($an = $this -> getMethodAnnotation($signalMethod, 'loginRequired')) { | |
if ($an->offsetExists('loginUrl')) $loginUrl = $an['loginUrl']; | |
$loginRequired = true; | |
} | |
}*/ | |
// check render for annotations | |
$renderMethod = $this->formatRenderMethod($this->view); | |
if ($an = $this -> getMethodAnnotation($renderMethod, 'permissionRequired')) { | |
if ($an->offsetExists('role')) $roleRequired = $an['role']; | |
if ($an->offsetExists('resource')) $resourceRequired = $an['resource']; | |
if ($an->offsetExists('privilege')) $privilegeRequired = $an['privilege']; | |
if ($an->offsetExists('loginUrl')) $loginUrl = $an['loginUrl']; | |
} elseif ($an = $this -> getMethodAnnotation($renderMethod, 'loginRequired')) { | |
if ($an->offsetExists('loginUrl')) $loginUrl = $an['loginUrl']; | |
$loginRequired = true; | |
} | |
$user = Environment::getUser(); | |
if (($loginRequired && !$user->isAuthenticated()) || | |
($roleRequired && !$user->isInRole($roleRequired)) || | |
($resourceRequired && $privilegeRequired && !$user->isAllowed($resourceRequired, $privilegeRequired)) || | |
($resourceRequired && !$privilegeRequired && $user->isAllowed($resourceRequired)) || | |
($privilegeRequired && !$resourceRequired && $user->isAllowed(null, $privilegeRequired))) { | |
$this -> redirect($loginUrl, array('backlink' => $this -> getApplication() -> storeRequest())); | |
} | |
} | |
/** | |
* Returns annotation. | |
* @param string $annotation | |
* @return array | |
*/ | |
protected function getAnnotation($annotation) { | |
return Annotations::get($this->getReflection(), $annotation); | |
} | |
/** | |
* Returns given method's annotation. | |
* @param string $method | |
* @param string $annotation | |
* @return array | |
*/ | |
protected function getMethodAnnotation($method, $annotation) { | |
if (!$this->getReflection()->hasMethod($method)) return false; | |
return Annotations::get(new ReflectionMethod($this->getClass(), $method), $annotation); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class DemoPresenter extends BaseAuthPresenter { | |
/** | |
* This render is public | |
*/ | |
public function renderDefault () { | |
// ... | |
} | |
/** | |
* This render is public as well | |
* | |
* @permissionRequired(role=guest) | |
*/ | |
public function renderGuest () { | |
// ... | |
} | |
/** | |
* This render requires user->isAuthenticated() == true | |
* | |
* @loginRequired | |
*/ | |
public function renderRequiresLogin () { | |
// ... | |
} | |
/** | |
* This render requires user->isAllowed('article', 'add') | |
* | |
* @permissionRequired(resource=article, privilege=add) | |
*/ | |
public function renderAddArticle () { | |
// ... | |
} | |
/** | |
* This render requires user->isAllowed('article', 'edit') and | |
* be in 'admin' role as well. | |
* | |
* @permissionRequired(resource=article, privilege=add, role=admin) | |
*/ | |
public function renderAdminEditArticle () { | |
// ... | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment