1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116:
<?php
namespace Kernel\Providers;
use Core\Providers\Config;
use Core\Providers\Session;
/**
* Manages the permissions required for a specific call (<b>Controller->action()</b>).<br/>
* If the user has not enough permissions, it returns a <b>__throw_to</b> action to redirect them to.
*
* @usage
* Enter the name of the Controller (but without writing "Controller"; e.g., for HomeController, write [Home].<br/>
* There is no ambiguity here, for there should be no direct access/permission to Model files.<br/>
*
* By default, <Controller>@<action> has permission level = 1 for all controllers and actions.<br/>
* That means, if you don't write it down there'll be no errors thrown, but also no security level!<br/>
*
* @example
* <code>
* ; For LoginController, it should look something like
* [Login]
* __throw_to = "Login" ; any unauthorized request goes to the Login path (check routing.ini)
* * = 2 ; As a general rule, in this example all calls require being authenticated
* showLogin = 1 ; Of course, to log in you must be guest, so this has level=1
* login = 1 ; user ; On submitting the login form, you are not authenticated yet! level=1
* showLoginHome = 2 ; Once logged in, you go to the "admin zone": level=2
* </code>
*
* @package Kernel
*/
class Permission {
/**
* @var Permission|false $instance A Permission instance
* @internal
*/
private static $instance;
/**
* @var Config The instance of the Config class
*/
private $config;
private function __construct() {
$this->config = Config::singleton();
}
/**
* Returns a Permission instance, creating it if it did not exist
* @return Permission
*/
public static function singleton() {
if (!self::$instance) {
$c = __CLASS__;
self::$instance = new $c();
}
return self::$instance;
}
/**
* Returns whether the user has permission to acces a given method
* @param string $controller The controller name
* @param string $method The method name
* @return bool $accessAllowed;
*/
public function checkPermission($controller, $method) {
$controllerPermission = $this->config->get('Permissions', $controller);
$classPermission = $this->getPermission($controllerPermission, $method);
$userPermission = $this->getUserPermission();
if ($classPermission <= $userPermission) {
return ['allowed' => TRUE];
} else {
return [
'allowed' => FALSE,
'throw_to' => $controllerPermission['__throw_to']
];
}
}
/**
* Returns the user permission as an integer.
* @return int user permission
*/
public function getUserPermission() {
$role = Session::getRole();
return $role ?: Session::setRole(__ROLE_GUEST__);
}
/**
* Sets a permission level to the current user
* @param int $level = 1 The permission level
* @return Permission
*/
public function setUserPermission($level = 1) {
Session::setRole($level);
return self::$instance;
}
/**
* Gets the user permission for a given class and method
* @param array $class
* @param string $method
* @return int ROLE level
*/
private function getPermission($class, $method) {
if (isset($class[$method])) {
return $class[$method];
} elseif (isset($class['*'])) {
return $class['*'];
} else {
return __ROLE_GUEST__;
}
}
}