This commit is contained in:
Andreas Moik
2016-08-01 16:33:07 +02:00
6 changed files with 485 additions and 227 deletions
+26 -211
View File
@@ -12,159 +12,28 @@
*/
// ------------------------------------------------------------------------
if(!defined("BASEPATH")) exit("No direct script access allowed");
if (!defined("BASEPATH")) exit("No direct script access allowed");
class PCRM extends APIv1_Controller
{
// Black list of resources that are no allowed to be used
private static $RESOURCES_BLACK_LIST = array("LogLib", "FilesystemLib", "MigrationLib", "REST_Controller");
/**
* Message API constructor.
* API constructor
*/
public function __construct()
{
parent::__construct();
// Loads the PCRMLib
$this->load->library("PCRMLib");
}
/**
* @return void
* Manages a HTTP get call
*/
public function getCall()
{
$parameters = $this->_getParameters($this->get());
$validation = $this->_validateCall($parameters);
// If the validation was passed
if($validation->error == EXIT_SUCCESS)
{
$loaded = null;
// Check if the resource is already loaded, it works only with libraries and drivers
if (($loaded = $this->load->is_loaded($parameters->resourceName)) === false)
{
// If the given resource is a model
if(strpos($parameters->resourceName, "_model") !== false)
{
try
{
// Try to load it
$loaded = $this->load->model($parameters->resourcePath . $parameters->resourceName);
}
catch(Exception $e)
{
// Errors while loading the model
$loaded = null;
$result = $this->_error($e->getMessage());
}
}
// If the given resource is a library
else if(strpos($parameters->resourceName, "Lib") !== false)
{
// The method "library" of the class CI_Loader provided by CI has some limitations,
// so to be able to check errors was used this workaround
try
{
// Gets all the configured resources paths
$packagePaths = $this->load->get_package_paths();
// Looking for a file in every paths with the same name of the resource
$found = null;
for ($i = 0; $i < count($packagePaths) && is_null($found); $i++)
{
if (file_exists($packagePaths[$i] . "libraries/" . $parameters->resourcePath . $parameters->resourceName . ".php"))
{
$found = $packagePaths[$i] . "libraries/" . $parameters->resourcePath . $parameters->resourceName . ".php";
}
}
// If the file was found
if (!is_null($found))
{
// Load the file
$loaded = $this->load->file($found);
// If the resource is not present inside the file
if (!class_exists($parameters->resourceName))
{
$loaded = null;
// Same phrase error as load->model()
$result = $this->_error($found . " exists, but doesn't declare class " . $parameters->resourceName);
}
}
else
{
$loaded = null;
// Same phrase error as load->model()
$result = $this->_error("Unable to load the requested class: " . $parameters->resourceName);
}
}
catch(Exception $e)
{
$result = $this->_error($e->getMessage());
}
}
// Wrong selection!
else
{
$result = $this->_error("Neither a lib nor model: " . $parameters->resourcePath . $parameters->resourceName);
}
}
// If the resource was found and loaded
if(!is_null($loaded))
{
try
{
// Get informations about the function
$reflectionMethod = new ReflectionMethod($parameters->resourceName, $parameters->function);
// If the number of given parameters is equal to the number of parameters required by the function
if ($reflectionMethod->getNumberOfRequiredParameters() == count($parameters->parameters))
{
// If the function is static
if ($reflectionMethod->isStatic() === true)
{
$classMethod = $parameters->resourceName . "::" . $parameters->function;
}
// If the function is not static
else
{
$classMethod = array(new $parameters->resourceName(), $parameters->function);
}
// If the function of that resource is callable
if(is_callable($classMethod))
{
// Call resource->function()
$resultCall = @call_user_func_array($classMethod, $parameters->parameters);
// If errors occurred while running it
if($resultCall === false)
{
$result = $this->_error("Error running " . $parameters->resourceName . "->" . $parameters->function . "()");
}
// Returns the result of resource->function()
else
{
$result = $resultCall;
}
}
else
{
$result = $this->_error($parameters->resourceName . "->" . $parameters->function . "() is not callable!");
}
}
else
{
$result = $this->_error("Wrong parameters number");
}
}
catch(Exception $e)
{
$result = $this->_error($e->getMessage());
}
}
}
else
{
$result = $validation;
}
// Start me up!
$result = $this->pcrmlib->start($this->get(), PermissionLib::SELECT_RIGHT);
// Print the result
$this->response($result, REST_Controller::HTTP_OK);
@@ -175,88 +44,34 @@ class PCRM extends APIv1_Controller
*/
public function postCall()
{
$validation = $this->_validatePostMessage($this->post());
// Start me up!
$result = $this->pcrmlib->start($this->post(), PermissionLib::UPDATE_RIGHT);
if(is_object($validation) && $validation->error == EXIT_SUCCESS)
{
$result = $this->messagelib->sendMessage(
$this->post()['person_id'], $this->post()['subject'], $this->post()['body'], PRIORITY_NORMAL, $this->post()['relationmessage_id'], $this->post()['oe_kurzbz']
);
$this->response($result, REST_Controller::HTTP_OK);
}
else
{
$this->response($validation, REST_Controller::HTTP_OK);
}
// Print the result
$this->response($result, REST_Controller::HTTP_OK);
}
/**
* Gets the parameters from the call
* @return void
*/
private function _getParameters($parametersArray)
public function putCall()
{
$parameters = new stdClass();
$parameters->parameters = array();
$count = 0;
// Start me up!
$result = $this->pcrmlib->start($this->put(), PermissionLib::INSERT_RIGHT);
foreach($parametersArray as $parameterName => $parameterValue)
{
// The name of the resource, path included
if($parameterName == "resource")
{
// Separates the resource path from the resource name
$splittedResource = preg_split("/\//", $parameterValue);
$parameters->resourceName = $splittedResource[count($splittedResource) - 1];
$parameters->resourcePath = str_replace($parameters->resourceName, "", $parameterValue);
}
// The name of the function
else if($parameterName == "function")
{
$parameters->function = $parameterValue;
}
// It is assumed that all other parameters are parameters to be passed to the function
// They will be passed to the function in the same order in which they are passed to
// this controller
else
{
$parameters->parameters[$count++] = $parameterValue;
}
}
return $parameters;
// Print the result
$this->response($result, REST_Controller::HTTP_OK);
}
/**
* Validate the given parameters
* @return void
*/
private function _validateCall($parameters)
public function deleteCall()
{
if (!is_object($parameters))
{
return $this->_error("Parameter is not an object");
}
if (!isset($parameters->resourcePath))
{
return $this->_error("Resource path is not specified");
}
if (!isset($parameters->resourceName))
{
return $this->_error("Resource name is not specified");
}
if (!isset($parameters->function))
{
return $this->_error("Function is not specified");
}
if (!is_array($parameters->parameters))
{
return $this->_error("Parameters are not specified");
}
if (in_array($parameters->resourceName, PCRM::$RESOURCES_BLACK_LIST))
{
return $this->_error("You are trying to access to unauthorized resources");
}
// Start me up!
$result = $this->pcrmlib->start($this->delete(), PermissionLib::DELETE_RIGHT);
return $this->_success("Input data are valid");
// Print the result
$this->response($result, REST_Controller::HTTP_OK);
}
}
+396
View File
@@ -0,0 +1,396 @@
<?php
if (! defined("BASEPATH")) exit("No direct script access allowed");
/**
*
*/
class PCRMLib
{
const RESOURCE_PARAMETER = "resource";
const FUNCTION_PARAMETER = "function";
const REG_SPLIT_EXPR = "/\//";
const LIB_PREFIX = "Lib";
const LIB_FILE_EXTENSION = ".php";
const LIBS_PATH = "libraries";
const MODEL_PREFIX = "_model";
// Black list of resources that are no allowed to be used
private static $RESOURCES_BLACK_LIST = array(
"PCRMLib", // disabled self loading
"LogLib", // hardly usefull and virtually dangerous
"MigrationLib", // virtually dangerous, DB manipulation
"FilesystemLib" // virtually dangerous, direct access to file system
);
/**
* Object initialization
*/
public function __construct()
{
// Gets CI instance
$this->ci =& get_instance();
// Loads helper message to manage returning messages
$this->ci->load->helper("message");
$this->ci->load->library("PermissionLib");
}
/**
* Everything starts here...
*/
public function start($callParameters, $permissionType)
{
$result = null;
$parameters = $this->_getParameters($callParameters);
$validation = $this->_validateCall($parameters);
// If the validation was passed
if ($validation->error == EXIT_SUCCESS)
{
$loaded = null;
// If the given resource is a model
if (strpos($parameters->resourceName, PCRMLib::MODEL_PREFIX) !== false)
{
// Try to load the model
$result = $this->_loadModel($parameters->resourcePath, $parameters->resourceName);
if ($result->error == EXIT_SUCCESS)
{
$loaded = $result->retval;
}
}
// If the given resource is a library
else if (strpos($parameters->resourceName, PCRMLib::LIB_PREFIX) !== false)
{
// Check if the resource is already loaded, it works only with libraries and drivers
$isLoaded = $this->ci->load->is_loaded($parameters->resourceName);
// If not loaded then load it
if ($isLoaded === false)
{
// Checks if the operation is permitted by the API caller
// Only for libraries, permissions are automatically handled by models
$result = $this->checkLibraryPermission(
$parameters->resourcePath,
$parameters->resourceName,
$parameters->function,
$permissionType
);
if ($result->error == EXIT_ERROR)
{
$loaded = null;
}
else
{
// Try to load the library
$result = $this->_loadLibrary($parameters->resourcePath, $parameters->resourceName);
if ($result->error == EXIT_SUCCESS)
{
$loaded = $result->retval;
}
}
}
// If it is already loaded $isLoaded contains the instance of the library
else
{
$loaded = $isLoaded;
}
}
// Wrong selection!
else
{
$result = $this->_error("Neither a lib nor model: " . $parameters->resourcePath . $parameters->resourceName);
}
// If the resource was found and loaded
if (!is_null($loaded))
{
$result = $this->_callThis($parameters->resourceName, $parameters->function, $parameters->parameters);
}
else
{
// Resource not loaded
}
}
else
{
$result = $validation;
}
return $result;
}
/**
* Gets the parameters from the call
*/
private function _getParameters($parametersArray)
{
$parameters = new stdClass();
$parameters->parameters = array();
$count = 0;
foreach ($parametersArray as $parameterName => $parameterValue)
{
// The name of the resource, path included
if ($parameterName == PCRMLib::RESOURCE_PARAMETER)
{
// Separates the resource path from the resource name
$splittedResource = preg_split(PCRMLib::REG_SPLIT_EXPR, $parameterValue);
$parameters->resourceName = $splittedResource[count($splittedResource) - 1];
$parameters->resourcePath = str_replace($parameters->resourceName, "", $parameterValue);
}
// The name of the function
else if ($parameterName == PCRMLib::FUNCTION_PARAMETER)
{
$parameters->function = $parameterValue;
}
// It is assumed that all other parameters are the parameters to be passed to the function
// They will be passed to the function in the same order in which they are passed to
// this controller
else
{
$parameters->parameters[$count++] = $parameterValue;
}
}
return $parameters;
}
/**
* Validate the given parameters
*/
private function _validateCall($parameters)
{
if (!is_object($parameters))
{
return $this->_error("Parameter is not an object");
}
if (!isset($parameters->resourcePath))
{
return $this->_error("Resource path is not specified");
}
if (!isset($parameters->resourceName))
{
return $this->_error("Resource name is not specified");
}
if (!isset($parameters->function))
{
return $this->_error("Function is not specified");
}
if (!is_array($parameters->parameters))
{
return $this->_error("Parameters are not specified");
}
if (in_array($parameters->resourceName, PCRMLib::$RESOURCES_BLACK_LIST))
{
return $this->_error("You are trying to access to unauthorized resources");
}
return $this->_success("Input data are valid");
}
/**
* Loads a model using the given path and name
*
* NOTE: the models automatically handle the permissions
*/
private function _loadModel($resourcePath, $resourceName)
{
$loaded = null;
$result = null;
try
{
$loaded = $this->ci->load->model($resourcePath . $resourceName);
}
catch (Exception $e)
{
// Errors while loading the model
$result = $this->_error("Errors while loading the model: " . $e->getMessage());
}
if (!is_null($loaded))
{
$result = $this->_success($loaded);
}
return $result;
}
private function checkLibraryPermission($resourcePath, $resourceName, $function, $permissionType)
{
$result = null;
$permissionPath = "";
if ($resourcePath != "")
{
$permissionPath = $resourcePath;
}
$permissionPath .= $resourceName . "." . $function;
if ($this->ci->permissionlib->hasPermission($permissionPath, $permissionType) === false)
{
$result = $this->_error(lang("fhc_".FHC_NORIGHT)." -> ".$permissionPath, FHC_NORIGHT);
}
else
{
$result = $this->_success("Has permission");
}
return $result;
}
/**
* Loads a library using the given path and name
*
* The method "library" of the class CI_Loader provided by CI has some limitations,
* so to be able to check errors was used a workaround.
* It consists in:
* - Checking if the file (identified by parameters $resourcePath and $resourceName) exists
* - If exists it will be loaded using the method "file" from CI_Loader
* - Checks if the loaded file contains a class identified by parameter $resourceName
*
* If one of the previous tests fails, it will be returned a null value
*/
private function _loadLibrary($resourcePath, $resourceName)
{
$loaded = null;
try
{
// Gets all the configured resources paths
$packagePaths = $this->ci->load->get_package_paths();
// Looking for a file in every paths with the same name of the resource
$found = null;
for ($i = 0; $i < count($packagePaths) && is_null($found); $i++)
{
$file = $packagePaths[$i] . PCRMLib::LIBS_PATH . DIRECTORY_SEPARATOR .
$resourcePath . $resourceName . PCRMLib::LIB_FILE_EXTENSION;
if (file_exists($file))
{
$found = $file;
}
}
// If the file was found
if (!is_null($found))
{
// Load the file
$loaded = $this->ci->load->file($found);
// If the resource is not present inside the file
if (!class_exists($resourceName))
{
$loaded = null;
// Same phrase error as load->model() provided by CI
$result = $this->_error($found . " exists, but doesn't declare class " . $resourceName);
}
}
else
{
$loaded = null;
// Same phrase error as load->model() provided by CI
$result = $this->_error("Unable to load the requested class: " . $resourceName);
}
}
catch (Exception $e)
{
// Errors while loading the library
$result = $this->_error("Errors while loading the library: " . $e->getMessage());
}
if (!is_null($loaded))
{
$result = $this->_success($loaded);
}
return $result;
}
/**
* Calls a method of a class with the given parameters and returns its result
*
* @param string $resourceName identifies the class name
* @param string $function identifies the method name
* @param array $parameters contains the parameters to be passed to the method
*/
private function _callThis($resourceName, $function, $parameters)
{
$result = null;
try
{
// Get informations about the function
$reflectionMethod = new ReflectionMethod($resourceName, $function);
// If the number of given parameters is greater or equal to the number of
// parameters required by the function
if (count($parameters) >= $reflectionMethod->getNumberOfRequiredParameters())
{
// If the function is static
if ($reflectionMethod->isStatic() === true)
{
$classMethod = $resourceName . "::" . $function;
}
// If the function is not static
else
{
$classMethod = array(new $resourceName(), $function);
}
// If the resource's function is callable
if (is_callable($classMethod))
{
// Call resource->function()
// @ was applied to prevent really ugly and unmanageable errors
$resultCall = @call_user_func_array($classMethod, $parameters);
// If errors occurred while running it
// NOTE: if the called function via call_user_func_array returns a boolean set as false,
// it will be recognized like a running error. A little bit tricky ;)
if ($resultCall === false)
{
$result = $this->_error("Error running " . $resourceName . "->" . $function . "()");
}
// Returns the result of resource->function()
else
{
$result = $this->_success($resultCall);
}
}
else
{
$result = $this->_error($resourceName . "->" . $function . "() is not callable!");
}
}
else
{
$result = $this->_error(
"Number of required parameters: " . $reflectionMethod->getNumberOfRequiredParameters() .
". Given: " . count($parameters)
);
}
}
catch (Exception $e)
{
$result = $this->_error($e->getMessage());
}
return $result;
}
/*
*
*/
private function _error($retval = '', $message = EXIT_ERROR)
{
return error($retval, $message);
}
/*
*
*/
private function _success($retval, $message = EXIT_SUCCESS)
{
return success($retval, $message);
}
}
+36 -14
View File
@@ -34,32 +34,54 @@ require_once(FCPATH.'include/benutzerberechtigung.class.php');
class PermissionLib
{
const SELECT_RIGHT = "s";
const UPDATE_RIGHT = "u";
const INSERT_RIGHT = "i";
const DELETE_RIGHT = "d";
public $bb;
/**
* Auth Username, Password over FH-Complete
*
* @param string $username
* @param string $password
* @return bool
*
*/
function __construct()
{
$this->CI =& get_instance();
$this->CI->load->helper('fhcauth');
// Loads CI instance
$this->ci =& get_instance();
// Loads the library to manage the rights system
$this->ci->load->library("FHC_DB_ACL");
// Loads the array of resources
$this->ci->fhc_db_acl->acl = $this->ci->config->item('fhc_acl');
}
/**
* @return bool <b>true</b> if a user has the right to access to the specified
* resource with a specified permission type, <b>false</b> otherwise
*/
public function hasPermission($sourceName, $permissionType)
{
// If the resource exists
if (isset($this->ci->fhc_db_acl->acl[$sourceName]))
{
// Checks permission
return $this->ci->fhc_db_acl->isBerechtigt($this->ci->fhc_db_acl->acl[$sourceName], $permissionType);
}
// if the resource does not exist, do not lose useful clock cycles
else
{
return false;
}
}
function isBerechtigt($berechtigung_kurzbz, $art = null, $oe_kurzbz = null, $kostenstelle_id = null)
{
$this->bb->getBerechtigungen(getAuthUID());
return $this->bb->isBerechtigt($berechtigung_kurzbz, $oe_kurzbz, $art, $kostenstelle_id);
}
function getPermissions($uid)
{
}
function isEntitled($berechtigung_kurzbz, $oe_kurzbz=null, $art=null, $kostenstelle_id=null)
{
}
function getPermissions($uid) {}
function isEntitled($berechtigung_kurzbz, $oe_kurzbz=null, $art=null, $kostenstelle_id=null) {}
}
+2 -2
View File
@@ -419,10 +419,10 @@ $error_msg='';
tbl_studiengang.studiengang_kz=tbl_lehrveranstaltung.studiengang_kz AND
(studiensemester_kurzbz='$studiensemester' OR
studiensemester_kurzbz='$stsem2') AND
mitarbeiter_uid NOT LIKE '\\_%' AND tbl_studiengang.studiengang_kz!=0 AND
mitarbeiter_uid NOT LIKE '\\\\_%' AND tbl_studiengang.studiengang_kz!=0 AND
(mitarbeiter_uid,UPPER(typ::varchar(1) || tbl_studiengang.kurzbz || '_lkt')) NOT IN
(SELECT uid, UPPER(gruppe_kurzbz) FROM public.tbl_benutzergruppe
WHERE gruppe_kurzbz LIKE '%\\_LKT' AND UPPER(gruppe_kurzbz)!=UPPER('tw_lkt') AND UPPER(gruppe_kurzbz)!=UPPER('tw_fix_lkt') AND UPPER(gruppe_kurzbz)!=UPPER('tw_ext_lkt') AND UPPER(gruppe_kurzbz)!=UPPER('moodle_lkt'))";
WHERE gruppe_kurzbz LIKE '%\\\\_LKT' AND UPPER(gruppe_kurzbz)!=UPPER('tw_lkt') AND UPPER(gruppe_kurzbz)!=UPPER('tw_fix_lkt') AND UPPER(gruppe_kurzbz)!=UPPER('tw_ext_lkt') AND UPPER(gruppe_kurzbz)!=UPPER('moodle_lkt'))";
//echo $sql_query;
if(!($result=$db->db_query($sql_query)))
$error_msg.=$db->db_last_error().$sql_query;
@@ -0,0 +1,21 @@
<?php
$I = new ApiTester($scenario);
$I->wantTo("Test API call v1/system/PCRM/Call");
$I->amHttpAuthenticated("admin", "1q2w3");
$I->haveHttpHeader("FHC-API-KEY", "testapikey@fhcomplete.org");
$I->sendGET("v1/system/PCRM/Call", array(
"resource" => "codex/Bundesland_model", "function" => "load", "bundesland_code" => "1")
);
$I->seeResponseCodeIs(200);
$I->seeResponseIsJson();
$I->seeResponseContainsJson(["error" => 0]);
$I->sendGET("v1/system/PCRM/Call", array(
"resource" => "PermissionLib", "function" => "hasPermission",
"sn" => "bis.tbl_archiv", "pt" => "s")
);
$I->seeResponseCodeIs(200);
$I->seeResponseIsJson();
$I->seeResponseContainsJson(["error" => 0]);
@@ -1286,6 +1286,10 @@ else
echo '&nbsp;<button type="submit" name="speichern"><img src="../../skin/images/list-add.png" alt="Ort hinzufügen" height="13px"></button>';
echo '</td></tr>';
}
else
{
echo '<tr><td colspan="2">Keine Berechtigung zum zuteilen von Räumen</td></tr>';
}
foreach ($orte->result AS $row)
{
//echo '<tr><td>&nbsp;</td><td>';