summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md4
-rw-r--r--src/OAuth2/Autoloader.php2
-rw-r--r--src/OAuth2/Controller/AccessController.php19
-rw-r--r--src/OAuth2/Controller/AccessControllerInterface.php15
-rw-r--r--src/OAuth2/Controller/AuthorizeController.php76
-rw-r--r--src/OAuth2/Controller/AuthorizeControllerInterface.php18
-rw-r--r--src/OAuth2/Controller/GrantController.php17
-rw-r--r--src/OAuth2/Controller/GrantControllerInterface.php12
-rw-r--r--src/OAuth2/GrantType/AuthorizationCode.php13
-rw-r--r--src/OAuth2/GrantType/ClientCredentials.php4
-rw-r--r--src/OAuth2/GrantType/JWTBearer.php100
-rw-r--r--src/OAuth2/GrantType/RefreshToken.php6
-rw-r--r--src/OAuth2/GrantType/UserCredentials.php6
-rw-r--r--src/OAuth2/GrantTypeInterface.php2
-rw-r--r--src/OAuth2/Request.php2
-rw-r--r--src/OAuth2/RequestInterface.php2
-rw-r--r--src/OAuth2/Response.php2
-rw-r--r--src/OAuth2/Response/AuthenticationError.php1
-rw-r--r--src/OAuth2/Response/Error.php1
-rw-r--r--src/OAuth2/Response/ProviderInterface.php4
-rw-r--r--src/OAuth2/Response/Redirect.php1
-rw-r--r--src/OAuth2/ResponseType/AccessToken.php2
-rw-r--r--src/OAuth2/ResponseType/AccessTokenInterface.php2
-rw-r--r--src/OAuth2/ResponseType/AuthorizationCode.php4
-rw-r--r--src/OAuth2/ResponseType/AuthorizationCodeInterface.php3
-rw-r--r--src/OAuth2/ResponseTypeInterface.php2
-rw-r--r--src/OAuth2/Server.php2
-rw-r--r--src/OAuth2/Storage/AccessTokenInterface.php2
-rw-r--r--src/OAuth2/Storage/AuthorizationCodeInterface.php15
-rw-r--r--src/OAuth2/Storage/ClientCredentialsInterface.php2
-rw-r--r--src/OAuth2/Storage/ClientInterface.php2
-rw-r--r--src/OAuth2/Storage/JWTBearerInterface.php9
-rw-r--r--src/OAuth2/Storage/Memory.php23
-rw-r--r--src/OAuth2/Storage/Pdo.php39
-rw-r--r--src/OAuth2/Storage/RefreshTokenInterface.php2
-rw-r--r--src/OAuth2/Storage/UserCredentialsInterface.php2
-rw-r--r--src/OAuth2/TokenType/Bearer.php2
-rw-r--r--src/OAuth2/TokenType/MAC.php2
-rw-r--r--src/OAuth2/TokenTypeInterface.php2
-rw-r--r--src/OAuth2/Util.php86
-rw-r--r--src/OAuth2/Util/Scope.php41
-rw-r--r--test/OAuth2/AutoloadTest.php2
-rw-r--r--test/OAuth2/GrantType/AuthorizationCodeTest.php38
-rw-r--r--test/OAuth2/GrantType/ClientCredentialsTest.php39
-rw-r--r--test/OAuth2/GrantType/JWTBearerTest.php39
-rw-r--r--test/OAuth2/GrantType/RefreshTokenTest.php35
-rw-r--r--test/OAuth2/GrantType/UserCredentialsTest.php38
-rw-r--r--test/OAuth2/RequestTest.php4
-rw-r--r--test/OAuth2/ResponseTest.php2
-rw-r--r--test/OAuth2/Server/Access/BasicValidationTest.php2
-rw-r--r--test/OAuth2/Server/Authorize/BasicValidationTest.php17
-rw-r--r--test/OAuth2/Server/Authorize/CodeTest.php2
-rw-r--r--test/OAuth2/Server/Authorize/ImplicitTest.php2
-rw-r--r--test/OAuth2/Server/Grant/BasicValidationTest.php26
-rw-r--r--test/OAuth2/Storage/PdoTest.php2
-rw-r--r--test/bootstrap.php2
-rw-r--r--test/config/storage.json9
-rw-r--r--test/lib/OAuth2/Request/TestRequest.php8
-rw-r--r--test/lib/OAuth2/Storage/Bootstrap.php2
59 files changed, 521 insertions, 299 deletions
diff --git a/README.md b/README.md
index a6db00a..3d87293 100644
--- a/README.md
+++ b/README.md
@@ -174,6 +174,10 @@ Supported grant types are as follows:
The client can use their credentials to retrieve an access token directly, which will allow access to resources under the client's control
+ 4. [JWT Authorization Grant](http://tools.ietf.org/html/draft-ietf-oauth-jwt-bearer-04#section-4)
+
+ The client can submit a JWT (JSON Web Token) in a request to the token endpoint. An access token (without a refresh token) is then returned directly.
+
Create a custom grant type by implementing the `OAuth2_GrantTypeInterface` and adding it to the OAuth2 Server object.
Acknowledgements
diff --git a/src/OAuth2/Autoloader.php b/src/OAuth2/Autoloader.php
index a9673d8..40a42fb 100644
--- a/src/OAuth2/Autoloader.php
+++ b/src/OAuth2/Autoloader.php
@@ -20,7 +20,7 @@ class OAuth2_Autoloader
/**
* Registers AdobeDigitalMarketing_Autoloader as an SPL autoloader.
*/
- static public function register($dir = null)
+ public static function register($dir = null)
{
ini_set('unserialize_callback_func', 'spl_autoload_call');
spl_autoload_register(array(new self($dir), 'autoload'));
diff --git a/src/OAuth2/Controller/AccessController.php b/src/OAuth2/Controller/AccessController.php
index 883c64a..3f2e9e2 100644
--- a/src/OAuth2/Controller/AccessController.php
+++ b/src/OAuth2/Controller/AccessController.php
@@ -1,16 +1,17 @@
<?php
/**
-*
-*/
+ * @see OAuth2_Controller_AccessControllerInterface
+ */
class OAuth2_Controller_AccessController implements OAuth2_Controller_AccessControllerInterface
{
private $response;
private $tokenType;
private $tokenStorage;
private $config;
+ private $scopeUtil;
- public function __construct(OAuth2_TokenTypeInterface $tokenType, OAuth2_Storage_AccessTokenInterface $tokenStorage, $config = array(), $util = null)
+ public function __construct(OAuth2_TokenTypeInterface $tokenType, OAuth2_Storage_AccessTokenInterface $tokenStorage, $config = array(), $scopeUtil = null)
{
$this->tokenType = $tokenType;
$this->tokenStorage = $tokenStorage;
@@ -19,10 +20,10 @@ class OAuth2_Controller_AccessController implements OAuth2_Controller_AccessCont
'www_realm' => 'Service',
), $config);
- if (is_null($util)) {
- $util = new OAuth2_Util();
+ if (is_null($scopeUtil)) {
+ $scopeUtil = new OAuth2_Util_Scope();
}
- $this->util = $util;
+ $this->scopeUtil = $scopeUtil;
}
public function verifyAccessRequest(OAuth2_RequestInterface $request)
@@ -30,7 +31,7 @@ class OAuth2_Controller_AccessController implements OAuth2_Controller_AccessCont
$token = $this->tokenType->getAccessTokenParameter($request);
$this->response = $this->tokenType->getResponse();
if ($token) {
- $access_token = $this->getAccessTokenData($token, $request->query('scope'));
+ $access_token = $this->getAccessTokenData($token, $this->scopeUtil->getScopeFromRequest($request));
return (bool) $access_token;
}
@@ -65,7 +66,7 @@ class OAuth2_Controller_AccessController implements OAuth2_Controller_AccessCont
// Check scope, if provided
// If token doesn't have a scope, it's null/empty, or it's insufficient, then throw an error
- if ($scope && (!isset($token["scope"]) || !$token["scope"] || !$this->util->checkScope($scope, $token["scope"]))) {
+ if ($scope && (!isset($token["scope"]) || !$token["scope"] || !$this->scopeUtil->checkScope($scope, $token["scope"]))) {
$this->response = new OAuth2_Response_AuthenticationError(401, 'insufficient_scope', 'The request requires higher privileges than provided by the access token', $this->tokenType->getTokenType(), $this->config['www_realm'], $scope);
return null;
}
@@ -77,4 +78,4 @@ class OAuth2_Controller_AccessController implements OAuth2_Controller_AccessCont
{
return $this->response;
}
-} \ No newline at end of file
+}
diff --git a/src/OAuth2/Controller/AccessControllerInterface.php b/src/OAuth2/Controller/AccessControllerInterface.php
index a7b77c8..9571b9d 100644
--- a/src/OAuth2/Controller/AccessControllerInterface.php
+++ b/src/OAuth2/Controller/AccessControllerInterface.php
@@ -1,8 +1,21 @@
<?php
+/**
+ * This controller is called when a "resource" is requested.
+ * call verifyAccessRequest in order to determine if the request
+ * contains a valid token.
+ *
+ * ex:
+ * > if (!$accessController->verifyAccessRequest(OAuth2_Request::createFromGlobals())) {
+ * > $accessController->getResponse()->send(); // authorization failed
+ * > die();
+ * > }
+ * > return json_encode($resource); // valid token! Send the stuff!
+ *
+ */
interface OAuth2_Controller_AccessControllerInterface extends OAuth2_Response_ProviderInterface
{
public function verifyAccessRequest(OAuth2_RequestInterface $request);
public function getAccessTokenData($token_param, $scope = null);
-} \ No newline at end of file
+}
diff --git a/src/OAuth2/Controller/AuthorizeController.php b/src/OAuth2/Controller/AuthorizeController.php
index 09ff56c..0a443f7 100644
--- a/src/OAuth2/Controller/AuthorizeController.php
+++ b/src/OAuth2/Controller/AuthorizeController.php
@@ -1,17 +1,17 @@
<?php
/**
-*
-*/
+ * @see OAuth2_Controller_AuthorizeControllerInterface
+ */
class OAuth2_Controller_AuthorizeController implements OAuth2_Controller_AuthorizeControllerInterface
{
private $response;
private $clientStorage;
private $responseTypes;
private $config;
- private $util;
+ private $scopeUtil;
- public function __construct(OAuth2_Storage_ClientInterface $clientStorage, array $responseTypes = array(), array $config = array(), $util = null)
+ public function __construct(OAuth2_Storage_ClientInterface $clientStorage, array $responseTypes = array(), array $config = array(), $scopeUtil = null)
{
$this->clientStorage = $clientStorage;
$this->responseTypes = $responseTypes;
@@ -21,10 +21,10 @@ class OAuth2_Controller_AuthorizeController implements OAuth2_Controller_Authori
'enforce_state' => false,
), $config);
- if (is_null($util)) {
- $util = new OAuth2_Util();
+ if (is_null($scopeUtil)) {
+ $scopeUtil = new OAuth2_Util_Scope();
}
- $this->util = $util;
+ $this->scopeUtil = $scopeUtil;
}
public function handleAuthorizeRequest(OAuth2_RequestInterface $request, $is_authorized, $user_id = null)
@@ -50,7 +50,7 @@ class OAuth2_Controller_AuthorizeController implements OAuth2_Controller_Authori
}
list($redirect_uri, $result) = $authResult;
- $uri = $this->util->buildUri($redirect_uri, $result);
+ $uri = $this->buildUri($redirect_uri, $result);
// return redirect response
return new OAuth2_Response_Redirect($uri);
@@ -94,7 +94,7 @@ class OAuth2_Controller_AuthorizeController implements OAuth2_Controller_Authori
}
// Only need to validate if redirect_uri provided on input and clientData.
- if ($clientData["redirect_uri"] && $redirect_uri && !$this->util->validateRedirectUri($redirect_uri, $clientData["redirect_uri"])) {
+ if ($clientData["redirect_uri"] && $redirect_uri && !$this->validateRedirectUri($redirect_uri, $clientData["redirect_uri"])) {
$this->response = new OAuth2_Response_Error(400, 'redirect_uri_mismatch', 'The redirect URI provided is missing or does not match');
return false;
}
@@ -103,7 +103,7 @@ class OAuth2_Controller_AuthorizeController implements OAuth2_Controller_Authori
$redirect_uri = $redirect_uri ? $redirect_uri : $clientData["redirect_uri"];
$response_type = $request->query('response_type');
$state = $request->query('state');
- $scope = $request->query('scope');
+ $scope = $this->scopeUtil->getScopeFromRequest($request);
// type and client_id are required
if (!$response_type || !in_array($response_type, array(self::RESPONSE_TYPE_AUTHORIZATION_CODE, self::RESPONSE_TYPE_ACCESS_TOKEN))) {
@@ -127,7 +127,7 @@ class OAuth2_Controller_AuthorizeController implements OAuth2_Controller_Authori
}
// Validate that the requested scope is supported
- if ($scope && !$this->util->checkScope($scope, $this->config['supported_scopes'])) {
+ if ($scope && !$this->scopeUtil->checkScope($scope, $this->config['supported_scopes'])) {
$this->response = new OAuth2_Response_Redirect($redirect_uri, 302, 'invalid_scope', 'An unsupported scope was requested', $state);
return false;
}
@@ -142,8 +142,60 @@ class OAuth2_Controller_AuthorizeController implements OAuth2_Controller_Authori
return ((array)$request->getAllQueryParameters() + $clientData + array('state' => null));
}
+ /**
+ * Build the absolute URI based on supplied URI and parameters.
+ *
+ * @param $uri
+ * An absolute URI.
+ * @param $params
+ * Parameters to be append as GET.
+ *
+ * @return
+ * An absolute URI with supplied parameters.
+ *
+ * @ingroup oauth2_section_4
+ */
+ private function buildUri($uri, $params)
+ {
+ $parse_url = parse_url($uri);
+
+ // Add our params to the parsed uri
+ foreach ( $params as $k => $v ) {
+ if (isset($parse_url[$k])) {
+ $parse_url[$k] .= "&" . http_build_query($v);
+ } else {
+ $parse_url[$k] = http_build_query($v);
+ }
+ }
+
+ // Put humpty dumpty back together
+ return
+ ((isset($parse_url["scheme"])) ? $parse_url["scheme"] . "://" : "")
+ . ((isset($parse_url["user"])) ? $parse_url["user"]
+ . ((isset($parse_url["pass"])) ? ":" . $parse_url["pass"] : "") . "@" : "")
+ . ((isset($parse_url["host"])) ? $parse_url["host"] : "")
+ . ((isset($parse_url["port"])) ? ":" . $parse_url["port"] : "")
+ . ((isset($parse_url["path"])) ? $parse_url["path"] : "")
+ . ((isset($parse_url["query"])) ? "?" . $parse_url["query"] : "")
+ . ((isset($parse_url["fragment"])) ? "#" . $parse_url["fragment"] : "")
+ ;
+ }
+
+ /**
+ * Internal method for validating redirect URI supplied
+ * @param string $inputUri
+ * @param string $storedUri
+ */
+ private function validateRedirectUri($inputUri, $storedUri)
+ {
+ if (!$inputUri || !$storedUri) {
+ return false; // if either one is missing, assume INVALID
+ }
+ return strcasecmp(substr($inputUri, 0, strlen($storedUri)), $storedUri) === 0;
+ }
+
public function getResponse()
{
return $this->response;
}
-} \ No newline at end of file
+}
diff --git a/src/OAuth2/Controller/AuthorizeControllerInterface.php b/src/OAuth2/Controller/AuthorizeControllerInterface.php
index 4110297..ed01b10 100644
--- a/src/OAuth2/Controller/AuthorizeControllerInterface.php
+++ b/src/OAuth2/Controller/AuthorizeControllerInterface.php
@@ -1,5 +1,21 @@
<?php
+/**
+ * This controller is called when a user should be authorized
+ * by an authorization server. As OAuth2 does not handle
+ * authorization directly, this controller ensures the request is valid, but
+ * requires the application to determine the value of $is_authorized
+ *
+ * ex:
+ * > $user_id = $this->somehowDetermineUserId();
+ * > $is_authorized = $this->somehowDetermineUserAuthorization();
+ * > $response = $authorizeController->handleAuthorizeRequest(
+ * > OAuth2_Request::createFromGlobals(),
+ * > $is_authorized,
+ * > $user_id);
+ * > $response->send();
+ *
+ */
interface OAuth2_Controller_AuthorizeControllerInterface extends OAuth2_Response_ProviderInterface
{
/**
@@ -17,4 +33,4 @@ interface OAuth2_Controller_AuthorizeControllerInterface extends OAuth2_Response
public function handleAuthorizeRequest(OAuth2_RequestInterface $request, $is_authorized, $user_id = null);
public function validateAuthorizeRequest(OAuth2_RequestInterface $request);
-} \ No newline at end of file
+}
diff --git a/src/OAuth2/Controller/GrantController.php b/src/OAuth2/Controller/GrantController.php
index ba7017b..45a08c3 100644
--- a/src/OAuth2/Controller/GrantController.php
+++ b/src/OAuth2/Controller/GrantController.php
@@ -1,14 +1,17 @@
<?php
+/**
+ * @see OAuth2_Controller_GrantControllerInterface
+ */
class OAuth2_Controller_GrantController implements OAuth2_Controller_GrantControllerInterface
{
private $response;
private $clientStorage;
private $accessToken;
private $grantTypes;
- private $util;
+ private $scopeUtil;
- public function __construct(OAuth2_Storage_ClientCredentialsInterface $clientStorage, OAuth2_ResponseType_AccessTokenInterface $accessToken, array $grantTypes = array(), $util = null)
+ public function __construct(OAuth2_Storage_ClientCredentialsInterface $clientStorage, OAuth2_ResponseType_AccessTokenInterface $accessToken, array $grantTypes = array(), $scopeUtil = null)
{
$this->clientStorage = $clientStorage;
$this->accessToken = $accessToken;
@@ -16,10 +19,10 @@ class OAuth2_Controller_GrantController implements OAuth2_Controller_GrantContro
$this->addGrantType($grantType);
}
- if (is_null($util)) {
- $util = new OAuth2_Util();
+ if (is_null($scopeUtil)) {
+ $scopeUtil = new OAuth2_Util_Scope();
}
- $this->util = $util;
+ $this->scopeUtil = $scopeUtil;
}
public function handleGrantRequest(OAuth2_RequestInterface $request)
@@ -134,8 +137,10 @@ class OAuth2_Controller_GrantController implements OAuth2_Controller_GrantContro
$tokenData["scope"] = null;
}
+ $scope = $this->scopeUtil->getScopeFromRequest($request);
// Check scope, if provided
- if (null != $request->query('scope') && (!is_array($tokenData) || !isset($tokenData["scope"]) || !$this->util->checkScope($request->query('scope'), $tokenData["scope"]))) {
+ // @TODO: ScopeStorage
+ if (null != $scope && (!is_array($tokenData) || !isset($tokenData["scope"]) || !$this->scopeUtil->checkScope($scope, $tokenData["scope"]))) {
$this->response = new OAuth2_Response_Error(400, 'invalid_scope', 'An unsupported scope was requested.');
return null;
}
diff --git a/src/OAuth2/Controller/GrantControllerInterface.php b/src/OAuth2/Controller/GrantControllerInterface.php
index 2bdcfd0..eec76a9 100644
--- a/src/OAuth2/Controller/GrantControllerInterface.php
+++ b/src/OAuth2/Controller/GrantControllerInterface.php
@@ -1,5 +1,15 @@
<?php
+/**
+ * This controller is called when a token is being requested.
+ * it is called to handle all grant types the application supports.
+ * It also validates the client's credentials
+ *
+ * ex:
+ * > $response = $grantController->handleGrantRequest(OAuth2_Request::createFromGlobals());
+ * > $response->send();
+ *
+ */
interface OAuth2_Controller_GrantControllerInterface extends OAuth2_Response_ProviderInterface
{
/**
@@ -14,4 +24,4 @@ interface OAuth2_Controller_GrantControllerInterface extends OAuth2_Response_Pro
public function grantAccessToken(OAuth2_RequestInterface $request);
public function getClientCredentials(OAuth2_RequestInterface $request);
-} \ No newline at end of file
+}
diff --git a/src/OAuth2/GrantType/AuthorizationCode.php b/src/OAuth2/GrantType/AuthorizationCode.php
index 2a40b2f..218867b 100644
--- a/src/OAuth2/GrantType/AuthorizationCode.php
+++ b/src/OAuth2/GrantType/AuthorizationCode.php
@@ -7,6 +7,7 @@ class OAuth2_GrantType_AuthorizationCode implements OAuth2_GrantTypeInterface, O
{
private $storage;
private $response;
+ private $code;
public function __construct(OAuth2_Storage_AuthorizationCodeInterface $storage)
{
@@ -20,7 +21,7 @@ class OAuth2_GrantType_AuthorizationCode implements OAuth2_GrantTypeInterface, O
public function validateRequest($request)
{
- if (!$request->query('code')) {
+ if (!$request->request('code')) {
$this->response = new OAuth2_Response_Error(400, 'invalid_request', 'Missing parameter: "code" is required');
return false;
}
@@ -30,7 +31,8 @@ class OAuth2_GrantType_AuthorizationCode implements OAuth2_GrantTypeInterface, O
public function getTokenDataFromRequest($request)
{
- if (!$tokenData = $this->storage->getAuthorizationCode($request->query('code'))) {
+ $this->code = $request->request('code');
+ if (!$tokenData = $this->storage->getAuthorizationCode($this->code)) {
$this->response = new OAuth2_Response_Error(400, 'invalid_grant', "Authorization code doesn't exist or is invalid for the client");
return null;
}
@@ -40,7 +42,7 @@ class OAuth2_GrantType_AuthorizationCode implements OAuth2_GrantTypeInterface, O
* @uri - http://tools.ietf.org/html/draft-ietf-oauth-v2-31#section-4.1.3
*/
if (isset($tokenData['redirect_uri']) && $tokenData['redirect_uri']) {
- if (!$request->query('redirect_uri') || urldecode($request->query('redirect_uri')) != $tokenData['redirect_uri']) {
+ if (!$request->request('redirect_uri') || urldecode($request->request('redirect_uri')) != $tokenData['redirect_uri']) {
$this->response = new OAuth2_Response_Error(400, 'redirect_uri_mismatch', "The redirect URI is missing or do not match", "#section-4.1.3");
return false;
}
@@ -68,7 +70,10 @@ class OAuth2_GrantType_AuthorizationCode implements OAuth2_GrantTypeInterface, O
public function createAccessToken(OAuth2_ResponseType_AccessTokenInterface $accessToken, array $clientData, array $tokenData)
{
- return $accessToken->createAccessToken($clientData['client_id'], $tokenData['user_id'], $tokenData['scope']);
+ $this->storage->expireAuthorizationCode($this->code);
+ $token = $accessToken->createAccessToken($clientData['client_id'], $tokenData['user_id'], $tokenData['scope']);
+
+ return $token;
}
public function getResponse()
diff --git a/src/OAuth2/GrantType/ClientCredentials.php b/src/OAuth2/GrantType/ClientCredentials.php
index 2dae255..a315717 100644
--- a/src/OAuth2/GrantType/ClientCredentials.php
+++ b/src/OAuth2/GrantType/ClientCredentials.php
@@ -16,7 +16,7 @@ class OAuth2_GrantType_ClientCredentials implements OAuth2_GrantTypeInterface
public function getTokenDataFromRequest($request)
{
// the only piece to pull is the "scope" parameter
- $scope = $request->headers('REQUEST_METHOD') == 'POST' ? $request->request('scope') : $request->query('scope');
+ $scope = $request->server('REQUEST_METHOD') == 'POST' ? $request->request('scope') : $request->query('scope');
return array(
"scope" => $scope
);
@@ -37,4 +37,4 @@ class OAuth2_GrantType_ClientCredentials implements OAuth2_GrantTypeInterface
$includeRefreshToken = false;
return $accessToken->createAccessToken($clientData['client_id'], $tokenData['user_id'], $tokenData['scope'], $includeRefreshToken);
}
-} \ No newline at end of file
+}
diff --git a/src/OAuth2/GrantType/JWTBearer.php b/src/OAuth2/GrantType/JWTBearer.php
index 81c139e..1572346 100644
--- a/src/OAuth2/GrantType/JWTBearer.php
+++ b/src/OAuth2/GrantType/JWTBearer.php
@@ -1,33 +1,54 @@
<?php
/**
-*
+* The JWT bearer authorization grant implements JWT (JSON Web Tokens) as a grant type per the IETF draft.
+* @see http://tools.ietf.org/html/draft-ietf-oauth-jwt-bearer-04#section-4
*/
class OAuth2_GrantType_JWTBearer implements OAuth2_GrantTypeInterface, OAuth2_Response_ProviderInterface, OAuth2_ClientAssertionTypeInterface
{
private $storage;
private $response;
- private $audience = NULL;
- private $jwt = NULL;
+ private $audience = null;
+ private $jwt = null;
private $jwtUtil;
+ /**
+ * Creates an instance of the JWT bearer grant type.
+ *
+ * @param OAuth2_Storage_JWTBearerInterface $storage
+ * A valid storage interface that implements storage hooks for the JWT bearer grant type.
+ * @param string $audience
+ * The audience to validate the token against. This is usually the full URI of the OAuth grant requests endpoint.
+ * @param OAuth2_Util_JWT OPTIONAL $jwtUtil
+ * The class used to decode, encode and verify JWTs.
+ */
public function __construct(OAuth2_Storage_JWTBearerInterface $storage, $audience, OAuth2_Util_JWT $jwtUtil = null)
{
$this->storage = $storage;
$this->audience = $audience;
-
- if (is_null($jwtUtil)) {
- $jwtUtil = new OAuth2_Util_JWT();
- }
-
+
+ if (is_null($jwtUtil)) {
+ $jwtUtil = new OAuth2_Util_JWT();
+ }
+
$this->jwtUtil = $jwtUtil;
}
+ /**
+ * Returns the grant_type get parameter to identify the grant type request as JWT bearer authorization grant.
+ * @return The string identifier for grant_type.
+ * @see OAuth2_GrantTypeInterface::getQuerystringIdentifier()
+ */
public function getQuerystringIdentifier()
{
return 'urn:ietf:params:oauth:grant-type:jwt-bearer';
}
+ /**
+ * Validates the request by making share all GET parameters exists.
+ * @return TRUE if the request is valid, otherwise FALSE.
+ * @see OAuth2_GrantTypeInterface::validateRequest()
+ */
public function validateRequest($request)
{
if (!$request->query("assertion")) {
@@ -39,6 +60,11 @@ class OAuth2_GrantType_JWTBearer implements OAuth2_GrantTypeInterface, OAuth2_Re
return true;
}
+ /**
+ * Gets the data from the decoded JWT.
+ * @return Array containing the token data if the JWT can be decoded. Otherwise, NULL is returned.
+ * @see OAuth2_GrantTypeInterface::getTokenDataFromRequest()
+ */
public function getTokenDataFromRequest($request)
{
@@ -50,7 +76,7 @@ class OAuth2_GrantType_JWTBearer implements OAuth2_GrantTypeInterface, OAuth2_Re
//Decode the JWT
try {
- $jwt = $this->jwtUtil->decode($request->query('assertion'), NULL, FALSE);
+ $jwt = $this->jwtUtil->decode($request->query('assertion'), null, false);
} catch (Exception $e) {
$this->response = new OAuth2_Response_Error(400, 'invalid_request', "JWT is malformed");
@@ -81,25 +107,47 @@ class OAuth2_GrantType_JWTBearer implements OAuth2_GrantTypeInterface, OAuth2_Re
return $tokenData;
}
+ /**
+ * Store a copy of the JWT
+ * @param string $jwt
+ */
private function setJWT($jwt)
{
$this->jwt = $jwt;
}
- private function getJWTParameter($parameter, $default = NULL)
+ /**
+ * Helper function to make it easier to return a JWT parameter.
+ * @param string $parameter
+ * The JWT parameter to get.
+ * @param mixed $default
+ * The value to return if the JWT parameter does not exist.
+ * @return mixed
+ * The JWT parameter.
+ */
+ private function getJWTParameter($parameter, $default = null)
{
- return isset($this->jwt->$parameter) ? $this->jwt->$parameter : NULL;
+ return isset($this->jwt->$parameter) ? $this->jwt->$parameter : null;
}
+ /**
+ * Return the data used to verify the request. For JWT bearer authorization grants, this is the 'iss' which is synonymous to the 'client_id'.
+ * @return array An array of the client data containing the client_id.
+ * @see OAuth2_ClientAssertionTypeInterface::getClientDataFromRequest()
+ */
public function getClientDataFromRequest(OAuth2_RequestInterface $request)
{
$tokenData = $this->getTokenDataFromRequest($request);
if($tokenData){
- return array('client_id' => $tokenData['iss']);
+ return array('client_id' => $tokenData['iss'], 'subject' => $tokenData['sub']);
}
}
+ /**
+ * Validates the client data by checking if the client_id exists in storage. It also checks to see if the client_id is associated with a key to decode the JWT.
+ * @see OAuth2_ClientAssertionTypeInterface::validateClientData()
+ */
public function validateClientData(array $clientData)
{
//Get the iss's public key (http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-06#section-4.1.1)
@@ -110,10 +158,10 @@ class OAuth2_GrantType_JWTBearer implements OAuth2_GrantTypeInterface, OAuth2_Re
return null;
}
- $publicKey = $this->storage->getClientKey($clientData['client_id']);
+ $publicKey = $this->storage->getClientKey($clientData['client_id'], $clientData['subject']);
if (!$publicKey) {
- $this->response = new OAuth2_Response_Error(400, 'invalid_grant', "Invalid issuer (iss) provided");
+ $this->response = new OAuth2_Response_Error(400, 'invalid_grant', "Invalid issuer (iss) or subject (sub) provided");
return null;
}
@@ -121,6 +169,11 @@ class OAuth2_GrantType_JWTBearer implements OAuth2_GrantTypeInterface, OAuth2_Re
return true;
}
+ /**
+ * Validates the token data using the rules in the IETF draft.
+ * @see http://tools.ietf.org/html/draft-ietf-oauth-jwt-bearer-04#section-3
+ * @see OAuth2_GrantTypeInterface::validateTokenData()
+ */
public function validateTokenData($tokenData, array $clientData)
{
// Note: Scope is validated in the client class
@@ -177,7 +230,7 @@ class OAuth2_GrantType_JWTBearer implements OAuth2_GrantTypeInterface, OAuth2_Re
//Verify the JWT
try {
- $this->jwtUtil->decode($this->jwt, $clientData['client_secret'], TRUE);
+ $this->jwtUtil->decode($this->jwt, $clientData['client_secret'], true);
} catch (Exception $e) {
$this->response = new OAuth2_Response_Error(400, 'invalid_grant', "JWT failed signature verification");
@@ -188,19 +241,22 @@ class OAuth2_GrantType_JWTBearer implements OAuth2_GrantTypeInterface, OAuth2_Re
return true;
}
+ /**
+ * Creates an access token that is NOT associated with a refresh token.
+ * If a subject (sub) the name of the user/account we are accessing data on behalf of.
+ * @see OAuth2_GrantTypeInterface::createAccessToken()
+ */
public function createAccessToken(OAuth2_ResponseType_AccessTokenInterface $accessToken, array $clientData, array $tokenData)
{
$includeRefreshToken = false;
- if (isset($tokenData['sub'])) {
- $user = $tokenData['sub'];
- } else {
- $user = $tokenData['iss'];
- }
-
- return $accessToken->createAccessToken($clientData['client_id'], $user, $tokenData['scope'], $includeRefreshToken);
+ return $accessToken->createAccessToken($clientData['client_id'], $tokenData['sub'], $tokenData['scope'], $includeRefreshToken);
}
+ /**
+ * Returns the response of this grant type.
+ * @see OAuth2_Response_ProviderInterface::getResponse()
+ */
public function getResponse()
{
return $this->response;
diff --git a/src/OAuth2/GrantType/RefreshToken.php b/src/OAuth2/GrantType/RefreshToken.php
index 5bc9732..2c54d79 100644
--- a/src/OAuth2/GrantType/RefreshToken.php
+++ b/src/OAuth2/GrantType/RefreshToken.php
@@ -25,7 +25,7 @@ class OAuth2_GrantType_RefreshToken implements OAuth2_GrantTypeInterface, OAuth2
public function validateRequest($request)
{
- if (!$request->query("refresh_token")) {
+ if (!$request->request("refresh_token")) {
$this->response = new OAuth2_Response_Error(400, 'invalid_request', 'Missing parameter: "refresh_token" is required');
return false;
}
@@ -35,7 +35,7 @@ class OAuth2_GrantType_RefreshToken implements OAuth2_GrantTypeInterface, OAuth2
public function getTokenDataFromRequest($request)
{
- if (!$stored = $this->storage->getRefreshToken($request->query("refresh_token"))) {
+ if (!$stored = $this->storage->getRefreshToken($request->request("refresh_token"))) {
$this->response = new OAuth2_Response_Error(400, 'invalid_grant', 'Invalid refresh token');
return false;
}
@@ -82,4 +82,4 @@ class OAuth2_GrantType_RefreshToken implements OAuth2_GrantTypeInterface, OAuth2
{
return $this->response;
}
-} \ No newline at end of file
+}
diff --git a/src/OAuth2/GrantType/UserCredentials.php b/src/OAuth2/GrantType/UserCredentials.php
index 51d05aa..0d4638e 100644
--- a/src/OAuth2/GrantType/UserCredentials.php
+++ b/src/OAuth2/GrantType/UserCredentials.php
@@ -20,7 +20,7 @@ class OAuth2_GrantType_UserCredentials implements OAuth2_GrantTypeInterface, OAu
public function validateRequest($request)
{
- if (!$request->query("password") || !$request->query("username")) {
+ if (!$request->request("password") || !$request->request("username")) {
$this->response = new OAuth2_Response_Error(400, 'invalid_request', 'Missing parameters: "username" and "password" required');
return false;
}
@@ -30,12 +30,12 @@ class OAuth2_GrantType_UserCredentials implements OAuth2_GrantTypeInterface, OAu
public function getTokenDataFromRequest($request)
{
- if (!$this->storage->checkUserCredentials($request->query("username"), $request->query("password"))) {
+ if (!$this->storage->checkUserCredentials($request->request("username"), $request->request("password"))) {
$this->response = new OAuth2_Response_Error(400, 'invalid_grant', 'Invalid username and password combination');
return false;
}
- $tokenData = $this->storage->getUserDetails($request->query("username"));
+ $tokenData = $this->storage->getUserDetails($request->request("username"));
// tokenData can be an empty array
if (false === $tokenData || is_null($tokenData)) {
diff --git a/src/OAuth2/GrantTypeInterface.php b/src/OAuth2/GrantTypeInterface.php
index 0573f9d..c029a1d 100644
--- a/src/OAuth2/GrantTypeInterface.php
+++ b/src/OAuth2/GrantTypeInterface.php
@@ -7,4 +7,4 @@ interface OAuth2_GrantTypeInterface
public function getTokenDataFromRequest($request);
public function validateTokenData($tokenData, array $clientData);
public function createAccessToken(OAuth2_ResponseType_AccessTokenInterface $accessToken, array $clientData, array $tokenData);
-} \ No newline at end of file
+}
diff --git a/src/OAuth2/Request.php b/src/OAuth2/Request.php
index 3ddc3ff..d0ed7fe 100644
--- a/src/OAuth2/Request.php
+++ b/src/OAuth2/Request.php
@@ -180,7 +180,7 @@ class OAuth2_Request implements OAuth2_RequestInterface
*
* @api
*/
- static public function createFromGlobals()
+ public static function createFromGlobals()
{
$class = __CLASS__;
$request = new $class($_GET, $_POST, array(), $_COOKIE, $_FILES, $_SERVER);
diff --git a/src/OAuth2/RequestInterface.php b/src/OAuth2/RequestInterface.php
index 0195605..61eb2d2 100644
--- a/src/OAuth2/RequestInterface.php
+++ b/src/OAuth2/RequestInterface.php
@@ -11,4 +11,4 @@ interface OAuth2_RequestInterface
public function headers($name, $default = null);
public function getAllQueryParameters();
-} \ No newline at end of file
+}
diff --git a/src/OAuth2/Response.php b/src/OAuth2/Response.php
index 183cd3f..4cc9b2b 100644
--- a/src/OAuth2/Response.php
+++ b/src/OAuth2/Response.php
@@ -10,7 +10,7 @@ class OAuth2_Response
protected $parameters = array();
protected $httpHeaders = array();
- static public $statusTexts = array(
+ public static $statusTexts = array(
100 => 'Continue',
101 => 'Switching Protocols',
200 => 'OK',
diff --git a/src/OAuth2/Response/AuthenticationError.php b/src/OAuth2/Response/AuthenticationError.php
index c3c5a62..f558401 100644
--- a/src/OAuth2/Response/AuthenticationError.php
+++ b/src/OAuth2/Response/AuthenticationError.php
@@ -15,4 +15,3 @@ class OAuth2_Response_AuthenticationError extends OAuth2_Response_Error
$this->setHttpHeader('WWW-Authenticate', $authHeader);
}
}
-
diff --git a/src/OAuth2/Response/Error.php b/src/OAuth2/Response/Error.php
index 1eaa26d..bacda74 100644
--- a/src/OAuth2/Response/Error.php
+++ b/src/OAuth2/Response/Error.php
@@ -46,4 +46,3 @@ class OAuth2_Response_Error extends OAuth2_Response
return $this->parameters['error_uri'];
}
}
-
diff --git a/src/OAuth2/Response/ProviderInterface.php b/src/OAuth2/Response/ProviderInterface.php
index b23c332..9b147c0 100644
--- a/src/OAuth2/Response/ProviderInterface.php
+++ b/src/OAuth2/Response/ProviderInterface.php
@@ -2,5 +2,5 @@
interface OAuth2_Response_ProviderInterface
{
- function getResponse();
-} \ No newline at end of file
+ public function getResponse();
+}
diff --git a/src/OAuth2/Response/Redirect.php b/src/OAuth2/Response/Redirect.php
index 4f6a0a2..86ec291 100644
--- a/src/OAuth2/Response/Redirect.php
+++ b/src/OAuth2/Response/Redirect.php
@@ -42,4 +42,3 @@ class OAuth2_Response_Redirect extends OAuth2_Response
}
}
}
-
diff --git a/src/OAuth2/ResponseType/AccessToken.php b/src/OAuth2/ResponseType/AccessToken.php
index 37b5e54..070fbbe 100644
--- a/src/OAuth2/ResponseType/AccessToken.php
+++ b/src/OAuth2/ResponseType/AccessToken.php
@@ -122,4 +122,4 @@ class OAuth2_ResponseType_AccessToken implements OAuth2_ResponseType_AccessToken
{
return $this->generateAccessToken(); // let's reuse the same scheme for token generation
}
-} \ No newline at end of file
+}
diff --git a/src/OAuth2/ResponseType/AccessTokenInterface.php b/src/OAuth2/ResponseType/AccessTokenInterface.php
index 457c3b8..d362893 100644
--- a/src/OAuth2/ResponseType/AccessTokenInterface.php
+++ b/src/OAuth2/ResponseType/AccessTokenInterface.php
@@ -3,4 +3,4 @@
interface OAuth2_ResponseType_AccessTokenInterface extends OAuth2_ResponseTypeInterface
{
public function createAccessToken($client_id, $user_id, $scope = null, $includeRefreshToken = true);
-} \ No newline at end of file
+}
diff --git a/src/OAuth2/ResponseType/AuthorizationCode.php b/src/OAuth2/ResponseType/AuthorizationCode.php
index 3f8b65c..d8a2626 100644
--- a/src/OAuth2/ResponseType/AuthorizationCode.php
+++ b/src/OAuth2/ResponseType/AuthorizationCode.php
@@ -3,7 +3,7 @@
/**
*
*/
-class OAuth2_ResponseType_AuthorizationCode implements OAuth2_ResponseTypeInterface
+class OAuth2_ResponseType_AuthorizationCode implements OAuth2_ResponseType_AuthorizationCodeInterface
{
private $storage;
private $config;
@@ -83,4 +83,4 @@ class OAuth2_ResponseType_AuthorizationCode implements OAuth2_ResponseTypeInterf
}
return substr(hash('sha512', $randomData), 0, $tokenLen);
}
-} \ No newline at end of file
+}
diff --git a/src/OAuth2/ResponseType/AuthorizationCodeInterface.php b/src/OAuth2/ResponseType/AuthorizationCodeInterface.php
index 04067c1..f139ae3 100644
--- a/src/OAuth2/ResponseType/AuthorizationCodeInterface.php
+++ b/src/OAuth2/ResponseType/AuthorizationCodeInterface.php
@@ -1,6 +1,6 @@
<?php
-interface OAuth2_GrantType_AuthorizationCodeInterface extends OAuth2_GrantTypeInterface
+interface OAuth2_ResponseType_AuthorizationCodeInterface extends OAuth2_ResponseTypeInterface
{
/**
* @return
@@ -10,4 +10,3 @@ interface OAuth2_GrantType_AuthorizationCodeInterface extends OAuth2_GrantTypeIn
public function createAuthorizationCode($client_id, $user_id, $redirect_uri, $scope = null);
}
-
diff --git a/src/OAuth2/ResponseTypeInterface.php b/src/OAuth2/ResponseTypeInterface.php
index 4eccaed..3df6821 100644
--- a/src/OAuth2/ResponseTypeInterface.php
+++ b/src/OAuth2/ResponseTypeInterface.php
@@ -3,4 +3,4 @@
interface OAuth2_ResponseTypeInterface
{
public function getAuthorizeResponse($params, $user_id = null);
-} \ No newline at end of file
+}
diff --git a/src/OAuth2/Server.php b/src/OAuth2/Server.php
index c67057d..51c8eb9 100644
--- a/src/OAuth2/Server.php
+++ b/src/OAuth2/Server.php
@@ -108,7 +108,7 @@ class OAuth2_Server implements OAuth2_Controller_AccessControllerInterface,
if ($this->config['token_type'] == 'bearer') {
$config = array_intersect_key($this->config, array_flip(explode(' ', 'token_param_name token_bearer_header_name')));
$tokenType = new OAuth2_TokenType_Bearer($config);
- } else if ($this->config['token_type'] == 'mac') {
+ } elseif ($this->config['token_type'] == 'mac') {
$tokenType = new OAuth2_TokenType_MAC();
} else {
throw new LogicException('unrecognized token type: '.$this->config['token_type']);
diff --git a/src/OAuth2/Storage/AccessTokenInterface.php b/src/OAuth2/Storage/AccessTokenInterface.php
index df3120e..d22be0d 100644
--- a/src/OAuth2/Storage/AccessTokenInterface.php
+++ b/src/OAuth2/Storage/AccessTokenInterface.php
@@ -45,4 +45,4 @@ interface OAuth2_Storage_AccessTokenInterface
* @ingroup oauth2_section_4
*/
public function setAccessToken($oauth_token, $client_id, $user_id, $expires, $scope = null);
-} \ No newline at end of file
+}
diff --git a/src/OAuth2/Storage/AuthorizationCodeInterface.php b/src/OAuth2/Storage/AuthorizationCodeInterface.php
index 4a90946..4b3ed9e 100644
--- a/src/OAuth2/Storage/AuthorizationCodeInterface.php
+++ b/src/OAuth2/Storage/AuthorizationCodeInterface.php
@@ -69,4 +69,17 @@ interface OAuth2_Storage_AuthorizationCodeInterface
*/
public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null);
-} \ No newline at end of file
+ /**
+ * once an Authorization Code is used, it must be exipired
+ *
+ * @see http://tools.ietf.org/html/draft-ietf-oauth-v2-31#section-4.1.2
+ *
+ * The client MUST NOT use the authorization code
+ * more than once. If an authorization code is used more than
+ * once, the authorization server MUST deny the request and SHOULD
+ * revoke (when possible) all tokens previously issued based on
+ * that authorization code
+ *
+ */
+ public function expireAuthorizationCode($code);
+}
diff --git a/src/OAuth2/Storage/ClientCredentialsInterface.php b/src/OAuth2/Storage/ClientCredentialsInterface.php
index 374d628..155506b 100644
--- a/src/OAuth2/Storage/ClientCredentialsInterface.php
+++ b/src/OAuth2/Storage/ClientCredentialsInterface.php
@@ -44,4 +44,4 @@ interface OAuth2_Storage_ClientCredentialsInterface extends OAuth2_Storage_Clien
* @ingroup oauth2_section_4
*/
public function checkRestrictedGrantType($client_id, $grant_type);
-} \ No newline at end of file
+}
diff --git a/src/OAuth2/Storage/ClientInterface.php b/src/OAuth2/Storage/ClientInterface.php
index dca3c3d..9020f43 100644
--- a/src/OAuth2/Storage/ClientInterface.php
+++ b/src/OAuth2/Storage/ClientInterface.php
@@ -18,4 +18,4 @@ interface OAuth2_Storage_ClientInterface
* @ingroup oauth2_section_4
*/
public function getClientDetails($client_id);
-} \ No newline at end of file
+}
diff --git a/src/OAuth2/Storage/JWTBearerInterface.php b/src/OAuth2/Storage/JWTBearerInterface.php
index 58f70fa..8ba8522 100644
--- a/src/OAuth2/Storage/JWTBearerInterface.php
+++ b/src/OAuth2/Storage/JWTBearerInterface.php
@@ -1,11 +1,10 @@
<?php
/**
- * All storage engines need to implement this interface in order to use OAuth2 server
- *
- * @author David Rochwerger <catch.dave@gmail.com>
+ * All storage engines need to implement this interface in order to use the JWT Authorization Grant.
+ * @author F21
*/
-interface OAuth2_Storage_JWTBearerInterface extends OAuth2_Storage_ClientInterface
+interface OAuth2_Storage_JWTBearerInterface
{
/**
@@ -18,5 +17,5 @@ interface OAuth2_Storage_JWTBearerInterface extends OAuth2_Storage_ClientInterfa
* STRING Return the public key for the client_id if it exists, and MUST return FALSE if it doesn't.
* @endcode
*/
- public function getClientKey($client_id);
+ public function getClientKey($client_id, $subject);
}
diff --git a/src/OAuth2/Storage/Memory.php b/src/OAuth2/Storage/Memory.php
index 3d3412f..62ac28e 100644
--- a/src/OAuth2/Storage/Memory.php
+++ b/src/OAuth2/Storage/Memory.php
@@ -53,6 +53,11 @@ class OAuth2_Storage_Memory implements OAuth2_Storage_AuthorizationCodeInterface
$this->authorizationCodes = $authorization_codes;
}
+ public function expireAuthorizationCode($code)
+ {
+ unset($this->authorizationCodes[$code]);
+ }
+
/* UserCredentialsInterface */
public function checkUserCredentials($username, $password)
{
@@ -105,7 +110,7 @@ class OAuth2_Storage_Memory implements OAuth2_Storage_AuthorizationCodeInterface
return isset($this->refreshTokens[$refresh_token]) ? $this->refreshTokens[$refresh_token] : null;
}
- public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = NULL)
+ public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = null)
{
$this->refreshTokens[$refresh_token] = compact('refresh_token', 'client_id', 'user_id', 'expires', 'scope');
}
@@ -132,8 +137,20 @@ class OAuth2_Storage_Memory implements OAuth2_Storage_AuthorizationCodeInterface
}
/*JWTBearerInterface */
- public function getClientKey($client_id)
+ public function getClientKey($client_id, $subject)
{
- return isset($this->jwt[$client_id]) ? $this->jwt[$client_id] : null;
+ if (isset($this->jwt[$client_id])) {
+
+ $jwt = $this->jwt[$client_id];
+
+ if ($jwt) {
+
+ if ($jwt["subject"] == $subject) {
+ return $jwt["key"];
+ }
+ }
+ }
+
+ return null;
}
}
diff --git a/src/OAuth2/Storage/Pdo.php b/src/OAuth2/Storage/Pdo.php
index 49fa4cf..54035f9 100644
--- a/src/OAuth2/Storage/Pdo.php
+++ b/src/OAuth2/Storage/Pdo.php
@@ -44,8 +44,8 @@ class OAuth2_Storage_Pdo implements OAuth2_Storage_AuthorizationCodeInterface,
/* ClientCredentialsInterface */
public function checkClientCredentials($client_id, $client_secret = null)
{
- $stmt = $this->db->prepare(sprintf('SELECT * from %s where client_id = "%s"', $this->config['client_table'], $client_id));
- $stmt->execute();
+ $stmt = $this->db->prepare(sprintf('SELECT * from %s where client_id = :client_id', $this->config['client_table']));
+ $stmt->execute(compact('client_id'));
$result = $stmt->fetch();
// make this extensible
@@ -54,8 +54,8 @@ class OAuth2_Storage_Pdo implements OAuth2_Storage_AuthorizationCodeInterface,
public function getClientDetails($client_id)
{
- $stmt = $this->db->prepare(sprintf('SELECT * from %s where client_id = "%s"', $this->config['client_table'], $client_id));
- $stmt->execute();
+ $stmt = $this->db->prepare(sprintf('SELECT * from %s where client_id = :client_id', $this->config['client_table']));
+ $stmt->execute(compact('client_id'));
return $stmt->fetch();
}
@@ -74,9 +74,9 @@ class OAuth2_Storage_Pdo implements OAuth2_Storage_AuthorizationCodeInterface,
/* AccessTokenInterface */
public function getAccessToken($access_token)
{
- $stmt = $this->db->prepare(sprintf('SELECT * from %s where access_token = "%s"', $this->config['access_token_table'], $access_token));
+ $stmt = $this->db->prepare(sprintf('SELECT * from %s where access_token = :access_token', $this->config['access_token_table']));
- $token = $stmt->execute();
+ $token = $stmt->execute(compact('access_token'));
if ($token = $stmt->fetch()) {
// convert date string back to timestamp
$token['expires'] = strtotime($token['expires']);
@@ -102,8 +102,8 @@ class OAuth2_Storage_Pdo implements OAuth2_Storage_AuthorizationCodeInterface,
/* AuthorizationCodeInterface */
public function getAuthorizationCode($code)
{
- $stmt = $this->db->prepare(sprintf('SELECT * from %s where authorization_code = "%s"', $this->config['code_table'], $code));
- $stmt->execute();
+ $stmt = $this->db->prepare(sprintf('SELECT * from %s where authorization_code = :code', $this->config['code_table']));
+ $stmt->execute(compact('code'));
if ($code = $stmt->fetch()) {
// convert date string back to timestamp
@@ -127,6 +127,13 @@ class OAuth2_Storage_Pdo implements OAuth2_Storage_AuthorizationCodeInterface,
return $stmt->execute(compact('code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope'));
}
+ public function expireAuthorizationCode($code)
+ {
+ $stmt = $this->db->prepare(sprintf('DELETE FROM %s WHERE authorization_code = :code', $this->config['code_table']));
+
+ return $stmt->execute(compact('code'));
+ }
+
/* UserCredentialsInterface */
public function checkUserCredentials($username, $password)
{
@@ -144,9 +151,9 @@ class OAuth2_Storage_Pdo implements OAuth2_Storage_AuthorizationCodeInterface,
/* RefreshTokenInterface */
public function getRefreshToken($refresh_token)
{
- $stmt = $this->db->prepare(sprintf('SELECT * FROM %s WHERE refresh_token = "%s"', $this->config['refresh_token_table'], $refresh_token));
+ $stmt = $this->db->prepare(sprintf('SELECT * FROM %s WHERE refresh_token = :refresh_token', $this->config['refresh_token_table']));
- $token = $stmt->execute();
+ $token = $stmt->execute(compact('refresh_token'));
if ($token = $stmt->fetch()) {
// convert expires to epoch time
$token['expires'] = strtotime($token['expires']);
@@ -155,7 +162,7 @@ class OAuth2_Storage_Pdo implements OAuth2_Storage_AuthorizationCodeInterface,
return $token;
}
- public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = NULL)
+ public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = null)
{
// convert expires to datestring
$expires = date('Y-m-d H:i:s', $expires);
@@ -167,9 +174,9 @@ class OAuth2_Storage_Pdo implements OAuth2_Storage_AuthorizationCodeInterface,
public function unsetRefreshToken($refresh_token)
{
- $stmt = $this->db->prepare(sprintf('DELETE FROM %s WHERE refresh_token = "%s"', $this->config['refresh_token_table'], $refresh_token));
+ $stmt = $this->db->prepare(sprintf('DELETE FROM %s WHERE refresh_token = :refresh_token', $this->config['refresh_token_table']));
- return $stmt->execute();
+ return $stmt->execute(compact('refresh_token'));
}
// plaintext passwords are bad! Override this for your application
@@ -196,11 +203,11 @@ class OAuth2_Storage_Pdo implements OAuth2_Storage_AuthorizationCodeInterface,
return $stmt->execute(compact('username', 'password', 'firstName', 'lastName'));
}
- public function getClientKey($client_id)
+ public function getClientKey($client_id, $subject)
{
- $stmt = $this->db->prepare($sql = sprintf('SELECT public_key from %s where client_id=:client_id', $this->config['jwt_table']));
+ $stmt = $this->db->prepare($sql = sprintf('SELECT public_key from %s where client_id=:client_id AND subject=:subject', $this->config['jwt_table']));
- $stmt->execute(array('client_id' => $client_id));
+ $stmt->execute(array('client_id' => $client_id, 'subject' => $subject));
return $stmt->fetch();
}
}
diff --git a/src/OAuth2/Storage/RefreshTokenInterface.php b/src/OAuth2/Storage/RefreshTokenInterface.php
index d1a32f7..1dbcdb6 100644
--- a/src/OAuth2/Storage/RefreshTokenInterface.php
+++ b/src/OAuth2/Storage/RefreshTokenInterface.php
@@ -75,4 +75,4 @@ interface OAuth2_Storage_RefreshTokenInterface
* @ingroup oauth2_section_6
*/
public function unsetRefreshToken($refresh_token);
-} \ No newline at end of file
+}
diff --git a/src/OAuth2/Storage/UserCredentialsInterface.php b/src/OAuth2/Storage/UserCredentialsInterface.php
index 9fff562..4ca7671 100644
--- a/src/OAuth2/Storage/UserCredentialsInterface.php
+++ b/src/OAuth2/Storage/UserCredentialsInterface.php
@@ -50,4 +50,4 @@ interface OAuth2_Storage_UserCredentialsInterface
*
*/
public function getUserDetails($username);
-} \ No newline at end of file
+}
diff --git a/src/OAuth2/TokenType/Bearer.php b/src/OAuth2/TokenType/Bearer.php
index 4b4135b..4773ad1 100644
--- a/src/OAuth2/TokenType/Bearer.php
+++ b/src/OAuth2/TokenType/Bearer.php
@@ -91,4 +91,4 @@ class OAuth2_TokenType_Bearer implements OAuth2_TokenTypeInterface, OAuth2_Respo
{
return $this->response;
}
-} \ No newline at end of file
+}
diff --git a/src/OAuth2/TokenType/MAC.php b/src/OAuth2/TokenType/MAC.php
index 6d47932..c6c8fe3 100644
--- a/src/OAuth2/TokenType/MAC.php
+++ b/src/OAuth2/TokenType/MAC.php
@@ -15,4 +15,4 @@ class OAuth2_TokenType_MAC implements OAuth2_TokenTypeInterface
throw new LogicException("Not supported");
}
-} \ No newline at end of file
+}
diff --git a/src/OAuth2/TokenTypeInterface.php b/src/OAuth2/TokenTypeInterface.php
index 27ca292..8960e9e 100644
--- a/src/OAuth2/TokenTypeInterface.php
+++ b/src/OAuth2/TokenTypeInterface.php
@@ -4,4 +4,4 @@ interface OAuth2_TokenTypeInterface
{
public function getTokenType();
public function getAccessTokenParameter(OAuth2_RequestInterface $request);
-} \ No newline at end of file
+}
diff --git a/src/OAuth2/Util.php b/src/OAuth2/Util.php
deleted file mode 100644
index 9e1a12d..0000000
--- a/src/OAuth2/Util.php
+++ /dev/null
@@ -1,86 +0,0 @@
-<?php
-
-/**
-* Class for common functions used across the Controller classes
-* This may be better off in a "BaseController" class
-*/
-class OAuth2_Util
-{
- /**
- * Check if everything in required scope is contained in available scope.
- *
- * @param $required_scope
- * Required scope to be check with.
- *
- * @return
- * TRUE if everything in required scope is contained in available scope,
- * and FALSE if it isn't.
- *
- * @see http://tools.ietf.org/html/draft-ietf-oauth-v2-20#section-7
- *
- * @ingroup oauth2_section_7
- */
- public function checkScope($required_scope, $available_scope)
- {
- // The required scope should match or be a subset of the available scope
- if (!is_array($required_scope)) {
- $required_scope = explode(' ', trim($required_scope));
- }
-
- if (!is_array($available_scope)) {
- $available_scope = explode(' ', trim($available_scope));
- }
-
- return (count(array_diff($required_scope, $available_scope)) == 0);
- }
-
- /**
- * Internal method for validating redirect URI supplied
- * @param string $inputUri
- * @param string $storedUri
- */
- public function validateRedirectUri($inputUri, $storedUri) {
- if (!$inputUri || !$storedUri) {
- return false; // if either one is missing, assume INVALID
- }
- return strcasecmp(substr($inputUri, 0, strlen($storedUri)), $storedUri) === 0;
- }
-
- /**
- * Build the absolute URI based on supplied URI and parameters.
- *
- * @param $uri
- * An absolute URI.
- * @param $params
- * Parameters to be append as GET.
- *
- * @return
- * An absolute URI with supplied parameters.
- *
- * @ingroup oauth2_section_4
- */
- public function buildUri($uri, $params) {
- $parse_url = parse_url($uri);
-
- // Add our params to the parsed uri
- foreach ( $params as $k => $v ) {
- if (isset($parse_url[$k])) {
- $parse_url[$k] .= "&" . http_build_query($v);
- } else {
- $parse_url[$k] = http_build_query($v);
- }
- }
-
- // Put humpty dumpty back together
- return
- ((isset($parse_url["scheme"])) ? $parse_url["scheme"] . "://" : "")
- . ((isset($parse_url["user"])) ? $parse_url["user"]
- . ((isset($parse_url["pass"])) ? ":" . $parse_url["pass"] : "") . "@" : "")
- . ((isset($parse_url["host"])) ? $parse_url["host"] : "")
- . ((isset($parse_url["port"])) ? ":" . $parse_url["port"] : "")
- . ((isset($parse_url["path"])) ? $parse_url["path"] : "")
- . ((isset($parse_url["query"])) ? "?" . $parse_url["query"] : "")
- . ((isset($parse_url["fragment"])) ? "#" . $parse_url["fragment"] : "")
- ;
- }
-} \ No newline at end of file
diff --git a/src/OAuth2/Util/Scope.php b/src/OAuth2/Util/Scope.php
new file mode 100644
index 0000000..cd6a4d8
--- /dev/null
+++ b/src/OAuth2/Util/Scope.php
@@ -0,0 +1,41 @@
+<?php
+
+/**
+* Class for common functions used across the Controller classes
+* This may be better off in a "BaseController" class
+*/
+class OAuth2_Util_Scope
+{
+ /**
+ * Check if everything in required scope is contained in available scope.
+ *
+ * @param $required_scope
+ * Required scope to be check with.
+ *
+ * @return
+ * TRUE if everything in required scope is contained in available scope,
+ * and FALSE if it isn't.
+ *
+ * @see http://tools.ietf.org/html/draft-ietf-oauth-v2-20#section-7
+ *
+ * @ingroup oauth2_section_7
+ */
+ public function checkScope($required_scope, $available_scope)
+ {
+ // The required scope should match or be a subset of the available scope
+ if (!is_array($required_scope)) {
+ $required_scope = explode(' ', trim($required_scope));
+ }
+
+ if (!is_array($available_scope)) {
+ $available_scope = explode(' ', trim($available_scope));
+ }
+
+ return (count(array_diff($required_scope, $available_scope)) == 0);
+ }
+
+ public function getScopeFromRequest(OAuth2_RequestInterface $request)
+ {
+ return $request->server('REQUEST_METHOD') == 'POST' ? $request->request('scope') : $request->query('scope');
+ }
+}
diff --git a/test/OAuth2/AutoloadTest.php b/test/OAuth2/AutoloadTest.php
index b7c2e10..eee1a00 100644
--- a/test/OAuth2/AutoloadTest.php
+++ b/test/OAuth2/AutoloadTest.php
@@ -11,4 +11,4 @@ class OAuth2_AutoloadTest extends PHPUnit_Framework_TestCase
$this->assertTrue(class_exists('OAuth2_GrantType_UserCredentials'));
$this->assertTrue(interface_exists('OAuth2_Storage_AccessTokenInterface'));
}
-} \ No newline at end of file
+}
diff --git a/test/OAuth2/GrantType/AuthorizationCodeTest.php b/test/OAuth2/GrantType/AuthorizationCodeTest.php
index b4af1d5..783a3ee 100644
--- a/test/OAuth2/GrantType/AuthorizationCodeTest.php
+++ b/test/OAuth2/GrantType/AuthorizationCodeTest.php
@@ -6,9 +6,9 @@ class OAuth2_GrantType_AuthorizationCodeTest extends PHPUnit_Framework_TestCase
{
$server = $this->getTestServer();
$request = OAuth2_Request::createFromGlobals();
- $request->query['grant_type'] = 'authorization_code'; // valid grant type
- $request->query['client_id'] = 'Test Client ID'; // valid client id
- $request->query['client_secret'] = 'TestSecret'; // valid client secret
+ $request->request['grant_type'] = 'authorization_code'; // valid grant type
+ $request->request['client_id'] = 'Test Client ID'; // valid client id
+ $request->request['client_secret'] = 'TestSecret'; // valid client secret
$response = $server->handleGrantRequest($request);
$this->assertEquals($response->getStatusCode(), 400);
@@ -20,10 +20,32 @@ class OAuth2_GrantType_AuthorizationCodeTest extends PHPUnit_Framework_TestCase
{
$server = $this->getTestServer();
$request = OAuth2_Request::createFromGlobals();
- $request->query['grant_type'] = 'authorization_code'; // valid grant type
- $request->query['client_id'] = 'Test Client ID'; // valid client id
- $request->query['client_secret'] = 'TestSecret'; // valid client secret
- $request->query['code'] = 'InvalidCode'; // invalid authorization code
+ $request->request['grant_type'] = 'authorization_code'; // valid grant type
+ $request->request['client_id'] = 'Test Client ID'; // valid client id
+ $request->request['client_secret'] = 'TestSecret'; // valid client secret
+ $request->request['code'] = 'InvalidCode'; // invalid authorization code
+ $response = $server->handleGrantRequest($request);
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_grant');
+ $this->assertEquals($response->getParameter('error_description'), 'Authorization code doesn\'t exist or is invalid for the client');
+ }
+
+ public function testCodeCannotBeUsedTwice()
+ {
+ $server = $this->getTestServer();
+ $request = OAuth2_Request::createFromGlobals();
+ $request->request['grant_type'] = 'authorization_code'; // valid grant type
+ $request->request['client_id'] = 'Test Client ID'; // valid client id
+ $request->request['client_secret'] = 'TestSecret'; // valid client secret
+ $request->request['code'] = 'testcode'; // valid code
+
+ $response = $server->handleGrantRequest($request);
+
+ $this->assertEquals($response->getStatusCode(), 200);
+ $this->assertNotNull($response->getParameter('access_token'));
+
+ // try to use the same code again
$response = $server->handleGrantRequest($request);
$this->assertEquals($response->getStatusCode(), 400);
@@ -39,4 +61,4 @@ class OAuth2_GrantType_AuthorizationCodeTest extends PHPUnit_Framework_TestCase
return $server;
}
-} \ No newline at end of file
+}
diff --git a/test/OAuth2/GrantType/ClientCredentialsTest.php b/test/OAuth2/GrantType/ClientCredentialsTest.php
index f6934f8..93d6051 100644
--- a/test/OAuth2/GrantType/ClientCredentialsTest.php
+++ b/test/OAuth2/GrantType/ClientCredentialsTest.php
@@ -6,9 +6,9 @@ class OAuth2_GrantType_ClientCredentialsTest extends PHPUnit_Framework_TestCase
{
$server = $this->getTestServer();
$request = OAuth2_Request::createFromGlobals();
- $request->query['grant_type'] = 'client_credentials'; // valid grant type
- $request->query['client_id'] = 'Test Client ID'; // valid client id
- $request->query['client_secret'] = 'FakeSecret'; // valid client secret
+ $request->request['grant_type'] = 'client_credentials'; // valid grant type
+ $request->request['client_id'] = 'Test Client ID'; // valid client id
+ $request->request['client_secret'] = 'FakeSecret'; // valid client secret
$response = $server->handleGrantRequest($request);
$this->assertEquals($response->getStatusCode(), 400);
@@ -20,10 +20,11 @@ class OAuth2_GrantType_ClientCredentialsTest extends PHPUnit_Framework_TestCase
{
$server = $this->getTestServer();
$request = OAuth2_Request::createFromGlobals();
- $request->query['grant_type'] = 'client_credentials'; // valid grant type
- $request->query['client_id'] = 'Test Client ID'; // valid client id
- $request->query['client_secret'] = 'TestSecret'; // valid client secret
- $request->query['scope'] = 'scope';
+ $request->server['REQUEST_METHOD'] = 'POST';
+ $request->request['grant_type'] = 'client_credentials'; // valid grant type
+ $request->request['client_id'] = 'Test Client ID'; // valid client id
+ $request->request['client_secret'] = 'TestSecret'; // valid client secret
+ $request->request['scope'] = 'scope';
$token = $server->grantAccessToken($request);
$this->assertNotNull($token);
@@ -36,9 +37,9 @@ class OAuth2_GrantType_ClientCredentialsTest extends PHPUnit_Framework_TestCase
{
$server = $this->getTestServer();
$request = OAuth2_Request::createFromGlobals();
- $request->query['grant_type'] = 'client_credentials'; // valid grant type
- $request->query['client_id'] = 'Test Client ID'; // valid client id
- $request->query['client_secret'] = 'TestSecret'; // valid client secret
+ $request->request['grant_type'] = 'client_credentials'; // valid grant type
+ $request->request['client_id'] = 'Test Client ID'; // valid client id
+ $request->request['client_secret'] = 'TestSecret'; // valid client secret
$token = $server->grantAccessToken($request);
$this->assertNotNull($token);
@@ -51,8 +52,8 @@ class OAuth2_GrantType_ClientCredentialsTest extends PHPUnit_Framework_TestCase
// create with HTTP_AUTHORIZATION in header
$server = $this->getTestServer();
$headers = array('HTTP_AUTHORIZATION' => 'Basic '.base64_encode('Test Client ID:TestSecret'));
- $query = array('grant_type' => 'client_credentials');
- $request = new OAuth2_Request($query, array(), array(), array(), array(), $headers);
+ $params = array('grant_type' => 'client_credentials');
+ $request = new OAuth2_Request(array(), $params, array(), array(), array(), $headers);
$token = $server->grantAccessToken($request);
$this->assertNotNull($token);
@@ -61,8 +62,8 @@ class OAuth2_GrantType_ClientCredentialsTest extends PHPUnit_Framework_TestCase
// create using PHP Authorization Globals
$headers = array('PHP_AUTH_USER' => 'Test Client ID', 'PHP_AUTH_PW' => 'TestSecret');
- $query = array('grant_type' => 'client_credentials');
- $request = new OAuth2_Request($query, array(), array(), array(), array(), $headers);
+ $params = array('grant_type' => 'client_credentials');
+ $request = new OAuth2_Request(array(), $params, array(), array(), array(), $headers);
$token = $server->grantAccessToken($request);
$this->assertNotNull($token);
@@ -75,7 +76,7 @@ class OAuth2_GrantType_ClientCredentialsTest extends PHPUnit_Framework_TestCase
$server = $this->getTestServer();
$request = OAuth2_Request::createFromGlobals();
$request->server['REQUEST_METHOD'] = 'POST';
- $request->query['grant_type'] = 'client_credentials'; // valid grant type
+ $request->request['grant_type'] = 'client_credentials'; // valid grant type
$request->request['client_id'] = 'Test Client ID'; // valid client id
$request->request['client_secret'] = 'TestSecret'; // valid client secret
$token = $server->grantAccessToken($request);
@@ -89,9 +90,9 @@ class OAuth2_GrantType_ClientCredentialsTest extends PHPUnit_Framework_TestCase
{
$server = $this->getTestServer();
$request = OAuth2_Request::createFromGlobals();
- $request->query['grant_type'] = 'client_credentials'; // valid grant type
- $request->query['client_id'] = 'Test Client ID'; // valid client id
- $request->query['client_secret'] = 'TestSecret'; // valid client secret
+ $request->request['grant_type'] = 'client_credentials'; // valid grant type
+ $request->request['client_id'] = 'Test Client ID'; // valid client id
+ $request->request['client_secret'] = 'TestSecret'; // valid client secret
$token = $server->grantAccessToken($request);
$this->assertNotNull($token);
@@ -107,4 +108,4 @@ class OAuth2_GrantType_ClientCredentialsTest extends PHPUnit_Framework_TestCase
return $server;
}
-} \ No newline at end of file
+}
diff --git a/test/OAuth2/GrantType/JWTBearerTest.php b/test/OAuth2/GrantType/JWTBearerTest.php
index 1d2064c..7bae26e 100644
--- a/test/OAuth2/GrantType/JWTBearerTest.php
+++ b/test/OAuth2/GrantType/JWTBearerTest.php
@@ -99,7 +99,7 @@ class OAuth2_GrantType_JWTBearerTest extends PHPUnit_Framework_TestCase
$request->query['grant_type'] = 'urn:ietf:params:oauth:grant-type:jwt-bearer'; // valid grant type
//Get a future NBF
- $jwt = $this->getJWT(NULL, time() + 10000);
+ $jwt = $this->getJWT(null, time() + 10000);
$request->query['assertion'] = $jwt;
$server->grantAccessToken($request);
@@ -117,7 +117,7 @@ class OAuth2_GrantType_JWTBearerTest extends PHPUnit_Framework_TestCase
$request->query['grant_type'] = 'urn:ietf:params:oauth:grant-type:jwt-bearer'; // valid grant type
//Get a non timestamp nbf
- $jwt = $this->getJWT(NULL, 'notatimestamp');
+ $jwt = $this->getJWT(null, 'notatimestamp');
$request->query['assertion'] = $jwt;
$server->grantAccessToken($request);
@@ -148,24 +148,40 @@ class OAuth2_GrantType_JWTBearerTest extends PHPUnit_Framework_TestCase
$server = $this->getTestServer();
$request = OAuth2_Request::createFromGlobals();
$request->query['grant_type'] = 'urn:ietf:params:oauth:grant-type:jwt-bearer'; // valid grant type
- $request->query['assertion'] = $this->getJWT(NULL, NULL, 'bad_client_id');
+ $request->query['assertion'] = $this->getJWT(null, null, null, 'bad_client_id');
$server->grantAccessToken($request);
$response = $server->getResponse();
$this->assertEquals($response->getStatusCode(), 400);
$this->assertEquals($response->getParameter('error'), 'invalid_grant');
- $this->assertEquals($response->getParameter('error_description'), 'Invalid issuer (iss) provided');
+ $this->assertEquals($response->getParameter('error_description'), 'Invalid issuer (iss) or subject (sub) provided');
+ }
+
+ public function testBadSbuject()
+ {
+ $server = $this->getTestServer();
+ $request = OAuth2_Request::createFromGlobals();
+ $request->query['grant_type'] = 'urn:ietf:params:oauth:grant-type:jwt-bearer'; // valid grant type
+ $request->query['assertion'] = $this->getJWT(null, null, 'anotheruser@ourdomain.com');
+
+ $server->grantAccessToken($request);
+ $response = $server->getResponse();
+
+ $this->assertEquals($response->getStatusCode(), 400);
+ $this->assertEquals($response->getParameter('error'), 'invalid_grant');
+ $this->assertEquals($response->getParameter('error_description'), 'Invalid issuer (iss) or subject (sub) provided');
}
/**
* Generates a JWT
- * @param The expiration date. If the current time is greater than the exp, the JWT is invalid. $exp
- * @param The "not before" time. If the current time is less than the nbf, the JWT is invalid. $nbf
- * @param The issuer, usually the client_id. $iss
+ * @param $exp The expiration date. If the current time is greater than the exp, the JWT is invalid.
+ * @param $nbf The "not before" time. If the current time is less than the nbf, the JWT is invalid.
+ * @param $sub The subject we are acting on behalf of. This could be the email address of the user in the system.
+ * @param $iss The issuer, usually the client_id.
* @return string
*/
- private function getJWT($exp = NULL, $nbf = NULL, $iss = 'Test Client ID')
+ private function getJWT($exp = null, $nbf = null, $sub = null, $iss = 'Test Client ID')
{
$privateKey = "-----BEGIN PRIVATE KEY----- MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCy2DNurVPKjODp af+6DLCeDgnbA85pInA9aUUV9/3YrrStCusIMNRJV66ELT5OOfsurfmAxmuxZrOX eiPgoAcEEVmoE96MRHRn+3XCBmRr3u6ihbYFyXFQyMvqwVb3YEubZ/Y+j9IOMp0Z HC3T6R2PYyCZ2ogO7spM0s9VL/fOTQuf4S233als4OFSWJgeRUXL9lm2hfrqWCAu NlcZ0E/akvH9wBHT0HSbVAMG+TMZ7CYXoeXSBeopIFB6XW+dHw+nZzwWOnewMHrm GJK1eZ9ro2kxkEBvi8Gnf1LJGtteI0fsZtigiIEG2CeFWDjMcAbpu2wTIC2ZUzRo yGfTVModAgMBAAECggEAdqL4q0iLNufxIqVQIEjeuFozq3eA6zkPH42/aG1TlPN/ ovKFKq/JgsWJXODuXdIUj8iUpBn7wniQVcGOHynIvagMw3Q6wu1+EqQ6X3UCFJST 1HfCYWBZrO8mZhnO6NaWEQcL0EBzZTup/sg0lkgjdcSaEbVnYBCDXibRpn7lcZGK MrsHzm6leR9tVbCB7IfT4nPmoWorkJOPcXRmE6kiRYKOKsdvX7p9leMz7ChTL7aF oCSjanO37sx3Vl1Qs8a0hdPO3slXso8/jEyDQEAgOo9SPPF1Eb6ymNIXu83ic/MC LmhFBlb7sjNXP+KCT9dMTSsw6+cYybCh+8Yq6hTgQQKBgQDesyPsWN/pzxT5qHni CngVnoRihK7JDJ2wMAdg853rLFrCn6I4u5jk9U3hDgxdq1N7vOfBtaUnGpeBHM1Q U0oUhukp81I3QyBFgUs1Bjsenu+rQi3zYELKKH/nuTRThKfUQhb5UDwkSKq69Ooc ln2grkOV+UR5nJ3e9aSZvbbXVQKBgQDNlkyso/qm06vzaRu7H6aakhgQb+nMA01z mj5SWimMjd/hv5Mrz3ts1UHqJwT7ElL12pQObDVocLfb5DgX7ttfy36q2OL1+7Pg AxY42lcmXt77olDq+PT4WMzkFbJ2XIeg7aavYIb0EoTxf1rLZNJ+g5gqAb0OCtsp 91NkdygXqQKBgG04kq/Bzt+O7oybMlvIIqkHu4nN5SM5isT0aUoFcTf74u9890S3 zP7NyEpOZ4YxFpqjRU7d1YfeJNvv0kpI7xYuLICkk3gC9frgtI/m5GvaK1Vk+cBZ P6iCQGjXjnA/qUgSuc3Aqh5pfUKAB6nJrQd3MDKHtCuowkytUPMN9nSZAoGAAIu7 nGG7EqJRPI404qRM3vAwXCrP5hjEJeBs9e8DWTovM/w8OcuNOla+nA6KdtgvnDN+ XSNwaNyTwGO0umuJ7ZEuvulggOKwMZIQhwodXR63XNere1Q54kbqFFjyZloMiiLX ZHPPJ+q8q5948D1OScOzrbjfdaAVwODFOekPFDECgYEAnGiC1mwF52JiG6RSwR7M iR1Q2bMJsUW3ofPgOX4diUvg4sihdCj4gmCoKy8Y/rhK9T4Ntti6GPFKqRtjWC7f ja52w2QQbsMYoxeGQoEG4AO92WkJW1Tmj/LufL8C3+Pun+TrSJGreIsMu955v/PF 00cvfSeAGKSc2bXBowyEQQ8= -----END PRIVATE KEY-----";
@@ -173,10 +189,15 @@ class OAuth2_GrantType_JWTBearerTest extends PHPUnit_Framework_TestCase
$exp = time() + 1000;
}
+ if(!$sub){
+ $sub = "testuser@ourdomain.com";
+ }
+
$params = array(
'iss' => $iss,
'exp' => $exp,
'iat' => time(),
+ 'sub' => $sub,
'aud' => 'http://myapp.com/oauth/auth',
'scope' => 'view_friends_list'
);
@@ -184,7 +205,7 @@ class OAuth2_GrantType_JWTBearerTest extends PHPUnit_Framework_TestCase
if ($nbf) {
$params['nbf'] = $nbf;
}
-
+
$jwtUtil = new OAuth2_Util_JWT();
return $jwtUtil->encode($params, $privateKey);
diff --git a/test/OAuth2/GrantType/RefreshTokenTest.php b/test/OAuth2/GrantType/RefreshTokenTest.php
index 7c23ca7..181c463 100644
--- a/test/OAuth2/GrantType/RefreshTokenTest.php
+++ b/test/OAuth2/GrantType/RefreshTokenTest.php
@@ -10,9 +10,9 @@ class OAuth2_GrantType_RefreshTokenTest extends PHPUnit_Framework_TestCase
$server->addGrantType(new OAuth2_GrantType_RefreshToken($this->storage));
$request = OAuth2_Request::createFromGlobals();
- $request->query['grant_type'] = 'refresh_token'; // valid grant type
- $request->query['client_id'] = 'Test Client ID'; // valid client id
- $request->query['client_secret'] = 'TestSecret'; // valid client secret
+ $request->request['grant_type'] = 'refresh_token'; // valid grant type
+ $request->request['client_id'] = 'Test Client ID'; // valid client id
+ $request->request['client_secret'] = 'TestSecret'; // valid client secret
$server->grantAccessToken($request);
$response = $server->getResponse();
@@ -27,10 +27,10 @@ class OAuth2_GrantType_RefreshTokenTest extends PHPUnit_Framework_TestCase
$server->addGrantType(new OAuth2_GrantType_RefreshToken($this->storage));
$request = OAuth2_Request::createFromGlobals();
- $request->query['grant_type'] = 'refresh_token'; // valid grant type
- $request->query['client_id'] = 'Test Client ID'; // valid client id
- $request->query['client_secret'] = 'TestSecret'; // valid client secret
- $request->query['refresh_token'] = 'fake-token'; // valid client secret
+ $request->request['grant_type'] = 'refresh_token'; // valid grant type
+ $request->request['client_id'] = 'Test Client ID'; // valid client id
+ $request->request['client_secret'] = 'TestSecret'; // valid client secret
+ $request->request['refresh_token'] = 'fake-token'; // valid client secret
$server->grantAccessToken($request);
$response = $server->getResponse();
@@ -45,17 +45,18 @@ class OAuth2_GrantType_RefreshTokenTest extends PHPUnit_Framework_TestCase
$server->addGrantType(new OAuth2_GrantType_RefreshToken($this->storage, array('always_issue_new_refresh_token' => true)));
$request = OAuth2_Request::createFromGlobals();
- $request->query['grant_type'] = 'refresh_token'; // valid grant type
- $request->query['client_id'] = 'Test Client ID'; // valid client id
- $request->query['client_secret'] = 'TestSecret'; // valid client secret
- $request->query['refresh_token'] = 'test-refreshtoken'; // valid client secret
+ $request->server['HTTP_METHOD'] = 'POST';
+ $request->request['grant_type'] = 'refresh_token'; // valid grant type
+ $request->request['client_id'] = 'Test Client ID'; // valid client id
+ $request->request['client_secret'] = 'TestSecret'; // valid client secret
+ $request->request['refresh_token'] = 'test-refreshtoken'; // valid client secret
$token = $server->grantAccessToken($request);
$this->assertTrue(isset($token['refresh_token']), 'refresh token should always refresh');
$refresh_token = $this->storage->getRefreshToken($token['refresh_token']);
$this->assertNotNull($refresh_token);
$this->assertEquals($refresh_token['refresh_token'], $token['refresh_token']);
- $this->assertEquals($refresh_token['client_id'], $request->query('client_id'));
+ $this->assertEquals($refresh_token['client_id'], $request->request('client_id'));
$this->assertTrue($token['refresh_token'] != 'test-refreshtoken', 'the refresh token returned is not the one used');
$used_token = $this->storage->getRefreshToken('test-refreshtoken');
$this->assertNull($used_token, 'the refresh token used is no longer valid');
@@ -67,10 +68,10 @@ class OAuth2_GrantType_RefreshTokenTest extends PHPUnit_Framework_TestCase
$server->addGrantType(new OAuth2_GrantType_RefreshToken($this->storage, array('always_issue_new_refresh_token' => false)));
$request = OAuth2_Request::createFromGlobals();
- $request->query['grant_type'] = 'refresh_token'; // valid grant type
- $request->query['client_id'] = 'Test Client ID'; // valid client id
- $request->query['client_secret'] = 'TestSecret'; // valid client secret
- $request->query['refresh_token'] = 'test-refreshtoken'; // valid client secret
+ $request->request['grant_type'] = 'refresh_token'; // valid grant type
+ $request->request['client_id'] = 'Test Client ID'; // valid client id
+ $request->request['client_secret'] = 'TestSecret'; // valid client secret
+ $request->request['refresh_token'] = 'test-refreshtoken'; // valid client secret
$token = $server->grantAccessToken($request);
$this->assertFalse(isset($token['refresh_token']), 'refresh token should not be returned');
@@ -85,4 +86,4 @@ class OAuth2_GrantType_RefreshTokenTest extends PHPUnit_Framework_TestCase
return $server;
}
-} \ No newline at end of file
+}
diff --git a/test/OAuth2/GrantType/UserCredentialsTest.php b/test/OAuth2/GrantType/UserCredentialsTest.php
index 81dfe15..463baec 100644
--- a/test/OAuth2/GrantType/UserCredentialsTest.php
+++ b/test/OAuth2/GrantType/UserCredentialsTest.php
@@ -6,10 +6,10 @@ class OAuth2_GrantType_UserCredentialsTest extends PHPUnit_Framework_TestCase
{
$server = $this->getTestServer();
$request = OAuth2_Request::createFromGlobals();
- $request->query['grant_type'] = 'password'; // valid grant type
- $request->query['client_id'] = 'Test Client ID'; // valid client id
- $request->query['client_secret'] = 'TestSecret'; // valid client secret
- $request->query['password'] = 'testpass'; // valid password
+ $request->request['grant_type'] = 'password'; // valid grant type
+ $request->request['client_id'] = 'Test Client ID'; // valid client id
+ $request->request['client_secret'] = 'TestSecret'; // valid client secret
+ $request->request['password'] = 'testpass'; // valid password
$server->grantAccessToken($request);
$response = $server->getResponse();
@@ -22,10 +22,10 @@ class OAuth2_GrantType_UserCredentialsTest extends PHPUnit_Framework_TestCase
{
$server = $this->getTestServer();
$request = OAuth2_Request::createFromGlobals();
- $request->query['grant_type'] = 'password'; // valid grant type
- $request->query['client_id'] = 'Test Client ID'; // valid client id
- $request->query['client_secret'] = 'TestSecret'; // valid client secret
- $request->query['username'] = 'test-username'; // valid username
+ $request->request['grant_type'] = 'password'; // valid grant type
+ $request->request['client_id'] = 'Test Client ID'; // valid client id
+ $request->request['client_secret'] = 'TestSecret'; // valid client secret
+ $request->request['username'] = 'test-username'; // valid username
$server->grantAccessToken($request);
$response = $server->getResponse();
@@ -38,11 +38,11 @@ class OAuth2_GrantType_UserCredentialsTest extends PHPUnit_Framework_TestCase
{
$server = $this->getTestServer();
$request = OAuth2_Request::createFromGlobals();
- $request->query['grant_type'] = 'password'; // valid grant type
- $request->query['client_id'] = 'Test Client ID'; // valid client id
- $request->query['client_secret'] = 'TestSecret'; // valid client secret
- $request->query['username'] = 'fake-username'; // valid username
- $request->query['password'] = 'testpass'; // valid password
+ $request->request['grant_type'] = 'password'; // valid grant type
+ $request->request['client_id'] = 'Test Client ID'; // valid client id
+ $request->request['client_secret'] = 'TestSecret'; // valid client secret
+ $request->request['username'] = 'fake-username'; // valid username
+ $request->request['password'] = 'testpass'; // valid password
$ret = $server->grantAccessToken($request);
$response = $server->getResponse();
@@ -55,11 +55,11 @@ class OAuth2_GrantType_UserCredentialsTest extends PHPUnit_Framework_TestCase
{
$server = $this->getTestServer();
$request = OAuth2_Request::createFromGlobals();
- $request->query['grant_type'] = 'password'; // valid grant type
- $request->query['client_id'] = 'Test Client ID'; // valid client id
- $request->query['client_secret'] = 'TestSecret'; // valid client secret
- $request->query['username'] = 'test-username'; // valid username
- $request->query['password'] = 'fakepass'; // valid password
+ $request->request['grant_type'] = 'password'; // valid grant type
+ $request->request['client_id'] = 'Test Client ID'; // valid client id
+ $request->request['client_secret'] = 'TestSecret'; // valid client secret
+ $request->request['username'] = 'test-username'; // valid username
+ $request->request['password'] = 'fakepass'; // valid password
$ret = $server->grantAccessToken($request);
$response = $server->getResponse();
@@ -76,4 +76,4 @@ class OAuth2_GrantType_UserCredentialsTest extends PHPUnit_Framework_TestCase
return $server;
}
-} \ No newline at end of file
+}
diff --git a/test/OAuth2/RequestTest.php b/test/OAuth2/RequestTest.php
index a362c2f..cd21f57 100644
--- a/test/OAuth2/RequestTest.php
+++ b/test/OAuth2/RequestTest.php
@@ -18,7 +18,7 @@ class OAuth2_RequestTest extends PHPUnit_Framework_TestCase
/*** make some valid requests ***/
// Valid Grant Request
- $request->setQuery(array(
+ $request->setPost(array(
'grant_type' => 'authorization_code',
'client_id' => 'Test Client ID',
'client_secret' => 'TestSecret',
@@ -40,4 +40,4 @@ class OAuth2_RequestTest extends PHPUnit_Framework_TestCase
return $server;
}
-} \ No newline at end of file
+}
diff --git a/test/OAuth2/ResponseTest.php b/test/OAuth2/ResponseTest.php
index a6d733b..7a65434 100644
--- a/test/OAuth2/ResponseTest.php
+++ b/test/OAuth2/ResponseTest.php
@@ -12,4 +12,4 @@ class OAuth2_ResponseTest extends PHPUnit_Framework_TestCase
$string = $response->getResponseBody('xml');
$this->assertContains('<response><bar>foo</bar><oates>halland</oates></response>', $string);
}
-} \ No newline at end of file
+}
diff --git a/test/OAuth2/Server/Access/BasicValidationTest.php b/test/OAuth2/Server/Access/BasicValidationTest.php
index c599509..f7f75d5 100644
--- a/test/OAuth2/Server/Access/BasicValidationTest.php
+++ b/test/OAuth2/Server/Access/BasicValidationTest.php
@@ -161,4 +161,4 @@ class OAuth2_Server_Access_BasicValidationTest extends PHPUnit_Framework_TestCas
return $server;
}
-} \ No newline at end of file
+}
diff --git a/test/OAuth2/Server/Authorize/BasicValidationTest.php b/test/OAuth2/Server/Authorize/BasicValidationTest.php
index acaeb92..127b9fe 100644
--- a/test/OAuth2/Server/Authorize/BasicValidationTest.php
+++ b/test/OAuth2/Server/Authorize/BasicValidationTest.php
@@ -104,6 +104,21 @@ class OAuth2_Server_Authorize_BasicValidationTest extends PHPUnit_Framework_Test
$this->assertEquals($query['error_description'], 'The state parameter is required');
}
+ public function testValidateRedirectUri()
+ {
+ $server = $this->getTestServer();
+ $request = OAuth2_Request::createFromGlobals();
+ $request->query['client_id'] = 'Test Client ID with Redirect Uri'; // valid client id
+ $request->query['redirect_uri'] = 'http://adobe.com'; // invalid redirect URI
+ $request->query['response_type'] = 'code';
+ $response = $server->handleAuthorizeRequest($request, true);
+
+ $this->assertEquals($response->getStatusCode(), 400);
+
+ $this->assertEquals($response->getParameter('error'), 'redirect_uri_mismatch');
+ $this->assertEquals($response->getParameter('error_description'), 'The redirect URI provided is missing or does not match');
+ }
+
private function getTestServer($config = array())
{
$storage = OAuth2_Storage_Bootstrap::getInstance()->getMemoryStorage();
@@ -114,4 +129,4 @@ class OAuth2_Server_Authorize_BasicValidationTest extends PHPUnit_Framework_Test
return $server;
}
-} \ No newline at end of file
+}
diff --git a/test/OAuth2/Server/Authorize/CodeTest.php b/test/OAuth2/Server/Authorize/CodeTest.php
index 62ed80f..c099298 100644
--- a/test/OAuth2/Server/Authorize/CodeTest.php
+++ b/test/OAuth2/Server/Authorize/CodeTest.php
@@ -112,4 +112,4 @@ class OAuth2_Server_Authorize_CodeTest extends PHPUnit_Framework_TestCase
return $server;
}
-} \ No newline at end of file
+}
diff --git a/test/OAuth2/Server/Authorize/ImplicitTest.php b/test/OAuth2/Server/Authorize/ImplicitTest.php
index 27ba933..30dcb39 100644
--- a/test/OAuth2/Server/Authorize/ImplicitTest.php
+++ b/test/OAuth2/Server/Authorize/ImplicitTest.php
@@ -126,4 +126,4 @@ class OAuth2_Server_Authorize_ImplicitTest extends PHPUnit_Framework_TestCase
return $server;
}
-} \ No newline at end of file
+}
diff --git a/test/OAuth2/Server/Grant/BasicValidationTest.php b/test/OAuth2/Server/Grant/BasicValidationTest.php
index c834f04..b30c665 100644
--- a/test/OAuth2/Server/Grant/BasicValidationTest.php
+++ b/test/OAuth2/Server/Grant/BasicValidationTest.php
@@ -18,7 +18,7 @@ class OAuth2_Server_Grant_BasicValidationTest extends PHPUnit_Framework_TestCase
// add the test parameters in memory
$server = $this->getTestServer();
$request = OAuth2_Request::createFromGlobals();
- $request->query['grant_type'] = 'invalid_grant_type'; // invalid grant type
+ $request->request['grant_type'] = 'invalid_grant_type'; // invalid grant type
$response = $server->handleGrantRequest($request);
$this->assertEquals($response->getStatusCode(), 400);
@@ -31,7 +31,7 @@ class OAuth2_Server_Grant_BasicValidationTest extends PHPUnit_Framework_TestCase
// add the test parameters in memory
$server = $this->getTestServer();
$request = OAuth2_Request::createFromGlobals();
- $request->query['grant_type'] = 'authorization_code'; // valid grant type
+ $request->request['grant_type'] = 'authorization_code'; // valid grant type
$response = $server->handleGrantRequest($request);
$this->assertEquals($response->getStatusCode(), 400);
@@ -44,8 +44,8 @@ class OAuth2_Server_Grant_BasicValidationTest extends PHPUnit_Framework_TestCase
// add the test parameters in memory
$server = $this->getTestServer();
$request = OAuth2_Request::createFromGlobals();
- $request->query['grant_type'] = 'authorization_code'; // valid grant type
- $request->query['client_id'] = 'Test Client ID'; // valid client id
+ $request->request['grant_type'] = 'authorization_code'; // valid grant type
+ $request->request['client_id'] = 'Test Client ID'; // valid client id
$response = $server->handleGrantRequest($request);
$this->assertEquals($response->getStatusCode(), 400);
@@ -58,9 +58,9 @@ class OAuth2_Server_Grant_BasicValidationTest extends PHPUnit_Framework_TestCase
// add the test parameters in memory
$server = $this->getTestServer();
$request = OAuth2_Request::createFromGlobals();
- $request->query['grant_type'] = 'authorization_code'; // valid grant type
- $request->query['client_id'] = 'Fake Client ID'; // invalid client id
- $request->query['client_secret'] = 'Fake Client Secret'; // invalid client secret
+ $request->request['grant_type'] = 'authorization_code'; // valid grant type
+ $request->request['client_id'] = 'Fake Client ID'; // invalid client id
+ $request->request['client_secret'] = 'Fake Client Secret'; // invalid client secret
$response = $server->handleGrantRequest($request);
$this->assertEquals($response->getStatusCode(), 400);
@@ -68,7 +68,7 @@ class OAuth2_Server_Grant_BasicValidationTest extends PHPUnit_Framework_TestCase
$this->assertEquals($response->getParameter('error_description'), 'The client credentials are invalid');
// try again with a real client ID, but an invalid secret
- $request->query['client_id'] = 'Test Client ID'; // valid client id
+ $request->request['client_id'] = 'Test Client ID'; // valid client id
$response = $server->handleGrantRequest($request);
$this->assertEquals($response->getStatusCode(), 400);
@@ -81,10 +81,10 @@ class OAuth2_Server_Grant_BasicValidationTest extends PHPUnit_Framework_TestCase
// add the test parameters in memory
$server = $this->getTestServer();
$request = OAuth2_Request::createFromGlobals();
- $request->query['grant_type'] = 'authorization_code'; // valid grant type
- $request->query['client_id'] = 'Test Client ID'; // valid client id
- $request->query['client_secret'] = 'TestSecret'; // valid client secret
- $request->query['code'] = 'testcode'; // valid authorization code
+ $request->request['grant_type'] = 'authorization_code'; // valid grant type
+ $request->request['client_id'] = 'Test Client ID'; // valid client id
+ $request->request['client_secret'] = 'TestSecret'; // valid client secret
+ $request->request['code'] = 'testcode'; // valid authorization code
$response = $server->handleGrantRequest($request);
$this->assertTrue($response instanceof OAuth2_Response);
@@ -104,4 +104,4 @@ class OAuth2_Server_Grant_BasicValidationTest extends PHPUnit_Framework_TestCase
return $server;
}
-} \ No newline at end of file
+}
diff --git a/test/OAuth2/Storage/PdoTest.php b/test/OAuth2/Storage/PdoTest.php
index a61748b..31c389d 100644
--- a/test/OAuth2/Storage/PdoTest.php
+++ b/test/OAuth2/Storage/PdoTest.php
@@ -155,4 +155,4 @@ class OAuth2_Storage_PdoTest extends PHPUnit_Framework_TestCase
array($mysql),
);
}
-} \ No newline at end of file
+}
diff --git a/test/bootstrap.php b/test/bootstrap.php
index 02bcc90..ff91fc0 100644
--- a/test/bootstrap.php
+++ b/test/bootstrap.php
@@ -4,4 +4,4 @@ require_once(dirname(__FILE__).'/../src/OAuth2/Autoloader.php');
OAuth2_Autoloader::register();
// register test classes
-OAuth2_Autoloader::register(dirname(__FILE__).'/lib'); \ No newline at end of file
+OAuth2_Autoloader::register(dirname(__FILE__).'/lib');
diff --git a/test/config/storage.json b/test/config/storage.json
index 48541a1..8bd35e6 100644
--- a/test/config/storage.json
+++ b/test/config/storage.json
@@ -11,6 +11,10 @@
"client_credentials" : {
"Test Client ID": {
"secret": "TestSecret"
+ },
+ "Test Client ID with Redirect Uri": {
+ "secret": "TestSecret2",
+ "redirect_uri": "http://brentertainment.com"
}
},
"user_credentials" : {
@@ -46,6 +50,9 @@
},
"jwt": {
- "Test Client ID": "-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAstgzbq1Tyozg6Wn/ugyw ng4J2wPOaSJwPWlFFff92K60rQrrCDDUSVeuhC0+Tjn7Lq35gMZrsWazl3oj4KAH BBFZqBPejER0Z/t1wgZka97uooW2BclxUMjL6sFW92BLm2f2Po/SDjKdGRwt0+kd j2MgmdqIDu7KTNLPVS/3zk0Ln+Ett92pbODhUliYHkVFy/ZZtoX66lggLjZXGdBP 2pLx/cAR09B0m1QDBvkzGewmF6Hl0gXqKSBQel1vnR8Pp2c8Fjp3sDB65hiStXmf a6NpMZBAb4vBp39SyRrbXiNH7GbYoIiBBtgnhVg4zHAG6btsEyAtmVM0aMhn01TK HQIDAQAB -----END PUBLIC KEY----- "
+ "Test Client ID": {
+ "key": "-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAstgzbq1Tyozg6Wn/ugyw ng4J2wPOaSJwPWlFFff92K60rQrrCDDUSVeuhC0+Tjn7Lq35gMZrsWazl3oj4KAH BBFZqBPejER0Z/t1wgZka97uooW2BclxUMjL6sFW92BLm2f2Po/SDjKdGRwt0+kd j2MgmdqIDu7KTNLPVS/3zk0Ln+Ett92pbODhUliYHkVFy/ZZtoX66lggLjZXGdBP 2pLx/cAR09B0m1QDBvkzGewmF6Hl0gXqKSBQel1vnR8Pp2c8Fjp3sDB65hiStXmf a6NpMZBAb4vBp39SyRrbXiNH7GbYoIiBBtgnhVg4zHAG6btsEyAtmVM0aMhn01TK HQIDAQAB -----END PUBLIC KEY----- ",
+ "subject": "testuser@ourdomain.com"
+ }
}
} \ No newline at end of file
diff --git a/test/lib/OAuth2/Request/TestRequest.php b/test/lib/OAuth2/Request/TestRequest.php
index 623d139..4772e28 100644
--- a/test/lib/OAuth2/Request/TestRequest.php
+++ b/test/lib/OAuth2/Request/TestRequest.php
@@ -43,4 +43,10 @@ class OAuth2_Request_TestRequest implements OAuth2_RequestInterface
{
$this->query = $query;
}
-} \ No newline at end of file
+
+ public function setPost(array $post)
+ {
+ $this->server['HTTP_METHOD'] = 'POST';
+ $this->post = $post;
+ }
+}
diff --git a/test/lib/OAuth2/Storage/Bootstrap.php b/test/lib/OAuth2/Storage/Bootstrap.php
index 4a214b3..354a508 100644
--- a/test/lib/OAuth2/Storage/Bootstrap.php
+++ b/test/lib/OAuth2/Storage/Bootstrap.php
@@ -91,4 +91,4 @@ class OAuth2_Storage_Bootstrap
{
return dirname(__FILE__).'/../../../config/test.sqlite';
}
-} \ No newline at end of file
+}