* @version $Id$ * @access public * @license http://opensource.org/licenses/gpl-3.0.html * Content Management */ class API { private $params = array(); protected $dispatcher = null; private $allowedMethods = ['indicator' => ['list', 'info', 'info-full', 'info-values', 'values', 'last-value'], // 'project' => ['list', 'info'], 'level' => ['list'], ]; private $permissions = []; public function __construct($getMethods = false) { $this->dispatcher = $GLOBALS['dispatcher']; // if user is going to use API we check permissions if(!$getMethods) { $uri = parse_url($_SERVER['REQUEST_URI']); // we get data from URI if(!isset($uri['query'])) $this->renderDocumentation(); parse_str($uri['query'], $this->params); // we retrieve query string parameters if(isset($this->params['id']) && !is_int((int) $this->params['id'])) die('no :-('); $this->isAllowed(); } } public function getallowedMethods(): array { return $this->allowedMethods; } public function __call($method, $arguments) { $event = $this->dispatcher->notifyUntil(new sfEvent($this, 'api.extensible_function', array( 'method' => $method, 'arguments' => $arguments ))); if (!$event->isProcessed()) { throw new Exception(sprintf('Call to undefined method %s::%s.', get_class($this), $method)); } return $event->getReturnValue(); } /** * Remove '-' in action * @param $actions * @return array */ private function formatAllowedAction($actions) { $tmp = []; foreach ($actions as $action) { array_push($tmp, str_replace('-', '', $action)); } return $tmp; } /** * @return true|void */ private function isAllowed() { // Notify the beginning of the current method $this->dispatcher->notify(new sfEvent($this, 'api.is_allowed', $this->params)); // if API_PROVIDE is disabled we return an error if(!defined('API_PROVIDE') || API_PROVIDE === 0) $this->error_output(_t('api', 'is_disabled')); // if URL syntax is incorrect, we return an error if(!isset($this->params['m']) || !isset($this->params['a']) || !in_array(($this->params['m']), array_keys($this->allowedMethods))) $this->error_output(_t('api', '404_error')); // we replace '-' by nothing $this->params['a'] = str_replace('-', '', $this->params['a']); // if action is not allowed, we return an error if(!in_array($this->params['a'], $this->formatAllowedAction($this->allowedMethods[$this->params['m']]))) { $this->error_output(sprintf(_t('api', 'method_not_defined'), $this->params['a'])); } // check if free access is granted for all if(defined('API_PROVIDE') && API_PROVIDE === "full-access") return true; // free access is granted for all // finally we check permissions from config file if needed if(defined('API_PROVIDE') && API_PROVIDE === "limited-access") { $filepaths = glob(THEME_PUBLIC_PATH.'override/api/api-permissions*.json'); if($filepaths === false) { $this->error_output(_t('api', 'not_allowed')); logfile(LOG_MAINFILE, array('[api] ERROR', 'configuration file is missing in '. THEME_PUBLIC_PATH.'override/api/ folder', 'API_PROVIDE='. API_PROVIDE)); } if(basename($filepaths[0]) == 'api-permissions.json') logfile(LOG_MAINFILE, array('[api] SECURITY WARNING', 'naming api-permissions.json without random chars is very unsafe ! Expected syntax : api-permissions-[A-Aa-z0-9].json', 'API_PROVIDE='. API_PROVIDE)); // we finally get settings from file $json = file_get_contents($filepaths[0]); $this->permissions = json_decode($json, true); // we open the configuration file // unable to find token if(!isset($this->permissions[$this->params['token']])) { $this->error_output(_t('api', 'not_allowed')); } else { // do the user has permissions on following module / action ? $userPermissions = $this->formatAllowedAction( $this->permissions[$this->params['token']]['permissions'][$this->params['m']]); if(!in_array($this->params['a'], $userPermissions) && !in_array('all', $userPermissions)) $this->error_output(_t('api', 'not_allowed')); else return true; } } } /** * @param $msg * @param $errorcode * @return void */ private function renderDocumentation() { $doc = ''; $header = '
'.$module.' description
'. PHP_EOL; foreach($v as $a) { $link = SITE_ROOT_URL.'api/index.php?m='.$module.'&a='.$a; if($a != 'list') $link .= '&id=1'; if(API_PROVIDE == 'limited-access') $link .= '&token=linea21-token'. PHP_EOL; $doc .= ''.$module . ' / ' . $a.' description
'. PHP_EOL; $doc .= ''. PHP_EOL; $doc .= '