Example #1
0
 /**
  * encodes any data passed in first parameter if not already encoded to json string throwing exception if json_encode
  * is not supported by system
  *
  * @error 15102
  * @param mixed $data expects the data to encode
  * @return string
  * @throws Xapp_Rpc_Response_Exception
  */
 public function encode($data)
 {
     if (function_exists('json_encode')) {
         if ($this->encoded($data)) {
             return $data;
         } else {
             $data = json_encode($data, (int) xapp_get_option(self::ENCODE_FLAGS, $this));
             if ($data !== false) {
                 return $data;
             } else {
                 if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
                     Xapp_Rpc_Fault::t('unable to encode object to json', array(1510202, -32700), XAPP_ERROR_IGNORE, array('jsonError' => $this->error(json_last_error())));
                 } else {
                     Xapp_Rpc_Fault::t('unable to encode object to json', array(1510202, -32700));
                 }
             }
         }
     } else {
         throw new Xapp_Rpc_Response_Exception(_("php function json_decode is not supported by system"), 1510201);
     }
 }
Example #2
0
 /**
  * decodes expected json raw data throwing error if phps native json_decode function is not supported by system.
  * returns data in first parameter if is not a string and supposed post array. throws fault if json string could not
  * be decoded
  *
  * @error 15002
  * @param mixed $data expects the raw json string to decode or post data
  * @return mixed
  * @throws Xapp_Rpc_Request_Exception
  */
 public function decode($data)
 {
     if (!is_string($data)) {
         return $data;
     }
     if (function_exists('json_decode')) {
         $data = json_decode($this->prepare($data), true);
         if ($data !== null) {
             return (array) $data;
         } else {
             return '{}';
             if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
                 Xapp_Rpc_Fault::t('unable to decode json string', array(1500202, -32700), XAPP_ERROR_IGNORE, array('jsonError' => $this->error(json_last_error())));
             } else {
                 Xapp_Rpc_Fault::t('unable to decode json string', array(1500202, -32700));
             }
         }
     } else {
         throw new Xapp_Rpc_Request_Exception(_("php function json_decode is not supported by system"), 1500201);
     }
 }
Example #3
0
 /**
  * validate jsonp request testing for request parameter to be valid and checking all
  * additional parameters
  *
  * @error 14705
  * @param array $call expects the call to validate
  * @return void
  * @throws Xapp_Rpc_Fault
  */
 protected function validate($call)
 {
     $get = $this->request()->getGet();
     $service = null;
     if ($this->smd()->has($call[2], $call[1])) {
         if ($call[2] !== null) {
             $service = $this->smd()->get($call[2] . '.' . $call[1]);
         } else {
             $service = $this->smd()->get($call[1]);
         }
     } else {
         Xapp_Rpc_Fault::t("method or function is not registered as service", array(1470501, -32601));
     }
     if (!empty($service->parameters)) {
         foreach ($service->parameters as $k => $v) {
             if (!$v->optional && (!array_key_exists($v->name, $get) || !xapp_is_value($get[$v->name]))) {
                 Xapp_Rpc_Fault::t(xapp_sprintf("param: %s must be set", array($v->name)), array(1470503, -32602));
             }
             if (isset($v->type) && array_key_exists($v->name, $get) && !in_array('mixed', (array) $v->type) && !in_array(xapp_type($get[$v->name], true), (array) $v->type)) {
                 Xapp_Rpc_Fault::t(xapp_sprintf("param: %s must be of the following types: %s", array($v->name, implode('|', (array) $v->type))), array(1470504, -32602));
             }
         }
     }
     if (xapp_is_option(self::ADDITIONAL_PARAMETERS, $this)) {
         foreach (xapp_get_option(self::ADDITIONAL_PARAMETERS, $this) as $k => $v) {
             $type = isset($v[0]) ? (array) $v[0] : false;
             $optional = isset($v[1]) ? (bool) $v[1] : true;
             if (!$optional && !array_key_exists($k, $get)) {
                 Xapp_Rpc_Fault::t(xapp_sprintf("additional param: %s must be set", array($k)), array(1470505, -32602));
             }
             if ($type && !in_array('mixed', $type) && !in_array(xapp_type($get[$k], true), $type)) {
                 Xapp_Rpc_Fault::t(xapp_sprintf("additional param: %s must be of the following types: %s", array($k, implode('|', $type))), array(1470506, -32602));
             }
         }
     }
 }
Example #4
0
 /**
  * validates all options that have been defined throwing rpc gateway faults if any of the
  * options fail to validate. see constant descriptions for what each constant does
  *
  * @error 14015
  * @param string $option expects the option name
  * @param null|mixed $value expects the options value
  * @throws Xapp_Rpc_Gateway_Exception
  * @throws Xapp_Rpc_Fault
  */
 protected function validate($option, $value = null)
 {
     $user = null;
     $option = strtoupper($option);
     switch ($option) {
         case self::BASIC_AUTH:
             if ($this->request()->has('PHP_AUTH_USER', 'SERVER') && $this->request()->has('PHP_AUTH_PW', 'SERVER') && isset($value[0]) && isset($value[1])) {
                 if ($this->server()->request()->getFrom('PHP_AUTH_USER', 'SERVER') !== $value[0] || $this->server()->request()->getFrom('PHP_AUTH_PW', 'SERVER') !== $value[1]) {
                     Xapp_Rpc_Fault::t("basic auth error - user or password not correct", array(1401501, -32001));
                 }
             } else {
                 Xapp_Rpc_Fault::t("basic auth error - credentials not set", array(1401502, -32002));
             }
             break;
         case self::ALLOW_IP:
             if (Xapp_Rpc_Request::getClientIp() !== null && !in_array(Xapp_Rpc_Request::getClientIp(), $value)) {
                 Xapp_Rpc_Fault::t("request denied from service", array(1401503, -32003));
             }
             break;
         case self::DENY_IP:
             if (Xapp_Rpc_Request::getClientIp() !== null && in_array(Xapp_Rpc_Request::getClientIp(), $value)) {
                 Xapp_Rpc_Fault::t("request denied from service", array(1401503, -32003));
             }
             break;
         case self::DISABLE:
             if ((bool) $value) {
                 Xapp_Rpc_Fault::t("gateway is disabled", array(1401504, -32004));
             }
             break;
         case self::DISABLE_SERVICE:
             if ($this->server()->hasServices()) {
                 foreach ($this->server()->getServices() as $service) {
                     if (preg_match(Xapp_Rpc::regex($value), $service)) {
                         Xapp_Rpc_Fault::t("requested service: {$service} is disabled", array(1401505, -32005));
                     }
                 }
             }
             break;
         case self::ALLOW_HOST:
             if (Xapp_Rpc_Request::getHost() !== null && !in_array(Xapp_Rpc_Request::getHost(), $value)) {
                 Xapp_Rpc_Fault::t("host denied from service", array(1401506, -32006));
             }
             break;
         case self::DENY_HOST:
             if (Xapp_Rpc_Request::getHost() !== null && in_array(Xapp_Rpc_Request::getHost(), $value)) {
                 Xapp_Rpc_Fault::t("host denied from service", array(1401506, -32006));
             }
             break;
         case self::FORCE_HTTPS:
             if ((bool) $value && Xapp_Rpc_Request::getScheme() !== 'HTTPS') {
                 Xapp_Rpc_Fault::t("request from none http secure host denied", array(1401507, -32007));
             }
             break;
         case self::ALLOW_USER_AGENT:
             if ($this->request()->has('HTTP_USER_AGENT', 'SERVER') && !preg_match('/(' . implode('|', trim($value, '()')) . ')/i', $this->request()->getFrom('HTTP_USER_AGENT', 'SERVER'))) {
                 Xapp_Rpc_Fault::t("client denied from service", array(1401508, -32008));
             }
             break;
         case self::DENY_USER_AGENT:
             if ($this->request()->has('HTTP_USER_AGENT', 'SERVER') && preg_match('/(' . implode('|', trim($value, '()')) . ')/i', $this->request()->getFrom('HTTP_USER_AGENT', 'SERVER'))) {
                 Xapp_Rpc_Fault::t("client denied from service", array(1401508, -32008));
             }
             break;
         case self::ALLOW_REFERER:
             if (Xapp_Rpc_Request::getReferer() !== null && !preg_match('/(' . implode('|', trim($value, '()')) . ')/i', Xapp_Rpc_Request::getReferer())) {
                 Xapp_Rpc_Fault::t("referer denied from service", array(1401509, -32009));
             }
             break;
         case self::SIGNED_REQUEST:
             if ((bool) $value) {
                 $tmp = array();
                 if (xapp_is_option(self::SIGNED_REQUEST_EXCLUDES, $this)) {
                     foreach ($this->server()->getServices() as $service) {
                         if (!preg_match(Xapp_Rpc::regex(xapp_get_option(self::SIGNED_REQUEST_EXCLUDES, $this)), $service)) {
                             $tmp[] = $service;
                         }
                     }
                 }
                 if (sizeof($tmp) > 0) {
                     $sign = $this->request()->getParam(xapp_get_option(self::SIGNED_REQUEST_SIGN_PARAM, $this), false);
                     $method = strtolower(xapp_get_option(self::SIGNED_REQUEST_METHOD, $this));
                     switch ($method) {
                         case 'host':
                             $user = $this->request()->getHost();
                             break;
                         case 'ip':
                             $user = $this->request()->getClientIp();
                             break;
                         case 'user':
                             $user = $this->request()->getParam(xapp_get_option(self::SIGNED_REQUEST_USER_PARAM, $this), false);
                             break;
                         default:
                             throw new Xapp_Rpc_Gateway_Exception(_("unsupported signed request user identification method"), 1401514);
                     }
                     if ($user === false || $user === null) {
                         Xapp_Rpc_Fault::t(vsprintf("signed request value for: %s not found in request", array(xapp_get_option(self::SIGNED_REQUEST_USER_PARAM, $this))), array(1401512, -32011));
                     }
                     if ($sign === false || $sign === null) {
                         Xapp_Rpc_Fault::t(vsprintf("signed request value for: %s not found in request", array(xapp_get_option(self::SIGNED_REQUEST_SIGN_PARAM, $this))), array(1401513, -32011));
                     }
                     $key = $this->getKey($user, null);
                     $params = $this->request()->getParams();
                     if (array_key_exists('xdmTarget', $params)) {
                         unset($params['xdmTarget']);
                     }
                     if (array_key_exists('view', $params)) {
                         unset($params['view']);
                     }
                     if (array_key_exists('xfToken', $params)) {
                         unset($params['xfToken']);
                     }
                     if (array_key_exists('time', $params)) {
                         unset($params['time']);
                     }
                     if (array_key_exists('xdm_e', $params)) {
                         unset($params['xdm_e']);
                     }
                     if (array_key_exists('user', $params)) {
                         unset($params['user']);
                     }
                     if (array_key_exists('xdm_c', $params)) {
                         unset($params['xdm_c']);
                     }
                     if (array_key_exists('xdm_p', $params)) {
                         unset($params['xdm_p']);
                     }
                     if (xapp_is_option(self::SIGNED_REQUEST_CALLBACK, $this)) {
                         if (!(bool) call_user_func_array(xapp_get_option(self::SIGNED_REQUEST_CALLBACK, $this), array($this->request(), $params, $key))) {
                             Xapp_Rpc_Fault::t("verifying signed request failed", array(1401510, -32010));
                         }
                     } else {
                         if ($key !== null) {
                             if (isset($params[xapp_get_option(self::SIGNED_REQUEST_SIGN_PARAM, $this)])) {
                                 unset($params[xapp_get_option(self::SIGNED_REQUEST_SIGN_PARAM, $this)]);
                             }
                             if ($sign !== self::sign($params, $key)) {
                                 Xapp_Rpc_Fault::t("verifying signed request failed", array(1401510, -32010));
                             }
                         } else {
                             throw new Xapp_Rpc_Gateway_Exception(_("user identification key must be set when using internal signed request verification"), 1401511);
                         }
                     }
                 }
             }
             break;
         default:
     }
 }
Example #5
0
 /**
  * validate json request object testing all request object parameters for validity. also checking all additional
  * parameters for validity and throwing fault if necessary
  *
  * @error 14604
  * @param array $call expects the call to validate
  * @return void
  * @throws Xapp_Rpc_Fault
  */
 protected function validate($call)
 {
     if (!xapp_get_option(self::VALIDATE, $this)) {
         return;
     }
     if ($this->request()->isPost()) {
         if ($this->request()->getRaw() === "") {
             Xapp_Rpc_Fault::t("empty or invalid request object", array(1460401, -32600));
         }
         if ($this->request()->getVersion($call[3]) != xapp_get_option(self::VERSION, $this)) {
             Xapp_Rpc_Fault::t("rpc version not set or version miss match", array(1460402, -32013));
         }
         if (!xapp_get_option(self::ALLOW_NOTIFICATIONS, $this) || array_key_exists('id', $call[3])) {
             if (!array_key_exists('id', $call[3])) {
                 Xapp_Rpc_Fault::t("rpc transaction id must be set", array(1460405, -32015));
             }
             if (!is_numeric($call[3]['id']) && !is_string($call[3]['id'])) {
                 Xapp_Rpc_Fault::t("rpc transaction id must be string or integer", array(1460406, -32016));
             }
             if (xapp_is_option(self::TRANSACTION_ID_REGEX, $this) && !preg_match(trim((string) xapp_get_option(self::TRANSACTION_ID_REGEX, $this)), $call[3]['id'])) {
                 Xapp_Rpc_Fault::t("rpc transaction id does not match transaction id regex pattern", array(1460411, -32017));
             }
         }
         if (!xapp_get_option(self::ALLOW_FUNCTIONS, $this) && empty($call[2])) {
             Xapp_Rpc_Fault::t("php functions as service are not supported by this rpc service", 1460412, -32018);
         }
         if (!array_key_exists('method', $call[3])) {
             Xapp_Rpc_Fault::t("rpc method must be set", array(1460403, -32014));
         }
         if (!$this->smd()->has($call[2], $call[1])) {
             Xapp_Rpc_Fault::t("method or function is not registered as service", array(1460404, -32601));
         }
         if (!is_null($call[2])) {
             $service = $this->smd()->get($call[2] . '.' . $call[1]);
         } else {
             $service = $this->smd()->get($call[1]);
         }
         if (!empty($service->parameters)) {
             $params = array_key_exists('params', $call[3]) ? $call[3]['params'] : null;
             $p = (array) $params;
             $k = is_null($params) || array_values($p) !== $p ? 'n' : 'i';
             $i = 0;
             foreach ($service->parameters as $v) {
                 $n = $v->name;
                 if (!$v->optional && (!array_key_exists(${$k}, $p) || !xapp_is_value($p[${$k}]))) {
                     Xapp_Rpc_Fault::t(xapp_sprintf("param: %s must be set", array(${$k})), array(1460407, -32602));
                 }
                 if (isset($v->type) && array_key_exists(${$k}, $p) && !in_array('mixed', (array) $v->type) && !in_array(xapp_type($p[${$k}]), (array) $v->type)) {
                     Xapp_Rpc_Fault::t(xapp_sprintf("param: %s must be of the following types: %s", array(${$k}, implode('|', (array) $v->type))), array(1460408, -32602));
                 }
                 $i++;
             }
         }
         if (xapp_is_option(self::ADDITIONAL_PARAMETERS, $this)) {
             foreach (xapp_get_option(self::ADDITIONAL_PARAMETERS, $this) as $k => $v) {
                 $type = isset($v[0]) ? (array) $v[0] : false;
                 $optional = isset($v[1]) ? (bool) $v[1] : true;
                 if (!$optional && !$this->request()->hasParam($k)) {
                     Xapp_Rpc_Fault::t(xapp_sprintf("additional param: %s must be set", array($k)), array(1460409, -32602));
                 }
                 if ($type && !in_array('mixed', $type) && !in_array(xapp_type($this->request()->getParam($k)), $type)) {
                     Xapp_Rpc_Fault::t(xapp_sprintf("additional param: %s must be of the following types: %s", array($k, implode('|', $type))), array(1460410, -32602));
                 }
             }
         }
     }
 }
Example #6
0
 /**
  * handles the request, executes service and flushes result to output stream.
  * nothing will happen unless this function is called! if the server was called
  * with GET and not GET parameters are set will flush smd directly
  *
  * @error 14213
  * @return void
  * @throws Xapp_Rpc_Fault
  */
 public final function handle()
 {
     xapp_debug('rpc server handler started', 'rpc');
     xapp_event('xapp.rpc.server.handle', array(&$this));
     if ($this->request()->isGet() && $this->request()->getParam('view') === 'rpc') {
         $this->response()->body($this->smd()->compile());
         $this->response()->flush();
     } else {
         if ($this->hasCalls()) {
             foreach ($this->_calls as $call) {
                 $this->execute($call);
             }
             $this->flush();
         } else {
             Xapp_Rpc_Fault::t("request is empty or does not contain any rpc action", array(1421301, -32600), XAPP_ERROR_IGNORE);
         }
     }
     xapp_debug('rpc server handler stopped', 'rpc');
 }