diff --git a/.gitattributes b/.gitattributes
index 2bed44304..3819f5cdd 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,4 +1,5 @@
tests/ export-ignore
phpunit.xml export-ignore
build.xml export-ignore
-test export-ignore
\ No newline at end of file
+test export-ignore
+.travis.yml export-ignore
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 371a1385f..ee1d55c7c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,5 @@
/vendor
/composer.lock
-/build/logs
-/build/coverage
+/tests/coverage
/docs
/testing
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
index 10787e9f5..d87ea88fd 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,5 +5,5 @@ php:
- 5.4
- 5.5
-before_script: composer install --dev
-script: phpunit
+before_script: composer install --prefer-source
+script: phpunit --configuration phpunit.xml.dist
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8da0979f1..56cabe6b5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,18 @@
# Changelog
+## 3.0 (released 2013-12-02)
+
+* Fixed spelling of Implicit grant class (Issue #84)
+* Travis CI now tests for PHP 5.5
+* Fixes for checking headers for resource server (Issues #79 and #)
+* The word "bearer" now has a capital "B" in JSON output to match OAuth 2.0 spec
+* All grants no longer remove old sessions by default
+* All grants now support custom access token TTL (Issue #92)
+* All methods which didn't before return a value now return `$this` to support method chaining
+* Removed the build in DB providers - these will be put in their own repos to remove baggage in the main repository
+* Removed support for PHP 5.3 because this library now uses traits and will use other modern PHP features going forward
+* Moved some grant related functions into a trait to reduce duplicate code
+
## 2.1.1 (released 2013-06-02)
* Added conditional `isValid()` flag to check for Authorization header only (thanks @alexmcroberts)
diff --git a/README.md b/README.md
index 907f3a030..79f5deaca 100644
--- a/README.md
+++ b/README.md
@@ -14,6 +14,17 @@ The framework is provided as a Composer package which can be installed by adding
}
```
+#### Master branch
+
+Latest stable version - [![Latest Stable Version](https://poser.pugx.org/league/oauth2-server/v/stable.png)](https://packagist.org/packages/league/oauth2-server)
+Code coverage - [![Coverage Status](https://coveralls.io/repos/php-loep/oauth2-server/badge.png?branch=master)](https://coveralls.io/r/php-loep/oauth2-server?branch=master)
+Downloads - [![Total Downloads](https://poser.pugx.org/league/oauth2-server/downloads.png)](https://packagist.org/packages/league/oauth2-server)
+
+#### Develop branch
+
+Latest unstable version - [![Latest Unstable Version](https://poser.pugx.org/league/oauth2-server/v/unstable.png)](https://packagist.org/packages/league/oauth2-server)
+Code coverage - [![Coverage Status](https://coveralls.io/repos/php-loep/oauth2-server/badge.png?branch=develop)](https://coveralls.io/r/php-loep/oauth2-server?branch=develop)
+
---
The library features 100% unit test code coverage. To run the tests yourself run `phpunit` from the project root.
@@ -47,52 +58,36 @@ If you are using MySQL and want to very quickly implement the library then all o
The wiki has lots of guides on how to use this library, check it out - [https://github.com/php-loep/oauth2-server/wiki](https://github.com/php-loep/oauth2-server/wiki).
-A tutorial on how to use the authorization server can be found at [https://github.com/php-loep/oauth2-server/wiki/Developing-an-OAuth-2.0-authorization-server](https://github.com/php-loep/oauth2-server/wiki/Developing-an-OAuth-2.0-authorization-server).
-
-A tutorial on how to use the resource server to secure an API server can be found at [https://github.com/php-loep/oauth2-server/wiki/Securing-your-API-with-OAuth-2.0](https://github.com/php-loep/oauth2-server/wiki/Securing-your-API-with-OAuth-2.0).
-
-## Future Goals
-
-### Authorization Server
-
-* Support for [JSON web tokens](http://tools.ietf.org/wg/oauth/draft-ietf-oauth-json-web-token/).
-* Support for [SAML assertions](http://tools.ietf.org/wg/oauth/draft-ietf-oauth-saml2-bearer/).
-
----
+A simple tutorial on how to use the authorization server can be found at [https://github.com/php-loep/oauth2-server/wiki/Developing-an-OAuth-2.0-authorization-server](https://github.com/php-loep/oauth2-server/wiki/Developing-an-OAuth-2.0-authorization-server).
-The initial code was developed as part of the [Linkey](http://linkey.blogs.lincoln.ac.uk) project which was funded by [JISC](http://jisc.ac.uk) under the Access and Identity Management programme.
+A simple tutorial on how to use the resource server to secure an API server can be found at [https://github.com/php-loep/oauth2-server/wiki/Securing-your-API-with-OAuth-2.0](https://github.com/php-loep/oauth2-server/wiki/Securing-your-API-with-OAuth-2.0).
-This code is principally developed and maintained by [@alexbilbie](https://twitter.com/).
+## Changelog
+[See the project releases page](https://github.com/php-loep/oauth2-server/releases)
-Credits
--------
+## Contributing
-* [Alex Bilbie](https://github.com/alexbilbie)
-* [Dan Horrigan](https://github.com/dandoescode)
-* [Nick Jackson](https://github.com/jacksonj04)
-* [Michael Gooden](https://github.com/MichaelGooden)
-* [Phil Sturgeon] (https://github.com/philsturgeon)
-* [All contributors](https://github.com/php-loep/oauth2-server/contributors)
+Please see [CONTRIBUTING](https://github.com/php-loep/oauth2-server/blob/master/CONTRIBUTING.md) for details.
-Changelog
----------
+## Support
-[See the changelog file](https://github.com/php-loep/oauth2-server/blob/master/CHANGELOG.md)
+Bugs and feature request are tracked on [GitHub](https://github.com/php-loep/oauth2-server/issues)
-Contributing
-------------
+## License
-Please see [CONTRIBUTING](https://github.com/php-loep/oauth2-server/blob/master/CONTRIBUTING.md) for details.
+This package is released under the MIT License. See the bundled [LICENSE](https://github.com/php-loep/oauth2-server/blob/master/LICENSE) file for details.
-Support
--------
+## Credits
-Bugs and feature request are tracked on [GitHub](https://github.com/php-loep/oauth2-server/issues)
+This code is principally developed and maintained by [Alex Bilbie](https://twitter.com/alexbilbie).
+Special thanks to:
-License
--------
+* [Dan Horrigan](https://github.com/dandoescode)
+* [Nick Jackson](https://github.com/jacksonj04)
+* [Michael Gooden](https://github.com/MichaelGooden)
+* [Phil Sturgeon](https://github.com/philsturgeon)
+* [and all the other contributors](https://github.com/php-loep/oauth2-server/contributors)
-oauth2-server is released under the MIT License. See the bundled
-[LICENSE](https://github.com/php-loep/oauth2-server/blob/master/LICENSE) file for details.
+The initial code was developed as part of the [Linkey](http://linkey.blogs.lincoln.ac.uk) project which was funded by [JISC](http://jisc.ac.uk) under the Access and Identity Management programme.
\ No newline at end of file
diff --git a/build.xml b/build.xml
deleted file mode 100644
index 8008f5021..000000000
--- a/build.xml
+++ /dev/null
@@ -1,142 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/composer.json b/composer.json
index 40db42734..3335690a4 100644
--- a/composer.json
+++ b/composer.json
@@ -1,14 +1,15 @@
{
"name": "league/oauth2-server",
"description": "A lightweight and powerful OAuth 2.0 authorization and resource server library with support for all the core specification grants. This library will allow you to secure your API with OAuth and allow your applications users to approve apps that want to access their data from your API.",
- "version": "2.1.1",
+ "version": "3.0",
"homepage": "https://github.com/php-loep/oauth2-server",
"license": "MIT",
"require": {
- "php": ">=5.3.0"
+ "php": ">=5.4.0"
},
"require-dev": {
- "mockery/mockery": ">=0.7.2"
+ "mockery/mockery": ">=0.7.2",
+ "league/phpunit-coverage-listener": "~1.0"
},
"repositories": [
{
@@ -23,7 +24,10 @@
"authorization",
"authentication",
"resource",
- "api"
+ "api",
+ "auth",
+ "protect",
+ "secure"
],
"authors": [
{
@@ -43,6 +47,6 @@
}
},
"suggest": {
- "zetacomponents/database": "Allows use of the build in PDO storage classes"
+
}
}
\ No newline at end of file
diff --git a/phpunit.xml b/phpunit.xml
index 219005bc8..ec749a085 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -15,17 +15,13 @@
PEAR_INSTALL_DIR
PHP_LIBDIR
- vendor/composer
- vendor/mockery
- vendor/phpunit
+ vendor
tests
testing
-
-
-
-
+
+
-
\ No newline at end of file
+
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
new file mode 100644
index 000000000..bc2e166c8
--- /dev/null
+++ b/phpunit.xml.dist
@@ -0,0 +1,53 @@
+
+
+
+
+ tests/authorization
+
+
+ tests/resource
+
+
+ tests/util
+
+
+
+
+ PEAR_INSTALL_DIR
+ PHP_LIBDIR
+ vendor
+ tests
+ testing
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ League\OAuth2\Server
+
+
+ DtNuuOrBh1QBXVyRqmVldC2Au11DVti9n
+
+
+ https://coveralls.io/api/v1/jobs
+
+
+ /tmp
+
+
+
+
+
+
diff --git a/src/League/OAuth2/Server/Authorization.php b/src/League/OAuth2/Server/Authorization.php
index 32748d8ad..4dec46951 100644
--- a/src/League/OAuth2/Server/Authorization.php
+++ b/src/League/OAuth2/Server/Authorization.php
@@ -261,6 +261,11 @@ public function hasGrantType($identifier)
return (array_key_exists($identifier, $this->grantTypes));
}
+ /**
+ * Returns response types
+ *
+ * @return array
+ */
public function getResponseTypes()
{
return $this->responseTypes;
@@ -287,11 +292,12 @@ public function scopeParamRequired()
/**
* Default scope to be used if none is provided and requireScopeParam is false
- * @var string|array
+ * @param string|array $default
*/
public function setDefaultScope($default = null)
{
$this->defaultScope = $default;
+ return $this;
}
/**
@@ -321,6 +327,7 @@ public function stateParamRequired()
public function requireStateParam($require = true)
{
$this->requireStateParam = $require;
+ return $this;
}
/**
@@ -341,6 +348,7 @@ public function getScopeDelimeter()
public function setScopeDelimeter($scopeDelimeter = ' ')
{
$this->scopeDelimeter = $scopeDelimeter;
+ return $this;
}
/**
@@ -359,6 +367,7 @@ public function getAccessTokenTTL()
public function setAccessTokenTTL($accessTokenTTL = 3600)
{
$this->accessTokenTTL = $accessTokenTTL;
+ return $this;
}
/**
@@ -369,6 +378,7 @@ public function setAccessTokenTTL($accessTokenTTL = 3600)
public function setRequest(Util\RequestInterface $request)
{
$this->request = $request;
+ return $this;
}
/**
@@ -381,7 +391,6 @@ public function getRequest()
if ($this->request === null) {
// @codeCoverageIgnoreStart
$this->request = Request::buildFromGlobals();
-
}
// @codeCoverageIgnoreEnd
diff --git a/src/League/OAuth2/Server/Grant/AuthCode.php b/src/League/OAuth2/Server/Grant/AuthCode.php
index 70447a41d..79a541af6 100644
--- a/src/League/OAuth2/Server/Grant/AuthCode.php
+++ b/src/League/OAuth2/Server/Grant/AuthCode.php
@@ -24,6 +24,8 @@
*/
class AuthCode implements GrantTypeInterface {
+ use GrantTrait;
+
/**
* Grant identifier
* @var string
@@ -64,34 +66,6 @@ public function __construct(Authorization $authServer)
$this->authServer = $authServer;
}
- /**
- * Return the identifier
- * @return string
- */
- public function getIdentifier()
- {
- return $this->identifier;
- }
-
- /**
- * Return the response type
- * @return string
- */
- public function getResponseType()
- {
- return $this->responseType;
- }
-
- /**
- * Override the default access token expire time
- * @param int $accessTokenTTL
- * @return void
- */
- public function setAccessTokenTTL($accessTokenTTL)
- {
- $this->accessTokenTTL = $accessTokenTTL;
- }
-
/**
* Override the default access token expire time
* @param int $authTokenTTL
@@ -276,7 +250,7 @@ public function completeFlow($inputParams = null)
$response = array(
'access_token' => $accessToken,
- 'token_type' => 'bearer',
+ 'token_type' => 'Bearer',
'expires' => $accessTokenExpires,
'expires_in' => $accessTokenExpiresIn
);
@@ -292,4 +266,4 @@ public function completeFlow($inputParams = null)
return $response;
}
-}
\ No newline at end of file
+}
diff --git a/src/League/OAuth2/Server/Grant/ClientCredentials.php b/src/League/OAuth2/Server/Grant/ClientCredentials.php
index 363dfb539..4d53bf23b 100644
--- a/src/League/OAuth2/Server/Grant/ClientCredentials.php
+++ b/src/League/OAuth2/Server/Grant/ClientCredentials.php
@@ -24,6 +24,8 @@
*/
class ClientCredentials implements GrantTypeInterface {
+ use GrantTrait;
+
/**
* Grant identifier
* @var string
@@ -163,7 +165,7 @@ public function completeFlow($inputParams = null)
$response = array(
'access_token' => $accessToken,
- 'token_type' => 'bearer',
+ 'token_type' => 'Bearer',
'expires' => $accessTokenExpires,
'expires_in' => $accessTokenExpiresIn
);
diff --git a/src/League/OAuth2/Server/Grant/GrantTrait.php b/src/League/OAuth2/Server/Grant/GrantTrait.php
new file mode 100644
index 000000000..e052ce57e
--- /dev/null
+++ b/src/League/OAuth2/Server/Grant/GrantTrait.php
@@ -0,0 +1,45 @@
+
+ * @copyright Copyright (c) 2013 PHP League of Extraordinary Packages
+ * @license http://mit-license.org/
+ * @link http://github.com/php-loep/oauth2-server
+ */
+
+namespace League\OAuth2\Server\Grant;
+
+trait GrantTrait {
+
+ /**
+ * Return the identifier
+ * @return string
+ */
+ public function getIdentifier()
+ {
+ return $this->identifier;
+ }
+
+ /**
+ * Return the response type
+ * @return string
+ */
+ public function getResponseType()
+ {
+ return $this->responseType;
+ }
+
+ /**
+ * Override the default access token expire time
+ * @param int $accessTokenTTL
+ * @return self
+ */
+ public function setAccessTokenTTL($accessTokenTTL)
+ {
+ $this->accessTokenTTL = $accessTokenTTL;
+ return $this;
+ }
+
+}
\ No newline at end of file
diff --git a/src/League/OAuth2/Server/Grant/GrantTypeInterface.php b/src/League/OAuth2/Server/Grant/GrantTypeInterface.php
index 2399c5219..ec0b906b4 100644
--- a/src/League/OAuth2/Server/Grant/GrantTypeInterface.php
+++ b/src/League/OAuth2/Server/Grant/GrantTypeInterface.php
@@ -28,18 +28,6 @@ interface GrantTypeInterface
*/
public function __construct(Authorization $authServer);
- /**
- * Returns the grant identifier (used to validate grant_type in League\OAuth2\Server\Authorization::issueAccessToken())
- * @return string
- */
- public function getIdentifier();
-
- /**
- * Returns the response type (used to validate response_type in League\OAuth2\Server\Grant\AuthCode::checkAuthoriseParams())
- * @return null|string
- */
- public function getResponseType();
-
/**
* Complete the grant flow
*
diff --git a/src/League/OAuth2/Server/Grant/Implicit.php b/src/League/OAuth2/Server/Grant/Implicit.php
index c3f39c094..a71afed53 100644
--- a/src/League/OAuth2/Server/Grant/Implicit.php
+++ b/src/League/OAuth2/Server/Grant/Implicit.php
@@ -22,7 +22,9 @@
/**
* Client credentials grant class
*/
-class Implict implements GrantTypeInterface {
+class Implicit implements GrantTypeInterface {
+
+ use GrantTrait;
/**
* Grant identifier
@@ -42,6 +44,12 @@ class Implict implements GrantTypeInterface {
*/
protected $authServer = null;
+ /**
+ * Access token expires in override
+ * @var int
+ */
+ protected $accessTokenTTL = null;
+
/**
* Constructor
* @param Authorization $authServer Authorization server instance
@@ -52,24 +60,6 @@ public function __construct(Authorization $authServer)
$this->authServer = $authServer;
}
- /**
- * Return the identifier
- * @return string
- */
- public function getIdentifier()
- {
- return $this->identifier;
- }
-
- /**
- * Return the response type
- * @return string
- */
- public function getResponseType()
- {
- return $this->responseType;
- }
-
/**
* Complete the client credentials grant
* @param null|array $inputParams
@@ -84,7 +74,8 @@ public function completeFlow($authParams = null)
$accessToken = SecureKey::make();
// Compute expiry time
- $accessTokenExpires = time() + $this->authServer->getAccessTokenTTL();
+ $accessTokenExpiresIn = ($this->accessTokenTTL !== null) ? $this->accessTokenTTL : $this->authServer->getAccessTokenTTL();
+ $accessTokenExpires = time() + $accessTokenExpiresIn;
// Create a new session
$sessionId = $this->authServer->getStorage('session')->createSession($authParams['client_id'], 'user', $authParams['user_id']);
@@ -98,10 +89,13 @@ public function completeFlow($authParams = null)
}
$response = array(
- 'access_token' => $accessToken
+ 'access_token' => $accessToken,
+ 'token_type' => 'Bearer',
+ 'expires' => $accessTokenExpires,
+ 'expires_in' => $accessTokenExpiresIn,
);
return $response;
}
-}
\ No newline at end of file
+}
diff --git a/src/League/OAuth2/Server/Grant/Password.php b/src/League/OAuth2/Server/Grant/Password.php
index 9cbb90e94..a81a62c37 100644
--- a/src/League/OAuth2/Server/Grant/Password.php
+++ b/src/League/OAuth2/Server/Grant/Password.php
@@ -24,6 +24,8 @@
*/
class Password implements GrantTypeInterface {
+ use GrantTrait;
+
/**
* Grant identifier
* @var string
@@ -64,34 +66,6 @@ public function __construct(Authorization $authServer)
$this->authServer = $authServer;
}
- /**
- * Return the identifier
- * @return string
- */
- public function getIdentifier()
- {
- return $this->identifier;
- }
-
- /**
- * Return the response type
- * @return string
- */
- public function getResponseType()
- {
- return $this->responseType;
- }
-
- /**
- * Override the default access token expire time
- * @param int $accessTokenTTL
- * @return void
- */
- public function setAccessTokenTTL($accessTokenTTL)
- {
- $this->accessTokenTTL = $accessTokenTTL;
- }
-
/**
* Set the callback to verify a user's username and password
* @param callable $callback The callback function
@@ -206,7 +180,7 @@ public function completeFlow($inputParams = null)
$response = array(
'access_token' => $accessToken,
- 'token_type' => 'bearer',
+ 'token_type' => 'Bearer',
'expires' => $accessTokenExpires,
'expires_in' => $accessTokenExpiresIn
);
@@ -222,4 +196,4 @@ public function completeFlow($inputParams = null)
return $response;
}
-}
\ No newline at end of file
+}
diff --git a/src/League/OAuth2/Server/Grant/RefreshToken.php b/src/League/OAuth2/Server/Grant/RefreshToken.php
index 99d759b02..4c4664f34 100644
--- a/src/League/OAuth2/Server/Grant/RefreshToken.php
+++ b/src/League/OAuth2/Server/Grant/RefreshToken.php
@@ -24,6 +24,8 @@
*/
class RefreshToken implements GrantTypeInterface {
+ use GrantTrait;
+
/**
* Grant identifier
* @var string
@@ -70,34 +72,6 @@ public function __construct(Authorization $authServer)
$this->authServer = $authServer;
}
- /**
- * Return the identifier
- * @return string
- */
- public function getIdentifier()
- {
- return $this->identifier;
- }
-
- /**
- * Return the response type
- * @return string
- */
- public function getResponseType()
- {
- return $this->responseType;
- }
-
- /**
- * Override the default access token expire time
- * @param int $accessTokenTTL
- * @return void
- */
- public function setAccessTokenTTL($accessTokenTTL)
- {
- $this->accessTokenTTL = $accessTokenTTL;
- }
-
/**
* Set the TTL of the refresh token
* @param int $refreshTokenTTL
diff --git a/src/League/OAuth2/Server/Resource.php b/src/League/OAuth2/Server/Resource.php
index 49f149ee8..553395670 100644
--- a/src/League/OAuth2/Server/Resource.php
+++ b/src/League/OAuth2/Server/Resource.php
@@ -93,6 +93,7 @@ public function __construct(SessionInterface $session)
public function setRequest(RequestInterface $request)
{
$this->request = $request;
+ return $this;
}
/**
@@ -129,6 +130,7 @@ public function getTokenKey()
public function setTokenKey($key)
{
$this->tokenKey = $key;
+ return $this;
}
/**
@@ -242,7 +244,7 @@ public function hasScope($scopes)
* @throws Exception\MissingAccessTokenException Thrown if there is no access token presented
* @return string
*/
- protected function determineAccessToken($headersOnly = false)
+ public function determineAccessToken($headersOnly = false)
{
if ($header = $this->getRequest()->header('Authorization')) {
// Check for special case, because cURL sometimes does an
diff --git a/src/League/OAuth2/Server/Storage/ClientInterface.php b/src/League/OAuth2/Server/Storage/ClientInterface.php
index 725385612..ac1a485c0 100644
--- a/src/League/OAuth2/Server/Storage/ClientInterface.php
+++ b/src/League/OAuth2/Server/Storage/ClientInterface.php
@@ -20,19 +20,21 @@ interface ClientInterface
*
*
* # Client ID + redirect URI
- * SELECT oauth_clients.id, oauth_clients.secret, oauth_client_endpoints.redirect_uri, oauth_clients.name
+ * SELECT oauth_clients.id, oauth_clients.secret, oauth_client_endpoints.redirect_uri, oauth_clients.name,
+ * oauth_clients.auto_approve
* FROM oauth_clients LEFT JOIN oauth_client_endpoints ON oauth_client_endpoints.client_id = oauth_clients.id
* WHERE oauth_clients.id = :clientId AND oauth_client_endpoints.redirect_uri = :redirectUri
*
* # Client ID + client secret
- * SELECT oauth_clients.id, oauth_clients.secret, oauth_clients.name FROM oauth_clients WHERE
- * oauth_clients.id = :clientId AND oauth_clients.secret = :clientSecret
+ * SELECT oauth_clients.id, oauth_clients.secret, oauth_clients.name, oauth_clients.auto_approve FROM oauth_clients
+ * WHERE oauth_clients.id = :clientId AND oauth_clients.secret = :clientSecret
*
* # Client ID + client secret + redirect URI
- * SELECT oauth_clients.id, oauth_clients.secret, oauth_client_endpoints.redirect_uri, oauth_clients.name FROM
- * oauth_clients LEFT JOIN oauth_client_endpoints ON oauth_client_endpoints.client_id = oauth_clients.id
- * WHERE oauth_clients.id = :clientId AND oauth_clients.secret = :clientSecret AND
- * oauth_client_endpoints.redirect_uri = :redirectUri
+ * SELECT oauth_clients.id, oauth_clients.secret, oauth_client_endpoints.redirect_uri, oauth_clients.name,
+ * oauth_clients.auto_approve FROM oauth_clients LEFT JOIN oauth_client_endpoints
+ * ON oauth_client_endpoints.client_id = oauth_clients.id
+ * WHERE oauth_clients.id = :clientId AND oauth_clients.secret = :clientSecret AND
+ * oauth_client_endpoints.redirect_uri = :redirectUri
*
*
* Response:
@@ -44,6 +46,7 @@ interface ClientInterface
* [client secret] => (string) The client secret
* [redirect_uri] => (string) The redirect URI used in this request
* [name] => (string) The name of the client
+ * [auto_approve] => (bool) Whether the client should auto approve
* )
*
*
@@ -54,4 +57,4 @@ interface ClientInterface
* @return bool|array Returns false if the validation fails, array on success
*/
public function getClient($clientId, $clientSecret = null, $redirectUri = null, $grantType = null);
-}
\ No newline at end of file
+}
diff --git a/src/League/OAuth2/Server/Storage/PDO/Client.php b/src/League/OAuth2/Server/Storage/PDO/Client.php
deleted file mode 100644
index 1fcb36421..000000000
--- a/src/League/OAuth2/Server/Storage/PDO/Client.php
+++ /dev/null
@@ -1,45 +0,0 @@
-prepare('SELECT oauth_clients.id, oauth_clients.secret, oauth_client_endpoints.redirect_uri, oauth_clients.name FROM oauth_clients LEFT JOIN oauth_client_endpoints ON oauth_client_endpoints.client_id = oauth_clients.id WHERE oauth_clients.id = :clientId AND oauth_client_endpoints.redirect_uri = :redirectUri');
- $stmt->bindValue(':redirectUri', $redirectUri);
- }
-
- elseif ( ! is_null($clientSecret) && is_null($redirectUri)) {
- $stmt = $db->prepare('SELECT oauth_clients.id, oauth_clients.secret, oauth_clients.name FROM oauth_clients WHERE oauth_clients.id = :clientId AND oauth_clients.secret = :clientSecret');
- $stmt->bindValue(':clientSecret', $clientSecret);
- }
-
- elseif ( ! is_null($clientSecret) && ! is_null($redirectUri)) {
- $stmt = $db->prepare('SELECT oauth_clients.id, oauth_clients.secret, oauth_client_endpoints.redirect_uri, oauth_clients.name FROM oauth_clients LEFT JOIN oauth_client_endpoints ON oauth_client_endpoints.client_id = oauth_clients.id WHERE oauth_clients.id = :clientId AND oauth_clients.secret = :clientSecret AND oauth_client_endpoints.redirect_uri = :redirectUri');
- $stmt->bindValue(':redirectUri', $redirectUri);
- $stmt->bindValue(':clientSecret', $clientSecret);
- }
-
- $stmt->bindValue(':clientId', $clientId);
- $stmt->execute();
-
- $row = $stmt->fetchObject();
-
- if ($row === false) {
- return false;
- }
-
- return array(
- 'client_id' => $row->id,
- 'client_secret' => $row->secret,
- 'redirect_uri' => (isset($row->redirect_uri)) ? $row->redirect_uri : null,
- 'name' => $row->name
- );
- }
-}
\ No newline at end of file
diff --git a/src/League/OAuth2/Server/Storage/PDO/Db.php b/src/League/OAuth2/Server/Storage/PDO/Db.php
deleted file mode 100644
index 5922df194..000000000
--- a/src/League/OAuth2/Server/Storage/PDO/Db.php
+++ /dev/null
@@ -1,17 +0,0 @@
-prepare('SELECT * FROM oauth_scopes WHERE oauth_scopes.scope = :scope');
- $stmt->bindValue(':scope', $scope);
- $stmt->execute();
-
- $row = $stmt->fetchObject();
-
- if ($row === false) {
- return false;
- }
-
- return array(
- 'id' => $row->id,
- 'scope' => $row->scope,
- 'name' => $row->name,
- 'description' => $row->description
- );
-
- }
-}
\ No newline at end of file
diff --git a/src/League/OAuth2/Server/Storage/PDO/Session.php b/src/League/OAuth2/Server/Storage/PDO/Session.php
deleted file mode 100644
index abde8b2bc..000000000
--- a/src/League/OAuth2/Server/Storage/PDO/Session.php
+++ /dev/null
@@ -1,206 +0,0 @@
-prepare('INSERT INTO oauth_sessions (client_id, owner_type, owner_id) VALUE
- (:clientId, :ownerType, :ownerId)');
- $stmt->bindValue(':clientId', $clientId);
- $stmt->bindValue(':ownerType', $ownerType);
- $stmt->bindValue(':ownerId', $ownerId);
- $stmt->execute();
-
- return $db->lastInsertId();
- }
-
- public function deleteSession($clientId, $ownerType, $ownerId)
- {
- $db = \ezcDbInstance::get();
-
- $stmt = $db->prepare('DELETE FROM oauth_sessions WHERE client_id = :clientId AND
- owner_type = :type AND owner_id = :typeId');
- $stmt->bindValue(':clientId', $clientId);
- $stmt->bindValue(':type', $ownerType);
- $stmt->bindValue(':typeId', $ownerId);
- $stmt->execute();
- }
-
- public function associateRedirectUri($sessionId, $redirectUri)
- {
- $db = \ezcDbInstance::get();
-
- $stmt = $db->prepare('INSERT INTO oauth_session_redirects (session_id, redirect_uri)
- VALUE (:sessionId, :redirectUri)');
- $stmt->bindValue(':sessionId', $sessionId);
- $stmt->bindValue(':redirectUri', $redirectUri);
- $stmt->execute();
- }
-
- public function associateAccessToken($sessionId, $accessToken, $expireTime)
- {
- $db = \ezcDbInstance::get();
-
- $stmt = $db->prepare('INSERT INTO oauth_session_access_tokens (session_id, access_token, access_token_expires)
- VALUE (:sessionId, :accessToken, :accessTokenExpire)');
- $stmt->bindValue(':sessionId', $sessionId);
- $stmt->bindValue(':accessToken', $accessToken);
- $stmt->bindValue(':accessTokenExpire', $expireTime);
- $stmt->execute();
-
- return $db->lastInsertId();
- }
-
- public function associateRefreshToken($accessTokenId, $refreshToken, $expireTime, $clientId)
- {
- $db = \ezcDbInstance::get();
-
- $stmt = $db->prepare('INSERT INTO oauth_session_refresh_tokens (session_access_token_id, refresh_token, refresh_token_expires, client_id) VALUE
- (:accessTokenId, :refreshToken, :expireTime, :clientId)');
- $stmt->bindValue(':accessTokenId', $accessTokenId);
- $stmt->bindValue(':refreshToken', $refreshToken);
- $stmt->bindValue(':expireTime', $expireTime);
- $stmt->bindValue(':clientId', $clientId);
- $stmt->execute();
- }
-
- public function associateAuthCode($sessionId, $authCode, $expireTime)
- {
- $db = \ezcDbInstance::get();
-
- $stmt = $db->prepare('INSERT INTO oauth_session_authcodes (session_id, auth_code, auth_code_expires)
- VALUE (:sessionId, :authCode, :authCodeExpires)');
- $stmt->bindValue(':sessionId', $sessionId);
- $stmt->bindValue(':authCode', $authCode);
- $stmt->bindValue(':authCodeExpires', $expireTime);
- $stmt->execute();
-
- return $db->lastInsertId();
- }
-
- public function removeAuthCode($sessionId)
- {
- $db = \ezcDbInstance::get();
-
- $stmt = $db->prepare('DELETE FROM oauth_session_authcodes WHERE session_id = :sessionId');
- $stmt->bindValue(':sessionId', $sessionId);
- $stmt->execute();
- }
-
- public function validateAuthCode($clientId, $redirectUri, $authCode)
- {
- $db = \ezcDbInstance::get();
-
- $stmt = $db->prepare('SELECT oauth_sessions.id AS session_id, oauth_session_authcodes.id AS authcode_id
- FROM oauth_sessions JOIN oauth_session_authcodes ON oauth_session_authcodes.`session_id`
- = oauth_sessions.id JOIN oauth_session_redirects ON oauth_session_redirects.`session_id`
- = oauth_sessions.id WHERE oauth_sessions.client_id = :clientId AND oauth_session_authcodes.`auth_code`
- = :authCode AND `oauth_session_authcodes`.`auth_code_expires` >= :time AND
- `oauth_session_redirects`.`redirect_uri` = :redirectUri');
- $stmt->bindValue(':clientId', $clientId);
- $stmt->bindValue(':redirectUri', $redirectUri);
- $stmt->bindValue(':authCode', $authCode);
- $stmt->bindValue(':time', time());
- $stmt->execute();
-
- $result = $stmt->fetchObject();
-
- return ($result === false) ? false : (array) $result;
- }
-
- public function validateAccessToken($accessToken)
- {
- $db = \ezcDbInstance::get();
-
- $stmt = $db->prepare('SELECT session_id, oauth_sessions.`client_id`, oauth_sessions.`owner_id`, oauth_sessions.`owner_type` FROM `oauth_session_access_tokens` JOIN oauth_sessions ON oauth_sessions.`id` = session_id WHERE access_token = :accessToken AND access_token_expires >= ' . time());
- $stmt->bindValue(':accessToken', $accessToken);
- $stmt->execute();
-
- $result = $stmt->fetchObject();
- return ($result === false) ? false : (array) $result;
- }
-
- public function removeRefreshToken($refreshToken)
- {
- $db = \ezcDbInstance::get();
-
- $stmt = $db->prepare('DELETE FROM `oauth_session_refresh_tokens` WHERE refresh_token = :refreshToken');
- $stmt->bindValue(':refreshToken', $refreshToken);
- $stmt->execute();
- }
-
- public function validateRefreshToken($refreshToken, $clientId)
- {
- $db = \ezcDbInstance::get();
-
- $stmt = $db->prepare('SELECT session_access_token_id FROM `oauth_session_refresh_tokens` WHERE
- refresh_token = :refreshToken AND client_id = :clientId AND refresh_token_expires >= ' . time());
- $stmt->bindValue(':refreshToken', $refreshToken);
- $stmt->bindValue(':clientId', $clientId);
- $stmt->execute();
-
- $result = $stmt->fetchObject();
- return ($result === false) ? false : $result->session_access_token_id;
- }
-
- public function getAccessToken($accessTokenId)
- {
- $db = \ezcDbInstance::get();
-
- $stmt = $db->prepare('SELECT * FROM `oauth_session_access_tokens` WHERE `id` = :accessTokenId');
- $stmt->bindValue(':accessTokenId', $accessTokenId);
- $stmt->execute();
-
- $result = $stmt->fetchObject();
- return ($result === false) ? false : (array) $result;
- }
-
- public function associateAuthCodeScope($authCodeId, $scopeId)
- {
- $db = \ezcDbInstance::get();
-
- $stmt = $db->prepare('INSERT INTO `oauth_session_authcode_scopes` (`oauth_session_authcode_id`, `scope_id`) VALUES (:authCodeId, :scopeId)');
- $stmt->bindValue(':authCodeId', $authCodeId);
- $stmt->bindValue(':scopeId', $scopeId);
- $stmt->execute();
- }
-
- public function getAuthCodeScopes($oauthSessionAuthCodeId)
- {
- $db = \ezcDbInstance::get();
-
- $stmt = $db->prepare('SELECT scope_id FROM `oauth_session_authcode_scopes` WHERE oauth_session_authcode_id = :authCodeId');
- $stmt->bindValue(':authCodeId', $oauthSessionAuthCodeId);
- $stmt->execute();
-
- return $stmt->fetchAll();
- }
-
- public function associateScope($accessTokenId, $scopeId)
- {
- $db = \ezcDbInstance::get();
-
- $stmt = $db->prepare('INSERT INTO `oauth_session_token_scopes` (`session_access_token_id`, `scope_id`)
- VALUE (:accessTokenId, :scopeId)');
- $stmt->bindValue(':accessTokenId', $accessTokenId);
- $stmt->bindValue(':scopeId', $scopeId);
- $stmt->execute();
- }
-
- public function getScopes($accessToken)
- {
- $db = \ezcDbInstance::get();
-
- $stmt = $db->prepare('SELECT oauth_scopes.* FROM oauth_session_token_scopes JOIN oauth_session_access_tokens ON oauth_session_access_tokens.`id` = `oauth_session_token_scopes`.`session_access_token_id` JOIN oauth_scopes ON oauth_scopes.id = `oauth_session_token_scopes`.`scope_id` WHERE access_token = :accessToken');
- $stmt->bindValue(':accessToken', $accessToken);
- $stmt->execute();
-
- return $stmt->fetchAll();
- }
-}
\ No newline at end of file
diff --git a/src/League/OAuth2/Server/Storage/SessionInterface.php b/src/League/OAuth2/Server/Storage/SessionInterface.php
index 08cd4c53e..051c4dbb1 100644
--- a/src/League/OAuth2/Server/Storage/SessionInterface.php
+++ b/src/League/OAuth2/Server/Storage/SessionInterface.php
@@ -74,7 +74,7 @@ public function associateRedirectUri($sessionId, $redirectUri);
* @param int $sessionId The session ID
* @param string $accessToken The access token
* @param int $expireTime Unix timestamp of the access token expiry time
- * @return void
+ * @return int The access token ID
*/
public function associateAccessToken($sessionId, $accessToken, $expireTime);
@@ -315,7 +315,8 @@ public function associateScope($accessTokenId, $scopeId);
*
* array (
* array(
- * 'key' => (string),
+ * 'id' => (int),
+ * 'scope' => (string),
* 'name' => (string),
* 'description' => (string)
* ),
diff --git a/src/League/OAuth2/Server/Util/Request.php b/src/League/OAuth2/Server/Util/Request.php
index 9f66a9209..548bf2526 100644
--- a/src/League/OAuth2/Server/Util/Request.php
+++ b/src/League/OAuth2/Server/Util/Request.php
@@ -39,6 +39,8 @@ public function __construct(array $get = array(), array $post = array(), array $
if (empty($headers)) {
$this->headers = $this->readHeaders();
+ } else {
+ $this->headers = $this->normalizeHeaders($headers);
}
}
@@ -88,7 +90,7 @@ protected function readHeaders()
}
}
- return $headers;
+ return $this->normalizeHeaders($headers);
}
protected function getPropertyValue($property, $index = null, $default = null)
@@ -106,4 +108,39 @@ protected function getPropertyValue($property, $index = null, $default = null)
return $this->{$property}[$index];
}
+
+ /**
+ * Takes all of the headers and normalizes them in a canonical form.
+ *
+ * @param array $headers The request headers.
+ * @return array An arry of headers with the header name normalized
+ */
+ protected function normalizeHeaders(array $headers)
+ {
+ $normalized = array();
+ foreach ($headers as $key => $value) {
+ $normalized[$this->normalizeKey($key)] = $value;
+ }
+
+ return $normalized;
+ }
+
+ /**
+ * Transform header name into canonical form
+ *
+ * Taken from the Slim codebase...
+ *
+ * @param string $key
+ * @return string
+ */
+ protected function normalizeKey($key)
+ {
+ $key = strtolower($key);
+ $key = str_replace(array('-', '_'), ' ', $key);
+ $key = preg_replace('#^http #', '', $key);
+ $key = ucwords($key);
+ $key = str_replace(' ', '-', $key);
+
+ return $key;
+ }
}
\ No newline at end of file
diff --git a/src/League/OAuth2/Server/Util/RequestInterface.php b/src/League/OAuth2/Server/Util/RequestInterface.php
index 820ce911d..00b8dc8ef 100644
--- a/src/League/OAuth2/Server/Util/RequestInterface.php
+++ b/src/League/OAuth2/Server/Util/RequestInterface.php
@@ -14,10 +14,6 @@
interface RequestInterface
{
- public static function buildFromGlobals();
-
- public function __construct(array $get = array(), array $post = array(), array $cookies = array(), array $files = array(), array $server = array(), $headers = array());
-
public function get($index = null);
public function post($index = null);
diff --git a/tests/util/RequestTest.php b/tests/util/RequestTest.php
index 1b4f144b8..205c70ad1 100644
--- a/tests/util/RequestTest.php
+++ b/tests/util/RequestTest.php
@@ -59,6 +59,20 @@ function test_header()
$this->assertEquals(array('Host' => 'foobar.com'), $this->request->header());
}
+ function test_canonical_header()
+ {
+ $request = new League\OAuth2\Server\Util\Request(
+ array('foo' => 'bar'),
+ array('foo' => 'bar'),
+ array('foo' => 'bar'),
+ array('foo' => 'bar'),
+ array('HTTP_HOST' => 'foobar.com'),
+ array('authorization' => 'Bearer ajdfkljadslfjasdlkj')
+ );
+
+ $this->assertEquals('Bearer ajdfkljadslfjasdlkj', $request->header('Authorization'));
+ }
+
/**
* @expectedException InvalidArgumentException
*/