示例#1
0
    public function run( $credentials )
    {
        $status = self::STATUS_TOKEN_INVALID; // Assume invalid token as a default, safer
        if ( !isset( $credentials->id ) )
        {
            return self::STATUS_TOKEN_UNAVAILABLE;
        }
        else
        {
            // Fetch and validate token for validity and optionally scope.
            // Either let the request pass, or immediately bail with 401.
            // Section 5.2.1 for error handling.
            //
            // invalid_request missing required params -> 400
            //
            // invalid_token Expired token which cannot be refreshed -> 401
            //
            // expired_token Token has expired -> 401
            //
            // insufficient_scope The requested scope is outside scope associated with token -> 403
            //
            // Do not include error info for requests which did not contain auth details.ref. 5.2.1

            // Checking for existance of token
            // Query made below will check if user's access grant is still valid
            $tokenInfo = ezpRestToken::fetch( $credentials->id );
            if ( !$tokenInfo instanceof ezpRestToken )
            {
                return self::STATUS_TOKEN_INVALID;
                //throw new ezpOauthInvalidTokenException( "Specified token does not exist." );
            }

            // Check expiry of token
            if ( $tokenInfo->expirytime > 0 )
            {
                if ( $tokenInfo->expirytime < time() )
                {
                    $d = date( "c", $tokenInfo->expirytime );
                    return self::STATUS_TOKEN_EXPIRED;
                    //throw new ezpOauthExpiredTokenException( "Token expired on {$d}" );
                }
            }

            self::$tokenInfo = $tokenInfo;

            // Scope checking to be implemented.
            // Currently some hooks ought to be added to eZP to maximise the
            // benefit to this field.

            $status = self::STATUS_OK;
        }

        return $status;
    }
 /**
  * Generates a new token against an authorization_code
  * Auth code is checked against clientId, clientSecret and redirectUri as registered for client in admin
  * Auth code is for one-use only and will be removed once the access token generated
  * @param string $clientId Client identifier
  * @param string $clientSecret Client secret key
  * @param string $authCode Authorization code provided by the client
  * @param string $redirectUri Redirect URI. Must be the same as registered in admin
  * @return ezpRestToken
  * @throws ezpOauthInvalidRequestException
  * @throws ezpOauthInvalidTokenException
  * @throws ezpOauthExpiredTokenException
  */
 public static function doRefreshTokenWithAuthorizationCode($clientId, $clientSecret, $authCode, $redirectUri)
 {
     $client = ezpRestClient::fetchByClientId($clientId);
     $tokenTTL = (int) eZINI::instance('rest.ini')->variable('OAuthSettings', 'TokenTTL');
     if (!$client instanceof ezpRestClient) {
         throw new ezpOauthInvalidRequestException(ezpOauthTokenEndpointErrorType::INVALID_CLIENT);
     }
     if (!$client->validateSecret($clientSecret)) {
         throw new ezpOauthInvalidRequestException(ezpOauthTokenEndpointErrorType::INVALID_CLIENT);
     }
     if (!$client->isEndPointValid($redirectUri)) {
         throw new ezpOauthInvalidRequestException(ezpOauthTokenEndpointErrorType::INVALID_REQUEST);
     }
     $session = ezcPersistentSessionInstance::get();
     $q = $session->createFindQuery('ezpRestAuthcode');
     $q->where($q->expr->eq('id', $q->bindValue($authCode)));
     $codeInfo = $session->find($q, 'ezpRestAuthcode');
     if (empty($codeInfo)) {
         throw new ezpOauthInvalidTokenException("Specified authorization code does not exist.");
     }
     $codeInfo = array_shift($codeInfo);
     // Validate client is still authorized, then validate code is not expired
     $authorized = ezpRestAuthorizedClient::fetchForClientUser($client, eZUser::fetch($codeInfo->user_id));
     if (!$authorized instanceof ezpRestAuthorizedClient) {
         throw new ezpOauthInvalidRequestException(ezpOauthTokenEndpointErrorType::INVALID_CLIENT);
     }
     // Check expiry of authorization_code
     if ($codeInfo->expirytime != 0) {
         if ($codeInfo->expirytime < time()) {
             $d = date("c", $codeInfo->expirytime);
             throw new ezpOauthExpiredTokenException("Authorization code expired on {$d}");
         }
     }
     // code ok, create access and refresh tokens
     $accessToken = ezpRestToken::generateToken('');
     $refreshToken = ezpRestToken::generateToken('');
     $token = new ezpRestToken();
     $token->id = $accessToken;
     $token->refresh_token = $refreshToken;
     $token->client_id = $clientId;
     $token->user_id = $codeInfo->user_id;
     $token->expirytime = time() + $tokenTTL;
     $session = ezcPersistentSessionInstance::get();
     $session->save($token);
     // After an auth code is used, we'll remove it so it is not abused
     $session->delete($codeInfo);
     return $token;
 }
    // Redirect to the redirect_uri with these parameters:
    // - code, only if request_type == code OR code_and_token @todo Implement
    // - access_token, only if request_type == token OR code_and_token
    // - expires_in, the token lifetime in seconds
    // - scope, the permission scope the provided code / token grants, if different from the requested one (not implemented yet)
    // - state, not implemented yet (state persistency related)
    $parameters = array();
    $rExpiresIn = $tokenTTL;
    $parameters[] = 'access_token=' . urlencode($rAccessToken);
    $parameters[] = 'refresh_token=' . urlencode($rRefreshToken);
    $parameters[] = "expires_in={$rExpiresIn}";
    $location = "{$pRedirectUri}?" . implode($parameters, '&');
    response('302 Found', $location);
} elseif ($pResponseType == 'code') {
    // At this point, the we know the user HAS granted access, and can hand over a token
    $rCode = ezpRestToken::generateToken($pScope);
    $code = new ezpRestAuthcode();
    $code->id = $rCode;
    $code->client_id = $pClientId;
    $code->user_id = $user->attribute('contentobject_id');
    $code->expirytime = time() + $tokenTTL;
    $session = ezcPersistentSessionInstance::get();
    $session->save($code);
    // The user has a agreed to authorize this app.
    // Redirect to the redirect_uri with these parameters:
    // - code, only if request_type == code OR code_and_token @todo Implement
    // - access_token, only if request_type == token OR code_and_token
    // - expires_in, the token lifetime in seconds
    // - scope, the permission scope the provided code / token grants, if different from the requested one (not implemented yet)
    // - state, not implemented yet (state persistency related)
    $parameters = array();
示例#4
0
 /**
  * Handles the POST request which is sent to obtain token data.
  *
  * Currently only authorization code access grant is supported, section 4.1.1
  *
  * @return ezcMvcResult
  */
 public function doHandleRequest()
 {
     // Check that the correct params are present
     // Params for token endpoint per section 4
     // REQUIRED: grant_type, client_id, client_secret
     // OPTIONAL: scope
     //
     // Supported grant types are: authorization_code and refresh_token
     //
     // Additional params for 'authorization_code', Section 4.1.1
     // REQUIRED: code, redirect_uri
     //
     // Additional param for 'refresh_token", Section 4.1.4
     // REQUIRED: refresh_token
     // Defining the required params for each stage of operation
     $initialRequiredParams = array('grant_type', 'client_id', 'client_secret');
     // params for grant_type=authorization_code
     $codeRequiredParams = array('code', 'redirect_uri');
     // params for grant_type=refresh_token
     $refreshRequiredParams = array('refresh_token');
     $this->checkParams($initialRequiredParams);
     // We can get the first set of required params
     $grant_type = $this->request->post['grant_type'];
     $client_id = $this->request->post['client_id'];
     $client_secret = $this->request->post['client_secret'];
     if (!$this->validateGrantType($grant_type)) {
         throw new ezpOauthInvalidRequestException(ezpOauthTokenEndpointErrorType::UNSUPPORTED_GRANT_TYPE);
     }
     switch ($grant_type) {
         case 'authorization_code':
             $this->checkParams($codeRequiredParams);
             $authCode = $this->request->post['code'];
             $redirect_uri = $this->request->post['redirect_uri'];
             $client = ezpRestClient::fetchByClientId($client_id);
             if (!$client instanceof ezpRestClient) {
                 throw new ezpOauthInvalidRequestException(ezpOauthTokenEndpointErrorType::INVALID_CLIENT);
             }
             if (!$client->validateSecret($client_secret)) {
                 throw new ezpOauthInvalidRequestException(ezpOauthTokenEndpointErrorType::INVALID_CLIENT);
             }
             if (!$client->isEndPointValid($redirect_uri)) {
                 throw new ezpOauthInvalidRequestException(ezpOauthTokenEndpointErrorType::INVALID_REQUEST);
             }
             $session = ezcPersistentSessionInstance::get();
             $q = $session->createFindQuery('ezpRestAuthcode');
             $q->where($q->expr->eq('id', $q->bindValue($authCode)));
             $codeInfo = $session->find($q, 'ezpRestAuthcode');
             if (empty($codeInfo)) {
                 // return self::STATUS_TOKEN_INVALID;
                 throw new ezpOauthInvalidTokenException("Specified authorization code does not exist.");
             }
             $codeInfo = array_shift($codeInfo);
             // Validate client is still authorized, then validate code is not expired
             $authorized = ezpRestAuthorizedClient::fetchForClientUser($client, eZUser::fetch($codeInfo->user_id));
             if (!$authorized instanceof ezpRestAuthorizedClient) {
                 throw new ezpOauthInvalidRequestException(ezpOauthTokenEndpointErrorType::INVALID_CLIENT);
             }
             // Check expiry of token
             if ($codeInfo->expirytime !== 0) {
                 if ($codeInfo->expirytime < time()) {
                     $d = date("c", $codeInfo->expirytime);
                     // return self::STATUS_TOKEN_EXPIRED;
                     throw new ezpOauthExpiredTokenException("Token expired on {$d}");
                 }
             }
             // code eok, create access token
             $accessToken = ezpRestToken::generateToken('');
             $refreshToken = ezpRestToken::generateToken('');
             $token = new ezpRestToken();
             $token->id = $accessToken;
             $token->refresh_token = $refreshToken;
             $token->client_id = $client_id;
             $token->user_id = $codeInfo->user_id;
             $token->expirytime = time() + 3600;
             $session = ezcPersistentSessionInstance::get();
             $session->save($token);
             //@TODO for later, check for transmission over https
             $r = new ezcMvcResult();
             $r->status = new ezcMvcExternalRedirect($redirect_uri . '?access_token=' . $token->id);
             return $r;
             break;
         case 'refresh_token':
             $this->checkParams($refreshRequiredParams);
             $refreshToken = $this->request->post['refresh_token'];
             break;
     }
 }