Created
December 31, 2011 20:12
-
-
Save hrach/1545209 to your computer and use it in GitHub Desktop.
Secured signlas - old NETTE!
This file contains 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 | |
/** | |
* Signály.cz – JP2 | |
* ---------------- | |
* | |
* @license MIT License http://en.wikipedia.org/wiki/MIT_License | |
* @link http://signaly.cz | |
*/ | |
use Nette; | |
use Nette\Debug; | |
use Nette\Logger; | |
use Nette\Logger\ILogger; | |
use Nette\Environment as Env; | |
use Nette\Application\AppForm; | |
use Nette\Application\BadRequestException; | |
use Nette\Application\ForbiddenRequestException; | |
use Nette\Application\Presenter; | |
use Nette\Security\AuthenticationException; | |
use DateTime; | |
abstract class BasePresenter extends Presenter | |
{ | |
/** | |
* Zkontroluje zda má uživatel potřebné oznámení oprávnení a pokud ne, podnikne patřičné kroky | |
* | |
* @author Jan Tvrdík | |
* @param string|IRowResource | |
* @param string | |
* @return void | |
* @throws ForbiddenRequestException | |
*/ | |
public function requirePrivilege($resource, $action = NULL) | |
{ | |
if (!$this->actor->isAllowed($resource, $action)) { | |
$this->requireLogin(); | |
throw new ForbiddenRequestException('Nemáš tady co dělat!'); | |
} | |
} | |
/** | |
* Vynutí přihlášenost uživatele. | |
* | |
* @author Jan Tvrdík | |
* @return void | |
*/ | |
public function requireLogin() | |
{ | |
if (!$this->actor->isLoggedIn()) { | |
$storedRequest = $this->getApplication()->storeRequest(); | |
$this->redirect(':Auth:requireLogin', array('backlink' => $storedRequest)); | |
} | |
} | |
/** | |
* Zpracuje anotace u dané metody | |
* | |
* Podporované anotace: | |
* - @privilege(resource, action) | |
* - @requireLogin | |
* - @allowedAction(edit) | |
* - @secured | |
* - @onlyAjax | |
* | |
* @author Jan Tvrdík | |
* @param string název metody | |
* @return void | |
*/ | |
private function processMethodAnnotations($method) | |
{ | |
if (!method_exists($this, $method)) return; // přeskočí zpracování, pokud metoda neexistuje | |
$reflection = $this->getReflection()->getMethod($method); | |
$annotations = $reflection->getAnnotations(); | |
if (isset($annotations['privilege'])) { | |
foreach ($annotations['privilege'] as $privilige) { | |
$this->requirePrivilege($privilige[0], $privilige[1]); | |
} | |
} | |
if (isset($annotations['requireLogin'])) { | |
$this->requireLogin(); | |
} | |
if (isset($annotations['allowedAction'])) { | |
$allowedActions = $annotations['allowedAction']; | |
if (!in_array($this->action, $allowedActions)) { | |
throw new ForbiddenRequestException('Volání metody ' . $method . ' není pro akci ' . $this->action . ' povoleno. Zkontrolujte anotaci @allowedAction.'); | |
} | |
} | |
if (isset($annotations['secured'])) { | |
$protectedParams = array(); | |
foreach ($reflection->getParameters() as $param) { | |
if ($param->isOptional()) continue; | |
$protectedParams[$param->name] = $this->getParam($param->name); | |
} | |
if ($this->getParam('__secu') !== $this->createSecureHash($protectedParams)) { | |
throw new ForbiddenRequestException('Secured parameters are not valid.'); | |
} | |
} | |
if (isset($annotations['onlyAjax'])) { | |
if (!$this->isAjax()) { | |
throw new ForbiddenRequestException("Metoda $method přijímá pouze AJAXové požadavky. Viz anotace @onlyAjax"); | |
} | |
} | |
} | |
// === Zabezpečení signalů ===================================================== | |
/** | |
* Zajistí vyhodnocení anotací nad handlerem signálu. | |
* | |
* @author Jan Skrasek, Jan Tvrdík | |
* @param string název signálu | |
* @return void | |
* @throws BadSignalException | |
*/ | |
public function signalReceived($signal) | |
{ | |
$this->processMethodAnnotations($this->formatSignalMethod($signal)); | |
parent::signalReceived($signal); | |
} | |
/** | |
* Generates link. If links points to @secure annotated signal handler method, additonal | |
* parameter preventing changing parameters will be added. | |
* | |
* @author Jan Skrasek | |
* @param string $destination | |
* @param array|mixed $args | |
* @return string | |
*/ | |
public function link($destination, $args = array()) | |
{ | |
if (!is_array($args)) { | |
$args = func_get_args(); | |
array_shift($args); | |
} | |
$link = parent::link($destination, $args); | |
$lastRequest = $this->presenter->lastCreatedRequest; | |
// spatny link | |
if ($lastRequest === NULL) return $link; | |
// neni signal | |
if (substr($destination, - 1) !== '!') return $link; | |
// jen na stejny presenter | |
if ($this->getPresenter()->getName() !== $lastRequest->getPresenterName()) return $link; | |
$destination = str_replace(':', '-', $destination); | |
if (strpos($destination, '-') !== FALSE) { | |
$pos = strrpos($destination, '-'); | |
$signal = substr($destination, $pos + 1, -1); | |
$component = substr($destination, 0, $pos); | |
$component = $this->getComponent($component); | |
} else { | |
$signal = substr($destination, 0, -1); | |
$component = $this; | |
} | |
// jen komponenty | |
if (!$component instanceof Nette\Application\PresenterComponent) return $link; | |
$method = $component->formatSignalMethod($signal); | |
$reflection = Nette\Reflection\MethodReflection::from($component, $method); | |
// nema anotaci | |
if (!$reflection->hasAnnotation('secured')) return $link; | |
$origParams = $lastRequest->getParams(); | |
$protectedParams = array(); | |
foreach ($reflection->getParameters() as $key => $param) { | |
if ($param->isOptional()) continue; | |
$protectedParams[$param->name] = $origParams[$component->getParamId($param->name)]; | |
} | |
$uniqueId = $this->getUniqueId(); | |
if (empty($uniqueId)) { | |
$paramName = $component->getParamId('__secu'); | |
} else { | |
$paramName = substr($component->getParamId('__secu'), strlen($uniqueId) + 1); | |
} | |
$args[$paramName] = $this->createSecureHash($protectedParams); | |
return parent::link($destination, $args); | |
} | |
/** | |
* Creates secure hash from array of arguments. | |
* | |
* @author Jan Skrasek | |
* @param array $param | |
* @return string | |
*/ | |
protected function createSecureHash($params) | |
{ | |
$ns = $this->getSession('securedlinks'); | |
if ($ns->key === NULL) { | |
$ns->key = uniqid(); | |
} | |
$s = implode('|', array_keys($params)) . '|' . implode('|', array_values($params)) . $ns->key; | |
return substr(md5($s), 4, 8); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment