예제 #1
0
 /**
  * Execute the method and return the result.
  *
  * OKAPI methods return OkapiHttpResponses, but some MAY also return
  * PHP objects (see OkapiRequest::construct_inside_request for details).
  *
  * If $request must be consistent with given method's options (must
  * include Consumer and Token, if they are required).
  */
 public static function call($service_name, OkapiRequest $request)
 {
     Okapi::init_internals();
     if (!self::exists($service_name)) {
         throw new Exception("Method does not exist: '{$service_name}'");
     }
     $options = self::options($service_name);
     if ($options['min_auth_level'] >= 2 && $request->consumer == null) {
         throw new Exception("Method '{$service_name}' called with mismatched OkapiRequest: " . "\$request->consumer MAY NOT be empty for Level 2 and Level 3 methods. Provide " . "a dummy Consumer if you have to.");
     }
     if ($options['min_auth_level'] >= 3 && $request->token == null) {
         throw new Exception("Method '{$service_name}' called with mismatched OkapiRequest: " . "\$request->token MAY NOT be empty for Level 3 methods.");
     }
     $time_started = microtime(true);
     Okapi::gettext_domain_init();
     try {
         require_once $GLOBALS['rootpath'] . "okapi/{$service_name}.php";
         $response = call_user_func(array('\\okapi\\' . str_replace('/', '\\', $service_name) . '\\WebService', 'call'), $request);
         Okapi::gettext_domain_restore();
     } catch (Exception $e) {
         Okapi::gettext_domain_restore();
         throw $e;
     }
     $runtime = microtime(true) - $time_started;
     # Log the request to the stats table. Only valid requests (these which didn't end up
     # with an exception) are logged.
     self::save_stats($service_name, $request, $runtime);
     return $response;
 }
예제 #2
0
 public static function dispatch_request($uri)
 {
     # Chop off the ?args=... part.
     if (strpos($uri, '?') !== false) {
         $uri = substr($uri, 0, strpos($uri, '?'));
     }
     # Chop off everything before "/okapi/". This should work for okay for most "weird"
     # server configurations. It will also address a more subtle issue described here:
     # http://stackoverflow.com/questions/8040461/request-uri-unexpectedly-contains-fqdn
     if (strpos($uri, "/okapi/") !== false) {
         $uri = substr($uri, strpos($uri, "/okapi/"));
     }
     # Make sure we're in the right directory (.htaccess should make sure of that).
     if (strpos($uri, "/okapi/") !== 0) {
         throw new Exception("'{$uri}' is outside of the /okapi/ path.");
     }
     $uri = substr($uri, 7);
     # Initializing internals and running pre-request cronjobs (we don't want
     # cronjobs to be run before "okapi/update", for example before database
     # was installed).
     $allow_cronjobs = $uri != "update";
     Okapi::init_internals($allow_cronjobs);
     # Checking for allowed patterns...
     try {
         foreach (OkapiUrls::$mapping as $pattern => $namespace) {
             $matches = null;
             if (preg_match("#{$pattern}#", $uri, $matches)) {
                 # Pattern matched! Moving on to the proper View...
                 array_shift($matches);
                 require_once $GLOBALS['rootpath'] . "okapi/views/{$namespace}.php";
                 $response = call_user_func_array(array('\\okapi\\views\\' . str_replace('/', '\\', $namespace) . '\\View', 'call'), $matches);
                 if ($response) {
                     $response->display();
                 }
                 return;
             }
         }
     } catch (Http404 $e) {
         /* pass */
     }
     # None of the patterns matched OR method threw the Http404 exception.
     require_once $GLOBALS['rootpath'] . "okapi/views/http404.php";
     $response = \okapi\views\http404\View::call();
     $response->display();
 }
예제 #3
0
파일: core.php 프로젝트: Slini11/okapi
 public function __construct($options)
 {
     Okapi::init_internals();
     $this->init_request();
     #
     # Parsing options.
     #
     $DEBUG_AS_USERNAME = null;
     foreach ($options as $key => $value) {
         switch ($key) {
             case 'min_auth_level':
                 if (!in_array($value, array(0, 1, 2, 3))) {
                     throw new Exception("'min_auth_level' option has invalid value: {$value}");
                 }
                 $this->opt_min_auth_level = $value;
                 break;
             case 'token_type':
                 if (!in_array($value, array("request", "access"))) {
                     throw new Exception("'token_type' option has invalid value: {$value}");
                 }
                 $this->opt_token_type = $value;
                 break;
             case 'DEBUG_AS_USERNAME':
                 $DEBUG_AS_USERNAME = $value;
                 break;
             default:
                 throw new Exception("Unknown option: {$key}");
                 break;
         }
     }
     if ($this->opt_min_auth_level === null) {
         throw new Exception("Required 'min_auth_level' option is missing.");
     }
     if ($DEBUG_AS_USERNAME != null) {
         # Enables debugging Level 2 and Level 3 methods. Should not be committed
         # at any time! If run on production server, make it an error.
         if (!Settings::get('DEBUG')) {
             throw new Exception("Attempted to use DEBUG_AS_USERNAME in " . "non-debug environment. Accidental commit?");
         }
         # Lower required authentication to Level 0, to pass the checks.
         $this->opt_min_auth_level = 0;
     }
     #
     # Let's see if the request is signed. If it is, verify the signature.
     # It it's not, check if it isn't against the rules defined in the $options.
     #
     if ($this->get_parameter('oauth_signature')) {
         # User is using OAuth.
         # Check for duplicate keys in the parameters. (Datastore doesn't
         # do that on its own, it caused vague server errors - issue #307.)
         $this->get_parameter('oauth_consumer');
         $this->get_parameter('oauth_version');
         $this->get_parameter('oauth_token');
         $this->get_parameter('oauth_nonce');
         # Verify OAuth request.
         list($this->consumer, $this->token) = Okapi::$server->verify_request2($this->request, $this->opt_token_type, $this->opt_min_auth_level == 3);
         if ($this->get_parameter('consumer_key') && $this->get_parameter('consumer_key') != $this->get_parameter('oauth_consumer_key')) {
             throw new BadRequest("Inproper mixing of authentication types. You used both 'consumer_key' " . "and 'oauth_consumer_key' parameters (Level 1 and Level 2), but they do not match with " . "each other. Were you trying to hack me? ;)");
         }
         if ($this->opt_min_auth_level == 3 && !$this->token) {
             throw new BadRequest("This method requires a valid Token to be included (Level 3 " . "Authentication). You didn't provide one.");
         }
     } else {
         if ($this->opt_min_auth_level >= 2) {
             throw new BadRequest("This method requires OAuth signature (Level " . $this->opt_min_auth_level . " Authentication). You didn't sign your request.");
         } else {
             $consumer_key = $this->get_parameter('consumer_key');
             if ($consumer_key) {
                 $this->consumer = Okapi::$data_store->lookup_consumer($consumer_key);
                 if (!$this->consumer) {
                     throw new InvalidParam('consumer_key', "Consumer does not exist.");
                 }
             }
             if ($this->opt_min_auth_level == 1 && !$this->consumer) {
                 throw new BadRequest("This method requires the 'consumer_key' argument (Level 1 " . "Authentication). You didn't provide one.");
             }
         }
     }
     if (is_object($this->consumer) && $this->consumer->hasFlag(OkapiConsumer::FLAG_SKIP_LIMITS)) {
         $this->skip_limits = true;
     }
     #
     # Prevent developers from accessing request parameters with PHP globals.
     # Remember, that OKAPI requests can be nested within other OKAPI requests!
     # Search the code for "new OkapiInternalRequest" to see examples.
     #
     $_GET = $_POST = $_REQUEST = null;
     # When debugging, simulate as if been run using a proper Level 3 Authentication.
     if ($DEBUG_AS_USERNAME != null) {
         # Note, that this will override any other valid authentication the
         # developer might have issued.
         $debug_user_id = Db::select_value("select user_id from user where username='******'DEBUG_AS_USERNAME']) . "'");
         if ($debug_user_id == null) {
             throw new Exception("Invalid user name in DEBUG_AS_USERNAME: '******'DEBUG_AS_USERNAME'] . "'");
         }
         $this->consumer = new OkapiDebugConsumer();
         $this->token = new OkapiDebugAccessToken($debug_user_id);
     }
     # Read the ETag.
     if (isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
         $this->etag = $_SERVER['HTTP_IF_NONE_MATCH'];
     }
 }
예제 #4
0
파일: facade.php 프로젝트: 4Vs/oc-server3
# order to get it to work with your code. Just call this after you
# include the Facade file: Facade::disable_error_handling().
# EXAMPLE OF USAGE:
# require_once($rootpath.'okapi/facade.php');
# \okapi\Facade::schedule_user_entries_check(...);
# \okapi\Facade::disable_error_handling();
use Exception;
use okapi\OkapiServiceRunner;
use okapi\OkapiInternalRequest;
use okapi\OkapiFacadeConsumer;
use okapi\OkapiFacadeAccessToken;
use okapi\Cache;
require_once $GLOBALS['rootpath'] . "okapi/core.php";
OkapiErrorHandler::$treat_notices_as_errors = true;
require_once $GLOBALS['rootpath'] . "okapi/service_runner.php";
Okapi::init_internals();
/**
 * Use this class to access OKAPI's services from external code (i.e. OC code).
 */
class Facade
{
    /**
     * Perform OKAPI service call, signed by internal 'facade' consumer key, and return the result
     * (this will be PHP object or OkapiHttpResponse, depending on the method). Use this method
     * whenever you need to access OKAPI services from within OC code. If you want to simulate
     * Level 3 Authentication, you should supply user's internal ID (the second parameter).
     */
    public static function service_call($service_name, $user_id_or_null, $parameters)
    {
        $request = new OkapiInternalRequest(new OkapiFacadeConsumer(), $user_id_or_null !== null ? new OkapiFacadeAccessToken($user_id_or_null) : null, $parameters);
        $request->perceive_as_http_request = true;