diff --git a/application/core/APIv1_Controller.php b/application/core/APIv1_Controller.php index 5303bf02d..43790c080 100644 --- a/application/core/APIv1_Controller.php +++ b/application/core/APIv1_Controller.php @@ -7,13 +7,31 @@ class APIv1_Controller extends REST_Controller /** * Standard constructor for all the RESTful resources */ - public function __construct() + public function __construct($requiredPermissions) { parent::__construct(); - + // Loads return messages $this->load->helper('message'); - + + // Loads permission lib + $this->load->library('PermissionLib'); + log_message('debug', 'Called API: '.$_SERVER['PHP_SELF'].'?'.$_SERVER['QUERY_STRING']); + + $this->_isAllowed($requiredPermissions); } + + /** + * Checks if the caller is allowed to access to this content with the given permissions + * If it is not allowed will set the HTTP header with code 401 + * Wrapper for _checkPermissions + */ + private function _isAllowed($requiredPermissions) + { + if (!$this->permissionlib->checkPermissions($requiredPermissions, $this->router->method)) + { + $this->response(error('You are not allowed to access to this content'), REST_Controller::HTTP_UNAUTHORIZED); + } + } } diff --git a/application/core/FHC_Controller.php b/application/core/FHC_Controller.php index a8e0cb820..fab8aea32 100644 --- a/application/core/FHC_Controller.php +++ b/application/core/FHC_Controller.php @@ -4,10 +4,6 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); class FHC_Controller extends CI_Controller { - // Conversion from HTTP method to access type method - const READ_HTTP_METHOD = 'GET'; - const WRITE_HTTP_METHOD = 'POST'; - /** * Standard construct for all the controllers, loads the authentication system * Checks the caller permissions @@ -16,8 +12,10 @@ class FHC_Controller extends CI_Controller { parent::__construct(); + // Loads authentication helper $this->load->helper('fhcauth'); + // Loads permission lib $this->load->library('PermissionLib'); $this->_isAllowed($requiredPermissions); @@ -30,103 +28,11 @@ class FHC_Controller extends CI_Controller */ private function _isAllowed($requiredPermissions) { - if (!$this->_checkPermissions($requiredPermissions)) + if (!$this->permissionlib->checkPermissions($requiredPermissions, $this->router->method)) { header('HTTP/1.0 401 Unauthorized'); echo 'You are not allowed to access to this content'; exit; } } - - /** - * Checks if the caller is allowed to access to this content with the given permissions - * - checks if the parameter $requiredPermissions is set, is an array and contains at least one element - * - checks if the given $requiredPermissions parameter contains the called method of the controller - * - checks if the HTTP method used to call is GET or POST - * - convert the required permissions to an array if needed - * - loops through the required permissions - * - checks if the permission is well formatted - * - retrives permission and required access type from the $requiredPermissions array - * - checks if the required access type is compliant with the HTTP method (GET => r, POST => w) - * - if the user has one of the permissions than exit the loop - * - checks if the user has the same required permissiond with the same required access type - * - returns true if all the checks are ok, otherwise false - */ - private function _checkPermissions($requiredPermissions) - { - $checkPermissions = false; - $method = $this->router->method; - $requestMethod = $_SERVER['REQUEST_METHOD']; - - // Checks if the parameter $requiredPermissions is set, is an array and contains at least one element - if (isset($requiredPermissions) && is_array($requiredPermissions) && count($requiredPermissions) > 0) - { - // Checks if the given $requiredPermissions parameter contains the called method of the controller - if (isset($requiredPermissions[$method])) - { - // Checks if the HTTP method used to call is GET or POST - if ($requestMethod == self::READ_HTTP_METHOD || $requestMethod == self::WRITE_HTTP_METHOD) - { - $permissions = $requiredPermissions[$method]; - // Convert the required permissions to an array if needed - if (!is_array($permissions)) - { - $permissions = array($requiredPermissions[$method]); - } - - // Loops through the required permissions - for ($pCounter = 0; $pCounter < count($permissions); $pCounter++) - { - // Checks if the permission is well formatted - if (strpos($permissions[$pCounter], PermissionLib::PERMISSION_SEPARATOR) !== false) - { - // Retrives permission and required access type from the $requiredPermissions array - list($permission, $requiredAccessType) = explode(PermissionLib::PERMISSION_SEPARATOR, $permissions[$pCounter]); - - $accessType = null; - - // Checks if the required access type is compliant with the HTTP method (GET => r, POST => w) - if ($requestMethod == self::READ_HTTP_METHOD - && strpos($requiredAccessType, PermissionLib::READ_RIGHT) !== false) - { - $accessType = PermissionLib::SELECT_RIGHT; // S - } - elseif ($requestMethod == self::WRITE_HTTP_METHOD - && strpos($requiredAccessType, PermissionLib::WRITE_RIGHT) !== false) - { - $accessType = PermissionLib::REPLACE_RIGHT.PermissionLib::DELETE_RIGHT; // UID - } - - if ($accessType != null) // if compliant - { - // Checks if the user has the same required permissiond with the same required access type - $checkPermissions = $this->permissionlib->isBerechtigt($permission, $accessType); - - // If the user has one of the permissionsm than exit the loop - if ($checkPermissions === true) break; - } - } - else - { - show_error('The given permission does not use the correct format'); - } - } - } - else - { - show_error('Your are trying to access to this content with a not valid HTTP method'); - } - } - else - { - show_error('The given permission array does not contain the called method'); - } - } - else - { - show_error('You must give the permissions array as parameter to the constructor of the controller'); - } - - return $checkPermissions; - } } diff --git a/application/libraries/PermissionLib.php b/application/libraries/PermissionLib.php index 8d23842fe..c43f6dec0 100644 --- a/application/libraries/PermissionLib.php +++ b/application/libraries/PermissionLib.php @@ -37,6 +37,10 @@ class PermissionLib const PERMISSION_SEPARATOR = ':'; // used as separator berween permission and right + // Conversion from HTTP method to access type method + const READ_HTTP_METHOD = 'GET'; + const WRITE_HTTP_METHOD = 'POST'; + private $acl; // conversion array from a source to a permission private static $bb; // benutzerberechtigung @@ -123,4 +127,98 @@ class PermissionLib return $isBerechtigt; } + + /** + * Checks if the caller is allowed to access to this content with the given permissions + * - checks if the parameter $requiredPermissions is set, is an array and contains at least one element + * - checks if the given $requiredPermissions parameter contains the called method of the controller + * - checks if the HTTP method used to call is GET or POST + * - convert the required permissions to an array if needed + * - loops through the required permissions + * - checks if the permission is well formatted + * - retrives permission and required access type from the $requiredPermissions array + * - checks if the required access type is compliant with the HTTP method (GET => r, POST => w) + * - if the user has one of the permissions than exit the loop + * - checks if the user has the same required permissiond with the same required access type + * - returns true if all the checks are ok, otherwise false + * + * NOTE: the displayed error messages are used to warn the developer about any issues that could occur, + * they are not intended for the final user! + */ + public function checkPermissions($requiredPermissions, $calledMethod) + { + $checkPermissions = false; + $requestMethod = $_SERVER['REQUEST_METHOD']; + + // Checks if the parameter $requiredPermissions is set, is an array and contains at least one element + if (isset($requiredPermissions) && is_array($requiredPermissions) && count($requiredPermissions) > 0) + { + // Checks if the given $requiredPermissions parameter contains the called method of the controller + if (isset($requiredPermissions[$calledMethod])) + { + // Checks if the HTTP method used to call is GET or POST + if ($requestMethod == self::READ_HTTP_METHOD || $requestMethod == self::WRITE_HTTP_METHOD) + { + $permissions = $requiredPermissions[$calledMethod]; + // Convert the required permissions to an array if needed + if (!is_array($permissions)) + { + $permissions = array($requiredPermissions[$calledMethod]); + } + + // Loops through the required permissions + for ($pCounter = 0; $pCounter < count($permissions); $pCounter++) + { + // Checks if the permission is well formatted + if (strpos($permissions[$pCounter], PermissionLib::PERMISSION_SEPARATOR) !== false) + { + // Retrives permission and required access type from the $requiredPermissions array + list($permission, $requiredAccessType) = explode(PermissionLib::PERMISSION_SEPARATOR, $permissions[$pCounter]); + + $accessType = null; + + // Checks if the required access type is compliant with the HTTP method (GET => r, POST => w) + if ($requestMethod == self::READ_HTTP_METHOD + && strpos($requiredAccessType, PermissionLib::READ_RIGHT) !== false) + { + $accessType = PermissionLib::SELECT_RIGHT; // S + } + elseif ($requestMethod == self::WRITE_HTTP_METHOD + && strpos($requiredAccessType, PermissionLib::WRITE_RIGHT) !== false) + { + $accessType = PermissionLib::REPLACE_RIGHT.PermissionLib::DELETE_RIGHT; // UID + } + + if ($accessType != null) // if compliant + { + // Checks if the user has the same required permissiond with the same required access type + $checkPermissions = $this->isBerechtigt($permission, $accessType); + + // If the user has one of the permissionsm than exit the loop + if ($checkPermissions === true) break; + } + } + else + { + show_error('The given permission does not use the correct format'); + } + } + } + else + { + show_error('Your are trying to access to this content with a not valid HTTP method'); + } + } + else + { + show_error('The given permission array does not contain the called method'); + } + } + else + { + show_error('You must give the permissions array as parameter to the constructor of the controller'); + } + + return $checkPermissions; + } }