public function testBrokenFromArray()
 {
     try {
         $c = ClientRegistration::fromArray(array("foo" => "bar"));
         $this->assertTrue(FALSE);
     } catch (ClientRegistrationException $e) {
         $this->assertEquals("not a valid client, 'id' not set", $e->getMessage());
     }
 }
Пример #2
0
 public function handleRequest(HttpRequest $request)
 {
     $response = new HttpResponse(200, "application/json");
     try {
         if (!$this->_config->getSectionValue("Api", "enableApi")) {
             throw new ApiException("forbidden", "api disabled");
         }
         $this->_rs->verifyAuthorizationHeader($request->getHeader("Authorization"));
         $storage = $this->_storage;
         // FIXME: can this be avoided??
         $rs = $this->_rs;
         // FIXME: can this be avoided??
         $request->matchRest("POST", "/authorizations/", function () use($request, $response, $storage, $rs) {
             $rs->requireScope("authorizations");
             $data = Json::dec($request->getContent());
             if (NULL === $data || !is_array($data) || !array_key_exists("client_id", $data) || !array_key_exists("scope", $data)) {
                 throw new ApiException("invalid_request", "missing required parameters");
             }
             // client needs to exist
             $clientId = $data['client_id'];
             $client = $storage->getClient($clientId);
             if (FALSE === $client) {
                 throw new ApiException("invalid_request", "client is not registered");
             }
             // scope should be part of "allowed_scope" of client registration
             $clientAllowedScope = new Scope($client['allowed_scope']);
             $requestedScope = new Scope($data['scope']);
             if (!$requestedScope->isSubSetOf($clientAllowedScope)) {
                 throw new ApiException("invalid_request", "invalid scope for this client");
             }
             $refreshToken = array_key_exists("refresh_token", $data) && $data['refresh_token'] ? Utils::randomHex(16) : NULL;
             // check to see if an authorization for this client/resource_owner already exists
             if (FALSE === $storage->getApprovalByResourceOwnerId($clientId, $rs->getResourceOwnerId())) {
                 if (FALSE === $storage->addApproval($clientId, $rs->getResourceOwnerId(), $data['scope'], $refreshToken)) {
                     throw new ApiException("invalid_request", "unable to add authorization");
                 }
             } else {
                 throw new ApiException("invalid_request", "authorization already exists for this client and resource owner");
             }
             $response->setStatusCode(201);
             $response->setContent(Json::enc(array("ok" => true)));
         });
         $request->matchRest("GET", "/authorizations/:id", function ($id) use($request, $response, $storage, $rs) {
             $rs->requireScope("authorizations");
             $data = $storage->getApprovalByResourceOwnerId($id, $rs->getResourceOwnerId());
             if (FALSE === $data) {
                 throw new ApiException("not_found", "the resource you are trying to retrieve does not exist");
             }
             $response->setContent(Json::enc($data));
         });
         $request->matchRest("GET", "/authorizations/:id", function ($id) use($request, $response, $storage, $rs) {
             $rs->requireScope("authorizations");
             $data = $storage->getApprovalByResourceOwnerId($id, $rs->getResourceOwnerId());
             if (FALSE === $data) {
                 throw new ApiException("not_found", "the resource you are trying to retrieve does not exist");
             }
             $response->setContent(Json::enc($data));
         });
         $request->matchRest("DELETE", "/authorizations/:id", function ($id) use($request, $response, $storage, $rs) {
             $rs->requireScope("authorizations");
             if (FALSE === $storage->deleteApproval($id, $rs->getResourceOwnerId())) {
                 throw new ApiException("not_found", "the resource you are trying to delete does not exist");
             }
             $response->setContent(Json::enc(array("ok" => true)));
         });
         $request->matchRest("GET", "/authorizations/", function () use($request, $response, $storage, $rs) {
             $rs->requireScope("authorizations");
             $data = $storage->getApprovals($rs->getResourceOwnerId());
             $response->setContent(Json::enc($data));
         });
         $request->matchRest("GET", "/applications/", function () use($request, $response, $storage, $rs) {
             $rs->requireScope("applications");
             // $rs->requireEntitlement("urn:x-oauth:entitlement:applications");    // do not require entitlement to list clients...
             $data = $storage->getClients();
             $response->setContent(Json::enc($data));
         });
         $request->matchRest("DELETE", "/applications/:id", function ($id) use($request, $response, $storage, $rs) {
             $rs->requireScope("applications");
             $rs->requireEntitlement("urn:x-oauth:entitlement:applications");
             if (FALSE === $storage->deleteClient($id)) {
                 throw new ApiException("not_found", "the resource you are trying to delete does not exist");
             }
             $response->setContent(Json::enc(array("ok" => true)));
         });
         $request->matchRest("GET", "/applications/:id", function ($id) use($request, $response, $storage, $rs) {
             $rs->requireScope("applications");
             $rs->requireEntitlement("urn:x-oauth:entitlement:applications");
             // FIXME: for now require entitlement as long as password hashing is not
             // implemented...
             $data = $storage->getClient($id);
             if (FALSE === $data) {
                 throw new ApiException("not_found", "the resource you are trying to retrieve does not exist");
             }
             $response->setContent(Json::enc($data));
         });
         $request->matchRest("POST", "/applications/", function () use($request, $response, $storage, $rs) {
             $rs->requireScope("applications");
             $rs->requireEntitlement("urn:x-oauth:entitlement:applications");
             try {
                 $client = ClientRegistration::fromArray(Json::dec($request->getContent()));
                 $data = $client->getClientAsArray();
                 // check to see if an application with this id already exists
                 if (FALSE === $storage->getClient($data['id'])) {
                     if (FALSE === $storage->addClient($data)) {
                         throw new ApiException("invalid_request", "unable to add application");
                     }
                 } else {
                     throw new ApiException("invalid_request", "application already exists");
                 }
                 $response->setStatusCode(201);
                 $response->setContent(Json::enc(array("ok" => true)));
             } catch (ClientRegistrationException $e) {
                 throw new ApiException("invalid_request", $e->getMessage());
             }
         });
         $request->matchRest("GET", "/stats/", function () use($request, $response, $storage, $rs) {
             $rs->requireScope("applications");
             $rs->requireEntitlement("urn:x-oauth:entitlement:applications");
             $data = $storage->getStats();
             $response->setContent(Json::enc($data));
         });
         $request->matchRest("PUT", "/applications/:id", function ($id) use($request, $response, $storage, $rs) {
             $rs->requireScope("applications");
             $rs->requireEntitlement("urn:x-oauth:entitlement:applications");
             try {
                 $client = ClientRegistration::fromArray(Json::dec($request->getContent()));
                 $data = $client->getClientAsArray();
                 if ($data['id'] !== $id) {
                     throw new ApiException("invalid_request", "resource does not match client id value");
                 }
                 if (FALSE === $storage->updateClient($id, $data)) {
                     throw new ApiException("invalid_request", "unable to update application");
                 }
             } catch (ClientRegistrationException $e) {
                 throw new ApiException("invalid_request", $e->getMessage());
             }
             $response->setContent(Json::enc(array("ok" => true)));
         });
         $request->matchRestDefault(function ($methodMatch, $patternMatch) use($request, $response) {
             if (in_array($request->getRequestMethod(), $methodMatch)) {
                 if (!$patternMatch) {
                     throw new ApiException("not_found", "resource not found");
                 }
             } else {
                 $response->setStatusCode(405);
                 $response->setHeader("Allow", implode(",", $methodMatch));
             }
         });
     } catch (ResourceServerException $e) {
         $response->setStatusCode($e->getResponseCode());
         if ("no_token" === $e->getMessage()) {
             // no authorization header is a special case, the client did not know
             // authentication was required, so tell it now without giving error message
             $hdr = 'Bearer realm="Resource Server"';
         } else {
             $hdr = sprintf('Bearer realm="Resource Server",error="%s",error_description="%s"', $e->getMessage(), $e->getDescription());
         }
         $response->setHeader("WWW-Authenticate", $hdr);
         $response->setContent(Json::enc(array("error" => $e->getMessage(), "error_description" => $e->getDescription())));
         if (NULL !== $this->_logger) {
             $this->_logger->logFatal($e->getLogMessage(TRUE) . PHP_EOL . $request . PHP_EOL . $response);
         }
     } catch (ApiException $e) {
         $response->setStatusCode($e->getResponseCode());
         $response->setContent(Json::enc(array("error" => $e->getMessage(), "error_description" => $e->getDescription())));
         if (NULL !== $this->_logger) {
             $this->_logger->logFatal($e->getLogMessage(TRUE) . PHP_EOL . $request . PHP_EOL . $response);
         }
     }
     return $response;
 }
<?php

require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . "vendor" . DIRECTORY_SEPARATOR . "autoload.php";
use RestService\Utils\Config;
use OAuth\PdoOAuthStorage;
use OAuth\ClientRegistration;
use RestService\Utils\Json;
$config = new Config(dirname(__DIR__) . DIRECTORY_SEPARATOR . "config" . DIRECTORY_SEPARATOR . "oauth.ini");
$storage = new PdoOAuthStorage($config);
$storage->initDatabase();
if ($argc !== 2) {
    echo "ERROR: specify manifest file or URL to parse" . PHP_EOL;
    die;
}
$manifestFile = $argv[1];
$fileContents = file_get_contents($manifestFile);
$data = Json::dec($fileContents);
if (NULL === $data || !is_array($data)) {
    echo "ERROR: manifest seems to be in wrong format" . PHP_EOL;
    die;
}
foreach ($data as $d) {
    // go over all app entries
    if (FALSE === $storage->getClient($d['key'])) {
        echo "Adding '" . $d['name'] . "'..." . PHP_EOL;
        $x = array("id" => $d['key'], "name" => $d['name'], "description" => $d['description'], "secret" => NULL, "type" => "user_agent_based_application", "icon" => $d['icons']['128'], "allowed_scope" => implode(" ", $d['permissions']), "redirect_uri" => $d['app']['launch']['web_url']);
        $y = ClientRegistration::fromArray($x);
        $storage->addClient($y->getClientAsArray());
    }
}
 private function _handleAuthorize(IResourceOwner $resourceOwner, array $get)
 {
     try {
         $clientId = Utils::getParameter($get, 'client_id');
         $responseType = Utils::getParameter($get, 'response_type');
         $redirectUri = Utils::getParameter($get, 'redirect_uri');
         // FIXME: scope can never be empty, if the client requests no scope we should have a default scope!
         $scope = new Scope(Utils::getParameter($get, 'scope'));
         $state = Utils::getParameter($get, 'state');
         if (NULL === $clientId) {
             throw new ResourceOwnerException('client_id missing');
         }
         if (NULL === $responseType) {
             throw new ResourceOwnerException('response_type missing');
         }
         $client = $this->_storage->getClient($clientId);
         if (FALSE === $client) {
             throw new ResourceOwnerException('client not registered');
         }
         if (NULL !== $redirectUri) {
             if ($client['redirect_uri'] !== $redirectUri) {
                 throw new ResourceOwnerException('specified redirect_uri not the same as registered redirect_uri');
             }
         }
         // we need to make sure the client can only request the grant types belonging to its profile
         $allowedClientProfiles = array("web_application" => array("code"), "native_application" => array("token", "code"), "user_agent_based_application" => array("token"));
         if (!in_array($responseType, $allowedClientProfiles[$client['type']])) {
             throw new ClientException("unsupported_response_type", "response_type not supported by client profile", $client, $state);
         }
         if (!$scope->isSubsetOf(new Scope($client['allowed_scope']))) {
             throw new ClientException("invalid_scope", "not authorized to request this scope", $client, $state);
         }
         $this->_storage->updateResourceOwner($resourceOwner);
         $approvedScope = $this->_storage->getApprovalByResourceOwnerId($clientId, $resourceOwner->getId());
         if (FALSE === $approvedScope || FALSE === $scope->isSubsetOf(new Scope($approvedScope['scope']))) {
             $ar = new AuthorizeResult(AuthorizeResult::ASK_APPROVAL);
             $ar->setClient(ClientRegistration::fromArray($client));
             $ar->setScope($scope);
             return $ar;
         } else {
             if ("token" === $responseType) {
                 // implicit grant
                 // FIXME: return existing access token if it exists for this exact client, resource owner and scope?
                 $accessToken = Utils::randomHex(16);
                 $this->_storage->storeAccessToken($accessToken, time(), $clientId, $resourceOwner->getId(), $scope->getScope(), $this->_config->getValue('accessTokenExpiry'));
                 $token = array("access_token" => $accessToken, "expires_in" => $this->_config->getValue('accessTokenExpiry'), "token_type" => "bearer");
                 $s = $scope->getScope();
                 if (!empty($s)) {
                     $token += array("scope" => $s);
                 }
                 if (NULL !== $state) {
                     $token += array("state" => $state);
                 }
                 $ar = new AuthorizeResult(AuthorizeResult::REDIRECT);
                 $ar->setRedirectUri(new Uri($client['redirect_uri'] . "#" . http_build_query($token)));
                 return $ar;
             } else {
                 // authorization code grant
                 $authorizationCode = Utils::randomHex(16);
                 $this->_storage->storeAuthorizationCode($authorizationCode, $resourceOwner->getId(), time(), $clientId, $redirectUri, $scope->getScope());
                 $token = array("code" => $authorizationCode);
                 if (NULL !== $state) {
                     $token += array("state" => $state);
                 }
                 $ar = new AuthorizeResult(AuthorizeResult::REDIRECT);
                 $separator = FALSE === strpos($client['redirect_uri'], "?") ? "?" : "&";
                 $ar->setRedirectUri(new Uri($client['redirect_uri'] . $separator . http_build_query($token)));
                 return $ar;
             }
         }
     } catch (ScopeException $e) {
         throw new ClientException("invalid_scope", "malformed scope", $client, $state);
     }
 }
<?php

require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . "vendor" . DIRECTORY_SEPARATOR . "autoload.php";
use RestService\Utils\Config;
use OAuth\PdoOAuthStorage;
use OAuth\ClientRegistration;
use RestService\Utils\Json;
$config = new Config(dirname(__DIR__) . DIRECTORY_SEPARATOR . "config" . DIRECTORY_SEPARATOR . "oauth.ini");
$storage = new PdoOAuthStorage($config);
if ($argc !== 2) {
    echo "ERROR: please specify file with client registration information" . PHP_EOL;
    die;
}
$registrationFile = $argv[1];
if (!file_exists($registrationFile) || !is_file($registrationFile) || !is_readable($registrationFile)) {
    echo "ERROR: unable to read client registration file" . PHP_EOL;
    die;
}
$registration = Json::dec(file_get_contents($registrationFile));
foreach ($registration as $r) {
    // first load it in ClientRegistration object to check it...
    $cr = ClientRegistration::fromArray($r);
    if (FALSE === $storage->getClient($cr->getId())) {
        // does not exist yet, install
        echo "Adding '" . $cr->getName() . "'..." . PHP_EOL;
        $storage->addClient($cr->getClientAsArray());
    }
}