Compare commits

...

572 Commits
0.3.5 ... 3.2.1

Author SHA1 Message Date
Alex Bilbie
4362f17fd6 Update composer.json 2014-07-11 16:21:40 +01:00
Alex Bilbie
6d81c1e57e Merge branch 'develop' 2014-07-11 15:27:19 +01:00
Alex Bilbie
1a88d3f4c5 Ignore build files 2014-07-11 15:21:32 +01:00
Alex Bilbie
4480aa3456 Merge pull request #178 from ushahidi/resource-server-errors
Resource server errors
2014-07-11 11:47:29 +01:00
Woody Gilk
44db2b295f Stop testing stdClass as an argument to hasScope, it is pointless 2014-07-10 17:02:50 -05:00
Woody Gilk
33f4f5b7ab Add $required parameter to hasScope(), triggers InsufficientScopeException 2014-07-10 17:02:16 -05:00
Woody Gilk
e61782975a Copy getExceptionType(), getExceptionMessage(), and getExceptionHttpHeaders() to Resource server 2014-07-10 17:02:16 -05:00
Woody Gilk
d7c1c50269 Throw MissingAccessTokenException in the Resource server when no token exists 2014-07-10 16:59:25 -05:00
Phil Sturgeon
4486b7120f Merge pull request #177 from ushahidi/notabs
Clean up mixed tabs and spaces in test files
2014-07-02 11:40:16 +01:00
Phil Sturgeon
687e794ce3 Merge pull request #182 from acairns/develop
Use utf8_unicode_ci as default collation
2014-07-02 11:39:59 +01:00
Andrew Cairns
c7dfc42d57 Use utf8_unicode_ci as default collation 2014-06-26 15:39:35 +01:00
Woody Gilk
cd767c07fa Replace all tabs with 4 spaces in test files 2014-05-31 16:30:32 -05:00
Alex Bilbie
8e164f4b99 Merge pull request #171 from acairns/develop
Fixing Bearer case for consistency
2014-05-22 09:31:47 +01:00
Andrew Cairns
400d4d8f1e Fixing Bearer case for consistency 2014-05-20 17:13:29 +01:00
Phil Sturgeon
5ffbe6ac37 Delete phpunit.xml 2014-05-13 14:01:13 +01:00
Alex Bilbie
ba5f2840fb Merge branch 'release/3.2' into develop 2014-04-06 22:04:27 +01:00
Alex Bilbie
e8aeaf0777 Merge branch 'release/3.2' 2014-04-06 22:04:19 +01:00
Alex Bilbie
fcc1388aeb Updated change log and version number 2014-04-06 22:04:12 +01:00
Alex Bilbie
d7ddfe6452 Updated docblock 2014-04-06 22:01:56 +01:00
Alex Bilbie
785d3bd21f Merge pull request #151 from giftcards/develop
add the ability to change the algorithm that is used to generate the token strings
2014-04-06 21:13:58 +01:00
Joseph Deray
cc1e78e1ff removed unused use statement 2014-03-11 12:42:26 -04:00
Joseph Deray
b12a1d84df added the ability to change the algorithm used to generate the token strings. added files missing in last commit 2014-03-11 12:41:21 -04:00
Joseph Deray
901aab9deb added the ability to change the algorithm used to generate the token strings 2014-03-11 12:39:09 -04:00
Phil Sturgeon
54ffa58e7b Merge branch 'develop' of github.com:thephpleague/oauth2-server 2014-02-26 18:15:37 -05:00
Phil Sturgeon
5f7c14789b Bumped composer.json version 2014-02-26 18:14:53 -05:00
Phil Sturgeon
0bc16c04d9 Fixed lots of links, and improved readability of links. 2014-02-26 17:45:32 -05:00
Phil Sturgeon
8a2922697f Merge branch 'release/3.1.2'
Conflicts:
	README.md
2014-02-26 17:45:16 -05:00
Phil Sturgeon
1045c70bac Fixed some links in README. 2014-02-26 17:37:33 -05:00
Phil Sturgeon
3c9fd6be27 Updated changelog. 2014-02-26 17:35:34 -05:00
Phil Sturgeon
f83a9a7fa4 Support Authorization header passed as ENV var
Some hosts (at this point I only know of Fortrabbit) require Authorization headers to be passed as an environment variable, which PHP will then shove into . See more: http://fortrabbit.com/docs/essentials/quirks-and-constraints\#authorization-header
2014-02-26 17:28:17 -05:00
Phil Sturgeon
8556f616d3 Ninja 5.6 test 2014-02-11 12:27:35 -05:00
Alex Bilbie
8e7a975f1a Update composer.json 2014-01-23 08:17:44 +00:00
Phil Sturgeon
5829781b38 Update composer.json 2014-01-22 11:28:23 -05:00
Phil Sturgeon
895a379ed3 Update composer.json 2014-01-22 11:27:38 -05:00
Alex Bilbie
25332be3d1 Update .travis.yml 2013-12-23 23:39:49 +00:00
Alex Bilbie
13b15dfa3a Update README.md 2013-12-19 12:33:39 +00:00
Alex Bilbie
7c1b913e49 Travis will now test against HHVM 2013-12-19 12:32:09 +00:00
Alex Bilbie
f563a59ce8 Update CONTRIBUTING.md 2013-12-06 10:50:22 +00:00
Alex Bilbie
324a3f0cdc Merge pull request #123 from alexbilbie/develop
Added CONTRIBUTING.md
2013-12-06 02:49:06 -08:00
Alex Bilbie
f07d169336 Added CONTRIBUTING.md 2013-12-06 10:48:38 +00:00
Alex Bilbie
227707c5dc Merge pull request #122 from andersonamuller/patch-1
Typo in docblock
2013-12-06 02:27:51 -08:00
Alex Bilbie
6d7887dc36 Removed unnecessary line 2013-12-06 10:20:42 +00:00
Alex Bilbie
5870368e33 Added TravisCI's new asset caching http://about.travis-ci.org/blog/2013-12-05-speed-up-your-builds-cache-your-dependencies/ 2013-12-06 10:20:03 +00:00
Anderson Müller
9b9cf79f39 Typo in docblock 2013-12-06 11:17:41 +01:00
Alex Bilbie
619d755008 Removed some tests that randomly fail 2013-12-06 10:17:33 +00:00
Alex Bilbie
2adefdf4c8 Removed section about built in PDO drivers 2013-12-05 21:42:48 +00:00
Alex Bilbie
b5854215a7 Went back to old title 2013-12-05 21:37:24 +00:00
Alex Bilbie
302026d437 Merge branch 'master' of github.com:php-loep/oauth2-server 2013-12-05 21:33:03 +00:00
Alex Bilbie
8d17049877 Merge branch 'refs/heads/master' into develop 2013-12-05 21:32:44 +00:00
Alex Bilbie
1f523c3a08 README updates 2013-12-05 21:32:29 +00:00
Alex Bilbie
924066166c Merge pull request #119 from bitdeli-chef/master
Add a Bitdeli Badge to README
2013-12-05 13:18:26 -08:00
Bitdeli Chef
0dcda992c7 Add a Bitdeli badge to README 2013-12-05 21:20:48 +00:00
Alex Bilbie
70aafb7521 Merge branch 'release/3.1.1' into develop 2013-12-05 21:10:03 +00:00
Alex Bilbie
f59213499c Merge branch 'release/3.1.1' 2013-12-05 21:09:43 +00:00
Alex Bilbie
d9917a57e1 Version bump 2013-12-05 21:09:35 +00:00
Alex Bilbie
dba976d6ac Fixes #108, fixes #114 - ucfirst headers 2013-12-05 20:57:22 +00:00
Alex Bilbie
8fe3ed7eb5 Merge branch 'release/3.1' into develop 2013-12-05 20:43:04 +00:00
Alex Bilbie
9099173db2 Merge branch 'release/3.1' 2013-12-05 20:42:52 +00:00
Alex Bilbie
c6ac1de26b Updated changelog 2013-12-05 20:42:42 +00:00
Alex Bilbie
e55ca5bc05 Version bump 2013-12-05 20:41:51 +00:00
Alex Bilbie
4febb90210 Merge branch 'feature/no-inject-server' into develop 2013-12-05 20:33:08 +00:00
Alex Bilbie
75482c9e20 Test setIdentifier because @philsturgeon didn't 2013-12-05 20:32:46 +00:00
Alex Bilbie
0db8850e81 Merge branch 'refs/heads/develop' into feature/no-inject-server
Conflicts:
	src/League/OAuth2/Server/Grant/GrantTrait.php
2013-12-05 20:28:31 +00:00
Alex Bilbie
9a224bd847 Merge branch 'feature/no-inject-server' into develop 2013-12-05 20:26:22 +00:00
Alex Bilbie
0c36045913 Updated unit tests 2013-12-05 20:25:55 +00:00
Alex Bilbie
262ce23fb9 No longer need to inject auth server into grant 2013-12-05 20:25:50 +00:00
Phil Sturgeon
1419ba8cdc Added GrantTrait::setIdentifier
I found it useful to be able to set the identifier so I could "alias" one for deprecation. Hopefully no issues here @alexbilbie
2013-12-04 17:23:19 -05:00
Alex Bilbie
b55b73c1e8 Merge branch 'release/3.0.1' into develop 2013-12-02 18:52:28 +00:00
Alex Bilbie
e95ae977cc Merge branch 'release/3.0.1' 2013-12-02 18:52:18 +00:00
Alex Bilbie
572e6935a6 Version bump + changelog 2013-12-02 18:49:44 +00:00
Alex Bilbie
dd88426323 Merge branch 'hotfix/travistest'
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
2013-12-02 18:48:09 +00:00
Alex Bilbie
14683bc65e Removed testing of PHP 5.3 2013-12-02 18:47:56 +00:00
Alex Bilbie
1d3bc85423 Merge branch 'release/3.0'
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
2013-12-02 18:44:48 +00:00
Alex Bilbie
10a4bf41ed Version bump 2013-12-02 18:44:08 +00:00
Alex Bilbie
041104e2b1 Updated changelog 2013-12-02 18:43:42 +00:00
Alex Bilbie
031cf3064a Moved some grant related functions into a trait to reduce duplicate code 2013-12-02 18:42:54 +00:00
Alex Bilbie
954ff19823 Removed suggested composer packages 2013-11-29 12:35:29 +00:00
Alex Bilbie
5bb1359ad7 Added some initial changelogs 2013-11-29 12:34:18 +00:00
Alex Bilbie
2bd61f040b Updated minimum PHP requirement to 5.4+ to support future changes 2013-11-29 12:34:08 +00:00
Alex Bilbie
bacc9ce316 Added some extra keywords 2013-11-29 12:23:35 +00:00
Alex Bilbie
5ec2c24b5c Removed build in DB providers, will be included in separate repos 2013-11-29 12:23:05 +00:00
Alex Bilbie
ec9a08af63 Updated .gitignore 2013-11-25 23:59:37 +00:00
Alex Bilbie
6cade987a2 Added html coverage 2013-11-25 23:59:10 +00:00
Alex Bilbie
44408b873f Make sure $this is returned 2013-11-25 23:58:42 +00:00
Alex Bilbie
b4bfa69c88 Removed nyan cat printer 2013-11-25 23:52:45 +00:00
Alex Bilbie
9c3c70a5fb Removed old build script 2013-11-25 23:52:25 +00:00
Alex Bilbie
556e9cc9ab Merge pull request #101 from jackshakes/develop
Update Implicit Grant token TTL and response structure
2013-11-25 15:05:22 -08:00
jlehner
d3158a830b Update Implicit Grant Type with the following:
- Added accessTokenTTL variable and setter method
 - Updated response in the completeFlow method to include all required parameters per OAuth2 spec
 - completeFlow function accounts for local grant TTL override
2013-09-26 14:40:56 -04:00
Alex Bilbie
4a71c376b8 Merge branch 'refs/heads/master' into develop
Conflicts:
	.travis.yml
	README.md
2013-09-26 11:18:10 +01:00
Alex Bilbie
ed427cba37 Merge pull request #92 from hailwood/patch-1
Adding 'auto_approve' to client details array (with updated interface docs)
2013-09-26 03:07:07 -07:00
Alex Bilbie
a358835522 Merge pull request #100 from fotovio/develop
Fixed Issues with Returns and Columns of Fluent Storage
2013-09-26 03:06:11 -07:00
Daniel Schniepp
23627c659e Fixed issues with returns and columns 2013-09-25 16:59:45 +02:00
Alex Bilbie
bee71c1e83 Merge pull request #94 from daveWid/request-interface-cleanup
Request interface cleanup
2013-09-08 03:23:26 -07:00
Alex Bilbie
ad97273455 Gave "bearer" a capital "B". Fixes #96 2013-09-07 18:00:13 +01:00
Alex Bilbie
0b55dc4c01 Gave "bearer" a capital "B" 2013-09-07 17:59:44 +01:00
Alex Bilbie
4985770d07 Gave "bearer" a capital "B" 2013-09-07 17:59:34 +01:00
Dave Widmer
a2bf4e0dfb Removing constructor and buildFromGlobals from RequestInterface. Fixes: #88 2013-09-06 09:14:24 -04:00
Alex Bilbie
cfbb037e07 Removed all code coverage output except text to stdout 2013-09-06 10:39:08 +01:00
Alex Bilbie
6c28fea213 Merge pull request #87 from daveWid/normalize-headers
Normalize headers
2013-09-06 02:36:54 -07:00
Matthew Hailwood
e5dc3001c4 Update ClientInterface.php 2013-09-04 12:43:12 +12:00
Matthew Hailwood
69531c3eb5 Adding auto_approve field to client details array. 2013-09-04 12:38:45 +12:00
Phil Sturgeon
89f3446b98 Merge pull request #79 from reinink/patch-1
Fixed link to authorization server guide.
2013-08-27 09:01:16 -07:00
Dave Widmer
69710a5909 Normalizing headers to a Ucfirst-With-Dashes format. 2013-08-20 11:40:02 -04:00
Phil Sturgeon
85353c5844 Test in PHP 5.5 too 2013-08-08 09:25:17 -04:00
Alex Bilbie
879d98abfb Merge pull request #84 from nhorvath/develop
Update Implicit.php
2013-08-02 11:58:01 -07:00
nhorvath
f612e105bd Update Implicit.php
Fix typo in class name. Change "Implict" to "Implicit"
2013-08-02 14:51:13 -04:00
Alex Bilbie
56f63bb4c0 Added printer, don't test anything in vendor/ 2013-07-30 10:17:59 +01:00
Alex Bilbie
8a42bc796f Removed printer [ci skip] 2013-07-30 10:13:47 +01:00
Alex Bilbie
8fa7b303fa Added Nyan printer for the lolz 2013-07-30 10:10:59 +01:00
Alex Bilbie
55b86e26ad [ci skip] 2013-07-30 10:10:29 +01:00
toopay
e1f09db6af update composer 2013-07-27 07:34:46 +07:00
toopay
1e28faabb9 Blacklist all vendors 2013-07-27 06:56:40 +07:00
toopay
9a3a91760a Update composer 2013-07-27 06:47:21 +07:00
toopay
78d65e102a update travis 2013-07-27 06:47:10 +07:00
toopay
701010b129 Update travis 2013-07-27 06:32:04 +07:00
toopay
84afff9ad2 Default phpunit config that will be ignored if phpunit.xml exists 2013-07-27 06:31:15 +07:00
toopay
cfc61147e1 Add phpunit coverage listener 2013-07-27 06:29:46 +07:00
Jonathan Reinink
66ddba808f Fixed link to authorization server guide. 2013-07-26 10:04:09 -04:00
Alex Bilbie
6324a97118 Added badges [ci skip] 2013-07-26 11:08:24 +01:00
Alex Bilbie
4170f4e841 Update .travis.yml 2013-07-26 10:56:23 +01:00
Alex Bilbie
5c21370691 Added satooshi/php-coveralls to composer.json [ci skip] 2013-07-26 10:55:56 +01:00
Phil Sturgeon
c176c1cddc Added contributors 2013-07-24 13:14:48 -04:00
Alex Bilbie
71b6f2c2bc Merge pull request #78 from philipbrown/fix_fluent_client_argument_default
Fix fluent client argument default
2013-07-18 09:11:31 -07:00
Philip Brown
f1567df802 Set $grantType default 2013-07-17 11:40:06 +01:00
Alex Bilbie
307964d571 Fixed missing $this 2013-06-18 18:27:34 +01:00
Alex Bilbie
a1ca904255 Merge branch 'develop' of github.com:php-loep/oauth2-server into develop 2013-06-18 18:17:02 +01:00
Alex Bilbie
6e045afa26 Merge pull request #70 from gstjohn/master
Fix to docblocks
2013-06-08 04:28:34 -07:00
Garrett St. John
8f15158d1c Fix to docblocks 2013-06-06 14:00:17 -07:00
Garrett St. John
ca4e749986 Fix to docblocks 2013-06-06 13:09:15 -07:00
Alex Bilbie
cc0ab4905a Merge pull request #68 from jasongrimes/public-determineAccessToken
Make determineAccessToken() public
2013-06-06 06:52:12 -07:00
Jason Grimes
e5a48c929b Make determineAccessToken() public in order to check if an access token was sent before checking its validity. 2013-06-05 23:59:29 -04:00
Alex Bilbie
829cef936a mErge branch 'feature/fluent' into develop 2013-06-02 14:59:31 +01:00
Alex Bilbie
f78e05cb08 Anal space fixes 2013-06-02 14:59:05 +01:00
Alex Bilbie
0999bf4de3 Added missing functions 2013-06-02 14:58:59 +01:00
Alex Bilbie
e442253e26 Anal spacing fixes and removed PHP5.4+ specific array syntax 2013-06-02 14:58:52 +01:00
Alex Bilbie
4c4155fdac Added \Illuminate\Support\Facades\DB namespace 2013-06-02 14:54:49 +01:00
Alex Bilbie
d901e90602 Added \Illuminate\Support\Facades\DB namespace 2013-06-02 14:41:38 +01:00
Alex Bilbie
32a7ed38a9 Updated PSR compliance. Added Illuminate\Support\Facades\DB namespace 2013-06-02 14:40:59 +01:00
Alex Bilbie
9dec6c4bfe Added Doctrine/DBAL implementation of storage classes (thanks @inanimatt) 2013-06-02 14:25:06 +01:00
Alex Bilbie
bcfb9ec475 Merge branch 'release/2.1.1' into develop 2013-06-02 13:55:12 +01:00
Alex Bilbie
98be9ab252 Merge branch 'release/2.1.1' 2013-06-02 13:55:01 +01:00
Alex Bilbie
e0f4ccb775 Updated changelog 2013-06-02 13:54:54 +01:00
Alex Bilbie
dca0898c2f Version bump 2013-06-02 13:54:47 +01:00
Alex Bilbie
7da9e1a9d7 Merge pull request #64 from alexmcroberts/develop
Conditional isValid flag to check for Authorization header only. Fixes #57
2013-06-02 05:46:45 -07:00
Alex McRoberts
a4a8f6e661 This fixes #57. By passing in a conditional flag refering to headersOnly, the library would stil respect RFC6749 Section 7 and RFC6750 Section 2. 2013-05-27 21:27:30 -07:00
Alex Bilbie
a9ecca92fc Fixed broken test 2013-05-27 19:38:07 +01:00
Alex Bilbie
47c24e3181 Corrected array key call. Fixes #63 2013-05-27 20:33:07 +02:00
Alex Bilbie
4d36ebd3e7 Added namespaces 2013-05-14 09:50:40 +01:00
Alex Bilbie
0b3a9dc888 Converted PHP 5.4 array syntax to old-skool syntax 2013-05-14 09:46:14 +01:00
Alex Bilbie
1fcdbf45b2 Removed docblocks 2013-05-14 09:45:19 +01:00
Alex Bilbie
94a064e2f4 Added fluent storage from #54 2013-05-14 09:44:12 +01:00
Alex Bilbie
92b6ce3335 Added default value for final argument in ClientInterface::getClient(). Fixes #56 2013-05-14 09:00:36 +01:00
Alex Bilbie
ee9549287e Updated docblocks 2013-05-14 08:59:53 +01:00
Alex Bilbie
4b3e0bf668 Fixed semantic meaning of requireScopeParam() and requireStateParam() by changing their default value to true 2013-05-10 23:01:54 -07:00
Alex Bilbie
05d4b68586 Optimised regex and re-added trim() following conversation in #52 2013-05-10 23:00:47 -07:00
Alex Bilbie
ec9c39c108 Merge branch 'release/2.1' into develop 2013-05-10 17:59:37 -07:00
Alex Bilbie
5d0b295a82 Merge branch 'release/2.1' 2013-05-10 17:59:29 -07:00
Alex Bilbie
9ec5442f90 Updated changelog 2013-05-10 17:59:08 -07:00
Alex Bilbie
4112913813 Version bump 2013-05-10 17:58:57 -07:00
Alex Bilbie
5eb4227709 Merge branch 'feature/auth-code-scopes' into develop. Fixes #44 2013-05-10 17:42:05 -07:00
Alex Bilbie
f5251a6080 Updated sessions 2013-05-10 17:39:29 -07:00
Alex Bilbie
86fb02d218 Added cascading relationship between oauth_sessions_authcodes and oauth_sessions 2013-05-10 17:32:39 -07:00
Alex Bilbie
ef4a138237 Fixed associateAuthCodeScope() query 2013-05-10 17:29:28 -07:00
Alex Bilbie
d531a37412 Don't add scope IDs 2013-05-10 17:26:23 -07:00
Alex Bilbie
ca599437f6 Added oauth_session_authcode_scopes 2013-05-10 17:24:46 -07:00
Alex Bilbie
252afddbd3 Updated oauth_session_authcodes table. Added id field, remove scope_ids field 2013-05-10 17:24:31 -07:00
Alex Bilbie
c57c4b1b4f Fixed key name 2013-05-10 17:19:53 -07:00
Alex Bilbie
ba2dc90f3b Altered associateScope logic 2013-05-10 17:08:20 -07:00
Alex Bilbie
7373f312da Updated variable name 2013-05-10 17:08:10 -07:00
Alex Bilbie
a01810d8fa Updated validateAuthCode in PDO Session 2013-05-10 17:07:29 -07:00
Alex Bilbie
3ea3eb5ebd Implemented getAuthCodeScopes() in PDO Session 2013-05-10 17:07:06 -07:00
Alex Bilbie
11022e16ef Updated validateAuthCode() in SessionInterface 2013-05-10 17:06:44 -07:00
Alex Bilbie
8d06a7b685 Updated getAuthCodeScopes() in SessionInterface 2013-05-10 17:06:05 -07:00
Alex Bilbie
c66c8092f9 Revert "Return the session_id for validateAuthCode instead of an array"
This reverts commit 51138f8738.
2013-05-10 16:57:39 -07:00
Alex Bilbie
591139f44d Added associateAuthCodeScope to PDO 2013-05-10 16:57:18 -07:00
Alex Bilbie
410ad09b5c Updated PDO associateAuthCode 2013-05-10 16:56:38 -07:00
Alex Bilbie
51138f8738 Return the session_id for validateAuthCode instead of an array 2013-05-10 16:53:52 -07:00
Alex Bilbie
aa8d38108f Associate scopes to auth codes in separate method. Creating an auth code now returns an ID 2013-05-10 16:53:21 -07:00
Alex Bilbie
9372cc85d0 Added getAuthCodeScopes() method 2013-05-10 16:50:34 -07:00
Alex Bilbie
accb80289f Added associateAuthCodeScope() method 2013-05-10 16:50:13 -07:00
Alex Bilbie
e591fbb25c Merge branch 'feature/refresh-token-rotation' into develop 2013-05-10 16:13:22 -07:00
Alex Bilbie
fdb89fb5e4 Updated tests 2013-05-10 16:13:11 -07:00
Alex Bilbie
ce51821043 If rotateRefreshTokens() is true then associate new access tokens 2013-05-10 16:13:06 -07:00
Alex Bilbie
eac33d50b3 Added missing semicolon 2013-05-10 16:12:43 -07:00
Alex Bilbie
2552b73b17 Added rotateRefreshTokens() method 2013-05-10 16:00:40 -07:00
Alex Bilbie
8c4019693b Updated @ziege's patch to overcome awkward access token definition requirement (i.e. access token can have a space in it) and also optimised code. Fixes #52 2013-05-10 12:57:34 -07:00
ziege
b88ef82563 Fixed two probems in access token check
1) The method returned the wrong result in case when the access token itself contained the string "Bearer".

2) When using cURL, the request is sometimes send twice (in my case when the first request returned a 404 error), and the Authorization header of the second request is doubled, so that you get a "Authorization: Bearer XXX, Bearer XXX". This case is checked now. (BTW: Tested with the current PHP version 5.4.15 on Windows.)
2013-05-10 20:00:01 +02:00
Alex Bilbie
3e5b4a1735 Move zetacomponents/database to "suggest" in composer.json. Fixes #51 2013-05-10 10:13:17 -07:00
Alex Bilbie
41a7125370 Accidentally used PHP 5.4 style bracket 2013-05-09 11:48:21 -07:00
Alex Bilbie
c40484abb1 Merge branch 'feature/refresh-token-rewrite' into develop 2013-05-09 11:42:31 -07:00
Alex Bilbie
f4bcfee687 Update associated scopes if requested in refresh access token. Fixes #47 2013-05-09 11:42:28 -07:00
Alex Bilbie
6d8eb9d05e Added removeRefreshToken method to SessionInterface 2013-05-09 11:40:29 -07:00
Alex Bilbie
76f2f6a5e1 Don't delete old sessions when issuing new access tokens using the Password or Client Credential grants. Fixes #32 2013-05-09 10:43:44 -07:00
Alex Bilbie
d677b765b2 Renamed scopes.key to scopes.scope. Updated ScopeInterface and PDO/Scope. Fixes #45 2013-05-09 10:23:41 -07:00
Alex Bilbie
7035792325 Allow for multiple default scopes. Fixes #42 2013-05-09 10:15:36 -07:00
Alex Bilbie
351c2e97ea If scope parameter is required and there are not requested scopes AND there is no default scope set then fail
Should have been included in with previous commit
2013-05-09 10:06:44 -07:00
Alex Bilbie
ddefb2ee16 Set the scope parameter to not be required by default. Fixes #43 2013-05-09 10:02:41 -07:00
Alex Bilbie
c3b41a5e8a Merge branch 'release/2.0.5' into develop 2013-05-09 09:47:33 -07:00
Alex Bilbie
b16c58bfe1 mErge branch 'release/2.0.5' 2013-05-09 09:47:21 -07:00
Alex Bilbie
e6d0a19e8f Version bump 2013-05-09 09:47:11 -07:00
Alex Bilbie
2296d09e92 Changelog update 2013-05-09 09:47:07 -07:00
Alex Bilbie
69af252844 Fixed docblock 2013-05-09 09:45:10 -07:00
Alex Bilbie
d9c598af3c Removed DEFAULT '' that has slipped in 2013-05-09 09:38:08 -07:00
Alex Bilbie
3cb79fc2b5 Fixed oauth_session_token_scopes primary key 2013-05-09 09:31:05 -07:00
Alex Bilbie
39379fe5b6 Merge branch 'release/2.0.4' into develop 2013-05-09 08:01:45 -07:00
Alex Bilbie
1375f91e15 Merge branch 'release/2.0.4' 2013-05-09 08:01:33 -07:00
Alex Bilbie
08a7055679 Version bump 2013-05-09 08:01:25 -07:00
Alex Bilbie
9f9a828294 Updated changelog 2013-05-09 08:01:18 -07:00
Alex Bilbie
77fbb2a851 Removed docblocks from session PDO class 2013-05-09 07:55:54 -07:00
Alex Bilbie
c0683586e2 A refresh token should be bound to a client ID 2013-05-09 07:55:10 -07:00
Alex Bilbie
86a483f288 Adding missing column to oauth_session_authcodes 2013-05-09 07:54:09 -07:00
Alex Bilbie
3617a3b37d Renamed primary key in oauth_client_endpoints table 2013-05-09 07:17:41 -07:00
Alex Bilbie
24634aabd7 Merge branch 'release/2.0.3' into develop 2013-05-08 22:09:35 -07:00
Alex Bilbie
ffc286c9f9 mErge branch 'release/2.0.3' 2013-05-08 22:09:18 -07:00
Alex Bilbie
7064442a4c Version bump 2013-05-08 22:09:10 -07:00
Alex Bilbie
68a64e9498 Fixed home page 2013-05-08 22:08:43 -07:00
Alex Bilbie
b04240b9e7 Merge branch 'release/2.0.2' into develop 2013-05-08 19:39:41 -07:00
Alex Bilbie
196a5aea13 Merge branch 'release/2.0.2' 2013-05-08 19:39:28 -07:00
Alex Bilbie
f2f99b429f Version bump 2013-05-08 19:39:15 -07:00
Alex Bilbie
561bda71a9 Link to wiki 2013-05-08 19:38:23 -07:00
Alex Bilbie
6b686a96e7 Updated tutorial links 2013-05-08 19:37:19 -07:00
Alex Bilbie
dbe21cc5a7 Removed null as default for parameters 2013-05-08 19:36:00 -07:00
Alex Bilbie
8b154054c3 Updated License 2013-05-08 19:04:40 -07:00
Alex Bilbie
972e517280 Added example queries and expected responses 2013-05-08 18:37:34 -07:00
Alex Bilbie
ca9760cd36 Updated docblocks and example queries in scope and client storage interfaces 2013-05-08 18:16:24 -07:00
Alex Bilbie
75894fd5bc Test for getClientId 2013-05-08 18:12:18 -07:00
Alex Bilbie
083a44df2e Fixed broken tests following previous commits 2013-05-08 18:10:43 -07:00
Alex Bilbie
1e57533127 Added getClientId method 2013-05-08 18:06:18 -07:00
Alex Bilbie
92e217d0ac Show default parameters 2013-05-08 18:06:09 -07:00
Alex Bilbie
707354348a Changed scope to be a delimiter to a space as required by the spec 2013-05-08 17:42:15 -07:00
Alex Bilbie
f0d493b064 Updated link to wiki 2013-05-08 17:04:17 -07:00
Alex Bilbie
46f0e6c84d Updated docblocks 2013-05-08 17:04:01 -07:00
Alex Bilbie
1dd768545a Updated more docblocks 2013-05-08 14:10:58 -07:00
Alex Bilbie
787c8c566f Updated docblocks 2013-05-08 14:10:48 -07:00
Alex Bilbie
fd10861065 Added missing docblock 2013-05-08 14:10:15 -07:00
Alex Bilbie
0812ca2927 Added missing clientId variable, fixed docblock 2013-05-08 13:59:17 -07:00
Alex Bilbie
a8a375ed1f Anal code style fix 2013-05-08 13:40:15 -07:00
Alex Bilbie
f4b32a2bc6 Optimised tests by removing unused variables and adding further assertions 2013-05-08 13:34:05 -07:00
Alex Bilbie
e2350a65b1 Removed unused functions 2013-05-08 13:24:29 -07:00
Alex Bilbie
437833cd32 Renamed AuthServer to Authorization, renamed ResourceServer to Resource. Updated all tests and other files 2013-05-08 11:42:23 -07:00
Alex Bilbie
1df524ae6e Added missing docblocks 2013-05-08 11:31:38 -07:00
Alex Bilbie
9d1693cf78 Fixed incorrect @link 2013-05-08 11:30:53 -07:00
Alex Bilbie
5524e9b9c8 Moved files into server namespace/folder and updated docblock copyright statements 2013-05-08 11:29:24 -07:00
Alex Bilbie
2d6cc3c98e Renamed package 2013-05-08 11:06:49 -07:00
Alex Bilbie
f4b955ccff Updated tests for new namespace 2013-05-08 11:06:21 -07:00
Alex Bilbie
850473ce40 Renamed namespace to League\OAuth2\ 2013-05-08 11:06:09 -07:00
Alex Bilbie
22d900def1 Updated the changelog 2013-05-08 10:52:13 -07:00
Alex Bilbie
41eef0c3e2 Updated the README 2013-05-08 10:51:56 -07:00
Alex Bilbie
037fd6e4f7 Test for setRefreshTokenTTL 2013-05-08 10:44:03 -07:00
Alex Bilbie
0b927ddfbb Test for setAuthTokenTTL 2013-05-08 10:43:53 -07:00
Alex Bilbie
56b8b7c64e Updated associateRefreshToken to use expire time 2013-05-08 10:38:16 -07:00
Alex Bilbie
0407dbb09b Added refresh token expires column 2013-05-08 10:35:24 -07:00
Alex Bilbie
d6932cbb5e Renamed get/setExpiresIn to get/setAccessTokenTTL 2013-05-08 10:35:13 -07:00
Alex Bilbie
c77484e97b Added refresh token TTL 2013-05-08 10:34:25 -07:00
Alex Bilbie
9f90cd2635 Added method to set the auth token TTL 2013-05-07 15:20:32 -07:00
Alex Bilbie
8fd9e3f312 Renamed setExpiresIn method to accessTokenTTL 2013-05-07 15:16:30 -07:00
Alex Bilbie
5df1338046 New test for getGrantType to test for exception 2013-05-06 15:42:11 -07:00
Alex Bilbie
5d7e0d67cc Updated tests for custom expires in 2013-05-06 15:36:59 -07:00
Alex Bilbie
fdebbac2df Allow grant access token expiresIn override 2013-05-06 15:04:00 -07:00
Alex Bilbie
a561a9d98a Throw an exception if a grant can't be loaded when called in getGrantType 2013-05-06 13:57:46 -07:00
Alex Bilbie
3ac6690ac9 Fixed repo url 2013-05-06 13:13:11 -07:00
Alex Bilbie
e1f83a50ae Merge branch 'refs/heads/develop'
Conflicts:
	composer.json
	src/OAuth2/AuthServer.php
	src/OAuth2/Grant/Password.php
2013-05-06 13:05:39 -07:00
Alex Bilbie
8cdc273dba Fixed composer.json replace key 2013-05-06 12:57:44 -07:00
Alex Bilbie
eada9053ad Updated README 2013-05-06 12:54:16 -07:00
Alex Bilbie
5867774bee Added "replace" key into composer.json 2013-05-06 12:53:39 -07:00
Alex Bilbie
18151d9a8e Version 2.0 baby! 2013-05-06 12:43:50 -07:00
Alex Bilbie
f207a1909f Updated package description 2013-05-06 12:43:38 -07:00
Alex Bilbie
e713d0df9c Renamed package 2013-05-06 12:43:27 -07:00
Alex Bilbie
1ca8a4f4c3 Updated authserver tests 2013-05-06 11:09:36 -07:00
Alex Bilbie
9349425ecd Fixed ResourceServerTest.php 2013-05-06 10:28:49 -07:00
Alex Bilbie
38f6be2aa0 Removed unnecessary methods 2013-05-05 18:22:03 +01:00
Alex Bilbie
d0abd8c295 Fixed getting of session scopes 2013-05-05 18:18:55 +01:00
Alex Bilbie
9be23cf222 Added session scopes 2013-05-05 18:16:28 +01:00
Alex Bilbie
90508a191d Get scopes by access token instead of session ID 2013-05-05 18:14:27 +01:00
Alex Bilbie
10d7d3cb3d Updated response params 2013-05-05 18:11:01 +01:00
Alex Bilbie
89850420f6 Updated query to return session details 2013-05-05 18:09:47 +01:00
Alex Bilbie
9b73eab07c SQL query fix 2013-05-05 18:06:00 +01:00
Alex Bilbie
6897e233d4 Changed variable syntax style to be PSR2 2013-05-05 18:05:46 +01:00
Alex Bilbie
acfadc8993 Actually fixed the bug in validateAccessToken this time 2013-05-05 18:01:00 +01:00
Alex Bilbie
cc81e20206 Bug fix in validateAccessToken 2013-05-05 18:00:08 +01:00
Alex Bilbie
92303c7b26 Implemented validateAccessToken in PDO 2013-05-05 17:58:40 +01:00
Alex Bilbie
2866185349 Updated implicit grant 2013-04-30 15:51:55 +01:00
Alex Bilbie
b9570ac6b0 Fixed getScopes 2013-04-30 15:48:11 +01:00
Alex Bilbie
2a3ae641ab Added getAccessToken, fixed validateRefreshToken docblock 2013-04-30 15:38:48 +01:00
Alex Bilbie
d149490c78 Updated getScopes 2013-04-30 15:32:07 +01:00
Alex Bilbie
c0d8a2c4fb Lots of updated functions 2013-04-30 15:08:20 +01:00
Alex Bilbie
5b03859467 Removed unnecessary code 2013-04-30 15:08:03 +01:00
Alex Bilbie
a661634194 Updated refresh token grant 2013-04-30 15:07:44 +01:00
Alex Bilbie
c73d45fc07 PSR-2 fix 2013-04-30 14:33:30 +01:00
Alex Bilbie
85a53d7470 Fixed Password grant to match past updates 2013-04-30 14:28:59 +01:00
Alex Bilbie
18eea191ed Fixed docblock 2013-04-30 14:28:40 +01:00
Alex Bilbie
14cff9ea44 Added missing db init 2013-04-29 11:59:45 +01:00
Alex Bilbie
1696903b8b Removed extra bracket 2013-04-29 11:53:20 +01:00
Alex Bilbie
13c67c9a40 Updated completeFlow 2013-04-29 11:31:07 +01:00
Alex Bilbie
2dcb81d93c Updated newAuthoriseRequest 2013-04-29 11:25:23 +01:00
Alex Bilbie
b39a9a5edc Added missing DB instance::get() calls 2013-04-29 11:13:31 +01:00
Alex Bilbie
325242e3aa Added missing third parameter 2013-04-29 11:12:35 +01:00
Alex Bilbie
757d2a4fd9 Removed scalar type hinting because it isn't supported 2013-04-29 11:11:16 +01:00
Alex Bilbie
725ab74e5c Updated PDO session 2013-04-29 11:02:32 +01:00
Alex Bilbie
b7ca5d330b Updated associateRefreshToken 2013-04-29 11:02:03 +01:00
Alex Bilbie
4034bea6d1 Updated client credentials grant 2013-04-29 10:36:35 +01:00
Alex Bilbie
6751c4d2fe Fixed mistake from previous commit 2013-04-29 10:35:47 +01:00
Alex Bilbie
53a55d4946 Completely scrapped the old SessionInterface and simplified it 2013-04-29 10:34:11 +01:00
Alex Bilbie
79338d0d75 Delete an associated auth code 2013-04-29 00:02:00 +01:00
Alex Bilbie
17bc6a1512 Comment update 2013-04-29 00:01:51 +01:00
Alex Bilbie
6543ebcd4d Updated updateSession code 2013-04-29 00:01:34 +01:00
Alex Bilbie
351bec6019 Don't associate a scope with a session, we associate it with an access token later 2013-04-29 00:01:07 +01:00
Alex Bilbie
a4715bfc3b Updated create a new session 2013-04-29 00:00:04 +01:00
Alex Bilbie
4ef8030a93 First commit of PDO storage class 2013-04-28 23:58:01 +01:00
Alex Bilbie
7bfbe81f61 Started PDO storage classes 2013-04-28 23:57:50 +01:00
Alex Bilbie
81d6bcf00a Changed params around and removed line breaks 2013-04-28 23:57:29 +01:00
Alex Bilbie
a93a039df3 Lots of table fixes 2013-04-28 23:56:17 +01:00
Alex Bilbie
d0d0d2a7c3 Require zetacompontents/database 2013-04-28 19:06:21 +01:00
Alex Bilbie
6f71439edd Renamed lots of columns 2013-04-23 14:20:38 +01:00
Alex Bilbie
b0d3ba7e70 Revert "Removed session_token_id column from oauth_session_authcode"
This reverts commit 859e6720bf.
2013-04-23 13:56:13 +01:00
Alex Bilbie
a265b027cc Removed stage parameter 2013-04-23 13:52:21 +01:00
Alex Bilbie
859e6720bf Removed session_token_id column from oauth_session_authcode 2013-04-23 13:45:07 +01:00
Alex Bilbie
b7bae1120b Fixed mysql character set 2013-04-23 13:44:21 +01:00
Alex Bilbie
4727a83d84 Removed stage parameter 2013-04-23 13:29:33 +01:00
Alex Bilbie
67641acdff Revert "renamed package to oauth2-server"
This reverts commit 09b74aa61d.
2013-04-17 14:27:09 +01:00
Alex Bilbie
09b74aa61d renamed package to oauth2-server 2013-04-17 14:22:42 +01:00
Alex Bilbie
d75d266376 Updated SQL structure 2013-04-03 15:50:07 +01:00
Alex Bilbie
645d412c02 Removed die(var_dump()) 2013-03-31 13:57:35 +01:00
Alex Bilbie
5f1609577e Added stateParamRequired method 2013-03-31 13:57:24 +01:00
Alex Bilbie
351580d9d8 Added getResponseTypes() method 2013-03-31 13:37:12 +01:00
Alex Bilbie
9c9db978c6 Move authorisation code grant stuff into own grant 2013-03-31 13:37:02 +01:00
Alex Bilbie
a18b4184f5 getScopes() now have the grant type and client ID passed 2013-03-28 10:44:45 +00:00
Alex Bilbie
a7b4f7d66b Added grant to getClient calls. Fixes #21 2013-03-27 14:47:07 +00:00
Alex Bilbie
18933d5075 Merge branch 'feature/http-headers' into develop. Fixes #29 2013-03-27 14:27:47 +00:00
Alex Bilbie
d53abc661c getExceptionHttpHeaders() unit tests 2013-03-27 14:27:06 +00:00
Alex Bilbie
3481ec8aa2 Variable name fixes + little changes to support unit tests 2013-03-27 14:26:46 +00:00
ziege
e563230f10 Method to get all headers for the error response
Method added to get all required headers for the error response, according to the RFC - the correct HTTP status code and the "WWW-Authenticate" header in special cases.
2013-03-27 13:33:09 +00:00
Alex Bilbie
28f85e3bea Fixed broken unit test. Fixes #28 2013-03-27 13:29:11 +00:00
ziege
4cb4d5ba21 Refresh token removed in Client Credentials Grant
As defined in RFC: http://tools.ietf.org/html/rfc6749#section-4.4.3
2013-03-27 13:25:58 +00:00
Alex Bilbie
be478561b6 Fixed unit tests following 74d9946db3 2013-03-22 16:28:45 +00:00
Alex Bilbie
608fdb3ac3 Merge pull request #26 from ziege/patch-1
Storage corrected
2013-03-22 09:27:14 -07:00
ziege
74d9946db3 Storage corrected
Wrong client storage replaced with session storage
2013-03-22 17:24:36 +01:00
Alex Bilbie
521e5b22aa Updated unit tests 2013-03-22 12:43:53 +00:00
Alex Bilbie
85312f6995 Updated ClientCredentials to properly include scopes 2013-03-22 12:36:18 +00:00
Alex Bilbie
f463eb9db1 Style fixes 2013-03-22 11:44:53 +00:00
Alex Bilbie
f4cdfa91c1 Updated Password grant 2013-03-22 11:41:04 +00:00
Alex Bilbie
fe6ecb1dcf Added test_issueAccessToken_HTTP_auth(). Fixes #22 2013-03-22 11:08:52 +00:00
Alex Bilbie
0bf2a5333a Added test_scopeParamRequired() 2013-03-22 11:07:55 +00:00
Alex Bilbie
105a5b2a31 Fixed client_id and client_secret retrieval from request in conformity with the RFC 2013-03-22 10:40:47 +00:00
Alex Bilbie
ecf2f2b9ea Updated ResourceServerTest 2013-03-22 10:37:01 +00:00
Alex Bilbie
493834fcbf Removed base64 decoding of token when present in authorization header. Fixes #23 2013-03-22 10:35:42 +00:00
Alex Bilbie
fb518715ce Updated authserver tests 2013-03-21 16:25:44 +00:00
Alex Bilbie
fce24aa74d Added getDefaultScope method 2013-03-21 16:22:44 +00:00
Alex Bilbie
0c30b9ca66 Added scopeParamRequired method 2013-03-21 16:22:29 +00:00
Alex Bilbie
03aa81450e Renamed method to setDefaultScope 2013-03-21 16:22:16 +00:00
Michael Gooden
6c34535155 First test case.
Signed-off-by: Michael Gooden <michael@bluepointweb.com>
2013-03-21 14:47:32 +00:00
Michael Gooden
5bd62fe942 Add optional default scope parameter.
Signed-off-by: Michael Gooden <me@michaelgooden.net>
2013-03-21 14:47:29 +00:00
lapause
26781d2c38 Corrected wrong return documentation for SessionInterface::validateAuthCode() method 2013-03-21 14:42:51 +00:00
lapause
18e1bb33de Added missing details (return values on failure) to methods of SessionInterface 2013-03-21 14:42:47 +00:00
lapause
3a6468897f Removed obsolete namespace inclusion 2013-03-21 14:42:43 +00:00
lapause
97484eea6a Typo correction in inline doc 2013-03-21 14:42:38 +00:00
Alex Bilbie
a2f87f20b7 Version bump 2013-03-18 16:48:38 +00:00
Alex Bilbie
b6ba08813d Small bug fixes. Fixes #13 2013-03-18 16:46:07 +00:00
Alex Bilbie
3341728eb2 Added implicit grant 2013-03-06 18:01:44 +00:00
Alex Bilbie
6b172d4c27 Made getGrantType public for use with implicit grant 2013-03-06 18:01:34 +00:00
Alex Bilbie
4962762c28 Change from static calls 2013-03-06 18:01:12 +00:00
Alex Bilbie
56b559894c Spelling fix 2013-03-06 17:57:48 +00:00
Alex Bilbie
a9a68a5cc8 Added scope parameter association for clientcredentials and password scope
TODO: Unit tests
2013-03-06 17:18:48 +00:00
Alex Bilbie
542ca52d49 Set a default parameter for getParam 2013-03-06 17:18:13 +00:00
Alex Bilbie
7d0c075b36 It ain't static anymore Jim 2013-03-06 17:18:04 +00:00
Alex Bilbie
c056be3e48 Updated .travis.yml 2013-03-06 17:05:07 +00:00
Alex Bilbie
f3e6f99696 Removed old build files 2013-03-06 17:04:49 +00:00
Alex Bilbie
3ad4010526 Cleaned up .gitignore 2013-03-06 17:04:31 +00:00
Alex Bilbie
07c07ccb5e Removed static functions, inject authserver instance into grants 2013-03-06 16:59:18 +00:00
Alex Bilbie
6a8f8bf7b7 Removed phpunit from composer.json 2013-03-06 16:58:29 +00:00
Alex Bilbie
4917bc228c Updated .gitignore 2013-03-06 16:57:29 +00:00
Alex Bilbie
b58082b536 Merge pull request #10 from MichaelGooden/patch-1
Fix state parameter check typo
2013-03-04 07:43:33 -08:00
Michael Gooden
f70c039275 Fix state parameter check typo 2013-03-04 17:31:59 +02:00
Alex Bilbie
f102b4fb68 Merge branch 'master' of github.com:lncd/OAuth2 2013-03-04 13:22:44 +00:00
Alex Bilbie
c003f699c7 1.0.7 merge 2013-03-04 13:22:01 +00:00
Alex Bilbie
ad78ec838b Version bump 2013-03-04 13:18:34 +00:00
Alex Bilbie
34a7d14557 Added requireStateParam() method. Fixes #9 2013-03-04 13:15:12 +00:00
Alex Bilbie
f5b6b43bef Added requireScopes() method 2013-03-04 13:10:00 +00:00
Michael Gooden
3be3794311 Normalise long function definition.
Signed-off-by: Michael Gooden <michael@bluepointweb.com>
2013-03-04 12:20:11 +00:00
Michael Gooden
710c65aa42 Fix typo in SessionInterface::validateAuthCode. 2013-03-04 12:20:11 +00:00
Alex Bilbie
7d3712a4b1 Added tutorial section 2013-02-28 17:03:15 +00:00
Alex Bilbie
d6955922e9 Added description of grants link 2013-02-28 16:26:06 +00:00
Alex Bilbie
352d49ec5a Fixed broken tests 2013-02-22 16:56:17 +00:00
Alex Bilbie
88616853c4 Fixed broken tests 2013-02-22 16:55:42 +00:00
Alex Bilbie
8eb7dc0d76 Spelling fix 2013-02-22 15:45:49 +00:00
Alex Bilbie
4cc3f97569 Spelling fix 2013-02-22 15:45:42 +00:00
Alex Bilbie
e6545f9dca Merge branch 'release/1.0.6' into develop 2013-02-22 15:42:47 +00:00
Alex Bilbie
7b1b5e94cb Merge branch 'release/1.0.6' 2013-02-22 15:42:38 +00:00
Alex Bilbie
eceb84b978 Version bump 2013-02-22 15:42:32 +00:00
Alex Bilbie
ffac434bcc Added missing state parameter 2013-02-22 15:38:47 +00:00
Alex Bilbie
e74e5061d8 Added tutorial links 2013-02-22 15:21:24 +00:00
Alex Bilbie
cb523e7e34 Added tutorial links 2013-02-22 13:31:05 +00:00
Alex Bilbie
da12c09fda Merge branch 'release/1.0.5' into develop 2013-02-21 17:52:10 +00:00
Alex Bilbie
e04e6d2fae Merge branch 'release/1.0.5' 2013-02-21 17:51:59 +00:00
Alex Bilbie
e555f67c8d v1.0.5 2013-02-21 17:51:51 +00:00
Alex Bilbie
822669fc0c Update getScopes 2013-02-21 17:51:01 +00:00
Alex Bilbie
828bc299b2 Merge branch 'develop' of github.com:lncd/OAuth2 into develop 2013-02-21 17:45:27 +00:00
Alex Bilbie
d22e489626 Merge branch 'release/1.0.4' into develop 2013-02-21 17:44:42 +00:00
Alex Bilbie
ab8bc44849 Merge branch 'release/1.0.4' 2013-02-21 17:44:33 +00:00
Alex Bilbie
4f832e1eb1 Version bump 2013-02-21 17:44:26 +00:00
Alex Bilbie
9add9edcc1 Merge branch 'hotfix/doc-fix' into develop 2013-02-21 17:42:55 +00:00
Alex Bilbie
59e23fb32a Merge branch 'hotfix/doc-fix' 2013-02-21 17:42:45 +00:00
Alex Bilbie
22dcef33da Fixed SQL to get a session\'s scopes 2013-02-21 17:42:30 +00:00
Alex Bilbie
866c598809 Merge branch 'release/1.0.3' into develop 2013-02-20 13:17:48 +00:00
Alex Bilbie
b6d99abcb0 Merge branch 'release/1.0.3' 2013-02-20 13:17:39 +00:00
Alex Bilbie
c692ac8bab Version bump 2013-02-20 13:17:36 +00:00
Alex Bilbie
43d064733f Changed all mentions of authentication to authorization server 2013-02-20 12:40:42 +00:00
Alex Bilbie
6c00aea91d Merge branch 'release/1.0.2' into develop 2013-02-20 12:33:59 +00:00
Alex Bilbie
ddff5f923d Merge branch 'release/1.0.2' 2013-02-20 12:33:50 +00:00
Alex Bilbie
17e72e0cf4 Fixed composer.json version + bump 2013-02-20 12:33:47 +00:00
Julien Chaumond
c25be195f9 Re-order MySQL table creations
Or it fails, at least on my version of MySQL (5.5.29), through
PhpMyAdmin
2013-02-20 12:32:55 +00:00
Julien Chaumond
d842d395d0 Fix composer element 2013-02-20 12:32:55 +00:00
Alex Bilbie
6b2f5944ef Merge branch 'release/1.0.1' into develop 2013-02-19 00:42:49 +00:00
Alex Bilbie
9afa707d54 Merge branch 'release/1.0.1' 2013-02-19 00:42:26 +00:00
Alex Bilbie
33a725606d Version bump 2013-02-19 00:41:37 +00:00
Alex Bilbie
e3f13bf545 Use self::getParam 2013-02-19 00:40:30 +00:00
Alex Bilbie
dbc80a4360 Minor fixes to tests 2013-02-19 00:40:22 +00:00
Alex Bilbie
4b63c20a58 Updated docblocks with correct SQL 2013-02-19 00:26:28 +00:00
Alex Bilbie
8fc0cadae4 Updated composer.json 2013-02-15 17:10:31 +00:00
Alex Bilbie
52bdc79f79 Merge branch 'release/1.0.0' 2013-02-15 17:09:24 +00:00
Alex Bilbie
4c46dd222e Added changelog 2013-02-15 17:08:41 +00:00
Alex Bilbie
6a81bcbefc Updated composer.json 2013-02-15 17:08:27 +00:00
Alex Bilbie
f42f45e42e Updated README 2013-02-15 17:08:21 +00:00
Alex Bilbie
333ce37c97 Removed authserver.md - going to be in docs instead 2013-02-15 16:56:54 +00:00
Alex Bilbie
645fc7210e Removed sillyness 2013-02-15 16:35:28 +00:00
Alex Bilbie
ff37850fea Pretty print github-style codeblocks 2013-02-15 16:33:18 +00:00
Alex Bilbie
57c24953be First draft of auth server docs 2013-02-15 16:30:32 +00:00
Alex Bilbie
92d9435bba Added method to get the exception type 2013-02-15 16:29:00 +00:00
Alex Bilbie
9f6bd64100 Renamed database.sql to mysql.sql 2013-02-15 15:05:40 +00:00
Alex Bilbie
e86d5cb3f1 Broke up grants into their own tests 2013-02-13 20:12:51 +00:00
Alex Bilbie
f818bdf40e Updated docblocks 2013-02-13 19:59:08 +00:00
Alex Bilbie
246732153c Updated grantTypes to use AuthServer::getParam() 2013-02-13 19:39:43 +00:00
Alex Bilbie
92ce378a93 Added more files+folders to ignore 2013-02-13 19:37:40 +00:00
Alex Bilbie
4506037bda Docblock updates 2013-02-13 19:36:56 +00:00
Alex Bilbie
d99002ef2f Renamed variable as $authParams is no longer used 2013-02-13 19:36:10 +00:00
Alex Bilbie
a98dcea6fe Fixed missing fields in oauth_sessions table 2013-02-13 19:35:42 +00:00
Alex Bilbie
1e2d2b3d25 Added AuthServer::getParam() function to reduce repetitive code 2013-02-13 18:25:10 +00:00
Alex Bilbie
0f4546db47 Changed 'oauth_token' to 'access_token' 2013-02-13 17:10:44 +00:00
Alex Bilbie
d0b1034f35 Ignore vendor/phpunit 2013-02-12 20:33:40 +00:00
Alex Bilbie
1cfe10105a Updated docblocks for the two main classes 2013-02-12 20:33:23 +00:00
Alex Bilbie
7739923273 Updated database 2013-02-12 20:33:03 +00:00
Alex Bilbie
e771099568 Removed unnecessary functions 2013-02-12 17:22:15 +00:00
Alex Bilbie
a361fbab14 Finished unit tests for AuthServer 2013-02-12 16:45:45 +00:00
Alex Bilbie
61d1685e84 Minor fixes to password grant 2013-02-12 16:45:33 +00:00
Alex Bilbie
d2267dbd24 Added Password grant 2013-02-12 16:22:14 +00:00
Alex Bilbie
87186d73b7 Removed old client code which can be now be found at lncd/oauth2-client 2013-02-12 16:01:02 +00:00
Alex Bilbie
e76111c2b7 Fixed silliness with access token verification 2013-02-08 11:45:51 +00:00
Alex Bilbie
60b2caf41d Various fixes and tweaks 2013-02-08 11:40:33 +00:00
Alex Bilbie
89f3c35466 Authorization header fixes 2013-02-07 16:16:09 +00:00
Alex Bilbie
55d68bd105 Import namespace for util\request 2013-02-07 14:54:56 +00:00
Alex Bilbie
7293d47234 Merge branch 'feature/reorg' into develop 2013-02-05 16:27:01 +00:00
Alex Bilbie
49e0088f72 Removed old unit tests 2013-02-05 16:26:55 +00:00
Alex Bilbie
37331c4dc8 Added resource server tests 2013-02-05 16:20:56 +00:00
Alex Bilbie
562c257596 Various bug fixes 2013-02-05 16:20:45 +00:00
Alex Bilbie
f481a9baeb Bug fix 2013-02-05 15:59:44 +00:00
Alex Bilbie
322eb15bb5 Revert "Removed unnecessary code"
This reverts commit c89a2346a8.
2013-02-05 15:57:24 +00:00
Alex Bilbie
6b4e51b3a3 Removed unnecessary interfaces 2013-02-05 15:56:03 +00:00
Alex Bilbie
daa352d126 Added resource server tests 2013-02-05 15:55:48 +00:00
Alex Bilbie
e903cbee68 Update request class namespace 2013-02-05 15:55:38 +00:00
Alex Bilbie
920fd9344f Moved request class to util folder 2013-02-05 15:55:04 +00:00
Alex Bilbie
463803f74d Added client credentials grant function 2013-02-05 14:48:10 +00:00
Alex Bilbie
7a646d3a84 Renamed client get function 2013-02-05 14:47:54 +00:00
Alex Bilbie
14a7142ad7 Lots more tests 2013-02-05 10:07:45 +00:00
Alex Bilbie
66bea97e8c Bug fixes based on previous code changes 2013-02-05 10:07:36 +00:00
Alex Bilbie
7214101cfc Ensure Travis installs Mockery 2013-02-04 19:47:11 +00:00
Alex Bilbie
81f3dc9a2b Added new auth server unit tests 2013-02-04 19:46:37 +00:00
Alex Bilbie
c7e9235db3 Added util unit tests 2013-02-04 19:46:29 +00:00
Alex Bilbie
2f010584ef Removed old auth server unit tests 2013-02-04 19:46:21 +00:00
Alex Bilbie
4a50af333d Added code coverage blocks 2013-02-04 19:46:06 +00:00
Alex Bilbie
c89a2346a8 Removed unnecessary code 2013-02-04 19:45:58 +00:00
Alex Bilbie
22f793a16f Fixed getClient call 2013-02-04 19:45:47 +00:00
Alex Bilbie
6edd486b4c Added code coverage ignore blocks to getRequest method 2013-02-04 19:45:34 +00:00
Alex Bilbie
8a6823b78d Removed resource tests, added util tests 2013-02-04 19:45:19 +00:00
Alex Bilbie
d80b2935fc Require mockery for unit tests 2013-02-04 19:45:03 +00:00
Alex Bilbie
d5ae471d94 Throw root exception 2013-02-04 18:58:26 +00:00
Alex Bilbie
9a265f7956 Fixed bad ternary statement. Added missing semicolon 2013-02-04 18:58:17 +00:00
Alex Bilbie
04b8394009 Updated method calls to reflect naming changes 2013-02-04 18:44:19 +00:00
Alex Bilbie
6ae4db460e $request parameter is static 2013-02-04 18:31:13 +00:00
Alex Bilbie
768dfb369c Renamed getCurrentGrantType to getGrantType 2013-02-04 18:30:56 +00:00
Alex Bilbie
0d173d4c35 Renamed methods to prevent ORM conflict 2013-02-04 17:10:30 +00:00
Alex Bilbie
4b8bc76622 Removed properties from Interface 2013-02-04 15:32:33 +00:00
Alex Bilbie
1a1bfd9348 Fix $expiresIn call as static 2013-02-04 15:32:21 +00:00
Alex Bilbie
91bf8cc241 Removed old Authentication folder 2013-02-04 14:42:14 +00:00
Alex Bilbie
3c7fe00130 Renamed some session methods to avoid conflicts with ORM methods 2013-02-04 14:41:40 +00:00
Alex Bilbie
5f8ca89772 Added docblocks to the grant interface 2013-02-04 13:59:34 +00:00
Alex Bilbie
f855b572e8 First commit of new refresh token grant 2013-02-01 16:50:59 +00:00
Alex Bilbie
5e365bb974 Function name fix 2013-02-01 16:02:38 +00:00
Alex Bilbie
85c42db355 Variable name fix 2013-02-01 16:02:04 +00:00
Alex Bilbie
a81c486e0e Spelling fix 2013-02-01 16:00:00 +00:00
Alex Bilbie
e8d43f2087 Anal restyle 2013-02-01 15:59:50 +00:00
Alex Bilbie
5abb84eda0 Validate all client credentials 2013-02-01 15:59:43 +00:00
Alex Bilbie
9fd7ccc137 Added ClientCredentials grant 2013-02-01 15:51:51 +00:00
Alex Bilbie
a3a617171a $grantTypes static access 2013-02-01 15:28:40 +00:00
Alex Bilbie
47731ce901 $expiresIn now static 2013-02-01 15:28:25 +00:00
Alex Bilbie
fcf57abbb2 Removed guzzle dependancy 2013-02-01 15:24:01 +00:00
Alex Bilbie
3aa8465640 Made $grantTypes static to fix ref bug 2013-02-01 15:23:04 +00:00
Alex Bilbie
2a8688b54e Update getRequest calls to static requests 2013-02-01 15:09:15 +00:00
Alex Bilbie
aec9aa908c Made getRequest static 2013-02-01 15:07:47 +00:00
Alex Bilbie
8de2cdb1d9 < PHP5.4 array syntax 2013-02-01 15:02:36 +00:00
Alex Bilbie
2c1dedfe8a Updated grantTypeInterface 2013-02-01 14:56:36 +00:00
Alex Bilbie
d732778f65 Finished AuthCode grant 2013-02-01 14:41:52 +00:00
Alex Bilbie
6eb5db0239 Lots of bug fixes. Some methods and variables made static so they can be accessed by grant classes. 2013-02-01 14:41:10 +00:00
Alex Bilbie
7a851084c6 Initial commit of AuthCode grant type 2013-02-01 10:50:39 +00:00
Alex Bilbie
9b6a92c506 Updated namespace use for Util\SecureKey 2013-01-29 16:53:39 +00:00
Alex Bilbie
781bf985c3 Renamed checkClientAuthoriseParams method to checkAuthoriseParams 2013-01-29 16:25:14 +00:00
Alex Bilbie
87a142cc30 Updated getCurrentGrantType method 2013-01-29 16:24:48 +00:00
Alex Bilbie
4fa37bb356 Updated issueAccessToken method 2013-01-29 16:24:28 +00:00
Alex Bilbie
514aabb838 Updated newAuthoriseRequest method 2013-01-29 16:23:41 +00:00
Alex Bilbie
3cb53448c5 Anal style fix 2013-01-29 16:21:53 +00:00
Alex Bilbie
8ae0dbcf46 Default to 40 characters (as that is what the DB table columns are set to) 2013-01-29 16:21:39 +00:00
Alex Bilbie
ffcad85d95 Renamed functions, changed some doc terms 2013-01-29 16:21:21 +00:00
Alex Bilbie
14b680f6be Moved GrantTypeInterface 2013-01-29 16:18:45 +00:00
Alex Bilbie
74f48d28a4 Added ClientException 2013-01-29 16:18:23 +00:00
Alex Bilbie
cab721923a Set relationship to scope_id 2013-01-29 16:17:30 +00:00
Alex Bilbie
dcd1026a98 Use scope_id instead of the scope name 2013-01-29 16:15:45 +00:00
Alex Bilbie
31c3b495bf Re-added checkClientAuthoriseParams() function 2013-01-29 14:56:17 +00:00
Alex Bilbie
a8b6389092 Updated SessionInterface 2013-01-29 14:55:50 +00:00
Alex Bilbie
5e91b95cb3 Updated ScopeInterface with get method 2013-01-29 14:25:49 +00:00
Alex Bilbie
1ed4c27420 Update ClientInterface with get() method 2013-01-29 14:23:28 +00:00
Alex Bilbie
57f825b0a8 Added exception codes and messages 2013-01-29 14:19:23 +00:00
Alex Bilbie
846a008c76 Explanation of the scope delimiter parameter 2013-01-29 14:18:13 +00:00
Alex Bilbie
a189156f26 Response types are now generated from grants that are injected in 2013-01-29 14:17:56 +00:00
Alex Bilbie
d63c0ea262 Added model variable storage 2013-01-29 14:16:47 +00:00
Alex Bilbie
f74a35074a Added getResponseType parameter 2013-01-29 14:15:05 +00:00
Alex Bilbie
9a41ab8bfc Removed unnecessary column from the table 2013-01-29 14:14:50 +00:00
Alex Bilbie
e415e0051a Version bump 2013-01-24 15:44:07 +00:00
Daniel Horrigan
945d60bd5d Renaming Server and Resource to AuthServer and ResourceServer to be less confusing. 2013-01-22 11:33:09 -05:00
Daniel Horrigan
892ae3a0d3 Started adding some Server methods, adding some Util classes and adding a way to get the token from the Resource 2013-01-22 11:25:51 -05:00
Daniel Horrigan
2727ba0078 Adding a few Getters to the Resource, moving Exceptions and adding some new ones. 2013-01-17 15:19:01 -05:00
Daniel Horrigan
c12472857b Changed Case of Oauth2 namespace to OAuth2 namespace 2013-01-08 16:35:29 -05:00
Daniel Horrigan
385111a1f2 Merge branch 'cleanup' of github.com:dandoescode/OAuth2 into feature/reorg
Conflicts:
	src/OAuth2/Authentication/Server.php
	src/Oauth2/Resource/Server.php
2013-01-08 16:26:17 -05:00
Nick Jackson
608bcb767b Bearer token now correctly base64 decoding 2013-01-08 15:52:17 +00:00
Daniel Horrigan
89e89a73dc Changing 'user_credentials' to password 2013-01-07 10:31:28 -05:00
Daniel Horrigan
2fecadd2a6 Fixing Resource bugs and moving the Request dep to a setter. 2013-01-04 17:21:24 -05:00
Daniel Horrigan
373ddf9f34 Changing Case in namespaces 2013-01-04 14:55:13 -05:00
Daniel Horrigan
a3fd22b3dd Changing Case 2013-01-04 14:44:58 -05:00
Alex Bilbie
e5e132f67a Merge branch 'release/0.4.1' into develop 2013-01-02 22:37:24 +00:00
Alex Bilbie
b4e8c27618 Merge branch 'release/0.4.1' 2013-01-02 22:36:48 +00:00
Alex Bilbie
d65cdaf028 Version bump 2013-01-02 22:36:41 +00:00
Alex Bilbie
5f1779c4e7 Autoload dependencies with autoloader in bootstrap.php 2013-01-02 22:32:49 +00:00
Alex Bilbie
b10613c5e3 Composer install 2013-01-02 21:31:33 +00:00
Alex Bilbie
1c3b319aa6 Altered the script parameter of .travis.yml 2013-01-02 21:22:09 +00:00
Alex Bilbie
1069507ab4 Revert require_once statements 2013-01-02 21:13:32 +00:00
Alex Bilbie
5ca63c921a Updated PHPUnit.xml 2013-01-02 21:13:12 +00:00
Alex Bilbie
943fc1cc82 Possible fix for Travis? 2013-01-02 20:34:09 +00:00
Alex Bilbie
a158883aed Another attempt to fix paths for travis 2013-01-02 20:32:38 +00:00
Alex Bilbie
8aba2b29b8 Better travis debugging 2013-01-02 20:24:45 +00:00
Alex Bilbie
b5e8f9206b Fool. 2013-01-02 20:21:25 +00:00
Alex Bilbie
755a753cb5 Test include path on travis 2013-01-02 20:19:26 +00:00
Alex Bilbie
e99211db31 Moved require_once statement outside of setUp tests method 2013-01-02 20:13:02 +00:00
Alex Bilbie
1142f8d86b Merge branch 'release/0.4' into develop 2013-01-02 19:17:12 +00:00
Alex Bilbie
5772a2f12f Merge branch 'release/0.4' 2013-01-02 19:17:01 +00:00
Alex Bilbie
f351cea442 Version bump 2013-01-02 19:16:51 +00:00
Alex Bilbie
2e1f1c05cf Updated README 2013-01-02 19:16:16 +00:00
Alex Bilbie
7279c8675b Merge branch 'feature/grants' into develop 2013-01-02 19:14:33 +00:00
Alex Bilbie
94945ec49e Added support for refresh tokens, user credentials and client credentials grant. 100% unit test code coverage for authentication. Fixes #2 2013-01-02 19:14:22 +00:00
Alex Bilbie
2b8a27ef47 Ignore code coverage in ../tests folder 2013-01-02 19:12:53 +00:00
Alex Bilbie
7d1aa28087 Added .travis.yml 2012-12-30 21:31:19 +00:00
Daniel Horrigan
31b36f23e7 Starting the reorganization 2012-12-28 15:12:16 -05:00
Alex Bilbie
0fcbeb8158 PSR fixes 2012-12-23 22:13:22 +00:00
Alex Bilbie
0876fd9ad3 Spacing fixes 2012-12-23 22:12:51 +00:00
Alex Bilbie
2545ea7dc1 Added refresh token params and examples 2012-12-23 22:12:44 +00:00
Alex Bilbie
6eeb7e13e4 Updated unit tests 2012-12-23 22:11:33 +00:00
Alex Bilbie
38c50c00b0 PSR fixes 2012-12-23 21:39:42 +00:00
Alex Bilbie
df85c98e53 PSR fixes 2012-12-23 21:36:30 +00:00
Alex Bilbie
0f30b2a803 Removed lots of unnecessary if/else blocks.
Removed null value of expires/expiresIn parameter
2012-12-23 21:21:37 +00:00
Alex Bilbie
f2dc89cdf3 Merge remote-tracking branch 'dhorrigan/master' into feature/grants 2012-12-23 20:34:21 +00:00
Alex Bilbie
c676ba9857 Merge remote-tracking branch 'origin/develop' into develop 2012-12-23 20:33:42 +00:00
Alex Bilbie
d99e871e11 Set a default token ttl of one hour 2012-12-23 20:31:16 +00:00
Daniel Horrigan
0f6f5e2939 Added the user_credentials and refresh_token grants. Fixed expires_in so it is inline with the spec, but added expires for the old usage of expires_in. Made redirect_uri in oauth_sessions ALLOW NULL since user_credential grants don't have a redirect 2012-12-19 16:12:48 -05:00
Alex Bilbie
9fd6f309df Merge branch 'release/0.3.5' into develop 2012-12-12 11:45:07 +00:00
Alex Bilbie
1b29c0f1a0 Merge branch 'release/0.3.2' into develop 2012-11-20 15:30:02 +00:00
76 changed files with 6042 additions and 3400 deletions

3
.gitattributes vendored
View File

@@ -1,4 +1,5 @@
tests/ export-ignore
phpunit.xml export-ignore
build.xml export-ignore
test export-ignore
test export-ignore
.travis.yml export-ignore

10
.gitignore vendored
View File

@@ -1,6 +1,6 @@
/vendor/
/vendor
/composer.lock
/docs/build/
/build/logs/
/build/coverage/
test
/tests/coverage
/docs
/testing
build/coverage

18
.travis.yml Normal file
View File

@@ -0,0 +1,18 @@
language: php
php:
- 5.4
- 5.5
- 5.6
- hhvm
matrix:
allow_failures:
- php: hhvm
before_script: composer install --prefer-source
script: phpunit --configuration phpunit.xml.dist
cache:
directories:
- vendor

124
CHANGELOG.md Normal file
View File

@@ -0,0 +1,124 @@
# Changelog
## 3.2 (released 2014-04-16)
* Added the ability to change the algorithm that is used to generate the token strings (Issue #151)
## 3.1.2 (released 2014-02-26)
* Support Authorization being an environment variable. [See more](http://fortrabbit.com/docs/essentials/quirks-and-constraints#authorization-header)
## 3.1.1 (released 2013-12-05)
* Normalize headers when `getallheaders()` is available (Issues #108 and #114)
## 3.1.0 (released 2013-12-05)
* No longer necessary to inject the authorisation server into a grant, the server will inject itself
* Added test for 1419ba8cdcf18dd034c8db9f7de86a2594b68605
## 3.0.1 (released 2013-12-02)
* Forgot to tell TravisCI from testing PHP 5.3
## 3.0.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)
* Fixed semantic meaning of `requireScopeParam()` and `requireStateParam()` by changing their default value to true
* Updated some duff docblocks
* Corrected array key call in Resource.php (Issue #63)
## 2.1 (released 2013-05-10)
* Moved zetacomponents/database to "suggest" in composer.json. If you rely on this feature you now need to include " zetacomponents/database" into "require" key in your own composer.json. (Issue #51)
* New method in Refresh grant called `rotateRefreshTokens()`. Pass in `true` to issue a new refresh token each time an access token is refreshed. This parameter needs to be set to true in order to request reduced scopes with the new access token. (Issue #47)
* Rename `key` column in oauth_scopes table to `scope` as `key` is a reserved SQL word. (Issue #45)
* The `scope` parameter is no longer required by default as per the RFC. (Issue #43)
* You can now set multiple default scopes by passing an array into `setDefaultScope()`. (Issue #42)
* The password and client credentials grants now allow for multiple sessions per user. (Issue #32)
* Scopes associated to authorization codes are not held in their own table (Issue #44)
* Database schema updates.
## 2.0.5 (released 2013-05-09)
* Fixed `oauth_session_token_scopes` table primary key
* Removed `DEFAULT ''` that has slipped into some tables
* Fixed docblock for `SessionInterface::associateRefreshToken()`
## 2.0.4 (released 2013-05-09)
* Renamed primary key in oauth_client_endpoints table
* Adding missing column to oauth_session_authcodes
* SECURITY FIX: A refresh token should be bound to a client ID
## 2.0.3 (released 2013-05-08)
* Fixed a link to code in composer.json
## 2.0.2 (released 2013-05-08)
* Updated README with wiki guides
* Removed `null` as default parameters in some methods in the storage interfaces
* Fixed license copyright
## 2.0.0 (released 2013-05-08)
**If you're upgrading from v1.0.8 there are lots of breaking changes**
* Rewrote the session storage interface from scratch so methods are more obvious
* Included a PDO driver which implements the storage interfaces so the library is more "get up and go"
* Further normalised the database structure so all sessions no longer contain infomation related to authorization grant (which may or may not be enabled)
* A session can have multiple associated access tokens
* Induvidual grants can have custom expire times for access tokens
* Authorization codes now have a TTL of 10 minutes by default (can be manually set)
* Refresh tokens now have a TTL of one week by default (can be manually set)
* The client credentials grant will no longer gives out refresh tokens as per the specification
## 1.0.8 (released 2013-03-18)
* Fixed check for required state parameter
* Fixed check that user's credentials are correct in Password grant
## 1.0.7 (released 2013-03-04)
* Added method `requireStateParam()`
* Added method `requireScopeParam()`
## 1.0.6 (released 2013-02-22)
* Added links to tutorials in the README
* Added missing `state` parameter request to the `checkAuthoriseParams()` method.
## 1.0.5 (released 2013-02-21)
* Fixed the SQL example for SessionInterface::getScopes()
## 1.0.3 (released 2013-02-20)
* Changed all instances of the "authentication server" to "authorization server"
## 1.0.2 (released 2013-02-20)
* Fixed MySQL create table order
* Fixed version number in composer.json
## 1.0.1 (released 2013-02-19)
* Updated AuthServer.php to use `self::getParam()`
## 1.0.0 (released 2013-02-15)
* First major release

15
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,15 @@
Thanks for contributing to this project.
**Please submit your pull request against the `develop` branch only.**
Please ensure that you run `phpunit` from the project root after you've made any changes.
If you've added something new please create a new unit test, if you've changed something please update any unit tests as appropritate.
We're trying to ensure there is **100%** test code coverage (including testing PHP errors and exceptions) so please ensure any new/updated tests cover all of your changes.
Thank you,
@alexbilbie

114
README.md
View File

@@ -1,47 +1,97 @@
# PHP OAuth Framework
# PHP OAuth 2.0 Server
The goal of this project is to develop a standards compliant [OAuth 2](http://tools.ietf.org/wg/oauth/draft-ietf-oauth-v2/) authentication server, resource server and client library with support for a major OAuth 2 providers.
[![Latest Stable Version](https://poser.pugx.org/league/oauth2-server/v/stable.png)](https://packagist.org/packages/league/oauth2-server) [![Coverage Status](https://coveralls.io/repos/thephpleague/oauth2-server/badge.png?branch=master)](https://coveralls.io/r/thephpleague/oauth2-server?branch=master) [![Total Downloads](https://poser.pugx.org/league/oauth2-server/downloads.png)](https://packagist.org/packages/league/oauth2-server) [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/thephpleague/oauth2-server/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
A standards compliant [OAuth 2.0](http://tools.ietf.org/wg/oauth/draft-ietf-oauth-v2/) authorization server and resource server written in PHP.
## Package Installation
The framework is provided as a Composer package which can be installed by adding the package to your composer.json file:
The framework is provided as a Composer package which can be installed by adding the package to your `composer.json` file:
```javascript
{
"require": {
"lncd\Oauth2": "*"
"require": {
"league/oauth2-server": "3.*"
}
}
```
## Package Integration
### Framework Integrations
Check out the [wiki](https://github.com/lncd/OAuth2/wiki)
## Current Features
### Authentication Server
The authentication server is a flexible class that supports the standard authorization code grant.
### Resource Server
The resource server allows you to secure your API endpoints by checking for a valid OAuth access token in the request and ensuring the token has the correct permission to access resources.
## Future Goals
### Authentication 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/).
### Client support
* Merge in https://github.com/philsturgeon/codeigniter-oauth2
* [Laravel Service Provider](https://packagist.org/packages/lucadegasperi/oauth2-server-laravel) by @lucadegasperi
* [Laravel Eloquent implementation](https://github.com/ScubaClick/scubaclick-oauth2) by @ScubaClick (under development)
---
This code will be developed as part of the [Linkey](http://linkey.blogs.lincoln.ac.uk) project which has been funded by [JISC](http://jisc.ac.uk) under the Access and Identity Management programme.
The library features 100% unit test code coverage. To run the tests yourself run `phpunit` from the project root.
[![Build Status](https://travis-ci.org/thephpleague/oauth2-server.png?branch=master)](https://travis-ci.org/thephpleague/oauth2-server) [master]
[![Build Status](https://travis-ci.org/thephpleague/oauth2-server.png?branch=develop)](https://travis-ci.org/thephpleague/oauth2-server) [develop]
## Current Features
### Authorization Server
The authorization server is a flexible class and the following core specification grants are implemented:
* authorization code ([section 4.1](http://tools.ietf.org/html/rfc6749#section-4.1))
* refresh token ([section 6](http://tools.ietf.org/html/rfc6749#section-6))
* client credentials ([section 2.3.1](http://tools.ietf.org/html/rfc6749#section-2.3.1))
* password (user credentials) ([section 4.3](http://tools.ietf.org/html/rfc6749#section-4.3))
An [overview of the different OAuth 2.0 grants](https://github.com/thephpleague/oauth2-server/wiki/Which-OAuth-2.0-grant-should-I-use%3F) can be found in the [wiki].
### Resource Server
The resource server allows you to secure your API endpoints by checking for a valid OAuth access token in the request and ensuring the token has the correct scope(s) (i.e. permissions) to access resources.
### Custom grants
Custom grants can be created easily by implementing an interface. Check out the [custom grant guide](https://github.com/thephpleague/oauth2-server/wiki/Creating-custom-grants).
## Tutorials and Documentation
* **[Wiki]** - The wiki has lots of guides on how to use this library.
* **[Developing an OAuth-2.0 Authorization Server]** - A simple tutorial on how to use the authorization server.
* **[Securing your API with OAuth 2.0]** - A simple tutorial on how to use the resource server to secure an API server.
[Wiki]: https://github.com/thephpleague/oauth2-server/wiki
[Securing your API with OAuth 2.0]: https://github.com/thephpleague/oauth2-server/wiki/Securing-your-API-with-OAuth-2.0
[Developing an OAuth-2.0 Authorization Server]: https://github.com/thephpleague/oauth2-server/wiki/Developing-an-OAuth-2.0-authorization-server
## Changelog
[See the project releases page](https://github.com/thephpleague/oauth2-server/releases)
## Contributing
Please see [CONTRIBUTING](https://github.com/thephpleague/oauth2-server/blob/master/CONTRIBUTING.md) for details.
## Support
Bugs and feature request are tracked on [GitHub](https://github.com/thephpleague/oauth2-server/issues)
## License
This package is released under the MIT License. See the bundled [LICENSE](https://github.com/thephpleague/oauth2-server/blob/master/LICENSE) file for details.
## Credits
This code is principally developed and maintained by [Alex Bilbie](https://twitter.com/alexbilbie).
Special thanks to:
* [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/thephpleague/oauth2-server/contributors)
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.
[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/thephpleague/oauth2-server/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

142
build.xml
View File

@@ -1,142 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="PHP OAuth 2.0 Server" default="build">
<target name="build" depends="prepare,lint,phploc,pdepend,phpmd-ci,phpcs-ci,phpcpd,composer,phpunit,phpdox,phpcb"/>
<target name="build-parallel" depends="prepare,lint,tools-parallel,phpcb"/>
<target name="minimal" depends="prepare,lint,phploc,pdepend,phpcpd,composer,phpunit,phpdox,phpcb" />
<target name="tools-parallel" description="Run tools in parallel">
<parallel threadCount="2">
<sequential>
<antcall target="pdepend"/>
<antcall target="phpmd-ci"/>
</sequential>
<antcall target="phpcpd"/>
<antcall target="phpcs-ci"/>
<antcall target="phploc"/>
<antcall target="phpdox"/>
</parallel>
</target>
<target name="clean" description="Cleanup build artifacts">
<delete dir="${basedir}/build/api"/>
<delete dir="${basedir}/build/code-browser"/>
<delete dir="${basedir}/build/coverage"/>
<delete dir="${basedir}/build/logs"/>
<delete dir="${basedir}/build/pdepend"/>
</target>
<target name="prepare" depends="clean" description="Prepare for build">
<mkdir dir="${basedir}/build/api"/>
<mkdir dir="${basedir}/build/code-browser"/>
<mkdir dir="${basedir}/build/coverage"/>
<mkdir dir="${basedir}/build/logs"/>
<mkdir dir="${basedir}/build/pdepend"/>
<mkdir dir="${basedir}/build/phpdox"/>
</target>
<target name="lint">
<apply executable="php" failonerror="true">
<arg value="-l" />
<fileset dir="${basedir}/src">
<include name="**/*.php" />
<modified />
</fileset>
</apply>
</target>
<target name="phploc" description="Measure project size using PHPLOC">
<exec executable="phploc">
<arg value="--log-csv" />
<arg value="${basedir}/build/logs/phploc.csv" />
<arg path="${basedir}/src" />
</exec>
</target>
<target name="pdepend" description="Calculate software metrics using PHP_Depend">
<exec executable="pdepend">
<arg value="--jdepend-xml=${basedir}/build/logs/jdepend.xml" />
<arg value="--jdepend-chart=${basedir}/build/pdepend/dependencies.svg" />
<arg value="--overview-pyramid=${basedir}/build/pdepend/overview-pyramid.svg" />
<arg path="${basedir}/src" />
</exec>
</target>
<target name="phpmd" description="Perform project mess detection using PHPMD and print human readable output. Intended for usage on the command line before committing.">
<exec executable="phpmd">
<arg path="${basedir}/src" />
<arg value="text" />
<arg value="${basedir}/build/phpmd.xml" />
</exec>
</target>
<target name="phpmd-ci" description="Perform project mess detection using PHPMD creating a log file for the continuous integration server">
<exec executable="phpmd">
<arg path="${basedir}/src" />
<arg value="xml" />
<arg value="${basedir}/build/phpmd.xml" />
<arg value="--reportfile" />
<arg value="${basedir}/build/logs/pmd.xml" />
</exec>
</target>
<target name="phpcs" description="Find coding standard violations using PHP_CodeSniffer and print human readable output. Intended for usage on the command line before committing.">
<exec executable="phpcs">
<arg value="--standard=${basedir}/build/phpcs.xml" />
<arg value="--extensions=php" />
<arg value="--ignore=third_party/CIUnit" />
<arg path="${basedir}/src" />
</exec>
</target>
<target name="phpcs-ci" description="Find coding standard violations using PHP_CodeSniffer creating a log file for the continuous integration server">
<exec executable="phpcs" output="/dev/null">
<arg value="--report=checkstyle" />
<arg value="--report-file=${basedir}/build/logs/checkstyle.xml" />
<arg value="--standard=${basedir}/build/phpcs.xml" />
<arg value="--extensions=php" />
<arg value="--ignore=third_party/CIUnit" />
<arg path="${basedir}/src" />
</exec>
</target>
<target name="phpcpd" description="Find duplicate code using PHPCPD">
<exec executable="phpcpd">
<arg value="--log-pmd" />
<arg value="${basedir}/build/logs/pmd-cpd.xml" />
<arg path="${basedir}/src" />
</exec>
</target>
<target name="composer" description="Install Composer requirements">
<exec executable="composer.phar" failonerror="true">
<arg value="install" />
<arg value="--dev" />
</exec>
</target>
<target name="phpunit" description="Run unit tests with PHPUnit">
<exec executable="${basedir}/vendor/bin/phpunit" failonerror="true">
<arg value="--configuration" />
<arg value="${basedir}/build/phpunit.xml" />
</exec>
</target>
<target name="phpdox" description="Generate API documentation using phpDox">
<exec executable="phpdox"/>
</target>
<target name="phpcb" description="Aggregate tool output with PHP_CodeBrowser">
<exec executable="phpcb">
<arg value="--log" />
<arg path="${basedir}/build/logs" />
<arg value="--source" />
<arg path="${basedir}/src" />
<arg value="--output" />
<arg path="${basedir}/build/code-browser" />
</exec>
</target>
</project>

View File

@@ -1,8 +0,0 @@
<?xml version="1.0"?>
<ruleset name="PHP_CodeSniffer">
<description>PHP_CodeSniffer configuration</description>
<rule ref="PSR2"/>
</ruleset>

View File

@@ -1,14 +0,0 @@
<ruleset name="OAuth 2.0 Server"
xmlns="http://pmd.sf.net/ruleset/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0
http://pmd.sf.net/ruleset_xml_schema.xsd"
xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
<description>
Ruleset for OAuth 2.0 server
</description>
<!-- Import the entire unused code rule set -->
<rule ref="rulesets/unusedcode.xml" />
</ruleset>

View File

@@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit colors="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" stopOnError="false" stopOnFailure="false" stopOnIncomplete="false" stopOnSkipped="false">
<testsuites>
<testsuite name="Authentication Server">
<directory suffix="test.php">../tests/authentication</directory>
</testsuite>
<testsuite name="Resource Server">
<directory suffix="test.php">../tests/resource</directory>
</testsuite>
</testsuites>
<filter>
<blacklist>
<directory suffix=".php">PEAR_INSTALL_DIR</directory>
<directory suffix=".php">PHP_LIBDIR</directory>
<directory suffix=".php">../vendor/composer</directory>
</blacklist>
</filter>
<logging>
<log type="coverage-html" target="coverage" title="lncd/OAuth" charset="UTF-8" yui="true" highlight="true" lowUpperBound="35" highLowerBound="70"/>
<log type="coverage-clover" target="logs/clover.xml"/>
<log type="junit" target="logs/junit.xml" logIncompleteSkipped="false"/>
</logging>
</phpunit>

View File

@@ -1,20 +1,18 @@
{
"name": "lncd/oauth2",
"description": "OAuth 2.0 Framework",
"version": "0.3.5",
"homepage": "https://github.com/lncd/OAuth2",
"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.",
"license": "MIT",
"require": {
"php": ">=5.3.0",
"guzzle/guzzle": "*"
"php": ">=5.4.0"
},
"require-dev": {
"phpunit/phpunit": "*"
"mockery/mockery": ">=0.7.2",
"league/phpunit-coverage-listener": "~1.0"
},
"repositories": [
{
"type": "git",
"url": "https://github.com/lncd/OAuth2"
"url": "https://github.com/thephpleague/oauth2-server.git"
}
],
"keywords": [
@@ -23,7 +21,11 @@
"server",
"authorization",
"authentication",
"resource"
"resource",
"api",
"auth",
"protect",
"secure"
],
"authors": [
{
@@ -33,12 +35,15 @@
"role": "Developer"
}
],
"replace": {
"lncd/oauth2": "*"
},
"autoload": {
"psr-0": {
"Oauth2": "src/"
"League\\OAuth2\\Server": "src/"
}
},
"suggest": {
"lncd/oauth2-facebook": "Adds support for Facebook as an IDP"
}
}
}

View File

@@ -1,20 +1,20 @@
MIT License
Copyright (C) 2012 University of Lincoln
Copyright (C) 2013 PHP League of Extraordinary Packages
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

53
phpunit.xml.dist Normal file
View File

@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit colors="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" stopOnError="false" stopOnFailure="false" stopOnIncomplete="false" stopOnSkipped="false" bootstrap="tests/Bootstrap.php">
<testsuites>
<testsuite name="Authorization Server">
<directory suffix="Test.php">tests/authorization</directory>
</testsuite>
<testsuite name="Resource Server">
<directory suffix="Test.php">tests/resource</directory>
</testsuite>
<testsuite name="Utility Methods">
<directory suffix="Test.php">tests/util</directory>
</testsuite>
</testsuites>
<filter>
<blacklist>
<directory suffix=".php">PEAR_INSTALL_DIR</directory>
<directory suffix=".php">PHP_LIBDIR</directory>
<directory suffix=".php">vendor</directory>
<directory suffix=".php">tests</directory>
<directory suffix=".php">testing</directory>
</blacklist>
</filter>
<logging>
<log type="coverage-clover" target="/tmp/coverage.xml"/>
<log type="coverage-text" target="php://stdout" showUncoveredFiles="false"/>
</logging>
<listeners>
<listener class="League\PHPUnitCoverageListener\Listener">
<arguments>
<array>
<element key="printer">
<object class="League\PHPUnitCoverageListener\Printer\StdOut"/>
</element>
<element key="hook">
<object class="League\PHPUnitCoverageListener\Hook\Travis"/>
</element>
<element key="namespace">
<string>League\OAuth2\Server</string>
</element>
<element key="repo_token">
<string>DtNuuOrBh1QBXVyRqmVldC2Au11DVti9n</string>
</element>
<element key="target_url">
<string>https://coveralls.io/api/v1/jobs</string>
</element>
<element key="coverage_dir">
<string>/tmp</string>
</element>
</array>
</arguments>
</listener>
</listeners>
</phpunit>

View File

@@ -1,59 +0,0 @@
-- Create syntax for TABLE 'clients'
CREATE TABLE `clients` (
`id` varchar(40) NOT NULL DEFAULT '',
`secret` varchar(40) NOT NULL DEFAULT '',
`name` varchar(255) NOT NULL DEFAULT '',
`auto_approve` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- Create syntax for TABLE 'client_endpoints'
CREATE TABLE `client_endpoints` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`client_id` varchar(40) NOT NULL DEFAULT '',
`redirect_uri` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `client_id` (`client_id`),
CONSTRAINT `client_endpoints_ibfk_1` FOREIGN KEY (`client_id`) REFERENCES `clients` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- Create syntax for TABLE 'oauth_sessions'
CREATE TABLE `oauth_sessions` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`client_id` varchar(40) NOT NULL DEFAULT '',
`redirect_uri` varchar(250) NOT NULL DEFAULT '',
`owner_type` enum('user','client') NOT NULL DEFAULT 'user',
`owner_id` varchar(255) DEFAULT NULL,
`auth_code` varchar(40) DEFAULT '',
`access_token` varchar(40) DEFAULT '',
`access_token_expires` int(10) DEFAULT NULL,
`stage` enum('requested','granted') NOT NULL DEFAULT 'requested',
`first_requested` int(10) unsigned NOT NULL,
`last_updated` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `client_id` (`client_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- Create syntax for TABLE 'scopes'
CREATE TABLE `scopes` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`scope` varchar(255) NOT NULL DEFAULT '',
`name` varchar(255) NOT NULL DEFAULT '',
`description` varchar(255) DEFAULT '',
PRIMARY KEY (`id`),
UNIQUE KEY `scope` (`scope`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- Create syntax for TABLE 'oauth_session_scopes'
CREATE TABLE `oauth_session_scopes` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`session_id` int(11) unsigned NOT NULL,
`access_token` varchar(40) NOT NULL DEFAULT '',
`scope` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `session_id` (`session_id`),
KEY `access_token` (`access_token`),
KEY `scope` (`scope`),
CONSTRAINT `oauth_session_scopes_ibfk_3` FOREIGN KEY (`scope`) REFERENCES `scopes` (`scope`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `oauth_session_scopes_ibfk_4` FOREIGN KEY (`session_id`) REFERENCES `oauth_sessions` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

95
sql/mysql.sql Normal file
View File

@@ -0,0 +1,95 @@
CREATE TABLE `oauth_clients` (
`id` CHAR(40) NOT NULL,
`secret` CHAR(40) NOT NULL,
`name` VARCHAR(255) NOT NULL,
`auto_approve` TINYINT(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `u_oacl_clse_clid` (`secret`,`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE utf8_unicode_ci;
CREATE TABLE `oauth_client_endpoints` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`client_id` char(40) NOT NULL,
`redirect_uri` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
KEY `i_oaclen_clid` (`client_id`),
CONSTRAINT `f_oaclen_clid` FOREIGN KEY (`client_id`) REFERENCES `oauth_clients` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_unicode_ci;
CREATE TABLE `oauth_sessions` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`client_id` char(40) NOT NULL,
`owner_type` enum('user','client') NOT NULL DEFAULT 'user',
`owner_id` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
KEY `i_uase_clid_owty_owid` (`client_id`,`owner_type`,`owner_id`),
CONSTRAINT `f_oase_clid` FOREIGN KEY (`client_id`) REFERENCES `oauth_clients` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_unicode_ci;
CREATE TABLE `oauth_session_access_tokens` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`session_id` int(10) unsigned NOT NULL,
`access_token` char(40) NOT NULL,
`access_token_expires` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `u_oaseacto_acto_seid` (`access_token`,`session_id`),
KEY `f_oaseto_seid` (`session_id`),
CONSTRAINT `f_oaseto_seid` FOREIGN KEY (`session_id`) REFERENCES `oauth_sessions` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_unicode_ci;
CREATE TABLE `oauth_session_authcodes` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`session_id` int(10) unsigned NOT NULL,
`auth_code` char(40) NOT NULL,
`auth_code_expires` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `session_id` (`session_id`),
CONSTRAINT `oauth_session_authcodes_ibfk_1` FOREIGN KEY (`session_id`) REFERENCES `oauth_sessions` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_unicode_ci;
CREATE TABLE `oauth_session_redirects` (
`session_id` int(10) unsigned NOT NULL,
`redirect_uri` varchar(255) NOT NULL,
PRIMARY KEY (`session_id`),
CONSTRAINT `f_oasere_seid` FOREIGN KEY (`session_id`) REFERENCES `oauth_sessions` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_unicode_ci;
CREATE TABLE `oauth_session_refresh_tokens` (
`session_access_token_id` int(10) unsigned NOT NULL,
`refresh_token` char(40) NOT NULL,
`refresh_token_expires` int(10) unsigned NOT NULL,
`client_id` char(40) NOT NULL,
PRIMARY KEY (`session_access_token_id`),
KEY `client_id` (`client_id`),
CONSTRAINT `oauth_session_refresh_tokens_ibfk_1` FOREIGN KEY (`client_id`) REFERENCES `oauth_clients` (`id`) ON DELETE CASCADE,
CONSTRAINT `f_oasetore_setoid` FOREIGN KEY (`session_access_token_id`) REFERENCES `oauth_session_access_tokens` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_unicode_ci;
CREATE TABLE `oauth_scopes` (
`id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
`scope` varchar(255) NOT NULL,
`name` varchar(255) NOT NULL,
`description` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `u_oasc_sc` (`scope`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_unicode_ci;
CREATE TABLE `oauth_session_token_scopes` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`session_access_token_id` int(10) unsigned DEFAULT NULL,
`scope_id` smallint(5) unsigned NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `u_setosc_setoid_scid` (`session_access_token_id`,`scope_id`),
KEY `f_oasetosc_scid` (`scope_id`),
CONSTRAINT `f_oasetosc_scid` FOREIGN KEY (`scope_id`) REFERENCES `oauth_scopes` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION,
CONSTRAINT `f_oasetosc_setoid` FOREIGN KEY (`session_access_token_id`) REFERENCES `oauth_session_access_tokens` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_unicode_ci;
CREATE TABLE `oauth_session_authcode_scopes` (
`oauth_session_authcode_id` int(10) unsigned NOT NULL,
`scope_id` smallint(5) unsigned NOT NULL,
KEY `oauth_session_authcode_id` (`oauth_session_authcode_id`),
KEY `scope_id` (`scope_id`),
CONSTRAINT `oauth_session_authcode_scopes_ibfk_2` FOREIGN KEY (`scope_id`) REFERENCES `oauth_scopes` (`id`) ON DELETE CASCADE,
CONSTRAINT `oauth_session_authcode_scopes_ibfk_1` FOREIGN KEY (`oauth_session_authcode_id`) REFERENCES `oauth_session_authcodes` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_unicode_ci;

View File

@@ -0,0 +1,479 @@
<?php
/**
* OAuth 2.0 Authorization Server
*
* @package php-loep/oauth2-server
* @author Alex Bilbie <hello@alexbilbie.com>
* @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;
use League\OAuth2\Server\Util\Request;
use League\OAuth2\Server\Util\SecureKey;
use League\OAuth2\Server\Storage\SessionInterface;
use League\OAuth2\Server\Storage\ClientInterface;
use League\OAuth2\Server\Storage\ScopeInterface;
use League\OAuth2\Server\Grant\GrantTypeInterface;
/**
* OAuth 2.0 authorization server class
*/
class Authorization
{
/**
* The delimeter between scopes specified in the scope query string parameter
*
* The OAuth 2 specification states it should be a space but most use a comma
* @var string
*/
protected $scopeDelimeter = ' ';
/**
* The TTL (time to live) of an access token in seconds (default: 3600)
* @var integer
*/
protected $accessTokenTTL = 3600;
/**
* The registered grant response types
* @var array
*/
protected $responseTypes = array();
/**
* The client, scope and session storage classes
* @var array
*/
protected $storages = array();
/**
* The registered grant types
* @var array
*/
protected $grantTypes = array();
/**
* Require the "scope" parameter to be in checkAuthoriseParams()
* @var boolean
*/
protected $requireScopeParam = false;
/**
* Default scope(s) to be used if none is provided
* @var string|array
*/
protected $defaultScope = null;
/**
* Require the "state" parameter to be in checkAuthoriseParams()
* @var boolean
*/
protected $requireStateParam = false;
/**
* The request object
* @var Util\RequestInterface
*/
protected $request = null;
/**
* Exception error codes
* @var array
*/
protected static $exceptionCodes = array(
0 => 'invalid_request',
1 => 'unauthorized_client',
2 => 'access_denied',
3 => 'unsupported_response_type',
4 => 'invalid_scope',
5 => 'server_error',
6 => 'temporarily_unavailable',
7 => 'unsupported_grant_type',
8 => 'invalid_client',
9 => 'invalid_grant'
);
/**
* Exception error messages
* @var array
*/
protected static $exceptionMessages = array(
'invalid_request' => 'The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Check the "%s" parameter.',
'unauthorized_client' => 'The client is not authorized to request an access token using this method.',
'access_denied' => 'The resource owner or authorization server denied the request.',
'unsupported_response_type' => 'The authorization server does not support obtaining an access token using this method.',
'invalid_scope' => 'The requested scope is invalid, unknown, or malformed. Check the "%s" scope.',
'server_error' => 'The authorization server encountered an unexpected condition which prevented it from fulfilling the request.',
'temporarily_unavailable' => 'The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server.',
'unsupported_grant_type' => 'The authorization grant type "%s" is not supported by the authorization server',
'invalid_client' => 'Client authentication failed',
'invalid_grant' => 'The provided authorization grant is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client. Check the "%s" parameter.',
'invalid_credentials' => 'The user credentials were incorrect.',
'invalid_refresh' => 'The refresh token is invalid.',
);
/**
* Exception error HTTP status codes
* @var array
*
* RFC 6749, section 4.1.2.1.:
* No 503 status code for 'temporarily_unavailable', because
* "a 503 Service Unavailable HTTP status code cannot be
* returned to the client via an HTTP redirect"
*/
protected static $exceptionHttpStatusCodes = array(
'invalid_request' => 400,
'unauthorized_client' => 400,
'access_denied' => 401,
'unsupported_response_type' => 400,
'invalid_scope' => 400,
'server_error' => 500,
'temporarily_unavailable' => 400,
'unsupported_grant_type' => 501,
'invalid_client' => 401,
'invalid_grant' => 400,
'invalid_credentials' => 400,
'invalid_refresh' => 400,
);
/**
* Get all headers that have to be send with the error response
*
* @param string $error The error message key
* @return array Array with header values
*/
public static function getExceptionHttpHeaders($error)
{
$headers = array();
switch (self::$exceptionHttpStatusCodes[$error]) {
case 401:
$headers[] = 'HTTP/1.1 401 Unauthorized';
break;
case 500:
$headers[] = 'HTTP/1.1 500 Internal Server Error';
break;
case 501:
$headers[] = 'HTTP/1.1 501 Not Implemented';
break;
case 400:
default:
$headers[] = 'HTTP/1.1 400 Bad Request';
}
// Add "WWW-Authenticate" header
//
// RFC 6749, section 5.2.:
// "If the client attempted to authenticate via the 'Authorization'
// request header field, the authorization server MUST
// respond with an HTTP 401 (Unauthorized) status code and
// include the "WWW-Authenticate" response header field
// matching the authentication scheme used by the client.
// @codeCoverageIgnoreStart
if ($error === 'invalid_client') {
$authScheme = null;
$request = new Request();
if ($request->server('PHP_AUTH_USER') !== null) {
$authScheme = 'Basic';
} else {
$authHeader = $request->header('Authorization');
if ($authHeader !== null) {
if (strpos($authHeader, 'Bearer') === 0) {
$authScheme = 'Bearer';
} elseif (strpos($authHeader, 'Basic') === 0) {
$authScheme = 'Basic';
}
}
}
if ($authScheme !== null) {
$headers[] = 'WWW-Authenticate: '.$authScheme.' realm=""';
}
}
// @codeCoverageIgnoreEnd
return $headers;
}
/**
* Get an exception message
*
* @param string $error The error message key
* @return string The error message
*/
public static function getExceptionMessage($error = '')
{
return self::$exceptionMessages[$error];
}
/**
* Get an exception code
*
* @param integer $code The exception code
* @return string The exception code type
*/
public static function getExceptionType($code = 0)
{
return self::$exceptionCodes[$code];
}
/**
* Create a new OAuth2 authorization server
*
* @param ClientInterface $client A class which inherits from Storage/ClientInterface
* @param SessionInterface $session A class which inherits from Storage/SessionInterface
* @param ScopeInterface $scope A class which inherits from Storage/ScopeInterface
*/
public function __construct(ClientInterface $client, SessionInterface $session, ScopeInterface $scope)
{
$this->storages = array(
'client' => $client,
'session' => $session,
'scope' => $scope
);
}
/**
* Enable support for a grant
* @param GrantTypeInterface $grantType A grant class which conforms to Interface/GrantTypeInterface
* @param null|string $identifier An identifier for the grant (autodetected if not passed)
*/
public function addGrantType(GrantTypeInterface $grantType, $identifier = null)
{
if (is_null($identifier)) {
$identifier = $grantType->getIdentifier();
}
// Inject server into grant
$grantType->setAuthorizationServer($this);
$this->grantTypes[$identifier] = $grantType;
if ( ! is_null($grantType->getResponseType())) {
$this->responseTypes[] = $grantType->getResponseType();
}
}
/**
* Check if a grant type has been enabled
* @param string $identifier The grant type identifier
* @return boolean Returns "true" if enabled, "false" if not
*/
public function hasGrantType($identifier)
{
return (array_key_exists($identifier, $this->grantTypes));
}
/**
* Returns response types
*
* @return array
*/
public function getResponseTypes()
{
return $this->responseTypes;
}
/**
* Require the "scope" paremter in checkAuthoriseParams()
* @param boolean $require
* @return void
*/
public function requireScopeParam($require = true)
{
$this->requireScopeParam = $require;
}
/**
* Is the scope parameter required?
* @return bool
*/
public function scopeParamRequired()
{
return $this->requireScopeParam;
}
/**
* Default scope to be used if none is provided and requireScopeParam is false
* @param string|array $default
*/
public function setDefaultScope($default = null)
{
$this->defaultScope = $default;
return $this;
}
/**
* Default scope to be used if none is provided and requireScopeParam is false
* @return string|null
*/
public function getDefaultScope()
{
return $this->defaultScope;
}
/**
* Require the "state" paremter in checkAuthoriseParams()
* @param boolean $require
* @return void
*/
public function stateParamRequired()
{
return $this->requireStateParam;
}
/**
* Require the "state" paremter in checkAuthoriseParams()
* @param boolean $require
* @return void
*/
public function requireStateParam($require = true)
{
$this->requireStateParam = $require;
return $this;
}
/**
* Get the scope delimeter
*
* @return string The scope delimiter (default: ",")
*/
public function getScopeDelimeter()
{
return $this->scopeDelimeter;
}
/**
* Set the scope delimiter
*
* @param string $scopeDelimeter
*/
public function setScopeDelimeter($scopeDelimeter = ' ')
{
$this->scopeDelimeter = $scopeDelimeter;
return $this;
}
/**
* Get the TTL for an access token
* @return int The TTL
*/
public function getAccessTokenTTL()
{
return $this->accessTokenTTL;
}
/**
* Set the TTL for an access token
* @param int $accessTokenTTL The new TTL
*/
public function setAccessTokenTTL($accessTokenTTL = 3600)
{
$this->accessTokenTTL = $accessTokenTTL;
return $this;
}
/**
* Sets the Request Object
*
* @param Util\RequestInterface The Request Object
*/
public function setRequest(Util\RequestInterface $request)
{
$this->request = $request;
return $this;
}
/**
* Gets the Request object. It will create one from the globals if one is not set.
*
* @return Util\RequestInterface
*/
public function getRequest()
{
if ($this->request === null) {
// @codeCoverageIgnoreStart
$this->request = Request::buildFromGlobals();
}
// @codeCoverageIgnoreEnd
return $this->request;
}
/**
* Return a storage class
* @param string $obj The class required
* @return Storage\ClientInterface|Storage\ScopeInterface|Storage\SessionInterface
*/
public function getStorage($obj)
{
return $this->storages[$obj];
}
/**
* Issue an access token
*
* @param array $inputParams Optional array of parsed $_POST keys
* @return array Authorise request parameters
*/
public function issueAccessToken($inputParams = array())
{
$grantType = $this->getParam('grant_type', 'post', $inputParams);
if (is_null($grantType)) {
throw new Exception\ClientException(sprintf(self::$exceptionMessages['invalid_request'], 'grant_type'), 0);
}
// Ensure grant type is one that is recognised and is enabled
if ( ! in_array($grantType, array_keys($this->grantTypes))) {
throw new Exception\ClientException(sprintf(self::$exceptionMessages['unsupported_grant_type'], $grantType), 7);
}
// Complete the flow
return $this->getGrantType($grantType)->completeFlow($inputParams);
}
/**
* Return a grant type class
* @param string $grantType The grant type identifer
* @return Grant\AuthCode|Grant\ClientCredentials|Grant\Implict|Grant\Password|Grant\RefreshToken
*/
public function getGrantType($grantType)
{
if (isset($this->grantTypes[$grantType])) {
return $this->grantTypes[$grantType];
}
throw new Exception\InvalidGrantTypeException(sprintf(self::$exceptionMessages['unsupported_grant_type'], $grantType), 9);
}
/**
* Get a parameter from passed input parameters or the Request class
* @param string|array $param Required parameter
* @param string $method Get/put/post/delete
* @param array $inputParams Passed input parameters
* @return mixed 'Null' if parameter is missing
*/
public function getParam($param = '', $method = 'get', $inputParams = array(), $default = null)
{
if (is_string($param)) {
if (isset($inputParams[$param])) {
return $inputParams[$param];
} elseif ($param === 'client_id' && ! is_null($clientId = $this->getRequest()->server('PHP_AUTH_USER'))) {
return $clientId;
} elseif ($param === 'client_secret' && ! is_null($clientSecret = $this->getRequest()->server('PHP_AUTH_PW'))) {
return $clientSecret;
} else {
return $this->getRequest()->{$method}($param, $default);
}
} else {
$response = array();
foreach ($param as $p) {
$response[$p] = $this->getParam($p, $method, $inputParams);
}
return $response;
}
}
}

View File

@@ -0,0 +1,20 @@
<?php
/**
* OAuth 2.0 Client Exception
*
* @package php-loep/oauth2-server
* @author Alex Bilbie <hello@alexbilbie.com>
* @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\Exception;
/**
* ClientException Exception
*/
class ClientException extends OAuth2Exception
{
}

View File

@@ -0,0 +1,20 @@
<?php
/**
* OAuth 2.0 Insufficient Scope Exception
*
* @package php-loep/oauth2-server
* @author Woody Gilk <woody@shadowhand.me>
* @copyright Copyright (c) 2014 PHP League of Extraordinary Packages
* @license http://mit-license.org/
* @link http://github.com/php-loep/oauth2-server
*/
namespace League\OAuth2\Server\Exception;
/**
* InsufficientScope Exception
*/
class InsufficientScopeException extends OAuth2Exception
{
}

View File

@@ -0,0 +1,20 @@
<?php
/**
* OAuth 2.0 Invalid Access Token Exception
*
* @package php-loep/oauth2-server
* @author Alex Bilbie <hello@alexbilbie.com>
* @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\Exception;
/**
* InvalidAccessToken Exception
*/
class InvalidAccessTokenException extends OAuth2Exception
{
}

View File

@@ -0,0 +1,20 @@
<?php
/**
* OAuth 2.0 Invalid Grant Type Exception
*
* @package php-loep/oauth2-server
* @author Alex Bilbie <hello@alexbilbie.com>
* @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\Exception;
/**
* InvalidGrantTypeException Exception
*/
class InvalidGrantTypeException extends OAuth2Exception
{
}

View File

@@ -0,0 +1,20 @@
<?php
/**
* OAuth 2.0 Missing Access Token Exception
*
* @package php-loep/oauth2-server
* @author Woody Gilk <woody@shadowhand.me>
* @copyright Copyright (c) 2014 PHP League of Extraordinary Packages
* @license http://mit-license.org/
* @link http://github.com/php-loep/oauth2-server
*/
namespace League\OAuth2\Server\Exception;
/**
* MissingAccessToken Exception
*/
class MissingAccessTokenException extends OAuth2Exception
{
}

View File

@@ -0,0 +1,20 @@
<?php
/**
* OAuth 2.0 Base Exception
*
* @package php-loep/oauth2-server
* @author Alex Bilbie <hello@alexbilbie.com>
* @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\Exception;
/**
* Exception class
*/
class OAuth2Exception extends \Exception
{
}

View File

@@ -0,0 +1,259 @@
<?php
/**
* OAuth 2.0 Auth code grant
*
* @package php-loep/oauth2-server
* @author Alex Bilbie <hello@alexbilbie.com>
* @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;
use League\OAuth2\Server\Request;
use League\OAuth2\Server\Authorization;
use League\OAuth2\Server\Exception;
use League\OAuth2\Server\Util\SecureKey;
use League\OAuth2\Server\Storage\SessionInterface;
use League\OAuth2\Server\Storage\ClientInterface;
use League\OAuth2\Server\Storage\ScopeInterface;
/**
* Auth code grant class
*/
class AuthCode implements GrantTypeInterface {
use GrantTrait;
/**
* Grant identifier
* @var string
*/
protected $identifier = 'authorization_code';
/**
* Response type
* @var string
*/
protected $responseType = 'code';
/**
* AuthServer instance
* @var AuthServer
*/
protected $authServer = null;
/**
* Access token expires in override
* @var int
*/
protected $accessTokenTTL = null;
/**
* The TTL of the auth token
* @var integer
*/
protected $authTokenTTL = 600;
/**
* Override the default access token expire time
* @param int $authTokenTTL
* @return void
*/
public function setAuthTokenTTL($authTokenTTL)
{
$this->authTokenTTL = $authTokenTTL;
}
/**
* Check authorise parameters
*
* @param array $inputParams Optional array of parsed $_GET keys
* @throws \OAuth2\Exception\ClientException
* @return array Authorise request parameters
*/
public function checkAuthoriseParams($inputParams = array())
{
// Auth params
$authParams = $this->authServer->getParam(array('client_id', 'redirect_uri', 'response_type', 'scope', 'state'), 'get', $inputParams);
if (is_null($authParams['client_id'])) {
throw new Exception\ClientException(sprintf($this->authServer->getExceptionMessage('invalid_request'), 'client_id'), 0);
}
if (is_null($authParams['redirect_uri'])) {
throw new Exception\ClientException(sprintf($this->authServer->getExceptionMessage('invalid_request'), 'redirect_uri'), 0);
}
if ($this->authServer->stateParamRequired() === true && is_null($authParams['state'])) {
throw new Exception\ClientException(sprintf($this->authServer->getExceptionMessage('invalid_request'), 'state'), 0);
}
// Validate client ID and redirect URI
$clientDetails = $this->authServer->getStorage('client')->getClient($authParams['client_id'], null, $authParams['redirect_uri'], $this->identifier);
if ($clientDetails === false) {
throw new Exception\ClientException($this->authServer->getExceptionMessage('invalid_client'), 8);
}
$authParams['client_details'] = $clientDetails;
if (is_null($authParams['response_type'])) {
throw new Exception\ClientException(sprintf($this->authServer->getExceptionMessage('invalid_request'), 'response_type'), 0);
}
// Ensure response type is one that is recognised
if ( ! in_array($authParams['response_type'], $this->authServer->getResponseTypes())) {
throw new Exception\ClientException($this->authServer->getExceptionMessage('unsupported_response_type'), 3);
}
// Validate scopes
$scopes = explode($this->authServer->getScopeDelimeter(), $authParams['scope']);
for ($i = 0; $i < count($scopes); $i++) {
$scopes[$i] = trim($scopes[$i]);
if ($scopes[$i] === '') unset($scopes[$i]); // Remove any junk scopes
}
if ($this->authServer->scopeParamRequired() === true && $this->authServer->getDefaultScope() === null && count($scopes) === 0) {
throw new Exception\ClientException(sprintf($this->authServer->getExceptionMessage('invalid_request'), 'scope'), 0);
} elseif (count($scopes) === 0 && $this->authServer->getDefaultScope() !== null) {
if (is_array($this->authServer->getDefaultScope())) {
$scopes = $this->authServer->getDefaultScope();
} else {
$scopes = array($this->authServer->getDefaultScope());
}
}
$authParams['scopes'] = array();
foreach ($scopes as $scope) {
$scopeDetails = $this->authServer->getStorage('scope')->getScope($scope, $authParams['client_id'], $this->identifier);
if ($scopeDetails === false) {
throw new Exception\ClientException(sprintf($this->authServer->getExceptionMessage('invalid_scope'), $scope), 4);
}
$authParams['scopes'][] = $scopeDetails;
}
return $authParams;
}
/**
* Parse a new authorise request
*
* @param string $type The session owner's type
* @param string $typeId The session owner's ID
* @param array $authParams The authorise request $_GET parameters
* @return string An authorisation code
*/
public function newAuthoriseRequest($type, $typeId, $authParams = array())
{
// Generate an auth code
$authCode = SecureKey::make();
// Remove any old sessions the user might have
$this->authServer->getStorage('session')->deleteSession($authParams['client_id'], $type, $typeId);
// Create a new session
$sessionId = $this->authServer->getStorage('session')->createSession($authParams['client_id'], $type, $typeId);
// Associate a redirect URI
$this->authServer->getStorage('session')->associateRedirectUri($sessionId, $authParams['redirect_uri']);
// Associate the auth code
$authCodeId = $this->authServer->getStorage('session')->associateAuthCode($sessionId, $authCode, time() + $this->authTokenTTL);
// Associate the scopes to the auth code
foreach ($authParams['scopes'] as $scope) {
$this->authServer->getStorage('session')->associateAuthCodeScope($authCodeId, $scope['id']);
}
return $authCode;
}
/**
* Complete the auth code grant
* @param null|array $inputParams
* @return array
*/
public function completeFlow($inputParams = null)
{
// Get the required params
$authParams = $this->authServer->getParam(array('client_id', 'client_secret', 'redirect_uri', 'code'), 'post', $inputParams);
if (is_null($authParams['client_id'])) {
throw new Exception\ClientException(sprintf($this->authServer->getExceptionMessage('invalid_request'), 'client_id'), 0);
}
if (is_null($authParams['client_secret'])) {
throw new Exception\ClientException(sprintf($this->authServer->getExceptionMessage('invalid_request'), 'client_secret'), 0);
}
if (is_null($authParams['redirect_uri'])) {
throw new Exception\ClientException(sprintf($this->authServer->getExceptionMessage('invalid_request'), 'redirect_uri'), 0);
}
// Validate client ID and redirect URI
$clientDetails = $this->authServer->getStorage('client')->getClient($authParams['client_id'], $authParams['client_secret'], $authParams['redirect_uri'], $this->identifier);
if ($clientDetails === false) {
throw new Exception\ClientException($this->authServer->getExceptionMessage('invalid_client'), 8);
}
$authParams['client_details'] = $clientDetails;
// Validate the authorization code
if (is_null($authParams['code'])) {
throw new Exception\ClientException(sprintf($this->authServer->getExceptionMessage('invalid_request'), 'code'), 0);
}
// Verify the authorization code matches the client_id and the request_uri
$authCodeDetails = $this->authServer->getStorage('session')->validateAuthCode($authParams['client_id'], $authParams['redirect_uri'], $authParams['code']);
if ( ! $authCodeDetails) {
throw new Exception\ClientException(sprintf($this->authServer->getExceptionMessage('invalid_grant'), 'code'), 9);
}
// Get any associated scopes
$scopes = $this->authServer->getStorage('session')->getAuthCodeScopes($authCodeDetails['authcode_id']);
// A session ID was returned so update it with an access token and remove the authorisation code
$accessToken = SecureKey::make();
$accessTokenExpiresIn = ($this->accessTokenTTL !== null) ? $this->accessTokenTTL : $this->authServer->getAccessTokenTTL();
$accessTokenExpires = time() + $accessTokenExpiresIn;
// Remove the auth code
$this->authServer->getStorage('session')->removeAuthCode($authCodeDetails['session_id']);
// Create an access token
$accessTokenId = $this->authServer->getStorage('session')->associateAccessToken($authCodeDetails['session_id'], $accessToken, $accessTokenExpires);
// Associate scopes with the access token
if (count($scopes) > 0) {
foreach ($scopes as $scope) {
$this->authServer->getStorage('session')->associateScope($accessTokenId, $scope['scope_id']);
}
}
$response = array(
'access_token' => $accessToken,
'token_type' => 'Bearer',
'expires' => $accessTokenExpires,
'expires_in' => $accessTokenExpiresIn
);
// Associate a refresh token if set
if ($this->authServer->hasGrantType('refresh_token')) {
$refreshToken = SecureKey::make();
$refreshTokenTTL = time() + $this->authServer->getGrantType('refresh_token')->getRefreshTokenTTL();
$this->authServer->getStorage('session')->associateRefreshToken($accessTokenId, $refreshToken, $refreshTokenTTL, $authParams['client_id']);
$response['refresh_token'] = $refreshToken;
}
return $response;
}
}

View File

@@ -0,0 +1,166 @@
<?php
/**
* OAuth 2.0 Client credentials grant
*
* @package php-loep/oauth2-server
* @author Alex Bilbie <hello@alexbilbie.com>
* @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;
use League\OAuth2\Server\Request;
use League\OAuth2\Server\Authorization;
use League\OAuth2\Server\Exception;
use League\OAuth2\Server\Util\SecureKey;
use League\OAuth2\Server\Storage\SessionInterface;
use League\OAuth2\Server\Storage\ClientInterface;
use League\OAuth2\Server\Storage\ScopeInterface;
/**
* Client credentials grant class
*/
class ClientCredentials implements GrantTypeInterface {
use GrantTrait;
/**
* Grant identifier
* @var string
*/
protected $identifier = 'client_credentials';
/**
* Response type
* @var string
*/
protected $responseType = null;
/**
* AuthServer instance
* @var AuthServer
*/
protected $authServer = null;
/**
* Access token expires in override
* @var int
*/
protected $accessTokenTTL = null;
/**
* 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;
}
/**
* Complete the client credentials grant
* @param null|array $inputParams
* @return array
*/
public function completeFlow($inputParams = null)
{
// Get the required params
$authParams = $this->authServer->getParam(array('client_id', 'client_secret'), 'post', $inputParams);
if (is_null($authParams['client_id'])) {
throw new Exception\ClientException(sprintf(Authorization::getExceptionMessage('invalid_request'), 'client_id'), 0);
}
if (is_null($authParams['client_secret'])) {
throw new Exception\ClientException(sprintf(Authorization::getExceptionMessage('invalid_request'), 'client_secret'), 0);
}
// Validate client ID and client secret
$clientDetails = $this->authServer->getStorage('client')->getClient($authParams['client_id'], $authParams['client_secret'], null, $this->identifier);
if ($clientDetails === false) {
throw new Exception\ClientException(Authorization::getExceptionMessage('invalid_client'), 8);
}
$authParams['client_details'] = $clientDetails;
// Validate any scopes that are in the request
$scope = $this->authServer->getParam('scope', 'post', $inputParams, '');
$scopes = explode($this->authServer->getScopeDelimeter(), $scope);
for ($i = 0; $i < count($scopes); $i++) {
$scopes[$i] = trim($scopes[$i]);
if ($scopes[$i] === '') unset($scopes[$i]); // Remove any junk scopes
}
if ($this->authServer->scopeParamRequired() === true && $this->authServer->getDefaultScope() === null && count($scopes) === 0) {
throw new Exception\ClientException(sprintf($this->authServer->getExceptionMessage('invalid_request'), 'scope'), 0);
} elseif (count($scopes) === 0 && $this->authServer->getDefaultScope() !== null) {
if (is_array($this->authServer->getDefaultScope())) {
$scopes = $this->authServer->getDefaultScope();
} else {
$scopes = array($this->authServer->getDefaultScope());
}
}
$authParams['scopes'] = array();
foreach ($scopes as $scope) {
$scopeDetails = $this->authServer->getStorage('scope')->getScope($scope, $authParams['client_id'], $this->identifier);
if ($scopeDetails === false) {
throw new Exception\ClientException(sprintf($this->authServer->getExceptionMessage('invalid_scope'), $scope), 4);
}
$authParams['scopes'][] = $scopeDetails;
}
// Generate an access token
$accessToken = SecureKey::make();
$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'], 'client', $authParams['client_id']);
// Add the access token
$accessTokenId = $this->authServer->getStorage('session')->associateAccessToken($sessionId, $accessToken, $accessTokenExpires);
// Associate scopes with the new session
foreach ($authParams['scopes'] as $scope)
{
$this->authServer->getStorage('session')->associateScope($accessTokenId, $scope['id']);
}
$response = array(
'access_token' => $accessToken,
'token_type' => 'Bearer',
'expires' => $accessTokenExpires,
'expires_in' => $accessTokenExpiresIn
);
return $response;
}
}

View File

@@ -0,0 +1,85 @@
<?php
/**
* OAuth 2.0 Client credentials grant
*
* @package php-loep/oauth2-server
* @author Alex Bilbie <hello@alexbilbie.com>
* @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;
use League\OAuth2\Server\Authorization;
trait GrantTrait {
/**
* Constructor
* @param Authorization $authServer Authorization server instance
* @return void
*/
public function __construct(Authorization $authServer = null)
{
// @codeCoverageIgnoreStart
if ($authServer instanceof Authorization) {
trigger_error(
'Server is now automatically injected into grant as of v3.1 of this library',
E_USER_DEPRECATED
);
} // @codeCoverageIgnoreEnd
}
/**
* Return the identifier
* @return string
*/
public function getIdentifier()
{
return $this->identifier;
}
/**
* Return the identifier
* @param string $identifier
* @return self
*/
public function setIdentifier($identifier)
{
$this->identifier = $identifier;
return $this;
}
/**
* 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;
}
/**
* Inject the authorization server into the grant
* @param Authorization $authServer The authorization server instance
* @return self
*/
public function setAuthorizationServer(Authorization $authServer)
{
$this->authServer = $authServer;
return $this;
}
}

View File

@@ -0,0 +1,48 @@
<?php
/**
* OAuth 2.0 Grant type interface
*
* @package php-loep/oauth2-server
* @author Alex Bilbie <hello@alexbilbie.com>
* @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;
use League\OAuth2\Server\Request;
use League\OAuth2\Server\Authorization;
use League\OAuth2\Server\Exception;
use League\OAuth2\Server\Util\SecureKey;
use League\OAuth2\Server\Storage\SessionInterface;
use League\OAuth2\Server\Storage\ClientInterface;
use League\OAuth2\Server\Storage\ScopeInterface;
interface GrantTypeInterface
{
/**
* Constructor
* @return void
*/
public function __construct(Authorization $authServer = null);
/**
* Complete the grant flow
*
* Example response:
* <code>
* array(
* 'access_token' => (string), // The access token
* 'refresh_token' => (string), // The refresh token (only set if the refresh token grant is enabled)
* 'token_type' => 'bearer', // Almost always "bearer" (exceptions: JWT, SAML)
* 'expires' => (int), // The timestamp of when the access token will expire
* 'expires_in' => (int) // The number of seconds before the access token will expire
* )
* </code>
*
* @param null|array $inputParams Null unless the input parameters have been manually set
* @return array An array of parameters to be passed back to the client
*/
public function completeFlow($inputParams = null);
}

View File

@@ -0,0 +1,91 @@
<?php
/**
* OAuth 2.0 implicit grant
*
* @package php-loep/oauth2-server
* @author Alex Bilbie <hello@alexbilbie.com>
* @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;
use League\OAuth2\Server\Request;
use League\OAuth2\Server\Authorization;
use League\OAuth2\Server\Exception;
use League\OAuth2\Server\Util\SecureKey;
use League\OAuth2\Server\Storage\SessionInterface;
use League\OAuth2\Server\Storage\ClientInterface;
use League\OAuth2\Server\Storage\ScopeInterface;
/**
* Client credentials grant class
*/
class Implicit implements GrantTypeInterface {
use GrantTrait;
/**
* Grant identifier
* @var string
*/
protected $identifier = 'implicit';
/**
* Response type
* @var string
*/
protected $responseType = 'token';
/**
* AuthServer instance
* @var AuthServer
*/
protected $authServer = null;
/**
* Access token expires in override
* @var int
*/
protected $accessTokenTTL = null;
/**
* Complete the client credentials grant
* @param null|array $inputParams
* @return array
*/
public function completeFlow($authParams = null)
{
// Remove any old sessions the user might have
$this->authServer->getStorage('session')->deleteSession($authParams['client_id'], 'user', $authParams['user_id']);
// Generate a new access token
$accessToken = SecureKey::make();
// Compute expiry time
$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']);
// Create an access token
$accessTokenId = $this->authServer->getStorage('session')->associateAccessToken($sessionId, $accessToken, $accessTokenExpires);
// Associate scopes with the access token
foreach ($authParams['scopes'] as $scope) {
$this->authServer->getStorage('session')->associateScope($accessTokenId, $scope['id']);
}
$response = array(
'access_token' => $accessToken,
'token_type' => 'Bearer',
'expires' => $accessTokenExpires,
'expires_in' => $accessTokenExpiresIn,
);
return $response;
}
}

View File

@@ -0,0 +1,189 @@
<?php
/**
* OAuth 2.0 Password grant
*
* @package php-loep/oauth2-server
* @author Alex Bilbie <hello@alexbilbie.com>
* @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;
use League\OAuth2\Server\Request;
use League\OAuth2\Server\Authorization;
use League\OAuth2\Server\Exception;
use League\OAuth2\Server\Util\SecureKey;
use League\OAuth2\Server\Storage\SessionInterface;
use League\OAuth2\Server\Storage\ClientInterface;
use League\OAuth2\Server\Storage\ScopeInterface;
/**
* Password grant class
*/
class Password implements GrantTypeInterface {
use GrantTrait;
/**
* Grant identifier
* @var string
*/
protected $identifier = 'password';
/**
* Response type
* @var string
*/
protected $responseType = null;
/**
* Callback to authenticate a user's name and password
* @var function
*/
protected $callback = null;
/**
* AuthServer instance
* @var AuthServer
*/
protected $authServer = null;
/**
* Access token expires in override
* @var int
*/
protected $accessTokenTTL = null;
/**
* Set the callback to verify a user's username and password
* @param callable $callback The callback function
* @return void
*/
public function setVerifyCredentialsCallback($callback)
{
$this->callback = $callback;
}
/**
* Return the callback function
* @return callable
*/
protected function getVerifyCredentialsCallback()
{
if (is_null($this->callback) || ! is_callable($this->callback)) {
throw new Exception\InvalidGrantTypeException('Null or non-callable callback set');
}
return $this->callback;
}
/**
* Complete the password grant
* @param null|array $inputParams
* @return array
*/
public function completeFlow($inputParams = null)
{
// Get the required params
$authParams = $this->authServer->getParam(array('client_id', 'client_secret', 'username', 'password'), 'post', $inputParams);
if (is_null($authParams['client_id'])) {
throw new Exception\ClientException(sprintf($this->authServer->getExceptionMessage('invalid_request'), 'client_id'), 0);
}
if (is_null($authParams['client_secret'])) {
throw new Exception\ClientException(sprintf($this->authServer->getExceptionMessage('invalid_request'), 'client_secret'), 0);
}
// Validate client credentials
$clientDetails = $this->authServer->getStorage('client')->getClient($authParams['client_id'], $authParams['client_secret'], null, $this->identifier);
if ($clientDetails === false) {
throw new Exception\ClientException($this->authServer->getExceptionMessage('invalid_client'), 8);
}
$authParams['client_details'] = $clientDetails;
if (is_null($authParams['username'])) {
throw new Exception\ClientException(sprintf($this->authServer->getExceptionMessage('invalid_request'), 'username'), 0);
}
if (is_null($authParams['password'])) {
throw new Exception\ClientException(sprintf($this->authServer->getExceptionMessage('invalid_request'), 'password'), 0);
}
// Check if user's username and password are correct
$userId = call_user_func($this->getVerifyCredentialsCallback(), $authParams['username'], $authParams['password']);
if ($userId === false) {
throw new Exception\ClientException($this->authServer->getExceptionMessage('invalid_credentials'), 0);
}
// Validate any scopes that are in the request
$scope = $this->authServer->getParam('scope', 'post', $inputParams, '');
$scopes = explode($this->authServer->getScopeDelimeter(), $scope);
for ($i = 0; $i < count($scopes); $i++) {
$scopes[$i] = trim($scopes[$i]);
if ($scopes[$i] === '') unset($scopes[$i]); // Remove any junk scopes
}
if ($this->authServer->scopeParamRequired() === true && $this->authServer->getDefaultScope() === null && count($scopes) === 0) {
throw new Exception\ClientException(sprintf($this->authServer->getExceptionMessage('invalid_request'), 'scope'), 0);
} elseif (count($scopes) === 0 && $this->authServer->getDefaultScope() !== null) {
if (is_array($this->authServer->getDefaultScope())) {
$scopes = $this->authServer->getDefaultScope();
} else {
$scopes = array($this->authServer->getDefaultScope());
}
}
$authParams['scopes'] = array();
foreach ($scopes as $scope) {
$scopeDetails = $this->authServer->getStorage('scope')->getScope($scope, $authParams['client_id'], $this->identifier);
if ($scopeDetails === false) {
throw new Exception\ClientException(sprintf($this->authServer->getExceptionMessage('invalid_scope'), $scope), 4);
}
$authParams['scopes'][] = $scopeDetails;
}
// Generate an access token
$accessToken = SecureKey::make();
$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', $userId);
// Associate an access token with the session
$accessTokenId = $this->authServer->getStorage('session')->associateAccessToken($sessionId, $accessToken, $accessTokenExpires);
// Associate scopes with the access token
foreach ($authParams['scopes'] as $scope) {
$this->authServer->getStorage('session')->associateScope($accessTokenId, $scope['id']);
}
$response = array(
'access_token' => $accessToken,
'token_type' => 'Bearer',
'expires' => $accessTokenExpires,
'expires_in' => $accessTokenExpiresIn
);
// Associate a refresh token if set
if ($this->authServer->hasGrantType('refresh_token')) {
$refreshToken = SecureKey::make();
$refreshTokenTTL = time() + $this->authServer->getGrantType('refresh_token')->getRefreshTokenTTL();
$this->authServer->getStorage('session')->associateRefreshToken($accessTokenId, $refreshToken, $refreshTokenTTL, $authParams['client_id']);
$response['refresh_token'] = $refreshToken;
}
return $response;
}
}

View File

@@ -0,0 +1,207 @@
<?php
/**
* OAuth 2.0 Refresh token grant
*
* @package php-loep/oauth2-server
* @author Alex Bilbie <hello@alexbilbie.com>
* @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;
use League\OAuth2\Server\Request;
use League\OAuth2\Server\Authorization;
use League\OAuth2\Server\Exception;
use League\OAuth2\Server\Util\SecureKey;
use League\OAuth2\Server\Storage\SessionInterface;
use League\OAuth2\Server\Storage\ClientInterface;
use League\OAuth2\Server\Storage\ScopeInterface;
/**
* Referesh token grant
*/
class RefreshToken implements GrantTypeInterface {
use GrantTrait;
/**
* Grant identifier
* @var string
*/
protected $identifier = 'refresh_token';
/**
* Response type
* @var string
*/
protected $responseType = null;
/**
* AuthServer instance
* @var AuthServer
*/
protected $authServer = null;
/**
* Access token expires in override
* @var int
*/
protected $accessTokenTTL = null;
/**
* Refresh token TTL
* @var integer
*/
protected $refreshTokenTTL = 604800;
/**
* Rotate refresh tokens
* @var boolean
*/
protected $rotateRefreshTokens = false;
/**
* Set the TTL of the refresh token
* @param int $refreshTokenTTL
* @return void
*/
public function setRefreshTokenTTL($refreshTokenTTL)
{
$this->refreshTokenTTL = $refreshTokenTTL;
}
/**
* Get the TTL of the refresh token
* @return int
*/
public function getRefreshTokenTTL()
{
return $this->refreshTokenTTL;
}
/**
* When a new access is token, expire the refresh token used and issue a new one.
* @param boolean $rotateRefreshTokens Set to true to enable (default = false)
* @return void
*/
public function rotateRefreshTokens($rotateRefreshTokens = false)
{
$this->rotateRefreshTokens = $rotateRefreshTokens;
}
/**
* Complete the refresh token grant
* @param null|array $inputParams
* @return array
*/
public function completeFlow($inputParams = null)
{
// Get the required params
$authParams = $this->authServer->getParam(array('client_id', 'client_secret', 'refresh_token', 'scope'), 'post', $inputParams);
if (is_null($authParams['client_id'])) {
throw new Exception\ClientException(sprintf($this->authServer->getExceptionMessage('invalid_request'), 'client_id'), 0);
}
if (is_null($authParams['client_secret'])) {
throw new Exception\ClientException(sprintf($this->authServer->getExceptionMessage('invalid_request'), 'client_secret'), 0);
}
// Validate client ID and client secret
$clientDetails = $this->authServer->getStorage('client')->getClient($authParams['client_id'], $authParams['client_secret'], null, $this->identifier);
if ($clientDetails === false) {
throw new Exception\ClientException($this->authServer->getExceptionMessage('invalid_client'), 8);
}
$authParams['client_details'] = $clientDetails;
if (is_null($authParams['refresh_token'])) {
throw new Exception\ClientException(sprintf($this->authServer->getExceptionMessage('invalid_request'), 'refresh_token'), 0);
}
// Validate refresh token
$accessTokenId = $this->authServer->getStorage('session')->validateRefreshToken($authParams['refresh_token'], $authParams['client_id']);
if ($accessTokenId === false) {
throw new Exception\ClientException($this->authServer->getExceptionMessage('invalid_refresh'), 0);
}
// Get the existing access token
$accessTokenDetails = $this->authServer->getStorage('session')->getAccessToken($accessTokenId);
// Get the scopes for the existing access token
$scopes = $this->authServer->getStorage('session')->getScopes($accessTokenDetails['access_token']);
// Generate new tokens and associate them to the session
$accessToken = SecureKey::make();
$accessTokenExpiresIn = ($this->accessTokenTTL !== null) ? $this->accessTokenTTL : $this->authServer->getAccessTokenTTL();
$accessTokenExpires = time() + $accessTokenExpiresIn;
// Associate the new access token with the session
$newAccessTokenId = $this->authServer->getStorage('session')->associateAccessToken($accessTokenDetails['session_id'], $accessToken, $accessTokenExpires);
if ($this->rotateRefreshTokens === true) {
// Generate a new refresh token
$refreshToken = SecureKey::make();
$refreshTokenExpires = time() + $this->getRefreshTokenTTL();
// Revoke the old refresh token
$this->authServer->getStorage('session')->removeRefreshToken($authParams['refresh_token']);
// Associate the new refresh token with the new access token
$this->authServer->getStorage('session')->associateRefreshToken($newAccessTokenId, $refreshToken, $refreshTokenExpires, $authParams['client_id']);
}
// There isn't a request for reduced scopes so assign the original ones (or we're not rotating scopes)
if ( ! isset($authParams['scope'])) {
foreach ($scopes as $scope) {
$this->authServer->getStorage('session')->associateScope($newAccessTokenId, $scope['id']);
}
} elseif ( isset($authParams['scope']) && $this->rotateRefreshTokens === true) {
// The request is asking for reduced scopes and rotate tokens is enabled
$reqestedScopes = explode($this->authServer->getScopeDelimeter(), $authParams['scope']);
for ($i = 0; $i < count($reqestedScopes); $i++) {
$reqestedScopes[$i] = trim($reqestedScopes[$i]);
if ($reqestedScopes[$i] === '') unset($reqestedScopes[$i]); // Remove any junk scopes
}
// Check that there aren't any new scopes being included
$existingScopes = array();
foreach ($scopes as $s) {
$existingScopes[] = $s['scope'];
}
foreach ($reqestedScopes as $reqScope) {
if ( ! in_array($reqScope, $existingScopes)) {
throw new Exception\ClientException(sprintf($this->authServer->getExceptionMessage('invalid_request'), 'scope'), 0);
}
// Associate with the new access token
$scopeDetails = $this->authServer->getStorage('scope')->getScope($reqScope, $authParams['client_id'], $this->identifier);
$this->authServer->getStorage('session')->associateScope($newAccessTokenId, $scopeDetails['id']);
}
}
$response = array(
'access_token' => $accessToken,
'token_type' => 'Bearer',
'expires' => $accessTokenExpires,
'expires_in' => $accessTokenExpiresIn
);
if ($this->rotateRefreshTokens === true) {
$response['refresh_token'] = $refreshToken;
}
return $response;
}
}

View File

@@ -0,0 +1,395 @@
<?php
/**
* OAuth 2.0 Resource Server
*
* @package php-loep/oauth2-server
* @author Alex Bilbie <hello@alexbilbie.com>
* @author Woody Gilk <woody@shadowhand.me>
* @copyright Copyright (c) 2013-2014 PHP League of Extraordinary Packages
* @license http://mit-license.org/
* @link http://github.com/php-loep/oauth2-server
*/
namespace League\OAuth2\Server;
use OutOfBoundsException;
use League\OAuth2\Server\Storage\SessionInterface;
use League\OAuth2\Server\Util\RequestInterface;
use League\OAuth2\Server\Util\Request;
/**
* OAuth 2.0 Resource Server
*/
class Resource
{
/**
* The access token
* @var string
*/
protected $accessToken = null;
/**
* The session ID
* @var string
*/
protected $sessionId = null;
/**
* The type of the owner of the access token
* @var string
*/
protected $ownerType = null;
/**
* The ID of the owner of the access token
* @var string
*/
protected $ownerId = null;
/**
* The scopes associated with the access token
* @var array
*/
protected $sessionScopes = array();
/**
* The client, scope and session storage classes
* @var array
*/
protected $storages = array();
/**
* The request object
* @var Util\RequestInterface
*/
protected $request = null;
/**
* The query string key which is used by clients to present the access token (default: access_token)
* @var string
*/
protected $tokenKey = 'access_token';
/**
* The client ID
* @var string
*/
protected $clientId = null;
/**
* Exception error codes
* @var array
*/
protected static $exceptionCodes = array(
0 => 'invalid_request',
1 => 'invalid_token',
2 => 'insufficient_scope',
);
/**
* Exception error messages
* @var array
*/
protected static $exceptionMessages = array(
'invalid_request' => 'The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Check the "%s" parameter.',
'invalid_token' => 'The access token provided is expired, revoked, malformed, or invalid for other reasons.',
'insufficient_scope' => 'The request requires higher privileges than provided by the access token. Required scopes are: %s.',
);
/**
* Exception error HTTP status codes
* @var array
*
* RFC 6750, section 3.1:
* When a request fails, the resource server responds using the
* appropriate HTTP status code (typically, 400, 401, 403, or 405) and
* includes one of the following error codes in the response:
*/
protected static $exceptionHttpStatusCodes = array(
'invalid_request' => 400,
'invalid_token' => 401,
'insufficient_scope' => 403,
);
/**
* Get an exception message
*
* @param string $error The error message key
* @return string The error message
*/
public static function getExceptionMessage($error = '')
{
return self::$exceptionMessages[$error];
}
/**
* Get an exception code
*
* @param integer $code The exception code
* @return string The exception code type
*/
public static function getExceptionType($code = 0)
{
return self::$exceptionCodes[$code];
}
/**
* Get all headers that have to be send with the error response
*
* @param string $error The error message key
* @return array Array with header values
*/
public static function getExceptionHttpHeaders($error)
{
$headers = array();
switch (self::$exceptionHttpStatusCodes[$error]) {
case 401:
$headers[] = 'HTTP/1.1 401 Unauthorized';
break;
case 403:
$headers[] = 'HTTP/1.1 403 Forbidden';
break;
case 400:
default:
$headers[] = 'HTTP/1.1 400 Bad Request';
}
// Add "WWW-Authenticate" header
//
// RFC 6749, section 5.2.:
// "If the client attempted to authenticate via the 'Authorization'
// request header field, the authorization server MUST
// respond with an HTTP 401 (Unauthorized) status code and
// include the "WWW-Authenticate" response header field
// matching the authentication scheme used by the client.
// @codeCoverageIgnoreStart
if ($error === 'insufficient_scope') {
$authScheme = null;
$request = new Request();
if ($request->server('PHP_AUTH_USER') !== null) {
$authScheme = 'Basic';
} else {
$authHeader = $request->header('Authorization');
if ($authHeader !== null) {
if (strpos($authHeader, 'Bearer') === 0) {
$authScheme = 'Bearer';
} elseif (strpos($authHeader, 'Basic') === 0) {
$authScheme = 'Basic';
}
}
}
if ($authScheme !== null) {
$headers[] = 'WWW-Authenticate: '.$authScheme.' realm=""';
}
}
// @codeCoverageIgnoreEnd
return $headers;
}
/**
* Sets up the Resource
*
* @param SessionInterface The Session Storage Object
*/
public function __construct(SessionInterface $session)
{
$this->storages['session'] = $session;
}
/**
* Sets the Request Object
*
* @param RequestInterface The Request Object
*/
public function setRequest(RequestInterface $request)
{
$this->request = $request;
return $this;
}
/**
* Gets the Request object. It will create one from the globals if one is not set.
*
* @return Util\RequestInterface
*/
public function getRequest()
{
if ($this->request === null) {
// @codeCoverageIgnoreStart
$this->request = Request::buildFromGlobals();
}
// @codeCoverageIgnoreEnd
return $this->request;
}
/**
* Returns the query string key for the access token.
*
* @return string
*/
public function getTokenKey()
{
return $this->tokenKey;
}
/**
* Sets the query string key for the access token.
*
* @param $key The new query string key
*/
public function setTokenKey($key)
{
$this->tokenKey = $key;
return $this;
}
/**
* Gets the access token owner ID.
*
* @return string
*/
public function getOwnerId()
{
return $this->ownerId;
}
/**
* Gets the owner type.
*
* @return string
*/
public function getOwnerType()
{
return $this->ownerType;
}
/**
* Gets the access token.
*
* @return string
*/
public function getAccessToken()
{
return $this->accessToken;
}
/**
* Gets the client ID that created the session
* @return string
*/
public function getClientId()
{
return $this->clientId;
}
/**
* Checks if the access token is valid or not.
*
* @param $headersOnly Limit Access Token to Authorization header only
* @throws Exception\InvalidAccessTokenException Thrown if the presented access token is not valid
* @return bool
*/
public function isValid($headersOnly = false)
{
$accessToken = $this->determineAccessToken($headersOnly);
$result = $this->storages['session']->validateAccessToken($accessToken);
if (! $result) {
throw new Exception\InvalidAccessTokenException(self::$exceptionMessages['invalid_token'], 1);
}
$this->accessToken = $accessToken;
$this->sessionId = $result['session_id'];
$this->clientId = $result['client_id'];
$this->ownerType = $result['owner_type'];
$this->ownerId = $result['owner_id'];
$sessionScopes = $this->storages['session']->getScopes($this->accessToken);
foreach ($sessionScopes as $scope) {
$this->sessionScopes[] = $scope['scope'];
}
return true;
}
/**
* Get the session scopes
* @return array
*/
public function getScopes()
{
return $this->sessionScopes;
}
/**
* Checks if the presented access token has the given scope(s).
*
* @param array|string An array of scopes or a single scope as a string
* @param bool If scopes are required, missing scope will trigger an exception
* @throws Exception\InsufficientScopeException Thrown if the any of the given scopes are not in the session
* @return bool Returns bool if all scopes are found, false if any fail
*/
public function hasScope($scopes, $required = false)
{
if (!is_array($scopes)) {
$scopes = array($scopes);
}
$missing = array_diff($scopes, $this->sessionScopes);
if ($missing) {
if ($required) {
$missing = implode(', ', $missing);
throw new Exception\InsufficientScopeException(sprintf(self::$exceptionMessages['insufficient_scope'], $missing), 3);
}
return false;
}
return true;
}
/**
* Reads in the access token from the headers.
*
* @param $headersOnly Limit Access Token to Authorization header only
* @throws Exception\MissingAccessTokenException Thrown if there is no access token presented
* @return string
*/
public function determineAccessToken($headersOnly = false)
{
// Try to get it directly from a header
if (! $header = $this->getRequest()->header('Authorization')) {
// Failing that try getting it from a server variable
$header = $this->getRequest()->server('HTTP_AUTHORIZATION');
}
// One of them worked
if ($header) {
// Check for special case, because cURL sometimes does an
// internal second request and doubles the authorization header,
// which always resulted in an error.
//
// 1st request: Authorization: Bearer XXX
// 2nd request: Authorization: Bearer XXX, Bearer XXX
if (strpos($header, ',') !== false) {
$headerPart = explode(',', $header);
$accessToken = trim(preg_replace('/^(?:\s+)?Bearer\s/', '', $headerPart[0]));
} else {
$accessToken = trim(preg_replace('/^(?:\s+)?Bearer\s/', '', $header));
}
$accessToken = ($accessToken === 'Bearer') ? '' : $accessToken;
} elseif ($headersOnly === false) {
$method = $this->getRequest()->server('REQUEST_METHOD');
$accessToken = $this->getRequest()->{$method}($this->tokenKey);
}
if (empty($accessToken)) {
throw new Exception\MissingAccessTokenException(self::$exceptionMessages['invalid_request'], 0);
}
return $accessToken;
}
}

View File

@@ -0,0 +1,60 @@
<?php
/**
* OAuth 2.0 Client storage interface
*
* @package php-loep/oauth2-server
* @author Alex Bilbie <hello@alexbilbie.com>
* @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\Storage;
interface ClientInterface
{
/**
* Validate a client
*
* Example SQL query:
*
* <code>
* # Client ID + redirect URI
* 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, 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,
* 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
* </code>
*
* Response:
*
* <code>
* Array
* (
* [client_id] => (string) The client ID
* [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
* )
* </code>
*
* @param string $clientId The client's ID
* @param string $clientSecret The client's secret (default = "null")
* @param string $redirectUri The client's redirect URI (default = "null")
* @param string $grantType The grant type used in the request (default = "null")
* @return bool|array Returns false if the validation fails, array on success
*/
public function getClient($clientId, $clientSecret = null, $redirectUri = null, $grantType = null);
}

View File

@@ -0,0 +1,43 @@
<?php
/**
* OAuth 2.0 Scope storage interface
*
* @package php-loep/oauth2-server
* @author Alex Bilbie <hello@alexbilbie.com>
* @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\Storage;
interface ScopeInterface
{
/**
* Return information about a scope
*
* Example SQL query:
*
* <code>
* SELECT * FROM oauth_scopes WHERE scope = :scope
* </code>
*
* Response:
*
* <code>
* Array
* (
* [id] => (int) The scope's ID
* [scope] => (string) The scope itself
* [name] => (string) The scope's name
* [description] => (string) The scope's description
* )
* </code>
*
* @param string $scope The scope
* @param string $clientId The client ID (default = "null")
* @param string $grantType The grant type used in the request (default = "null")
* @return bool|array If the scope doesn't exist return false
*/
public function getScope($scope, $clientId = null, $grantType = null);
}

View File

@@ -0,0 +1,332 @@
<?php
/**
* OAuth 2.0 Session storage interface
*
* @package php-loep/oauth2-server
* @author Alex Bilbie <hello@alexbilbie.com>
* @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\Storage;
interface SessionInterface
{
/**
* Create a new session
*
* Example SQL query:
*
* <code>
* INSERT INTO oauth_sessions (client_id, owner_type, owner_id)
* VALUE (:clientId, :ownerType, :ownerId)
* </code>
*
* @param string $clientId The client ID
* @param string $ownerType The type of the session owner (e.g. "user")
* @param string $ownerId The ID of the session owner (e.g. "123")
* @return int The session ID
*/
public function createSession($clientId, $ownerType, $ownerId);
/**
* Delete a session
*
* Example SQL query:
*
* <code>
* DELETE FROM oauth_sessions WHERE client_id = :clientId AND owner_type = :type AND owner_id = :typeId
* </code>
*
* @param string $clientId The client ID
* @param string $ownerType The type of the session owner (e.g. "user")
* @param string $ownerId The ID of the session owner (e.g. "123")
* @return void
*/
public function deleteSession($clientId, $ownerType, $ownerId);
/**
* Associate a redirect URI with a session
*
* Example SQL query:
*
* <code>
* INSERT INTO oauth_session_redirects (session_id, redirect_uri) VALUE (:sessionId, :redirectUri)
* </code>
*
* @param int $sessionId The session ID
* @param string $redirectUri The redirect URI
* @return void
*/
public function associateRedirectUri($sessionId, $redirectUri);
/**
* Associate an access token with a session
*
* Example SQL query:
*
* <code>
* INSERT INTO oauth_session_access_tokens (session_id, access_token, access_token_expires)
* VALUE (:sessionId, :accessToken, :accessTokenExpire)
* </code>
*
* @param int $sessionId The session ID
* @param string $accessToken The access token
* @param int $expireTime Unix timestamp of the access token expiry time
* @return int The access token ID
*/
public function associateAccessToken($sessionId, $accessToken, $expireTime);
/**
* Associate a refresh token with a session
*
* Example SQL query:
*
* <code>
* INSERT INTO oauth_session_refresh_tokens (session_access_token_id, refresh_token, refresh_token_expires,
* client_id) VALUE (:accessTokenId, :refreshToken, :expireTime, :clientId)
* </code>
*
* @param int $accessTokenId The access token ID
* @param string $refreshToken The refresh token
* @param int $expireTime Unix timestamp of the refresh token expiry time
* @param string $clientId The client ID
* @return void
*/
public function associateRefreshToken($accessTokenId, $refreshToken, $expireTime, $clientId);
/**
* Assocate an authorization code with a session
*
* Example SQL query:
*
* <code>
* INSERT INTO oauth_session_authcodes (session_id, auth_code, auth_code_expires)
* VALUE (:sessionId, :authCode, :authCodeExpires)
* </code>
*
* @param int $sessionId The session ID
* @param string $authCode The authorization code
* @param int $expireTime Unix timestamp of the access token expiry time
* @return int The auth code ID
*/
public function associateAuthCode($sessionId, $authCode, $expireTime);
/**
* Remove an associated authorization token from a session
*
* Example SQL query:
*
* <code>
* DELETE FROM oauth_session_authcodes WHERE session_id = :sessionId
* </code>
*
* @param int $sessionId The session ID
* @return void
*/
public function removeAuthCode($sessionId);
/**
* Validate an authorization code
*
* Example SQL query:
*
* <code>
* 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
* </code>
*
* Expected response:
*
* <code>
* array(
* 'session_id' => (int)
* 'authcode_id' => (int)
* )
* </code>
*
* @param string $clientId The client ID
* @param string $redirectUri The redirect URI
* @param string $authCode The authorization code
* @return array|bool False if invalid or array as above
*/
public function validateAuthCode($clientId, $redirectUri, $authCode);
/**
* Validate an access token
*
* Example SQL query:
*
* <code>
* 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 >= UNIX_TIMESTAMP(NOW())
* </code>
*
* Expected response:
*
* <code>
* array(
* 'session_id' => (int),
* 'client_id' => (string),
* 'owner_id' => (string),
* 'owner_type' => (string)
* )
* </code>
*
* @param string $accessToken The access token
* @return array|bool False if invalid or an array as above
*/
public function validateAccessToken($accessToken);
/**
* Removes a refresh token
*
* Example SQL query:
*
* <code>
* DELETE FROM `oauth_session_refresh_tokens` WHERE refresh_token = :refreshToken
* </code>
*
* @param string $refreshToken The refresh token to be removed
* @return void
*/
public function removeRefreshToken($refreshToken);
/**
* Validate a refresh token
*
* Example SQL query:
*
* <code>
* SELECT session_access_token_id FROM `oauth_session_refresh_tokens` WHERE refresh_token = :refreshToken
* AND refresh_token_expires >= UNIX_TIMESTAMP(NOW()) AND client_id = :clientId
* </code>
*
* @param string $refreshToken The refresh token
* @param string $clientId The client ID
* @return int|bool The ID of the access token the refresh token is linked to (or false if invalid)
*/
public function validateRefreshToken($refreshToken, $clientId);
/**
* Get an access token by ID
*
* Example SQL query:
*
* <code>
* SELECT * FROM `oauth_session_access_tokens` WHERE `id` = :accessTokenId
* </code>
*
* Expected response:
*
* <code>
* array(
* 'id' => (int),
* 'session_id' => (int),
* 'access_token' => (string),
* 'access_token_expires' => (int)
* )
* </code>
*
* @param int $accessTokenId The access token ID
* @return array
*/
public function getAccessToken($accessTokenId);
/**
* Associate scopes with an auth code (bound to the session)
*
* Example SQL query:
*
* <code>
* INSERT INTO `oauth_session_authcode_scopes` (`oauth_session_authcode_id`, `scope_id`) VALUES
* (:authCodeId, :scopeId)
* </code>
*
* @param int $authCodeId The auth code ID
* @param int $scopeId The scope ID
* @return void
*/
public function associateAuthCodeScope($authCodeId, $scopeId);
/**
* Get the scopes associated with an auth code
*
* Example SQL query:
*
* <code>
* SELECT scope_id FROM `oauth_session_authcode_scopes` WHERE oauth_session_authcode_id = :authCodeId
* </code>
*
* Expected response:
*
* <code>
* array(
* array(
* 'scope_id' => (int)
* ),
* array(
* 'scope_id' => (int)
* ),
* ...
* )
* </code>
*
* @param int $oauthSessionAuthCodeId The session ID
* @return array
*/
public function getAuthCodeScopes($oauthSessionAuthCodeId);
/**
* Associate a scope with an access token
*
* Example SQL query:
*
* <code>
* INSERT INTO `oauth_session_token_scopes` (`session_access_token_id`, `scope_id`) VALUE (:accessTokenId, :scopeId)
* </code>
*
* @param int $accessTokenId The ID of the access token
* @param int $scopeId The ID of the scope
* @return void
*/
public function associateScope($accessTokenId, $scopeId);
/**
* Get all associated access tokens for an access token
*
* Example SQL query:
*
* <code>
* 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
* </code>
*
* Expected response:
*
* <code>
* array (
* array(
* 'id' => (int),
* 'scope' => (string),
* 'name' => (string),
* 'description' => (string)
* ),
* ...
* ...
* )
* </code>
*
* @param string $accessToken The access token
* @return array
*/
public function getScopes($accessToken);
}

View File

@@ -0,0 +1,38 @@
<?php
/**
* OAuth 2.0 Secure key default algorithm
*
* @package php-loep/oauth2-server
* @author Alex Bilbie <hello@alexbilbie.com>
* @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\Util\KeyAlgorithm;
class DefaultAlgorithm implements KeyAlgorithmInterface
{
/**
* @param int $len
* @return string
* @throws \Exception
*/
public function make($len = 40)
{
// We generate twice as many bytes here because we want to ensure we have
// enough after we base64 encode it to get the length we need because we
// take out the "/", "+", and "=" characters.
$bytes = openssl_random_pseudo_bytes($len * 2, $strong);
// We want to stop execution if the key fails because, well, that is bad.
if ($bytes === false || $strong === false) {
// @codeCoverageIgnoreStart
throw new \Exception('Error Generating Key');
// @codeCoverageIgnoreEnd
}
return substr(str_replace(array('/', '+', '='), '', base64_encode($bytes)), 0, $len);
}
}

View File

@@ -0,0 +1,18 @@
<?php
/**
* OAuth 2.0 Key algorithm interface
*
* @package php-loep/oauth2-server
* @author Alex Bilbie <hello@alexbilbie.com>
* @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\Util\KeyAlgorithm;
interface KeyAlgorithmInterface
{
public function make($len = 40);
}

View File

@@ -0,0 +1,31 @@
<?php
/**
* OAuth 2.0 Redirect URI generator
*
* @package php-loep/oauth2-server
* @author Alex Bilbie <hello@alexbilbie.com>
* @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\Util;
/**
* RedirectUri class
*/
class RedirectUri
{
/**
* Generate a new redirect uri
* @param string $uri The base URI
* @param array $params The query string parameters
* @param string $queryDelimeter The query string delimeter (default: "?")
* @return string The updated URI
*/
public static function make($uri, $params = array(), $queryDelimeter = '?')
{
$uri .= (strstr($uri, $queryDelimeter) === false) ? $queryDelimeter : '&';
return $uri.http_build_query($params);
}
}

View File

@@ -0,0 +1,146 @@
<?php
/**
* OAuth 2.0 Request class
*
* @package php-loep/oauth2-server
* @author Alex Bilbie <hello@alexbilbie.com>
* @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\Util;
use OutOfBoundsException;
use InvalidMethodCallException;
use InvalidArgumentException;
class Request implements RequestInterface
{
protected $get = array();
protected $post = array();
protected $cookies = array();
protected $files = array();
protected $server = array();
protected $headers = array();
public static function buildFromGlobals()
{
return new static($_GET, $_POST, $_COOKIE, $_FILES, $_SERVER);
}
public function __construct(array $get = array(), array $post = array(), array $cookies = array(), array $files = array(), array $server = array(), $headers = array())
{
$this->get = $get;
$this->post = $post;
$this->cookies = $cookies;
$this->files = $files;
$this->server = $server;
if (empty($headers)) {
$this->headers = $this->readHeaders();
} else {
$this->headers = $this->normalizeHeaders($headers);
}
}
public function get($index = null, $default = null)
{
return $this->getPropertyValue('get', $index, $default);
}
public function post($index = null, $default = null)
{
return $this->getPropertyValue('post', $index, $default);
}
public function file($index = null, $default = null)
{
return $this->getPropertyValue('files', $index, $default);
}
public function cookie($index = null, $default = null)
{
return $this->getPropertyValue('cookies', $index, $default);
}
public function server($index = null, $default = null)
{
return $this->getPropertyValue('server', $index, $default);
}
public function header($index = null, $default = null)
{
return $this->getPropertyValue('headers', $index, $default);
}
protected function readHeaders()
{
if (function_exists('getallheaders')) {
// @codeCoverageIgnoreStart
$headers = getallheaders();
} else {
// @codeCoverageIgnoreEnd
$headers = array();
foreach ($this->server() as $name => $value) {
if (substr($name, 0, 5) == 'HTTP_') {
$name = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))));
$headers[$name] = $value;
}
}
}
return $this->normalizeHeaders($headers);
}
protected function getPropertyValue($property, $index = null, $default = null)
{
if ( ! isset($this->{$property})) {
throw new InvalidArgumentException("Property '$property' does not exist.");
}
if (is_null($index)) {
return $this->{$property};
}
if ( ! array_key_exists($index, $this->{$property})) {
return $default;
}
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[ucfirst($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;
}
}

View File

@@ -0,0 +1,29 @@
<?php
/**
* OAuth 2.0 Request class interface
*
* @package php-loep/oauth2-server
* @author Alex Bilbie <hello@alexbilbie.com>
* @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\Util;
interface RequestInterface
{
public function get($index = null);
public function post($index = null);
public function cookie($index = null);
public function file($index = null);
public function server($index = null);
public function header($index = null);
}

View File

@@ -0,0 +1,54 @@
<?php
/**
* OAuth 2.0 Secure key generator
*
* @package php-loep/oauth2-server
* @author Alex Bilbie <hello@alexbilbie.com>
* @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\Util;
use League\OAuth2\Server\Util\KeyAlgorithm\DefaultAlgorithm;
use League\OAuth2\Server\Util\KeyAlgorithm\KeyAlgorithmInterface;
/**
* SecureKey class
*/
class SecureKey
{
protected static $algorithm;
/**
* Generate a new unique code
* @param integer $len Length of the generated code
* @return string
*/
public static function make($len = 40)
{
return self::getAlgorithm()->make($len);
}
/**
* @param KeyAlgorithmInterface $algorithm
*/
public static function setAlgorithm(KeyAlgorithmInterface $algorithm)
{
self::$algorithm = $algorithm;
}
/**
* @return KeyAlgorithmInterface
*/
public static function getAlgorithm()
{
if (!self::$algorithm) {
self::$algorithm = new DefaultAlgorithm();
}
return self::$algorithm;
}
}

View File

@@ -1,332 +0,0 @@
<?php
namespace Oauth2\Authentication;
interface Database
{
/**
* Validate a client
*
* Database query:
*
* <code>
* # Client ID + redirect URI
* SELECT clients.id FROM clients LEFT JOIN client_endpoints ON
* client_endpoints.client_id = clients.id WHERE clients.id = $clientId AND
* client_endpoints.redirect_uri = $redirectUri
*
* # Client ID + client secret
* SELECT clients.id FROM clients WHERE clients.id = $clientId AND
* clients.secret = $clientSecret
*
* # Client ID + client secret + redirect URI
* SELECT clients.id FROM clients LEFT JOIN client_endpoints ON
* client_endpoints.client_id = clients.id WHERE clients.id = $clientId AND
* clients.secret = $clientSecret AND client_endpoints.redirect_uri =
* $redirectUri
* </code>
*
* Response:
*
* <code>
* Array
* (
* [client_id] => (string) The client ID
* [client secret] => (string) The client secret
* [redirect_uri] => (string) The redirect URI used in this request
* [name] => (string) The name of the client
* )
* </code>
*
* @param string $clientId The client's ID
* @param string $clientSecret The client's secret (default = "null")
* @param string $redirectUri The client's redirect URI (default = "null")
* @return bool|array Returns false if the validation fails, array on success
*/
public function validateClient(
$clientId,
$clientSecret = null,
$redirectUri = null
);
/**
* Create a new OAuth session
*
* Database query:
*
* <code>
* INSERT INTO oauth_sessions (client_id, redirect_uri, owner_type,
* owner_id, auth_code, access_token, stage, first_requested, last_updated)
* VALUES ($clientId, $redirectUri, $type, $typeId, $authCode,
* $accessToken, $stage, UNIX_TIMESTAMP(NOW()), UNIX_TIMESTAMP(NOW()))
* </code>
*
* @param string $clientId The client ID
* @param string $redirectUri The redirect URI
* @param string $type The session owner's type (default = "user")
* @param string $typeId The session owner's ID (default = "null")
* @param string $authCode The authorisation code (default = "null")
* @param string $accessToken The access token (default = "null")
* @param string $stage The stage of the session (default ="request")
* @return int The session ID
*/
public function newSession(
$clientId,
$redirectUri,
$type = 'user',
$typeId = null,
$authCode = null,
$accessToken = null,
$accessTokenExpire = null,
$stage = 'requested'
);
/**
* Update an OAuth session
*
* Database query:
*
* <code>
* UPDATE oauth_sessions SET auth_code = $authCode, access_token =
* $accessToken, stage = $stage, last_updated = UNIX_TIMESTAMP(NOW()) WHERE
* id = $sessionId
* </code>
*
* @param string $sessionId The session ID
* @param string $authCode The authorisation code (default = "null")
* @param string $accessToken The access token (default = "null")
* @param string $stage The stage of the session (default ="request")
* @return void
*/
public function updateSession(
$sessionId,
$authCode = null,
$accessToken = null,
$accessTokenExpire = null,
$stage = 'requested'
);
/**
* Delete an OAuth session
*
* <code>
* DELETE FROM oauth_sessions WHERE client_id = $clientId AND owner_type =
* $type AND owner_id = $typeId
* </code>
*
* @param string $clientId The client ID
* @param string $type The session owner's type
* @param string $typeId The session owner's ID
* @return void
*/
public function deleteSession(
$clientId,
$type,
$typeId
);
/**
* Validate that an authorisation code is valid
*
* Database query:
*
* <code>
* SELECT id FROM oauth_sessions WHERE client_id = $clientID AND
* redirect_uri = $redirectUri AND auth_code = $authCode
* </code>
*
* Response:
*
* <code>
* Array
* (
* [id] => (int) The session ID
* [client_id] => (string) The client ID
* [redirect_uri] => (string) The redirect URI
* [owner_type] => (string) The session owner type
* [owner_id] => (string) The session owner's ID
* [auth_code] => (string) The authorisation code
* [stage] => (string) The session's stage
* [first_requested] => (int) Unix timestamp of the time the session was
* first generated
* [last_updated] => (int) Unix timestamp of the time the session was
* last updated
* )
* </code>
*
* @param string $clientId The client ID
* @param string $redirectUri The redirect URI
* @param string $authCode The authorisation code
* @return int|bool Returns the session ID if the auth code
* is valid otherwise returns false
*/
public function validateAuthCode(
$clientId,
$redirectUri,
$authCode
);
/**
* Return the session ID for a given session owner and client combination
*
* Database query:
*
* <code>
* SELECT id FROM oauth_sessions WHERE client_id = $clientId
* AND owner_type = $type AND owner_id = $typeId
* </code>
*
* @param string $type The session owner's type
* @param string $typeId The session owner's ID
* @param string $clientId The client ID
* @return string|null Return the session ID as an integer if
* found otherwise returns false
*/
public function hasSession(
$type,
$typeId,
$clientId
);
/**
* Return the access token for a given session
*
* Database query:
*
* <code>
* SELECT access_token FROM oauth_sessions WHERE id = $sessionId
* </code>
*
* @param int $sessionId The OAuth session ID
* @return string|null Returns the access token as a string if
* found otherwise returns null
*/
public function getAccessToken($sessionId);
/**
* Removes an authorisation code associated with a session
*
* Database query:
*
* <code>
* UPDATE oauth_sessions SET auth_code = NULL WHERE id = $sessionId
* </code>
*
* @param int $sessionId The OAuth session ID
* @return void
*/
public function removeAuthCode($sessionId);
/**
* Sets a sessions access token
*
* Database query:
*
* <code>
* UPDATE oauth_sessions SET access_token = $accessToken WHERE id =
* $sessionId
* </code>
*
* @param int $sessionId The OAuth session ID
* @param string $accessToken The access token
* @return void
*/
public function setAccessToken(
$sessionId,
$accessToken
);
/**
* Associates a session with a scope
*
* Database query:
*
* <code>
* INSERT INTO oauth_session_scopes (session_id, scope) VALUE ($sessionId,
* $scope)
* </code>
*
* @param int $sessionId The session ID
* @param string $scope The scope
* @return void
*/
public function addSessionScope(
$sessionId,
$scope
);
/**
* Return information about a scope
*
* Database query:
*
* <code>
* SELECT * FROM scopes WHERE scope = $scope
* </code>
*
* Response:
*
* <code>
* Array
* (
* [id] => (int) The scope's ID
* [scope] => (string) The scope itself
* [name] => (string) The scope's name
* [description] => (string) The scope's description
* )
* </code>
*
* @param string $scope The scope
* @return array
*/
public function getScope($scope);
/**
* Associate a session's scopes with an access token
*
* Database query:
*
* <code>
* UPDATE oauth_session_scopes SET access_token = $accessToken WHERE
* session_id = $sessionId
* </code>
*
* @param int $sessionId The session ID
* @param string $accessToken The access token
* @return void
*/
public function updateSessionScopeAccessToken(
$sessionId,
$accessToken
);
/**
* Return the scopes associated with an access token
*
* Database query:
*
* <code>
* SELECT scopes.scope, scopes.name, scopes.description FROM
* oauth_session_scopes JOIN scopes ON oauth_session_scopes.scope =
* scopes.scope WHERE access_token = $accessToken
* </code>
*
* Response:
*
* <code>
* Array
* (
* [0] => Array
* (
* [scope] => (string) The scope
* [name] => (string) The scope's name
* [description] => (string) The scope's description
* )
* )
* </code>
*
* @param string $accessToken The access token
* @return array
*/
public function accessTokenScopes($accessToken);
}

View File

@@ -1,559 +0,0 @@
<?php
namespace Oauth2\Authentication;
class ClientException extends \Exception
{
}
class UserException extends \Exception
{
}
class ServerException extends \Exception
{
}
class Server
{
/**
* Reference to the database abstractor
* @var object
*/
private $_db = null;
/**
* Server configuration
* @var array
*/
private $_config = array(
'scope_delimeter' => ',',
'access_token_ttl' => null
);
/**
* Supported response types
* @var array
*/
private $_responseTypes = array(
'code'
);
/**
* Supported grant types
* @var array
*/
private $_grantTypes = array(
'authorization_code'
);
/**
* Exception error codes
* @var array
*/
public $exceptionCodes = array(
0 => 'invalid_request',
1 => 'unauthorized_client',
2 => 'access_denied',
3 => 'unsupported_response_type',
4 => 'invalid_scope',
5 => 'server_error',
6 => 'temporarily_unavailable',
7 => 'unsupported_grant_type',
8 => 'invalid_client',
9 => 'invalid_grant'
);
/**
* Error codes.
*
* To provide i8ln errors just overwrite the keys
*
* @var array
*/
public $errors = array(
'invalid_request' => 'The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Check the "%s" parameter.',
'unauthorized_client' => 'The client is not authorized to request an access token using this method.',
'access_denied' => 'The resource owner or authorization server denied the request.',
'unsupported_response_type' => 'The authorization server does not support obtaining an access token using this method.',
'invalid_scope' => 'The requested scope is invalid, unknown, or malformed. Check the "%s" scope.',
'server_error' => 'The authorization server encountered an unexpected condition which prevented it from fulfilling the request.',
'temporarily_unavailable' => 'The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server.',
'unsupported_grant_type' => 'The authorization grant type is not supported by the authorization server',
'invalid_client' => 'Client authentication failed',
'invalid_grant' => 'The provided authorization grant is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client. Check the "%s" parameter.'
);
/**
* Constructor
*
* @access public
* @param array $options Optional list of options to overwrite the defaults
* @return void
*/
public function __construct($options = null)
{
if ($options !== null) {
$this->options = array_merge($this->_config, $options);
}
}
/**
* Register a database abstrator class
*
* @access public
* @param object $db A class that implements OAuth2ServerDatabase
* @return void
*/
public function registerDbAbstractor($db)
{
$this->_db = $db;
}
/**
* Check client authorise parameters
*
* @access public
* @param array $authParams Optional array of parsed $_GET keys
* @return array Authorise request parameters
*/
public function checkClientAuthoriseParams($authParams = null)
{
$params = array();
// Client ID
if ( ! isset($authParams['client_id']) && ! isset($_GET['client_id'])) {
throw new ClientException(sprintf($this->errors['invalid_request'], 'client_id'), 0);
} else {
$params['client_id'] = (isset($authParams['client_id'])) ?
$authParams['client_id'] :
$_GET['client_id'];
}
// Redirect URI
if ( ! isset($authParams['redirect_uri']) && ! isset($_GET['redirect_uri'])) {
throw new ClientException(sprintf($this->errors['invalid_request'], 'redirect_uri'), 0);
} else {
$params['redirect_uri'] = (isset($authParams['redirect_uri'])) ?
$authParams['redirect_uri'] :
$_GET['redirect_uri'];
}
// Validate client ID and redirect URI
$clientDetails = $this->_dbCall(
'validateClient',
$params['client_id'],
null,
$params['redirect_uri']
);
if ($clientDetails === false) {
throw new ClientException($this->errors['invalid_client'], 8);
}
$params['client_details'] = $clientDetails;
// Response type
if ( ! isset($authParams['response_type']) && ! isset($_GET['response_type'])) {
throw new ClientException(sprintf($this->errors['invalid_request'], 'response_type'), 0);
} else {
$params['response_type'] = (isset($authParams['response_type'])) ?
$authParams['response_type'] :
$_GET['response_type'];
// Ensure response type is one that is recognised
if ( ! in_array($params['response_type'], $this->_responseTypes)) {
throw new ClientException($this->errors['unsupported_response_type'], 3);
}
}
// Get and validate scopes
if (isset($authParams['scope']) || isset($_GET['scope'])) {
$scopes = (isset($_GET['scope'])) ?
$_GET['scope'] :
$authParams['scope'];
$scopes = explode($this->_config['scope_delimeter'], $scopes);
// Remove any junk scopes
for ($i = 0; $i < count($scopes); $i++) {
$scopes[$i] = trim($scopes[$i]);
if ($scopes[$i] === '') {
unset($scopes[$i]);
}
}
if (count($scopes) === 0) {
throw new ClientException(sprintf($this->errors['invalid_request'], 'scope'), 0);
}
$params['scopes'] = array();
foreach ($scopes as $scope) {
$scopeDetails = $this->_dbCall(
'getScope',
$scope
);
if ($scopeDetails === false) {
throw new ClientException(sprintf($this->errors['invalid_scope'], $scope), 4);
}
$params['scopes'][] = $scopeDetails;
}
}
return $params;
}
/**
* Parse a new authorise request
*
* @param string $type The session owner's type
* @param string $typeId The session owner's ID
* @param array $authoriseParams The authorise request $_GET parameters
* @return string An authorisation code
*/
public function newAuthoriseRequest($type, $typeId, $authoriseParams)
{
// Remove any old sessions the user might have
$this->_dbCall(
'deleteSession',
$authoriseParams['client_id'],
$type,
$typeId
);
// Create the new auth code
$authCode = $this->newAuthCode(
$authoriseParams['client_id'],
'user',
$typeId,
$authoriseParams['redirect_uri'],
$authoriseParams['scopes']
);
return $authCode;
}
/**
* Generate a unique code
*
* Generate a unique code for an authorisation code, or token
*
* @return string A unique code
*/
private function generateCode()
{
return sha1(uniqid(microtime()));
}
/**
* Create a new authorisation code
*
* @param string $clientId The client ID
* @param string $type The type of the owner of the session
* @param string $typeId The session owner's ID
* @param string $redirectUri The redirect URI
* @param array $scopes The requested scopes
* @param string $accessToken The access token (default = null)
* @return string An authorisation code
*/
private function newAuthCode($clientId, $type, $typeId, $redirectUri, $scopes = array(), $accessToken = null)
{
$authCode = $this->generateCode();
// If an access token exists then update the existing session with the
// new authorisation code otherwise create a new session
if ($accessToken !== null) {
$this->_dbCall(
'updateSession',
$clientId,
$type,
$typeId,
$authCode,
$accessToken,
'requested'
);
} else {
// Delete any existing sessions just to be sure
$this->_dbCall('deleteSession', $clientId, $type, $typeId);
// Create a new session
$sessionId = $this->_dbCall(
'newSession',
$clientId,
$redirectUri,
$type,
$typeId,
$authCode,
null,
null,
'requested'
);
// Add the scopes
foreach ($scopes as $key => $scope) {
$this->_dbCall(
'addSessionScope',
$sessionId,
$scope['scope']
);
}
}
return $authCode;
}
/**
* Issue an access token
*
* @access public
*
* @param array $authParams Optional array of parsed $_POST keys
*
* @return array Authorise request parameters
*/
public function issueAccessToken($authParams = null)
{
$params = array();
if ( ! isset($authParams['grant_type']) && ! isset($_POST['grant_type'])) {
throw new ClientException(sprintf($this->errors['invalid_request'], 'grant_type'), 0);
} else {
$params['grant_type'] = (isset($authParams['grant_type'])) ?
$authParams['grant_type'] :
$_POST['grant_type'];
// Ensure grant type is one that is recognised
if ( ! in_array($params['grant_type'], $this->_grantTypes)) {
throw new ClientException($this->errors['unsupported_grant_type'], 7);
}
}
switch ($params['grant_type'])
{
case 'authorization_code': // Authorization code grant
return $this->completeAuthCodeGrant($authParams, $params);
break;
case 'refresh_token': // Refresh token
case 'password': // Resource owner password credentials grant
case 'client_credentials': // Client credentials grant
default: // Unsupported
throw new ServerException($this->errors['server_error'] . 'Tried to process an unsuppported grant type.', 5);
break;
}
}
/**
* Complete the authorisation code grant
*
* @access private
*
* @param array $authParams Array of parsed $_POST keys
* @param array $params Generated parameters from issueAccessToken()
*
* @return array Authorise request parameters
*/
private function completeAuthCodeGrant($authParams = array(), $params = array())
{
// Client ID
if ( ! isset($authParams['client_id']) && ! isset($_POST['client_id'])) {
throw new ClientException(sprintf($this->errors['invalid_request'], 'client_id'), 0);
} else {
$params['client_id'] = (isset($authParams['client_id'])) ?
$authParams['client_id'] :
$_POST['client_id'];
}
// Client secret
if ( ! isset($authParams['client_secret']) && ! isset($_POST['client_secret'])) {
throw new ClientException(sprintf($this->errors['invalid_request'], 'client_secret'), 0);
} else {
$params['client_secret'] = (isset($authParams['client_secret'])) ?
$authParams['client_secret'] :
$_POST['client_secret'];
}
// Redirect URI
if ( ! isset($authParams['redirect_uri']) && ! isset($_POST['redirect_uri'])) {
throw new ClientException(sprintf($this->errors['invalid_request'], 'redirect_uri'), 0);
} else {
$params['redirect_uri'] = (isset($authParams['redirect_uri'])) ?
$authParams['redirect_uri'] :
$_POST['redirect_uri'];
}
// Validate client ID and redirect URI
$clientDetails = $this->_dbCall(
'validateClient',
$params['client_id'],
$params['client_secret'],
$params['redirect_uri']
);
if ($clientDetails === false) {
throw new ClientException($this->errors['invalid_client'], 8);
}
// The authorization code
if ( ! isset($authParams['code']) && ! isset($_POST['code'])) {
throw new ClientException(sprintf($this->errors['invalid_request'], 'code'), 0);
} else {
$params['code'] = (isset($authParams['code'])) ?
$authParams['code'] :
$_POST['code'];
}
// Verify the authorization code matches the client_id and the
// request_uri
$session = $this->_dbCall(
'validateAuthCode',
$params['client_id'],
$params['redirect_uri'],
$params['code']
);
if ( ! $session) {
throw new ClientException(sprintf($this->errors['invalid_grant'], 'code'), 9);
} else {
// A session ID was returned so update it with an access token,
// remove the authorisation code, change the stage to 'granted'
$accessToken = $this->generateCode();
$accessTokenExpires = ($this->_config['access_token_ttl'] === null) ?
null :
time() + $this->_config['access_token_ttl'];
$this->_dbCall(
'updateSession',
$session['id'],
null,
$accessToken,
$accessTokenExpires,
'granted'
);
// Update the session's scopes to reference the access token
$this->_dbCall(
'updateSessionScopeAccessToken',
$session['id'],
$accessToken
);
return array(
'access_token' => $accessToken,
'token_type' => 'bearer',
'expires_in' => $this->_config['access_token_ttl']
);
}
}
/**
* Generates the redirect uri with appended params
*
* @param string $redirectUri The redirect URI
* @param array $params The parameters to be appended to the URL
* @param string $query_delimeter The query string delimiter (default: ?)
*
* @return string The updated redirect URI
*/
public function redirectUri($redirectUri, $params = array(), $queryDelimeter = '?')
{
if (strstr($redirectUri, $queryDelimeter)) {
$redirectUri = $redirectUri . '&' . http_build_query($params);
} else {
$redirectUri = $redirectUri . $queryDelimeter . http_build_query($params);
}
return $redirectUri;
}
/**
* Call database methods from the abstractor
*
* @return mixed The query result
*/
private function _dbCall()
{
if ($this->_db === null) {
throw new ServerException('No registered database abstractor');
}
if ( ! $this->_db instanceof Database) {
throw new ServerException('Registered database abstractor is not an instance of Oauth2\Authentication\Database');
}
$args = func_get_args();
$method = $args[0];
unset($args[0]);
$params = array_values($args);
return call_user_func_array(array($this->_db, $method), $params);
}
}

View File

@@ -1,230 +0,0 @@
<?php
namespace OAuth2\Client;
use Guzzle\Service\Client as GuzzleClient;
class IDPException extends \Exception
{
protected $result;
public function __construct($result)
{
$this->result = $result;
$code = isset($result['code']) ? $result['code'] : 0;
if (isset($result['error'])) {
// OAuth 2.0 Draft 10 style
$message = $result['error'];
} elseif (isset($result['message'])) {
// cURL style
$message = $result['message'];
} else {
$message = 'Unknown Error.';
}
parent::__construct($message['message'], $message['code']);
}
public function getType()
{
if (isset($this->result['error'])) {
$message = $this->result['error'];
if (is_string($message)) {
// OAuth 2.0 Draft 10 style
return $message;
}
}
return 'Exception';
}
/**
* To make debugging easier.
*
* @returns
* The string representation of the error.
*/
public function __toString()
{
$str = $this->getType() . ': ';
if ($this->code != 0) {
$str .= $this->code . ': ';
}
return $str . $this->message;
}
}
abstract class IDP {
public $clientId = '';
public $clientSecret = '';
public $redirectUri = '';
public $name;
public $uidKey = 'uid';
public $scopes = array();
public $method = 'post';
public $scopeSeperator = ',';
public $responseType = 'json';
public function __construct($options)
{
foreach ($options as $option => $value) {
if (isset($this->{$option})) {
$this->{$option} = $value;
}
}
}
abstract public function urlAuthorize();
abstract public function urlAccessToken();
abstract public function urlUserDetails(\Oauth2\Client\Token\Access $token);
abstract public function userDetails($response, \Oauth2\Client\Token\Access $token);
public function authorize($options = array())
{
$state = md5(uniqid(rand(), TRUE));
setcookie($this->name.'_authorize_state', $state);
$params = array(
'client_id' => $this->clientId,
'redirect_uri' => $this->redirectUri,
'state' => $state,
'scope' => is_array($this->scope) ? implode($this->scopeSeperator, $this->scope) : $this->scope,
'response_type' => isset($options['response_type']) ? $options['response_type'] : 'code',
'approval_prompt' => 'force' // - google force-recheck
);
header('Location: ' . $this->urlAuthorize().'?'.http_build_query($params));
exit;
}
public function getAccessToken($code = NULL, $options = array())
{
if ($code === NULL) {
throw new \BadMethodCallException('Missing authorization code');
}
$params = array(
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
'grant_type' => isset($options['grantType']) ? $options['grantType'] : 'authorization_code',
);
switch ($params['grant_type']) {
case 'authorization_code':
$params['code'] = $code;
$params['redirect_uri'] = isset($options['redirectUri']) ? $options['redirectUri'] : $this->redirectUri;
break;
case 'refresh_token':
$params['refresh_token'] = $code;
break;
}
try {
switch ($this->method) {
case 'get':
$client = new GuzzleClient($this->urlAccessToken() . '?' . http_build_query($params));
$request = $client->send();
$response = $request->getBody();
break;
case 'post':
$client = new GuzzleClient($this->urlAccessToken());
$request = $client->post(null, null, $params)->send();
$response = $request->getBody();
break;
}
}
catch (\Guzzle\Http\Exception\BadResponseException $e)
{
$raw_response = explode("\n", $e->getResponse());
$response = end($raw_response);
}
switch ($this->responseType) {
case 'json':
$result = json_decode($response, true);
break;
case 'string':
parse_str($response, $result);
break;
}
if (isset($result['error']) && ! empty($result['error'])) {
throw new \Oauth2\Client\IDPException($result);
}
switch ($params['grant_type']) {
case 'authorization_code':
return \Oauth2\Client\Token::factory('access', $result);
break;
case 'refresh_token':
return \Oauth2\Client\Token::factory('refresh', $result);
break;
}
}
public function getUserDetails(\Oauth2\Client\Token\Access $token)
{
$url = $this->urlUserDetails($token);
try {
$client = new GuzzleClient($url);
$request = $client->get()->send();
$response = $request->getBody();
return $this->userDetails(json_decode($response), $token);
}
catch (\Guzzle\Http\Exception\BadResponseException $e)
{
$raw_response = explode("\n", $e->getResponse());
throw new \Oauth2\Client\IDPException(end($raw_response));
}
}
}

View File

@@ -1,19 +0,0 @@
<?php
namespace OAuth2\Client;
class Provider
{
private function __constuct() {}
public static function factory($name, array $options = null)
{
if ( ! class_exists($name)) {
throw new OAuth2\Client\Exception('There is no identity provider called: '.$name);
}
return new $name($options);
}
}

View File

@@ -1,42 +0,0 @@
<?php
class Blooie extends Oauth2\Client\IDP
{
public $scope = array('user.profile', 'user.picture');
public $method = 'POST';
public function urlAuthorize()
{
return 'https://bloo.ie/oauth';
}
public function urlAccessToken()
{
return 'https://bloo.ie/oauth/access_token';
}
public function getUserInfo(Oauth2\Token\Access $token)
{
$url = 'https://graph.facebook.com/me?'.http_build_query(array(
'access_token' => $token->access_token,
));
$user = json_decode(file_get_contents($url));
return array(
'uid' => $user->id,
'nickname' => $user->username,
'name' => $user->name,
'first_name' => $user->first_name,
'last_name' => $user->last_name,
'email' => isset($user->email) ? $user->email : null,
'location' => isset($user->hometown->name) ? $user->hometown->name : null,
'description' => isset($user->bio) ? $user->bio : null,
'image' => 'https://graph.facebook.com/me/picture?type=normal&access_token='.$token->access_token,
'urls' => array(
'Facebook' => $user->link,
),
);
}
}

View File

@@ -1,49 +0,0 @@
<?php
/**
* Facebook OAuth2 Provider
*
* @package CodeIgniter/OAuth2
* @category Provider
* @author Phil Sturgeon
* @copyright (c) 2012 HappyNinjas Ltd
* @license http://philsturgeon.co.uk/code/dbad-license
*/
class Facebook extends Oauth2\Client\IDP
{
protected $scope = array('offline_access', 'email', 'read_stream');
public function urlAuthorize()
{
return 'https://www.facebook.com/dialog/oauth';
}
public function urlAccessToken()
{
return 'https://graph.facebook.com/oauth/access_token';
}
public function getUserInfo(Oauth2\Token\Access $token)
{
$url = 'https://graph.facebook.com/me?'.http_build_query(array(
'access_token' => $token->access_token,
));
$user = json_decode(file_get_contents($url));
return array(
'uid' => $user->id,
'nickname' => isset($user->username) ? $user->username : null,
'name' => $user->name,
'first_name' => $user->first_name,
'last_name' => $user->last_name,
'email' => isset($user->email) ? $user->email : null,
'location' => isset($user->hometown->name) ? $user->hometown->name : null,
'description' => isset($user->bio) ? $user->bio : null,
'image' => 'https://graph.facebook.com/me/picture?type=normal&access_token='.$token->access_token,
'urls' => array(
'Facebook' => $user->link,
),
);
}
}

View File

@@ -1,45 +0,0 @@
<?php
/**
* Foursquare OAuth2 Provider
*
* @package CodeIgniter/OAuth2
* @category Provider
* @author Phil Sturgeon
* @copyright (c) 2012 HappyNinjas Ltd
* @license http://philsturgeon.co.uk/code/dbad-license
*/
class Foursquare extends Oauth2\Client\IDP
{
public $method = 'POST';
public function urlAuthorize()
{
return 'https://foursquare.com/oauth2/authenticate';
}
public function urlAccessToken()
{
return 'https://foursquare.com/oauth2/access_token';
}
public function getUserInfo(Oauth2\Token\Access $token)
{
$url = 'https://api.foursquare.com/v2/users/self?'.http_build_query(array(
'oauth_token' => $token->access_token,
));
$response = json_decode(file_get_contents($url));
$user = $response->response->user;
// Create a response from the request
return array(
'uid' => $user->id,
'name' => sprintf('%s %s', $user->firstName, $user->lastName),
'email' => $user->contact->email,
'image' => $user->photo,
'location' => $user->homeCity,
);
}
}

View File

@@ -1,43 +0,0 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* GitHub OAuth2 Provider
*
* @package CodeIgniter/OAuth2
* @category Provider
* @author Phil Sturgeon
* @copyright (c) 2012 HappyNinjas Ltd
* @license http://philsturgeon.co.uk/code/dbad-license
*/
class OAuth2_Provider_Github extends Oauth2\Client\IDP
{
public function urlAuthorize()
{
return 'https://github.com/login/oauth/authorize';
}
public function urlAccessToken()
{
return 'https://github.com/login/oauth/access_token';
}
public function getUserInfo(Oauth\Token\Access $token)
{
$url = 'https://api.github.com/user?'.http_build_query(array(
'access_token' => $token->access_token,
));
$user = json_decode(file_get_contents($url));
return array(
'uid' => $user->id,
'nickname' => $user->login,
'name' => $user->name,
'email' => $user->email,
'urls' => array(
'GitHub' => 'http://github.com/'.$user->login,
'Blog' => $user->blog,
),
);
}
}

View File

@@ -1,84 +0,0 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* Google OAuth2 Provider
*
* @package CodeIgniter/OAuth2
* @category Provider
* @author Phil Sturgeon
* @copyright (c) 2012 HappyNinjas Ltd
* @license http://philsturgeon.co.uk/code/dbad-license
*/
class OAuth2_Provider_Google extends OAuth2_Provider
{
/**
* @var string the method to use when requesting tokens
*/
public $method = 'POST';
/**
* @var string scope separator, most use "," but some like Google are spaces
*/
public $scope_seperator = ' ';
public function url_authorize()
{
return 'https://accounts.google.com/o/oauth2/auth';
}
public function url_access_token()
{
return 'https://accounts.google.com/o/oauth2/token';
}
public function __construct(array $options = array())
{
// Now make sure we have the default scope to get user data
empty($options['scope']) and $options['scope'] = array(
'https://www.googleapis.com/auth/userinfo.profile',
'https://www.googleapis.com/auth/userinfo.email'
);
// Array it if its string
$options['scope'] = (array) $options['scope'];
parent::__construct($options);
}
/*
* Get access to the API
*
* @param string The access code
* @return object Success or failure along with the response details
*/
public function access($code, $options = array())
{
if ($code === null)
{
throw new OAuth2_Exception(array('message' => 'Expected Authorization Code from '.ucfirst($this->name).' is missing'));
}
return parent::access($code, $options);
}
public function get_user_info(OAuth2_Token_Access $token)
{
$url = 'https://www.googleapis.com/oauth2/v1/userinfo?alt=json&'.http_build_query(array(
'access_token' => $token->access_token,
));
$user = json_decode(file_get_contents($url), true);
return array(
'uid' => $user['id'],
'nickname' => url_title($user['name'], '_', true),
'name' => $user['name'],
'first_name' => $user['given_name'],
'last_name' => $user['family_name'],
'email' => $user['email'],
'location' => null,
'image' => (isset($user['picture'])) ? $user['picture'] : null,
'description' => null,
'urls' => array(),
);
}
}

View File

@@ -1,48 +0,0 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* Instagram OAuth2 Provider
*
* @package CodeIgniter/OAuth2
* @category Provider
* @author Phil Sturgeon
* @copyright (c) 2012 HappyNinjas Ltd
* @license http://philsturgeon.co.uk/code/dbad-license
*/
class OAuth2_Provider_Instagram extends OAuth2_Provider
{
/**
* @var string scope separator, most use "," but some like Google are spaces
*/
public $scope_seperator = '+';
/**
* @var string the method to use when requesting tokens
*/
public $method = 'POST';
public function url_authorize()
{
return 'https://api.instagram.com/oauth/authorize';
}
public function url_access_token()
{
return 'https://api.instagram.com/oauth/access_token';
}
public function get_user_info(OAuth2_Token_Access $token)
{
$user = $token->user;
return array(
'uid' => $user->id,
'nickname' => $user->username,
'name' => $user->full_name,
'image' => $user->profile_picture,
'urls' => array(
'website' => $user->website,
),
);
}
}

View File

@@ -1,36 +0,0 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* Mailchimp OAuth2 Provider
*
* @package CodeIgniter/OAuth2
* @category Provider
* @author Phil Sturgeon
* @copyright (c) 2012 HappyNinjas Ltd
* @license http://philsturgeon.co.uk/code/dbad-license
*/
class OAuth2_Provider_Mailchimp extends OAuth2_Provider
{
/**
* @var string the method to use when requesting tokens
*/
protected $method = 'POST';
public function url_authorize()
{
return 'https://login.mailchimp.com/oauth2/authorize';
}
public function url_access_token()
{
return 'https://login.mailchimp.com/oauth2/token';
}
public function get_user_info(OAuth2_Token_Access $token)
{
// Create a response from the request
return array(
'uid' => $token->access_token,
);
}
}

View File

@@ -1,73 +0,0 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* Mailru OAuth2 Provider
*
* @package CodeIgniter/OAuth2
* @category Provider
* @author Lavr Lyndin
*/
class OAuth2_Provider_Mailru extends OAuth2_Provider
{
public $method = 'POST';
public function url_authorize()
{
return 'https://connect.mail.ru/oauth/authorize';
}
public function url_access_token()
{
return 'https://connect.mail.ru/oauth/token';
}
protected function sign_server_server(array $request_params, $secret_key)
{
ksort($request_params);
$params = '';
foreach ($request_params as $key => $value) {
$params .= "$key=$value";
}
return md5($params . $secret_key);
}
public function get_user_info(OAuth2_Token_Access $token)
{
$request_params = array(
'app_id' => $this->client_id,
'method' => 'users.getInfo',
'uids' => $token->uid,
'access_token' => $token->access_token,
'secure' => 1
);
$sig = $this->sign_server_server($request_params,$this->client_secret);
$url = 'http://www.appsmail.ru/platform/api?'.http_build_query($request_params).'&sig='.$sig;
$user = json_decode(file_get_contents($url));
return array(
'uid' => $user[0]->uid,
'nickname' => $user[0]->nick,
'name' => $user[0]->first_name.' '.$user[0]->last_name,
'first_name' => $user[0]->first_name,
'last_name' => $user[0]->last_name,
'email' => isset($user[0]->email) ? $user[0]->email : null,
'image' => isset($user[0]->pic_big) ? $user[0]->pic_big : null,
);
}
public function authorize($options = array())
{
$state = md5(uniqid(rand(), TRUE));
get_instance()->session->set_userdata('state', $state);
$params = array(
'client_id' => $this->client_id,
'redirect_uri' => isset($options['redirect_uri']) ? $options['redirect_uri'] : $this->redirect_uri,
'response_type' => 'code',
);
redirect($this->url_authorize().'?'.http_build_query($params));
}
}

View File

@@ -1,59 +0,0 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* PayPal OAuth2 Provider
*
* @package CodeIgniter/OAuth2
* @category Provider
* @author Phil Sturgeon
* @copyright (c) 2012 HappyNinjas Ltd
* @license http://philsturgeon.co.uk/code/dbad-license
*/
class OAuth2_Provider_Paypal extends OAuth2_Provider
{
/**
* @var string default scope (useful if a scope is required for user info)
*/
protected $scope = array('https://identity.x.com/xidentity/resources/profile/me');
/**
* @var string the method to use when requesting tokens
*/
protected $method = 'POST';
public function url_authorize()
{
return 'https://identity.x.com/xidentity/resources/authorize';
}
public function url_access_token()
{
return 'https://identity.x.com/xidentity/oauthtokenservice';
}
public function get_user_info(OAuth2_Token_Access $token)
{
$url = 'https://identity.x.com/xidentity/resources/profile/me?' . http_build_query(array(
'oauth_token' => $token->access_token
));
$user = json_decode(file_get_contents($url));
$user = $user->identity;
return array(
'uid' => $user['userId'],
'nickname' => url_title($user['fullName'], '_', true),
'name' => $user['fullName'],
'first_name' => $user['firstName'],
'last_name' => $user['lastName'],
'email' => $user['emails'][0],
'location' => $user->addresses[0],
'image' => null,
'description' => null,
'urls' => array(
'PayPal' => null
)
);
}
}

View File

@@ -1,51 +0,0 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* Soundcloud OAuth2 Provider
*
* @package CodeIgniter/OAuth2
* @category Provider
* @author Phil Sturgeon
* @copyright (c) 2012 HappyNinjas Ltd
* @license http://philsturgeon.co.uk/code/dbad-license
*/
class OAuth2_Provider_Soundcloud extends OAuth2_Provider
{
/**
* @var string the method to use when requesting tokens
*/
protected $method = 'POST';
public function url_authorize()
{
return 'https://soundcloud.com/connect';
}
public function url_access_token()
{
return 'https://api.soundcloud.com/oauth2/token';
}
public function get_user_info(OAuth2_Token_Access $token)
{
$url = 'https://api.soundcloud.com/me.json?'.http_build_query(array(
'oauth_token' => $token->access_token,
));
$user = json_decode(file_get_contents($url));
// Create a response from the request
return array(
'uid' => $user->id,
'nickname' => $user->username,
'name' => $user->full_name,
'location' => $user->country.' ,'.$user->country,
'description' => $user->description,
'image' => $user->avatar_url,
'urls' => array(
'MySpace' => $user->myspace_name,
'Website' => $user->website,
),
);
}
}

View File

@@ -1,54 +0,0 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* Vkontakte OAuth2 Provider
*
* @package CodeIgniter/OAuth2
* @category Provider
* @author Lavr Lyndin
*/
class OAuth2_Provider_Vkontakte extends OAuth2_Provider
{
protected $method = 'POST';
public $uid_key = 'user_id';
public function url_authorize()
{
return 'http://oauth.vk.com/authorize';
}
public function url_access_token()
{
return 'https://oauth.vk.com/access_token';
}
public function get_user_info(OAuth2_Token_Access $token)
{
$scope = array('nickname', 'screen_name','photo_big');
$url = 'https://api.vk.com/method/users.get?'.http_build_query(array(
'uids' => $token->uid,
'fields' => implode(",",$scope),
'access_token' => $token->access_token,
));
$user = json_decode(file_get_contents($url))->response;
if(sizeof($user)==0)
return null;
else
$user = $user[0];
return array(
'uid' => $user->uid,
'nickname' => isset($user->nickname) ? $user->nickname : null,
'name' => isset($user->name) ? $user->name : null,
'first_name' => isset($user->first_name) ? $user->first_name : null,
'last_name' => isset($user->last_name) ? $user->last_name : null,
'email' => null,
'location' => null,
'description' => null,
'image' => isset($user->photo_big) ? $user->photo_big : null,
'urls' => array(),
);
}
}

View File

@@ -1,60 +0,0 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* Windows Live OAuth2 Provider
*
* @package CodeIgniter/OAuth2
* @category Provider
* @author Phil Sturgeon
* @copyright (c) 2012 HappyNinjas Ltd
* @license http://philsturgeon.co.uk/code/dbad-license
*/
class OAuth2_Provider_Windowslive extends OAuth2_Provider
{
protected $scope = array('wl.basic', 'wl.emails');
/**
* @var string the method to use when requesting tokens
*/
protected $method = 'POST';
// authorise url
public function url_authorize()
{
return 'https://oauth.live.com/authorize';
}
// access token url
public function url_access_token()
{
return 'https://oauth.live.com/token';
}
// get basic user information
/********************************
** this can be extended through the
** use of scopes, check out the document at
** http://msdn.microsoft.com/en-gb/library/hh243648.aspx#user
*********************************/
public function get_user_info(OAuth2_Token_Access $token)
{
// define the get user information token
$url = 'https://apis.live.net/v5.0/me?'.http_build_query(array(
'access_token' => $token->access_token,
));
// perform network request
$user = json_decode(file_get_contents($url));
// create a response from the request and return it
return array(
'uid' => $user->id,
'name' => $user->name,
'nickname' => url_title($user->name, '_', true),
// 'location' => $user[''], # scope wl.postal_addresses is required
# but won't be implemented by default
'locale' => $user->locale,
'urls' => array('Windows Live' => $user->link),
);
}
}

View File

@@ -1,115 +0,0 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* Yandex OAuth2 Provider
*
* @package CodeIgniter/OAuth2
* @category Provider
* @author Lavr Lyndin
*/
class OAuth2_Provider_Yandex extends OAuth2_Provider
{
public $method = 'POST';
public function url_authorize()
{
return 'https://oauth.yandex.ru/authorize';
}
public function url_access_token()
{
return 'https://oauth.yandex.ru/token';
}
public function get_user_info(OAuth2_Token_Access $token)
{
$opts = array(
'http' => array(
'method' => 'GET',
'header' => 'Authorization: OAuth '.$token->access_token
)
);
$_default_opts = stream_context_get_params(stream_context_get_default());
$opts = array_merge_recursive($_default_opts['options'], $opts);
$context = stream_context_create($opts);
$url = 'http://api-yaru.yandex.ru/me/?format=json';
$user = json_decode(file_get_contents($url,false,$context));
preg_match("/\d+$/",$user->id,$uid);
return array(
'uid' => $uid[0],
'nickname' => isset($user->name) ? $user->name : null,
'name' => isset($user->name) ? $user->name : null,
'first_name' => isset($user->first_name) ? $user->first_name : null,
'last_name' => isset($user->last_name) ? $user->last_name : null,
'email' => isset($user->email) ? $user->email : null,
'location' => isset($user->hometown->name) ? $user->hometown->name : null,
'description' => isset($user->bio) ? $user->bio : null,
'image' => $user->links->userpic,
);
}
public function access($code, $options = array())
{
$params = array(
'client_id' => $this->client_id,
'client_secret' => $this->client_secret,
'grant_type' => isset($options['grant_type']) ? $options['grant_type'] : 'authorization_code',
);
switch ($params['grant_type'])
{
case 'authorization_code':
$params['code'] = $code;
$params['redirect_uri'] = isset($options['redirect_uri']) ? $options['redirect_uri'] : $this->redirect_uri;
break;
case 'refresh_token':
$params['refresh_token'] = $code;
break;
}
$response = null;
$url = $this->url_access_token();
$curl = curl_init($url);
$headers[] = 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8;';
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
// curl_setopt($curl, CURLOPT_USERAGENT, 'yamolib-php');
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($curl, CURLOPT_TIMEOUT, 80);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($params));
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
// curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
// curl_setopt($curl, CURLOPT_CAINFO, dirname(__FILE__) . '/../data/ca-certificate.crt');
$response = curl_exec($curl);
curl_close($curl);
$return = json_decode($response, true);
if ( ! empty($return['error']))
{
throw new OAuth2_Exception($return);
}
switch ($params['grant_type'])
{
case 'authorization_code':
return OAuth2_Token::factory('access', $return);
break;
case 'refresh_token':
return OAuth2_Token::factory('refresh', $return);
break;
}
}
}

View File

@@ -1,46 +0,0 @@
<?php
namespace Oauth2\Client;
abstract class Token
{
/**
* Create a new token object.
*
* @param string token type
* @param array token options
* @return Token
*/
public static function factory($name = 'access', array $options = null)
{
include_once 'Token/'.ucfirst(strtolower($name)).'.php';
$class = 'Oauth2\Client\Token\\'.ucfirst($name);
return new $class($options);
}
/**
* Return the value of any protected class variable.
*
* @param string variable name
* @return mixed
*/
public function __get($key)
{
return $this->$key;
}
/**
* Return a boolean if the property is set
*
* @param string variable name
* @return bool
*/
public function __isset($key)
{
return isset($this->$key);
}
} // End Token

View File

@@ -1,79 +0,0 @@
<?php
namespace Oauth2\Client\Token;
/**
* OAuth2 Token
*
* @package OAuth2
* @category Token
* @author Phil Sturgeon
* @copyright (c) 2011 HappyNinjas Ltd
*/
class Access extends \Oauth2\Client\Token
{
/**
* @var string accessToken
*/
protected $accessToken;
/**
* @var int expires
*/
protected $expires;
/**
* @var string refreshToken
*/
protected $refreshToken;
/**
* @var string uid
*/
protected $uid;
/**
* Sets the token, expiry, etc values.
*
* @param array token options
* @return void
*/
public function __construct(array $options = null)
{
if ( ! isset($options['access_token'])) {
throw new \BadMethodCallException('Required option not passed: access_token'.PHP_EOL.print_r($options, true));
}
$this->accessToken = $options['access_token'];
// Some providers (not many) give the uid here, so lets take it
isset($options['uid']) and $this->uid = $options['uid'];
//Vkontakte uses user_id instead of uid
isset($options['user_id']) and $this->uid = $options['user_id'];
//Mailru uses x_mailru_vid instead of uid
isset($options['x_mailru_vid']) and $this->uid = $options['x_mailru_vid'];
// We need to know when the token expires, add num. seconds to current time
isset($options['expires_in']) and $this->expires = time() + ((int) $options['expires_in']);
// Facebook is just being a spec ignoring jerk
isset($options['expires']) and $this->expires = time() + ((int) $options['expires']);
// Grab a refresh token so we can update access tokens when they expires
isset($options['refresh_token']) and $this->refreshToken = $options['refresh_token'];
}
/**
* Returns the token key.
*
* @return string
*/
public function __toString()
{
return (string) $this->accessToken;
}
}

View File

@@ -1,55 +0,0 @@
<?php
/**
* OAuth2 Token
*
* @package OAuth2
* @category Token
* @author Phil Sturgeon
* @copyright (c) 2011 HappyNinjas Ltd
*/
class Authorize extends \Oauth2\Client\Token
{
/**
* @var string code
*/
protected $code;
/**
* @var string redirect_uri
*/
protected $redirectUri;
/**
* Sets the token, expiry, etc values.
*
* @param array token options
* @return void
*/
public function __construct(array $options)
{
if ( ! isset($options['code'])) {
throw new Exception('Required option not passed: code');
} elseif ( ! isset($options['redirect_uri'])) {
throw new Exception('Required option not passed: redirect_uri');
}
$this->code = $options['code'];
$this->redirectUri = $options['redirect_uri'];
}
/**
* Returns the token key.
*
* @return string
*/
public function __toString()
{
return (string) $this->code;
}
}

View File

@@ -1,59 +0,0 @@
<?php
namespace Oauth2\Resource;
interface Database
{
/**
* Validate an access token and return the session details.
*
* Database query:
*
* <code>
* SELECT id, owner_type, owner_id FROM oauth_sessions WHERE access_token =
* $accessToken AND stage = 'granted' AND
* access_token_expires > UNIX_TIMESTAMP(now())
* </code>
*
* Response:
*
* <code>
* Array
* (
* [id] => (int) The session ID
* [owner_type] => (string) The session owner type
* [owner_id] => (string) The session owner's ID
* )
* </code>
*
* @param string $accessToken The access token
* @return array|bool Return an array on success or false on failure
*/
public function validateAccessToken($accessToken);
/**
* Returns the scopes that the session is authorised with.
*
* Database query:
*
* <code>
* SELECT scope FROM oauth_session_scopes WHERE session_id =
* $sessionId
* </code>
*
* Response:
*
* <code>
* Array
* (
* [0] => (string) A scope
* [1] => (string) Another scope
* ...
* )
* </code>
*
* @param int $sessionId The session ID
* @return array A list of scopes
*/
public function sessionScopes($sessionId);
}

View File

@@ -1,253 +0,0 @@
<?php
namespace Oauth2\Resource;
class ServerException extends \Exception
{
}
class ClientException extends \Exception
{
}
class Server
{
/**
* Reference to the database abstractor
* @var object
*/
private $_db = null;
/**
* The access token.
* @access private
*/
private $_accessToken = null;
/**
* The scopes the access token has access to.
* @access private
*/
private $_scopes = array();
/**
* The type of owner of the access token.
* @access private
*/
private $_type = null;
/**
* The ID of the owner of the access token.
* @access private
*/
private $_typeId = null;
/**
* Server configuration
* @var array
*/
private $_config = array(
'token_key' => 'oauth_token'
);
/**
* Error codes.
*
* To provide i8ln errors just overwrite the keys
*
* @var array
*/
public $errors = array(
'missing_access_token' => 'An access token was not presented with the request',
'invalid_access_token' => 'The access token is not registered with the resource server',
'missing_access_token_details' => 'The registered database abstractor did not return a valid access token details response',
'invalid_access_token_scopes' => 'The registered database abstractor did not return a valid access token scopes response',
);
/**
* Constructor
*
* @access public
* @return void
*/
public function __construct($options = null)
{
if ($options !== null) {
$this->_config = array_merge($this->_config, $options);
}
}
/**
* Magic method to test if access token represents a particular owner type
* @param string $method The method name
* @param mixed $arguements The method arguements
* @return bool If method is valid, and access token is owned by the requested party then true,
*/
public function __call($method, $arguements = null)
{
if (substr($method, 0, 2) === 'is') {
if ($this->_type === strtolower(substr($method, 2))) {
return $this->_typeId;
}
return false;
}
trigger_error('Call to undefined function ' . $method . '()');
}
/**
* Register a database abstrator class
*
* @access public
* @param object $db A class that implements OAuth2ServerDatabase
* @return void
*/
public function registerDbAbstractor($db)
{
$this->_db = $db;
}
/**
* Init function
*
* @access public
* @return void
*/
public function init()
{
$accessToken = null;
$_SERVER['REQUEST_METHOD'] = isset($_SERVER['REQUEST_METHOD']) ?
$_SERVER['REQUEST_METHOD'] :
null;
// Try and get the access token via an access_token or oauth_token parameter
switch ($_SERVER['REQUEST_METHOD'])
{
case 'POST':
$accessToken = isset($_POST[$this->_config['token_key']]) ?
$_POST[$this->_config['token_key']] :
null;
break;
default:
$accessToken = isset($_GET[$this->_config['token_key']]) ?
$_GET[$this->_config['token_key']] :
null;
break;
}
// Try and get an access token from the auth header
if (function_exists('getallheaders')) {
$headers = getallheaders();
if (isset($headers['Authorization'])) {
$rawToken = trim(str_replace('Bearer', '', $headers['Authorization']));
if ( ! empty($rawToken)) {
$accessToken = $rawToken;
}
}
}
if ($accessToken) {
$result = $this->_dbCall('validateAccessToken', $accessToken);
if ($result === false) {
throw new ClientException($this->errors['invalid_access_token']);
} else {
if ( ! array_key_exists('id', $result) ||
! array_key_exists('owner_id', $result) ||
! array_key_exists('owner_type', $result)) {
throw new ServerException($this->errors['missing_access_token_details']);
}
$this->_accessToken = $accessToken;
$this->_type = $result['owner_type'];
$this->_typeId = $result['owner_id'];
// Get the scopes
$scopes = $this->_dbCall('sessionScopes', $result['id']);
if ( ! is_array($scopes))
{
throw new ServerException($this->errors['invalid_access_token_scopes']);
}
$this->_scopes = $scopes;
}
} else {
throw new ClientException($this->errors['missing_access_token']);
}
}
/**
* Test if the access token has a specific scope
*
* @param mixed $scopes Scope(s) to check
*
* @access public
* @return string|bool
*/
public function hasScope($scopes)
{
if (is_string($scopes)) {
if (in_array($scopes, $this->_scopes)) {
return true;
}
return false;
} elseif (is_array($scopes)) {
foreach ($scopes as $scope) {
if ( ! in_array($scope, $this->_scopes)) {
return false;
}
}
return true;
}
return false;
}
/**
* Call database methods from the abstractor
*
* @return mixed The query result
*/
private function _dbCall()
{
if ($this->_db === null) {
throw new ServerException('No registered database abstractor');
}
if ( ! $this->_db instanceof Database) {
throw new ServerException('The registered database abstractor is not an instance of Oauth2\Resource\Database');
}
$args = func_get_args();
$method = $args[0];
unset($args[0]);
$params = array_values($args);
return call_user_func_array(array($this->_db, $method), $params);
}
}

6
tests/Bootstrap.php Normal file
View File

@@ -0,0 +1,6 @@
<?php
if ( ! @include_once __DIR__ . '/../vendor/autoload.php')
{
exit("You must set up the project dependencies, run the following commands:\n> wget http://getcomposer.org/composer.phar\n> php composer.phar install\n");
}

View File

@@ -1,154 +0,0 @@
<?php
use Oauth2\Authentication\Database;
class OAuthdb implements Database
{
private $sessions = array();
private $sessions_client_type_id = array();
private $sessions_code = array();
private $session_scopes = array();
private $clients = array(0 => array(
'client_id' => 'test',
'client_secret' => 'test',
'redirect_uri' => 'http://example.com/test',
'name' => 'Test Client'
));
private $scopes = array('test' => array(
'id' => 1,
'scope' => 'test',
'name' => 'test',
'description' => 'test'
));
public function validateClient($clientId, $clientSecret = null, $redirectUri = null)
{
if ($clientId !== $this->clients[0]['client_id'])
{
return false;
}
if ($clientSecret !== null && $clientSecret !== $this->clients[0]['client_secret'])
{
return false;
}
if ($redirectUri !== null && $redirectUri !== $this->clients[0]['redirect_uri'])
{
return false;
}
return $this->clients[0];
}
public function newSession($clientId, $redirectUri, $type = 'user', $typeId = null, $authCode = null, $accessToken = null, $accessTokenExpire = null, $stage = 'requested')
{
$id = count($this->sessions);
$this->sessions[$id] = array(
'id' => $id,
'client_id' => $clientId,
'redirect_uri' => $redirectUri,
'owner_type' => $type,
'owner_id' => $typeId,
'auth_code' => $authCode,
'access_token' => $accessToken,
'access_token_expire' => $accessTokenExpire,
'stage' => $stage
);
$this->sessions_client_type_id[$clientId . ':' . $type . ':' . $typeId] = $id;
$this->sessions_code[$clientId . ':' . $redirectUri . ':' . $authCode] = $id;
return $id;
}
public function updateSession($sessionId, $authCode = null, $accessToken = null, $accessTokenExpire = null, $stage = 'requested')
{
$this->sessions[$sessionId]['auth_code'] = $authCode;
$this->sessions[$sessionId]['access_token'] = $accessToken;
$this->sessions[$sessionId]['access_token_expire'] = $accessTokenExpire;
$this->sessions[$sessionId]['stage'] = $stage;
return true;
}
public function deleteSession($clientId, $type, $typeId)
{
$key = $clientId . ':' . $type . ':' . $typeId;
if (isset($this->sessions_client_type_id[$key]))
{
unset($this->sessions[$this->sessions_client_type_id[$key]]);
}
return true;
}
public function validateAuthCode($clientId, $redirectUri, $authCode)
{
$key = $clientId . ':' . $redirectUri . ':' . $authCode;
if (isset($this->sessions_code[$key]))
{
return $this->sessions[$this->sessions_code[$key]];
}
return false;
}
public function hasSession($type, $typeId, $clientId)
{
die('not implemented hasSession');
}
public function getAccessToken($sessionId)
{
die('not implemented getAccessToken');
}
public function removeAuthCode($sessionId)
{
die('not implemented removeAuthCode');
}
public function setAccessToken(
$sessionId,
$accessToken
)
{
die('not implemented setAccessToken');
}
public function addSessionScope($sessionId, $scope)
{
if ( ! isset($this->session_scopes[$sessionId]))
{
$this->session_scopes[$sessionId] = array();
}
$this->session_scopes[$sessionId][] = $scope;
return true;
}
public function getScope($scope)
{
if ( ! isset($this->scopes[$scope]))
{
return false;
}
return $this->scopes[$scope];
}
public function updateSessionScopeAccessToken($sessionId, $accessToken)
{
return true;
}
public function accessTokenScopes($accessToken)
{
die('not implemented accessTokenScopes');
}
}

View File

@@ -1,398 +0,0 @@
<?php
class Authentication_Server_test extends PHPUnit_Framework_TestCase {
function setUp()
{
$this->oauth = new Oauth2\Authentication\Server();
require_once('database_mock.php');
$this->oauthdb = new OAuthdb();
$this->assertInstanceOf('Oauth2\Authentication\Database', $this->oauthdb);
$this->oauth->registerDbAbstractor($this->oauthdb);
}
function test_generateCode()
{
$reflector = new ReflectionClass($this->oauth);
$method = $reflector->getMethod('generateCode');
$method->setAccessible(true);
$result = $method->invoke($this->oauth);
$result2 = $method->invoke($this->oauth);
$this->assertEquals(40, strlen($result));
$this->assertNotEquals($result, $result2);
}
function test_redirectUri()
{
$result1 = $this->oauth->redirectUri('http://example.com/foo');
$result2 = $this->oauth->redirectUri('http://example.com/foo', array('foo' => 'bar'));
$result3 = $this->oauth->redirectUri('http://example.com/foo', array('foo' => 'bar'), '#');
$this->assertEquals('http://example.com/foo?', $result1);
$this->assertEquals('http://example.com/foo?foo=bar', $result2);
$this->assertEquals('http://example.com/foo#foo=bar', $result3);
}
function test_checkClientAuthoriseParams_GET()
{
$_GET['client_id'] = 'test';
$_GET['redirect_uri'] = 'http://example.com/test';
$_GET['response_type'] = 'code';
$_GET['scope'] = 'test';
$expect = array(
'client_id' => 'test',
'redirect_uri' => 'http://example.com/test',
'response_type' => 'code',
'scopes' => array(
0 => array(
'id' => 1,
'scope' => 'test',
'name' => 'test',
'description' => 'test'
)
)
);
$result = $this->oauth->checkClientAuthoriseParams();
$this->assertEquals($expect, $result);
}
function test_checkClientAuthoriseParams_PassedParams()
{
unset($_GET['client_id']);
unset($_GET['redirect_uri']);
unset($_GET['response_type']);
unset($_GET['scope']);
$params = array(
'client_id' => 'test',
'redirect_uri' => 'http://example.com/test',
'response_type' => 'code',
'scope' => 'test'
);
$this->assertEquals(array(
'client_id' => 'test',
'redirect_uri' => 'http://example.com/test',
'response_type' => 'code',
'scopes' => array(0 => array(
'id' => 1,
'scope' => 'test',
'name' => 'test',
'description' => 'test'
))
), $this->oauth->checkClientAuthoriseParams($params));
}
/**
* @expectedException Oauth2\Authentication\ClientException
* @expectedExceptionCode 0
*/
function test_checkClientAuthoriseParams_missingClientId()
{
$this->oauth->checkClientAuthoriseParams();
}
/**
* @expectedException Oauth2\Authentication\ClientException
* @expectedExceptionCode 0
*/
function test_checkClientAuthoriseParams_missingRedirectUri()
{
$_GET['client_id'] = 'test';
$this->oauth->checkClientAuthoriseParams();
}
/**
* @expectedException Oauth2\Authentication\ClientException
* @expectedExceptionCode 0
*/
function test_checkClientAuthoriseParams_missingResponseType()
{
$_GET['client_id'] = 'test';
$_GET['redirect_uri'] = 'http://example.com/test';
$this->oauth->checkClientAuthoriseParams();
}
/**
* @expectedException Oauth2\Authentication\ClientException
* @expectedExceptionCode 0
*/
function test_checkClientAuthoriseParams_missingScopes()
{
$_GET['client_id'] = 'test';
$_GET['redirect_uri'] = 'http://example.com/test';
$_GET['response_type'] = 'code';
$_GET['scope'] = ' ';
$this->oauth->checkClientAuthoriseParams();
}
/**
* @expectedException Oauth2\Authentication\ClientException
* @expectedExceptionCode 4
*/
function test_checkClientAuthoriseParams_invalidScopes()
{
$_GET['client_id'] = 'test';
$_GET['redirect_uri'] = 'http://example.com/test';
$_GET['response_type'] = 'code';
$_GET['scope'] = 'blah';
$this->oauth->checkClientAuthoriseParams();
}
function test_newAuthoriseRequest()
{
$result = $this->oauth->newAuthoriseRequest('user', '123', array(
'client_id' => 'test',
'redirect_uri' => 'http://example.com/test',
'scopes' => array(array(
'id' => 1,
'scope' => 'test',
'name' => 'test',
'description' => 'test'
))
));
$this->assertEquals(40, strlen($result));
}
function test_newAuthoriseRequest_isUnique()
{
$result1 = $this->oauth->newAuthoriseRequest('user', '123', array(
'client_id' => 'test',
'redirect_uri' => 'http://example.com/test',
'scopes' => array(array(
'id' => 1,
'scope' => 'test',
'name' => 'test',
'description' => 'test'
))
));
$result2 = $this->oauth->newAuthoriseRequest('user', '123', array(
'client_id' => 'test',
'redirect_uri' => 'http://example.com/test',
'scopes' => array(array(
'id' => 1,
'scope' => 'test',
'name' => 'test',
'description' => 'test'
))
));
$this->assertNotEquals($result1, $result2);
}
function test_issueAccessToken_POST()
{
$auth_code = $this->oauth->newAuthoriseRequest('user', '123', array(
'client_id' => 'test',
'redirect_uri' => 'http://example.com/test',
'scopes' => array(array(
'id' => 1,
'scope' => 'test',
'name' => 'test',
'description' => 'test'
))
));
$_POST['client_id'] = 'test';
$_POST['client_secret'] = 'test';
$_POST['redirect_uri'] = 'http://example.com/test';
$_POST['grant_type'] = 'authorization_code';
$_POST['code'] = $auth_code;
$result = $this->oauth->issueAccessToken();
$this->assertCount(3, $result);
$this->assertArrayHasKey('access_token', $result);
$this->assertArrayHasKey('token_type', $result);
$this->assertArrayHasKey('expires_in', $result);
}
function test_issueAccessToken_PassedParams()
{
$auth_code = $this->oauth->newAuthoriseRequest('user', '123', array(
'client_id' => 'test',
'redirect_uri' => 'http://example.com/test',
'scopes' => array(array(
'id' => 1,
'scope' => 'test',
'name' => 'test',
'description' => 'test'
))
));
$params['client_id'] = 'test';
$params['client_secret'] = 'test';
$params['redirect_uri'] = 'http://example.com/test';
$params['grant_type'] = 'authorization_code';
$params['code'] = $auth_code;
$result = $this->oauth->issueAccessToken($params);
$this->assertCount(3, $result);
$this->assertArrayHasKey('access_token', $result);
$this->assertArrayHasKey('token_type', $result);
$this->assertArrayHasKey('expires_in', $result);
}
/**
* @expectedException Oauth2\Authentication\ClientException
* @expectedExceptionCode 0
*/
function test_issueAccessToken_missingGrantType()
{
$this->oauth->issueAccessToken();
}
/**
* @expectedException Oauth2\Authentication\ClientException
* @expectedExceptionCode 7
*/
function test_issueAccessToken_unsupportedGrantType()
{
$params['grant_type'] = 'blah';
$this->oauth->issueAccessToken($params);
}
/**
* @expectedException Oauth2\Authentication\ClientException
* @expectedExceptionCode 0
*/
function test_completeAuthCodeGrant_missingClientId()
{
$reflector = new ReflectionClass($this->oauth);
$method = $reflector->getMethod('completeAuthCodeGrant');
$method->setAccessible(true);
$method->invoke($this->oauth);
}
/**
* @expectedException Oauth2\Authentication\ClientException
* @expectedExceptionCode 0
*/
function test_completeAuthCodeGrant_missingClientSecret()
{
$reflector = new ReflectionClass($this->oauth);
$method = $reflector->getMethod('completeAuthCodeGrant');
$method->setAccessible(true);
$authParams['client_id'] = 'test';
$method->invoke($this->oauth, $authParams);
}
/**
* @expectedException Oauth2\Authentication\ClientException
* @expectedExceptionCode 0
*/
function test_completeAuthCodeGrant_missingRedirectUri()
{
$reflector = new ReflectionClass($this->oauth);
$method = $reflector->getMethod('completeAuthCodeGrant');
$method->setAccessible(true);
$authParams['client_id'] = 'test';
$authParams['client_secret'] = 'test';
$method->invoke($this->oauth, $authParams);
}
/**
* @expectedException Oauth2\Authentication\ClientException
* @expectedExceptionCode 8
*/
function test_completeAuthCodeGrant_invalidClient()
{
$reflector = new ReflectionClass($this->oauth);
$method = $reflector->getMethod('completeAuthCodeGrant');
$method->setAccessible(true);
$authParams['client_id'] = 'test';
$authParams['client_secret'] = 'test123';
$authParams['redirect_uri'] = 'http://example.com/test';
$method->invoke($this->oauth, $authParams);
}
/**
* @expectedException Oauth2\Authentication\ClientException
* @expectedExceptionCode 0
*/
function test_completeAuthCodeGrant_missingCode()
{
$reflector = new ReflectionClass($this->oauth);
$method = $reflector->getMethod('completeAuthCodeGrant');
$method->setAccessible(true);
$authParams['client_id'] = 'test';
$authParams['client_secret'] = 'test';
$authParams['redirect_uri'] = 'http://example.com/test';
$method->invoke($this->oauth, $authParams);
}
/**
* @expectedException Oauth2\Authentication\ClientException
* @expectedExceptionCode 9
*/
function test_completeAuthCodeGrant_invalidCode()
{
$reflector = new ReflectionClass($this->oauth);
$method = $reflector->getMethod('completeAuthCodeGrant');
$method->setAccessible(true);
$authParams['client_id'] = 'test';
$authParams['client_secret'] = 'test';
$authParams['redirect_uri'] = 'http://example.com/test';
$authParams['code'] = 'blah';
$method->invoke($this->oauth, $authParams);
}
/**
* @expectedException Oauth2\Authentication\ServerException
* @expectedExceptionMessage No registered database abstractor
*/
function test_noRegisteredDatabaseAbstractor()
{
$reflector = new ReflectionClass($this->oauth);
$method = $reflector->getMethod('_dbCall');
$method->setAccessible(true);
$dbAbstractor = $reflector->getProperty('_db');
$dbAbstractor->setAccessible(true);
$dbAbstractor->setValue($this->oauth, null);
$result = $method->invoke($this->oauth);
}
/**
* @expectedException Oauth2\Authentication\ServerException
* @expectedExceptionMessage Registered database abstractor is not an instance of Oauth2\Authentication\Database
*/
function test_invalidRegisteredDatabaseAbstractor()
{
$fake = new stdClass;
$this->oauth->registerDbAbstractor($fake);
$reflector = new ReflectionClass($this->oauth);
$method = $reflector->getMethod('_dbCall');
$method->setAccessible(true);
$result = $method->invoke($this->oauth);
}
}

View File

@@ -0,0 +1,428 @@
<?php
use \Mockery as m;
class Auth_Code_Grant_Test extends PHPUnit_Framework_TestCase
{
private $client;
private $session;
private $scope;
public function setUp()
{
$this->client = M::mock('League\OAuth2\Server\Storage\ClientInterface');
$this->session = M::mock('League\OAuth2\Server\Storage\SessionInterface');
$this->scope = M::mock('League\OAuth2\Server\Storage\ScopeInterface');
}
private function returnDefault()
{
return new League\OAuth2\Server\Authorization($this->client, $this->session, $this->scope);
}
/**
* @expectedException PHPUnit_Framework_Error
*/
public function test__construct()
{
$a = $this->returnDefault();
$grant = new League\OAuth2\Server\Grant\AuthCode($a);
}
public function test_setIdentifier()
{
$grant = new League\OAuth2\Server\Grant\AuthCode();
$grant->setIdentifier('foobar');
$this->assertEquals($grant->getIdentifier(), 'foobar');
}
public function test_setAuthTokenTTL()
{
$a = $this->returnDefault();
$grant = new League\OAuth2\Server\Grant\AuthCode();
$grant->setAuthTokenTTL(30);
$reflector = new ReflectionClass($grant);
$requestProperty = $reflector->getProperty('authTokenTTL');
$requestProperty->setAccessible(true);
$v = $requestProperty->getValue($grant);
$this->assertEquals(30, $v);
}
/**
* @expectedException League\OAuth2\Server\Exception\ClientException
* @expectedExceptionCode 0
*/
public function test_checkAuthoriseParams_noClientId()
{
$a = $this->returnDefault();
$g = new League\OAuth2\Server\Grant\AuthCode();
$a->addGrantType($g);
$g->checkAuthoriseParams();
}
/**
* @expectedException League\OAuth2\Server\Exception\ClientException
* @expectedExceptionCode 0
*/
public function test_checkAuthoriseParams_noRedirectUri()
{
$a = $this->returnDefault();
$g = new League\OAuth2\Server\Grant\AuthCode();
$a->addGrantType($g);
$g->checkAuthoriseParams(array(
'client_id' => 1234
));
}
/**
* @expectedException League\OAuth2\Server\Exception\ClientException
* @expectedExceptionCode 0
*/
public function test_checkAuthoriseParams_noRequiredState()
{
$a = $this->returnDefault();
$g = new League\OAuth2\Server\Grant\AuthCode();
$a->addGrantType($g);
$a->requireStateParam(true);
$g->checkAuthoriseParams(array(
'client_id' => 1234,
'redirect_uri' => 'http://foo/redirect'
));
}
/**
* @expectedException League\OAuth2\Server\Exception\ClientException
* @expectedExceptionCode 8
*/
public function test_checkAuthoriseParams_badClient()
{
$this->client->shouldReceive('getClient')->andReturn(false);
$a = $this->returnDefault();
$g = new League\OAuth2\Server\Grant\AuthCode();
$a->addGrantType($g);
$g->checkAuthoriseParams(array(
'client_id' => 1234,
'redirect_uri' => 'http://foo/redirect'
));
}
/**
* @expectedException League\OAuth2\Server\Exception\ClientException
* @expectedExceptionCode 0
*/
public function test_checkAuthoriseParams_missingResponseType()
{
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$a = $this->returnDefault();
$g = new League\OAuth2\Server\Grant\AuthCode();
$a->addGrantType($g);
$g->checkAuthoriseParams(array(
'client_id' => 1234,
'redirect_uri' => 'http://foo/redirect'
));
}
/**
* @expectedException League\OAuth2\Server\Exception\ClientException
* @expectedExceptionCode 3
*/
public function test_checkAuthoriseParams_badResponseType()
{
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$a = $this->returnDefault();
$g = new League\OAuth2\Server\Grant\AuthCode();
$a->addGrantType($g);
$g->checkAuthoriseParams(array(
'client_id' => 1234,
'redirect_uri' => 'http://foo/redirect',
'response_type' => 'foo'
));
}
/**
* @expectedException League\OAuth2\Server\Exception\ClientException
* @expectedExceptionCode 0
*/
public function test_checkAuthoriseParams_missingScopes()
{
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$a = $this->returnDefault();
$g = new League\OAuth2\Server\Grant\AuthCode();
$a->addGrantType($g);
$a->addGrantType(new League\OAuth2\Server\Grant\AuthCode());
$a->requireScopeParam(true);
$g->checkAuthoriseParams(array(
'client_id' => 1234,
'redirect_uri' => 'http://foo/redirect',
'response_type' => 'code',
'scope' => ''
));
}
public function test_checkAuthoriseParams_defaultScope()
{
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->scope->shouldReceive('getScope')->andReturn(array(
'id' => 1,
'scope' => 'foo',
'name' => 'Foo Name',
'description' => 'Foo Name Description'
));
$a = $this->returnDefault();
$g = new League\OAuth2\Server\Grant\AuthCode();
$a->addGrantType($g);
$a->addGrantType(new League\OAuth2\Server\Grant\AuthCode());
$a->setDefaultScope('test.scope');
$a->requireScopeParam(false);
$params = $g->checkAuthoriseParams(array(
'client_id' => 1234,
'redirect_uri' => 'http://foo/redirect',
'response_type' => 'code',
'scope' => ''
));
$this->assertArrayHasKey('scopes', $params);
$this->assertEquals(1, count($params['scopes']));
}
public function test_checkAuthoriseParams_defaultScopeArray()
{
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->scope->shouldReceive('getScope')->andReturn(array(
'id' => 1,
'scope' => 'foo',
'name' => 'Foo Name',
'description' => 'Foo Name Description'
));
$a = $this->returnDefault();
$g = new League\OAuth2\Server\Grant\AuthCode();
$a->addGrantType($g);
$a->addGrantType(new League\OAuth2\Server\Grant\AuthCode());
$a->setDefaultScope(array('test.scope', 'test.scope2'));
$a->requireScopeParam(false);
$params = $g->checkAuthoriseParams(array(
'client_id' => 1234,
'redirect_uri' => 'http://foo/redirect',
'response_type' => 'code',
'scope' => ''
));
$this->assertArrayHasKey('scopes', $params);
$this->assertEquals(2, count($params['scopes']));
}
/**
* @expectedException League\OAuth2\Server\Exception\ClientException
* @expectedExceptionCode 4
*/
public function test_checkAuthoriseParams_badScopes()
{
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->scope->shouldReceive('getScope')->andReturn(false);
$a = $this->returnDefault();
$g = new League\OAuth2\Server\Grant\AuthCode();
$a->addGrantType($g);
$a->addGrantType(new League\OAuth2\Server\Grant\AuthCode());
$g->checkAuthoriseParams(array(
'client_id' => 1234,
'redirect_uri' => 'http://foo/redirect',
'response_type' => 'code',
'scope' => 'foo'
));
}
public function test_checkAuthoriseParams_passedInput()
{
$a = $this->returnDefault();
$g = new League\OAuth2\Server\Grant\AuthCode();
$a->addGrantType($g);
$a->addGrantType(new League\OAuth2\Server\Grant\AuthCode());
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->scope->shouldReceive('getScope')->andReturn(array(
'id' => 1,
'scope' => 'foo',
'name' => 'Foo Name',
'description' => 'Foo Name Description'
));
$v = $g->checkAuthoriseParams(array(
'client_id' => 1234,
'redirect_uri' => 'http://foo/redirect',
'response_type' => 'code',
'scope' => 'foo',
'state' => 'xyz'
));
$this->assertEquals(array(
'client_id' => 1234,
'redirect_uri' => 'http://foo/redirect',
'client_details' => array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
),
'response_type' => 'code',
'scopes' => array(
array(
'id' => 1,
'scope' => 'foo',
'name' => 'Foo Name',
'description' => 'Foo Name Description'
)
),
'scope' => 'foo',
'state' => 'xyz'
), $v);
}
public function test_checkAuthoriseParams()
{
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->scope->shouldReceive('getScope')->andReturn(array(
'id' => 1,
'scope' => 'foo',
'name' => 'Foo Name',
'description' => 'Foo Name Description'
));
$a = $this->returnDefault();
$g = new League\OAuth2\Server\Grant\AuthCode();
$a->addGrantType($g);
$a->addGrantType(new League\OAuth2\Server\Grant\AuthCode());
$_GET['client_id'] = 1234;
$_GET['redirect_uri'] = 'http://foo/redirect';
$_GET['response_type'] = 'code';
$_GET['scope'] = 'foo';
$_GET['state'] = 'xyz';
$request = new League\OAuth2\Server\Util\Request($_GET);
$a->setRequest($request);
$v = $g->checkAuthoriseParams();
$this->assertEquals(array(
'client_id' => 1234,
'redirect_uri' => 'http://foo/redirect',
'client_details' => array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
),
'response_type' => 'code',
'scopes' => array(
array(
'id' => 1,
'scope' => 'foo',
'name' => 'Foo Name',
'description' => 'Foo Name Description'
)
),
'scope' => 'foo',
'state' => 'xyz'
), $v);
}
function test_newAuthoriseRequest()
{
$this->session->shouldReceive('deleteSession')->andReturn(null);
$this->session->shouldReceive('createSession')->andReturn(1);
$this->session->shouldReceive('associateScope')->andReturn(null);
$this->session->shouldReceive('associateRedirectUri')->andReturn(null);
$this->session->shouldReceive('associateAuthCode')->andReturn(1);
$this->session->shouldReceive('associateAuthCodeScope')->andReturn(null);
$a = $this->returnDefault();
$g = new League\OAuth2\Server\Grant\AuthCode();
$a->addGrantType($g);
$params = array(
'client_id' => 1234,
'redirect_uri' => 'http://foo/redirect',
'client_details' => array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
),
'response_type' => 'code',
'scopes' => array(
array(
'id' => 1,
'scope' => 'foo',
'name' => 'Foo Name',
'description' => 'Foo Name Description'
)
)
);
$v = $g->newAuthoriseRequest('user', 123, $params);
$this->assertEquals(40, strlen($v));
}
}

View File

@@ -0,0 +1,513 @@
<?php
use \Mockery as m;
class Authorization_Server_test extends PHPUnit_Framework_TestCase
{
private $client;
private $session;
private $scope;
public function setUp()
{
$this->client = M::mock('League\OAuth2\Server\Storage\ClientInterface');
$this->session = M::mock('League\OAuth2\Server\Storage\SessionInterface');
$this->scope = M::mock('League\OAuth2\Server\Storage\ScopeInterface');
}
private function returnDefault()
{
return new League\OAuth2\Server\Authorization($this->client, $this->session, $this->scope);
}
/**
* @expectedException PHPUnit_Framework_Error
*/
public function test__construct_NoStorage()
{
new League\OAuth2\Server\Authorization;
}
public function test__contruct_WithStorage()
{
$this->returnDefault();
}
public function test_getExceptionMessage()
{
$m = League\OAuth2\Server\Authorization::getExceptionMessage('access_denied');
$reflector = new ReflectionClass($this->returnDefault());
$exceptionMessages = $reflector->getProperty('exceptionMessages');
$exceptionMessages->setAccessible(true);
$v = $exceptionMessages->getValue();
$this->assertEquals($v['access_denied'], $m);
}
public function test_getExceptionCode()
{
$this->assertEquals('access_denied', League\OAuth2\Server\Authorization::getExceptionType(2));
}
public function test_getExceptionHttpHeaders()
{
$this->assertEquals(array('HTTP/1.1 401 Unauthorized'), League\OAuth2\Server\Authorization::getExceptionHttpHeaders('access_denied'));
$this->assertEquals(array('HTTP/1.1 500 Internal Server Error'), League\OAuth2\Server\Authorization::getExceptionHttpHeaders('server_error'));
$this->assertEquals(array('HTTP/1.1 501 Not Implemented'), League\OAuth2\Server\Authorization::getExceptionHttpHeaders('unsupported_grant_type'));
$this->assertEquals(array('HTTP/1.1 400 Bad Request'), League\OAuth2\Server\Authorization::getExceptionHttpHeaders('invalid_refresh'));
}
public function test_hasGrantType()
{
$a = $this->returnDefault();
$this->assertFalse($a->hasGrantType('test'));
}
public function test_addGrantType()
{
$a = $this->returnDefault();
$grant = M::mock('League\OAuth2\Server\Grant\GrantTypeInterface');
$grant->shouldReceive('getResponseType')->andReturn('test');
$grant->shouldReceive('setAuthorizationServer')->andReturn($grant);
$a->addGrantType($grant, 'test');
$this->assertTrue($a->hasGrantType('test'));
}
public function test_addGrantType_noIdentifier()
{
$a = $this->returnDefault();
$grant = M::mock('League\OAuth2\Server\Grant\GrantTypeInterface');
$grant->shouldReceive('getIdentifier')->andReturn('test');
$grant->shouldReceive('getResponseType')->andReturn('test');
$grant->shouldReceive('setAuthorizationServer')->andReturn($grant);
$a->addGrantType($grant);
$this->assertTrue($a->hasGrantType('test'));
}
public function test_getScopeDelimeter()
{
$a = $this->returnDefault();
$this->assertEquals(' ', $a->getScopeDelimeter());
}
public function test_setScopeDelimeter()
{
$a = $this->returnDefault();
$a->setScopeDelimeter(',');
$this->assertEquals(',', $a->getScopeDelimeter());
}
public function test_requireScopeParam()
{
$a = $this->returnDefault();
$a->requireScopeParam(false);
$reflector = new ReflectionClass($a);
$requestProperty = $reflector->getProperty('requireScopeParam');
$requestProperty->setAccessible(true);
$v = $requestProperty->getValue($a);
$this->assertFalse($v);
}
public function test_scopeParamRequired()
{
$a = $this->returnDefault();
$a->requireScopeParam(false);
$this->assertFalse($a->scopeParamRequired());
}
public function test_setDefaultScope()
{
$a = $this->returnDefault();
$a->setDefaultScope('test.default');
$reflector = new ReflectionClass($a);
$requestProperty = $reflector->getProperty('defaultScope');
$requestProperty->setAccessible(true);
$v = $requestProperty->getValue($a);
$this->assertEquals('test.default', $v);
}
public function test_getDefaultScope()
{
$a = $this->returnDefault();
$a->setDefaultScope('test.default');
$this->assertEquals('test.default', $a->getDefaultScope());
}
public function test_requireStateParam()
{
$a = $this->returnDefault();
$a->requireStateParam(true);
$reflector = new ReflectionClass($a);
$requestProperty = $reflector->getProperty('requireStateParam');
$requestProperty->setAccessible(true);
$v = $requestProperty->getValue($a);
$this->assertTrue($v);
}
public function test_getAccessTokenTTL()
{
$a = $this->returnDefault();
$a->setAccessTokenTTL(7200);
$this->assertEquals(7200, $a->getAccessTokenTTL());
}
public function test_setAccessTokenTTL()
{
$a = $this->returnDefault();
$a->setScopeDelimeter(';');
$this->assertEquals(';', $a->getScopeDelimeter());
}
public function test_setRequest()
{
$a = $this->returnDefault();
$request = new League\OAuth2\Server\Util\Request();
$a->setRequest($request);
$reflector = new ReflectionClass($a);
$requestProperty = $reflector->getProperty('request');
$requestProperty->setAccessible(true);
$v = $requestProperty->getValue($a);
$this->assertTrue($v instanceof League\OAuth2\Server\Util\RequestInterface);
}
public function test_getRequest()
{
$a = $this->returnDefault();
$request = new League\OAuth2\Server\Util\Request();
$a->setRequest($request);
$v = $a->getRequest();
$this->assertTrue($v instanceof League\OAuth2\Server\Util\RequestInterface);
}
public function test_getStorage()
{
$a = $this->returnDefault();
$this->assertTrue($a->getStorage('session') instanceof League\OAuth2\Server\Storage\SessionInterface);
}
public function test_getGrantType()
{
$a = $this->returnDefault();
$a->addGrantType(new League\OAuth2\Server\Grant\AuthCode());
$reflector = new ReflectionClass($a);
$method = $reflector->getMethod('getGrantType');
$method->setAccessible(true);
$result = $method->invoke($a, 'authorization_code');
$this->assertTrue($result instanceof League\OAuth2\Server\Grant\GrantTypeInterface);
}
/**
* @expectedException League\OAuth2\Server\Exception\InvalidGrantTypeException
* @expectedExceptionCode 9
*/
public function test_getGrantType_fail()
{
$a = $this->returnDefault();
$a->getGrantType('blah');
}
/**
* @expectedException League\OAuth2\Server\Exception\ClientException
* @expectedExceptionCode 0
*/
public function test_issueAccessToken_missingGrantType()
{
$a = $this->returnDefault();
$a->addGrantType(new League\OAuth2\Server\Grant\AuthCode());
$a->issueAccessToken();
}
/**
* @expectedException League\OAuth2\Server\Exception\ClientException
* @expectedExceptionCode 7
*/
public function test_issueAccessToken_badGrantType()
{
$a = $this->returnDefault();
$a->addGrantType(new League\OAuth2\Server\Grant\AuthCode());
$a->issueAccessToken(array('grant_type' => 'foo'));
}
/**
* @expectedException League\OAuth2\Server\Exception\ClientException
* @expectedExceptionCode 0
*/
public function test_issueAccessToken_missingClientId()
{
$a = $this->returnDefault();
$a->addGrantType(new League\OAuth2\Server\Grant\AuthCode());
$a->issueAccessToken(array(
'grant_type' => 'authorization_code'
));
}
/**
* @expectedException League\OAuth2\Server\Exception\ClientException
* @expectedExceptionCode 0
*/
public function test_issueAccessToken_missingClientSecret()
{
$a = $this->returnDefault();
$a->addGrantType(new League\OAuth2\Server\Grant\AuthCode());
$a->issueAccessToken(array(
'grant_type' => 'authorization_code',
'client_id' => 1234
));
}
/**
* @expectedException League\OAuth2\Server\Exception\ClientException
* @expectedExceptionCode 0
*/
public function test_issueAccessToken_missingRedirectUri()
{
$a = $this->returnDefault();
$a->addGrantType(new League\OAuth2\Server\Grant\AuthCode());
$a->issueAccessToken(array(
'grant_type' => 'authorization_code',
'client_id' => 1234,
'client_secret' => 5678
));
}
/**
* @expectedException League\OAuth2\Server\Exception\ClientException
* @expectedExceptionCode 8
*/
public function test_issueAccessToken_badClient()
{
$this->client->shouldReceive('getClient')->andReturn(false);
$a = $this->returnDefault();
$a->addGrantType(new League\OAuth2\Server\Grant\AuthCode());
$a->issueAccessToken(array(
'grant_type' => 'authorization_code',
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect'
));
}
/**
* @expectedException League\OAuth2\Server\Exception\ClientException
* @expectedExceptionCode 0
*/
public function test_issueAccessToken_missingCode()
{
$this->client->shouldReceive('getClient')->andReturn(array());
$a = $this->returnDefault();
$a->addGrantType(new League\OAuth2\Server\Grant\AuthCode());
$a->issueAccessToken(array(
'grant_type' => 'authorization_code',
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect'
));
}
/**
* @expectedException League\OAuth2\Server\Exception\ClientException
* @expectedExceptionCode 9
*/
public function test_issueAccessToken_badCode()
{
$this->client->shouldReceive('getClient')->andReturn(array());
$this->session->shouldReceive('validateAuthCode')->andReturn(false);
$a = $this->returnDefault();
$a->addGrantType(new League\OAuth2\Server\Grant\AuthCode());
$a->issueAccessToken(array(
'grant_type' => 'authorization_code',
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'code' => 'foobar'
));
}
public function test_issueAccessToken_passedInput()
{
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->session->shouldReceive('validateAuthCode')->andReturn(array(
'session_id' => 1,
'authcode_id' => 1
));
$this->session->shouldReceive('updateSession')->andReturn(null);
$this->session->shouldReceive('removeAuthCode')->andReturn(null);
$this->session->shouldReceive('associateAccessToken')->andReturn(1);
$this->session->shouldReceive('associateScope')->andReturn(null);
$this->session->shouldReceive('getAuthCodeScopes')->andReturn(array('scope_id' => 1));
$a = $this->returnDefault();
$a->addGrantType(new League\OAuth2\Server\Grant\AuthCode());
$v = $a->issueAccessToken(array(
'grant_type' => 'authorization_code',
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'code' => 'foobar'
));
$this->assertArrayHasKey('access_token', $v);
$this->assertArrayHasKey('token_type', $v);
$this->assertArrayHasKey('expires', $v);
$this->assertArrayHasKey('expires_in', $v);
$this->assertEquals($a->getAccessTokenTTL(), $v['expires_in']);
}
public function test_issueAccessToken()
{
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->session->shouldReceive('validateAuthCode')->andReturn(1);
$this->session->shouldReceive('updateSession')->andReturn(null);
$this->session->shouldReceive('removeAuthCode')->andReturn(null);
$this->session->shouldReceive('associateAccessToken')->andReturn(1);
$this->session->shouldReceive('getAuthCodeScopes')->andReturn(array('scope_id' => 1));
$this->session->shouldReceive('associateScope')->andReturn(null);
$a = $this->returnDefault();
$a->addGrantType(new League\OAuth2\Server\Grant\AuthCode());
$_POST['grant_type'] = 'authorization_code';
$_POST['client_id'] = 1234;
$_POST['client_secret'] = 5678;
$_POST['redirect_uri'] = 'http://foo/redirect';
$_POST['code'] = 'foobar';
$request = new League\OAuth2\Server\Util\Request(array(), $_POST);
$a->setRequest($request);
$v = $a->issueAccessToken();
$this->assertArrayHasKey('access_token', $v);
$this->assertArrayHasKey('token_type', $v);
$this->assertArrayHasKey('expires', $v);
$this->assertArrayHasKey('expires_in', $v);
$this->assertEquals($a->getAccessTokenTTL(), $v['expires_in']);
}
public function test_issueAccessToken_customExpiresIn()
{
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->session->shouldReceive('validateAuthCode')->andReturn(1);
$this->session->shouldReceive('updateSession')->andReturn(null);
$this->session->shouldReceive('removeAuthCode')->andReturn(null);
$this->session->shouldReceive('associateAccessToken')->andReturn(1);
$this->session->shouldReceive('getAuthCodeScopes')->andReturn(array('scope_id' => 1));
$this->session->shouldReceive('associateScope')->andReturn(null);
$a = $this->returnDefault();
$grant = new League\OAuth2\Server\Grant\AuthCode();
$grant->setAccessTokenTTL(30);
$a->addGrantType($grant);
$_POST['grant_type'] = 'authorization_code';
$_POST['client_id'] = 1234;
$_POST['client_secret'] = 5678;
$_POST['redirect_uri'] = 'http://foo/redirect';
$_POST['code'] = 'foobar';
$request = new League\OAuth2\Server\Util\Request(array(), $_POST);
$a->setRequest($request);
$v = $a->issueAccessToken();
$this->assertArrayHasKey('access_token', $v);
$this->assertArrayHasKey('token_type', $v);
$this->assertArrayHasKey('expires', $v);
$this->assertArrayHasKey('expires_in', $v);
$this->assertNotEquals($a->getAccessTokenTTL(), $v['expires_in']);
$this->assertNotEquals(time()+$a->getAccessTokenTTL(), $v['expires']);
$this->assertEquals(30, $v['expires_in']);
$this->assertEquals(time()+30, $v['expires']);
}
public function test_issueAccessToken_HTTP_auth()
{
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->session->shouldReceive('validateAuthCode')->andReturn(1);
$this->session->shouldReceive('updateSession')->andReturn(null);
$this->session->shouldReceive('removeAuthCode')->andReturn(null);
$this->session->shouldReceive('associateAccessToken')->andReturn(1);
$this->session->shouldReceive('getAuthCodeScopes')->andReturn(array('scope_id' => 1));
$this->session->shouldReceive('associateScope')->andReturn(null);
$a = $this->returnDefault();
$a->addGrantType(new League\OAuth2\Server\Grant\AuthCode());
$_POST['grant_type'] = 'authorization_code';
$_SERVER['PHP_AUTH_USER'] = 1234;
$_SERVER['PHP_AUTH_PW'] = 5678;
$_POST['redirect_uri'] = 'http://foo/redirect';
$_POST['code'] = 'foobar';
$request = new League\OAuth2\Server\Util\Request(array(), $_POST, array(), array(), $_SERVER);
$a->setRequest($request);
$v = $a->issueAccessToken();
$this->assertArrayHasKey('access_token', $v);
$this->assertArrayHasKey('token_type', $v);
$this->assertArrayHasKey('expires', $v);
$this->assertArrayHasKey('expires_in', $v);
$this->assertEquals($a->getAccessTokenTTL(), $v['expires_in']);
}
public function tearDown() {
M::close();
}
}

View File

@@ -0,0 +1,411 @@
<?php
use \Mockery as m;
class Client_Credentials_Grant_Test extends PHPUnit_Framework_TestCase
{
private $client;
private $session;
private $scope;
public function setUp()
{
$this->client = M::mock('League\OAuth2\Server\Storage\ClientInterface');
$this->session = M::mock('League\OAuth2\Server\Storage\SessionInterface');
$this->scope = M::mock('League\OAuth2\Server\Storage\ScopeInterface');
}
private function returnDefault()
{
return new League\OAuth2\Server\Authorization($this->client, $this->session, $this->scope);
}
/**
* @expectedException League\OAuth2\Server\Exception\ClientException
* @expectedExceptionCode 0
*/
public function test_issueAccessToken_clientCredentialsGrant_missingClientId()
{
$a = $this->returnDefault();
$a->addGrantType(new League\OAuth2\Server\Grant\ClientCredentials());
$request = new League\OAuth2\Server\Util\Request(array(), $_POST);
$a->setRequest($request);
$a->issueAccessToken(array(
'grant_type' => 'client_credentials'
));
}
/**
* @expectedException League\OAuth2\Server\Exception\ClientException
* @expectedExceptionCode 0
*/
public function test_issueAccessToken_clientCredentialsGrant_missingClientPassword()
{
$a = $this->returnDefault();
$a->addGrantType(new League\OAuth2\Server\Grant\ClientCredentials());
$request = new League\OAuth2\Server\Util\Request(array(), $_POST);
$a->setRequest($request);
$a->issueAccessToken(array(
'grant_type' => 'client_credentials',
'client_id' => 1234
));
}
/**
* @expectedException League\OAuth2\Server\Exception\ClientException
* @expectedExceptionCode 8
*/
public function test_issueAccessToken_clientCredentialsGrant_badClient()
{
$this->client->shouldReceive('getClient')->andReturn(false);
$a = $this->returnDefault();
$a->addGrantType(new League\OAuth2\Server\Grant\ClientCredentials());
$request = new League\OAuth2\Server\Util\Request(array(), $_POST);
$a->setRequest($request);
$a->issueAccessToken(array(
'grant_type' => 'client_credentials',
'client_id' => 1234,
'client_secret' => 5678
));
}
/**
* @expectedException League\OAuth2\Server\Exception\ClientException
* @expectedExceptionCode 0
*/
public function test_issueAccessToken_clientCredentialsGrant_missingScopes()
{
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->client->shouldReceive('validateRefreshToken')->andReturn(1);
$this->session->shouldReceive('validateAuthCode')->andReturn(1);
$this->session->shouldReceive('createSession')->andReturn(1);
$this->session->shouldReceive('deleteSession')->andReturn(null);
$a = $this->returnDefault();
$a->addGrantType(new League\OAuth2\Server\Grant\ClientCredentials());
$a->requireScopeParam(true);
$a->issueAccessToken(array(
'grant_type' => 'client_credentials',
'client_id' => 1234,
'client_secret' => 5678
));
}
public function test_issueAccessToken_clientCredentialsGrant_defaultScope()
{
$this->scope->shouldReceive('getScope')->andReturn(array(
'id' => 1,
'key' => 'foo',
'name' => 'Foo Name',
'description' => 'Foo Name Description'
));
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->client->shouldReceive('validateRefreshToken')->andReturn(1);
$this->session->shouldReceive('validateAuthCode')->andReturn(1);
$this->session->shouldReceive('createSession')->andReturn(1);
$this->session->shouldReceive('deleteSession')->andReturn(null);
$this->session->shouldReceive('associateScope')->andReturn(null);
$this->session->shouldReceive('associateAccessToken')->andReturn(1);
$a = $this->returnDefault();
$a->addGrantType(new League\OAuth2\Server\Grant\ClientCredentials());
$a->requireScopeParam(false);
$a->setDefaultScope('foobar');
$v = $a->issueAccessToken(array(
'grant_type' => 'client_credentials',
'client_id' => 1234,
'client_secret' => 5678,
'scope' => ''
));
$this->assertArrayHasKey('access_token', $v);
$this->assertArrayHasKey('token_type', $v);
$this->assertArrayHasKey('expires', $v);
$this->assertArrayHasKey('expires_in', $v);
}
public function test_issueAccessToken_clientCredentialsGrant_defaultScopeArray()
{
$this->scope->shouldReceive('getScope')->andReturn(array(
'id' => 1,
'key' => 'foo',
'name' => 'Foo Name',
'description' => 'Foo Name Description'
));
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->client->shouldReceive('validateRefreshToken')->andReturn(1);
$this->session->shouldReceive('validateAuthCode')->andReturn(1);
$this->session->shouldReceive('createSession')->andReturn(1);
$this->session->shouldReceive('deleteSession')->andReturn(null);
$this->session->shouldReceive('associateScope')->andReturn(null);
$this->session->shouldReceive('associateAccessToken')->andReturn(1);
$a = $this->returnDefault();
$a->addGrantType(new League\OAuth2\Server\Grant\ClientCredentials());
$a->requireScopeParam(false);
$a->setDefaultScope(array('foobar', 'barfoo'));
$v = $a->issueAccessToken(array(
'grant_type' => 'client_credentials',
'client_id' => 1234,
'client_secret' => 5678,
'scope' => ''
));
$this->assertArrayHasKey('access_token', $v);
$this->assertArrayHasKey('token_type', $v);
$this->assertArrayHasKey('expires', $v);
$this->assertArrayHasKey('expires_in', $v);
}
/**
* @expectedException League\OAuth2\Server\Exception\ClientException
* @expectedExceptionCode 4
*/
public function test_issueAccessToken_clientCredentialsGrant_badScope()
{
$this->scope->shouldReceive('getScope')->andReturn(false);
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->client->shouldReceive('validateRefreshToken')->andReturn(1);
$this->session->shouldReceive('validateAuthCode')->andReturn(1);
$this->session->shouldReceive('createSession')->andReturn(1);
$this->session->shouldReceive('deleteSession')->andReturn(null);
$this->session->shouldReceive('associateScope')->andReturn(null);
$a = $this->returnDefault();
$a->addGrantType(new League\OAuth2\Server\Grant\ClientCredentials());
$a->issueAccessToken(array(
'grant_type' => 'client_credentials',
'client_id' => 1234,
'client_secret' => 5678,
'scope' => 'blah'
));
}
public function test_issueAccessToken_clientCredentialsGrant_goodScope()
{
$this->scope->shouldReceive('getScope')->andReturn(array(
'id' => 1,
'key' => 'foo',
'name' => 'Foo Name',
'description' => 'Foo Name Description'
));
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->client->shouldReceive('validateRefreshToken')->andReturn(1);
$this->session->shouldReceive('validateAuthCode')->andReturn(1);
$this->session->shouldReceive('createSession')->andReturn(1);
$this->session->shouldReceive('deleteSession')->andReturn(null);
$this->session->shouldReceive('associateScope')->andReturn(null);
$this->session->shouldReceive('associateAccessToken')->andReturn(1);
$a = $this->returnDefault();
$a->addGrantType(new League\OAuth2\Server\Grant\ClientCredentials());
$v = $a->issueAccessToken(array(
'grant_type' => 'client_credentials',
'client_id' => 1234,
'client_secret' => 5678,
'scope' => 'blah'
));
$this->assertArrayHasKey('access_token', $v);
$this->assertArrayHasKey('token_type', $v);
$this->assertArrayHasKey('expires', $v);
$this->assertArrayHasKey('expires_in', $v);
}
function test_issueAccessToken_clientCredentialsGrant_passedInput()
{
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->client->shouldReceive('validateRefreshToken')->andReturn(1);
$this->session->shouldReceive('validateAuthCode')->andReturn(1);
$this->session->shouldReceive('createSession')->andReturn(1);
$this->session->shouldReceive('deleteSession')->andReturn(null);
$this->session->shouldReceive('associateAccessToken')->andReturn(1);
$a = $this->returnDefault();
$a->addGrantType(new League\OAuth2\Server\Grant\ClientCredentials());
$a->requireScopeParam(false);
$v = $a->issueAccessToken(array(
'grant_type' => 'client_credentials',
'client_id' => 1234,
'client_secret' => 5678,
));
$this->assertArrayHasKey('access_token', $v);
$this->assertArrayHasKey('token_type', $v);
$this->assertArrayHasKey('expires', $v);
$this->assertArrayHasKey('expires_in', $v);
$this->assertEquals($a->getAccessTokenTTL(), $v['expires_in']);
}
function test_issueAccessToken_clientCredentialsGrant()
{
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->client->shouldReceive('validateRefreshToken')->andReturn(1);
$this->session->shouldReceive('validateAuthCode')->andReturn(1);
$this->session->shouldReceive('createSession')->andReturn(1);
$this->session->shouldReceive('deleteSession')->andReturn(null);
$this->session->shouldReceive('associateAccessToken')->andReturn(1);
$a = $this->returnDefault();
$a->addGrantType(new League\OAuth2\Server\Grant\ClientCredentials());
$a->requireScopeParam(false);
$_POST['grant_type'] = 'client_credentials';
$_POST['client_id'] = 1234;
$_POST['client_secret'] = 5678;
$request = new League\OAuth2\Server\Util\Request(array(), $_POST);
$a->setRequest($request);
$v = $a->issueAccessToken();
$this->assertArrayHasKey('access_token', $v);
$this->assertArrayHasKey('token_type', $v);
$this->assertArrayHasKey('expires', $v);
$this->assertArrayHasKey('expires_in', $v);
$this->assertEquals($a->getAccessTokenTTL(), $v['expires_in']);
}
function test_issueAccessToken_clientCredentialsGrant_customExpiresIn()
{
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->client->shouldReceive('validateRefreshToken')->andReturn(1);
$this->session->shouldReceive('validateAuthCode')->andReturn(1);
$this->session->shouldReceive('createSession')->andReturn(1);
$this->session->shouldReceive('deleteSession')->andReturn(null);
$this->session->shouldReceive('associateAccessToken')->andReturn(1);
$a = $this->returnDefault();
$grant = new League\OAuth2\Server\Grant\ClientCredentials();
$grant->setAccessTokenTTL(30);
$a->addGrantType($grant);
$a->requireScopeParam(false);
$_POST['grant_type'] = 'client_credentials';
$_POST['client_id'] = 1234;
$_POST['client_secret'] = 5678;
$request = new League\OAuth2\Server\Util\Request(array(), $_POST);
$a->setRequest($request);
$v = $a->issueAccessToken();
$this->assertArrayHasKey('access_token', $v);
$this->assertArrayHasKey('token_type', $v);
$this->assertArrayHasKey('expires', $v);
$this->assertArrayHasKey('expires_in', $v);
$this->assertNotEquals($a->getAccessTokenTTL(), $v['expires_in']);
$this->assertNotEquals(time()+$a->getAccessTokenTTL(), $v['expires']);
$this->assertEquals(30, $v['expires_in']);
$this->assertEquals(time()+30, $v['expires']);
}
function test_issueAccessToken_clientCredentialsGrant_withRefreshToken()
{
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->client->shouldReceive('validateRefreshToken')->andReturn(1);
$this->session->shouldReceive('validateAuthCode')->andReturn(1);
$this->session->shouldReceive('createSession')->andReturn(1);
$this->session->shouldReceive('deleteSession')->andReturn(null);
$this->session->shouldReceive('associateAccessToken')->andReturn(1);
$a = $this->returnDefault();
$a->addGrantType(new League\OAuth2\Server\Grant\ClientCredentials());
$a->requireScopeParam(false);
$_POST['grant_type'] = 'client_credentials';
$_POST['client_id'] = 1234;
$_POST['client_secret'] = 5678;
$request = new League\OAuth2\Server\Util\Request(array(), $_POST);
$a->setRequest($request);
$v = $a->issueAccessToken();
$this->assertArrayHasKey('access_token', $v);
$this->assertArrayHasKey('token_type', $v);
$this->assertArrayHasKey('expires', $v);
$this->assertArrayHasKey('expires_in', $v);
$this->assertEquals($a->getAccessTokenTTL(), $v['expires_in']);
}
}

View File

@@ -0,0 +1,613 @@
<?php
use \Mockery as m;
class Password_Grant_Test extends PHPUnit_Framework_TestCase
{
private $client;
private $session;
private $scope;
public function setUp()
{
$this->client = M::mock('League\OAuth2\Server\Storage\ClientInterface');
$this->session = M::mock('League\OAuth2\Server\Storage\SessionInterface');
$this->scope = M::mock('League\OAuth2\Server\Storage\ScopeInterface');
}
private function returnDefault()
{
return new League\OAuth2\Server\Authorization($this->client, $this->session, $this->scope);
}
/**
* @expectedException League\OAuth2\Server\Exception\ClientException
* @expectedExceptionCode 0
*/
public function test_issueAccessToken_passwordGrant_missingClientId()
{
$a = $this->returnDefault();
$a->addGrantType(new League\OAuth2\Server\Grant\Password());
$request = new League\OAuth2\Server\Util\Request(array(), $_POST);
$a->setRequest($request);
$a->issueAccessToken(array(
'grant_type' => 'password'
));
}
/**
* @expectedException League\OAuth2\Server\Exception\ClientException
* @expectedExceptionCode 0
*/
public function test_issueAccessToken_passwordGrant_missingClientPassword()
{
$a = $this->returnDefault();
$a->addGrantType(new League\OAuth2\Server\Grant\Password());
$request = new League\OAuth2\Server\Util\Request(array(), $_POST);
$a->setRequest($request);
$a->issueAccessToken(array(
'grant_type' => 'password',
'client_id' => 1234
));
}
/**
* @expectedException League\OAuth2\Server\Exception\ClientException
* @expectedExceptionCode 8
*/
public function test_issueAccessToken_passwordGrant_badClient()
{
$this->client->shouldReceive('getClient')->andReturn(false);
$a = $this->returnDefault();
$a->addGrantType(new League\OAuth2\Server\Grant\Password());
$request = new League\OAuth2\Server\Util\Request(array(), $_POST);
$a->setRequest($request);
$a->issueAccessToken(array(
'grant_type' => 'password',
'client_id' => 1234,
'client_secret' => 5678
));
}
/**
* @expectedException League\OAuth2\Server\Exception\InvalidGrantTypeException
*/
function test_issueAccessToken_passwordGrant_invalidCallback()
{
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->client->shouldReceive('validateRefreshToken')->andReturn(1);
$this->session->shouldReceive('validateAuthCode')->andReturn(1);
$this->session->shouldReceive('createSession')->andReturn(1);
$this->session->shouldReceive('deleteSession')->andReturn(null);
$this->session->shouldReceive('updateRefreshToken')->andReturn(null);
$testCredentials = null;
$a = $this->returnDefault();
$pgrant = new League\OAuth2\Server\Grant\Password();
$pgrant->setVerifyCredentialsCallback($testCredentials);
$a->addGrantType($pgrant);
$a->issueAccessToken(array(
'grant_type' => 'password',
'client_id' => 1234,
'client_secret' => 5678,
'username' => 'foo',
'password' => 'bar'
));
}
/**
* @expectedException League\OAuth2\Server\Exception\ClientException
* @expectedExceptionCode 0
*/
function test_issueAccessToken_passwordGrant_missingUsername()
{
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->client->shouldReceive('validateRefreshToken')->andReturn(1);
$this->session->shouldReceive('validateAuthCode')->andReturn(1);
$this->session->shouldReceive('createSession')->andReturn(1);
$this->session->shouldReceive('deleteSession')->andReturn(null);
$this->session->shouldReceive('updateRefreshToken')->andReturn(null);
$testCredentials = function() { return false; };
$a = $this->returnDefault();
$pgrant = new League\OAuth2\Server\Grant\Password();
$pgrant->setVerifyCredentialsCallback($testCredentials);
$a->addGrantType($pgrant);
$a->issueAccessToken(array(
'grant_type' => 'password',
'client_id' => 1234,
'client_secret' => 5678
));
}
/**
* @expectedException League\OAuth2\Server\Exception\ClientException
* @expectedExceptionCode 0
*/
function test_issueAccessToken_passwordGrant_missingPassword()
{
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->client->shouldReceive('validateRefreshToken')->andReturn(1);
$this->session->shouldReceive('validateAuthCode')->andReturn(1);
$this->session->shouldReceive('createSession')->andReturn(1);
$this->session->shouldReceive('deleteSession')->andReturn(null);
$this->session->shouldReceive('updateRefreshToken')->andReturn(null);
$testCredentials = function() { return false; };
$a = $this->returnDefault();
$pgrant = new League\OAuth2\Server\Grant\Password();
$pgrant->setVerifyCredentialsCallback($testCredentials);
$a->addGrantType($pgrant);
$a->issueAccessToken(array(
'grant_type' => 'password',
'client_id' => 1234,
'client_secret' => 5678,
'username' => 'foo'
));
}
/**
* @expectedException League\OAuth2\Server\Exception\ClientException
* @expectedExceptionCode 0
*/
function test_issueAccessToken_passwordGrant_badCredentials()
{
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->client->shouldReceive('validateRefreshToken')->andReturn(1);
$this->session->shouldReceive('validateAuthCode')->andReturn(1);
$this->session->shouldReceive('createSession')->andReturn(1);
$this->session->shouldReceive('deleteSession')->andReturn(null);
$this->session->shouldReceive('updateRefreshToken')->andReturn(null);
$testCredentials = function() { return false; };
$a = $this->returnDefault();
$pgrant = new League\OAuth2\Server\Grant\Password();
$pgrant->setVerifyCredentialsCallback($testCredentials);
$a->addGrantType($pgrant);
$a->issueAccessToken(array(
'grant_type' => 'password',
'client_id' => 1234,
'client_secret' => 5678,
'username' => 'foo',
'password' => 'bar'
));
}
/**
* @expectedException League\OAuth2\Server\Exception\ClientException
* @expectedExceptionCode 4
*/
public function test_issueAccessToken_passwordGrant_badScopes()
{
$this->scope->shouldReceive('getScope')->andReturn(false);
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->client->shouldReceive('validateRefreshToken')->andReturn(1);
$this->session->shouldReceive('validateAuthCode')->andReturn(1);
$this->session->shouldReceive('createSession')->andReturn(1);
$this->session->shouldReceive('deleteSession')->andReturn(null);
$this->session->shouldReceive('updateRefreshToken')->andReturn(null);
$testCredentials = function() { return 1; };
$a = $this->returnDefault();
$pgrant = new League\OAuth2\Server\Grant\Password();
$pgrant->setVerifyCredentialsCallback($testCredentials);
$a->addGrantType($pgrant);
$a->issueAccessToken(array(
'grant_type' => 'password',
'client_id' => 1234,
'client_secret' => 5678,
'username' => 'foo',
'password' => 'bar',
'scope' => 'blah'
));
}
/**
* @expectedException League\OAuth2\Server\Exception\ClientException
* @expectedExceptionCode 0
*/
public function test_issueAccessToken_passwordGrant_missingScopes()
{
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->client->shouldReceive('validateRefreshToken')->andReturn(1);
$this->session->shouldReceive('validateAuthCode')->andReturn(1);
$this->session->shouldReceive('createSession')->andReturn(1);
$this->session->shouldReceive('deleteSession')->andReturn(null);
$this->session->shouldReceive('updateRefreshToken')->andReturn(null);
$testCredentials = function() { return 1; };
$a = $this->returnDefault();
$pgrant = new League\OAuth2\Server\Grant\Password();
$pgrant->setVerifyCredentialsCallback($testCredentials);
$a->addGrantType($pgrant);
$a->requireScopeParam(true);
$a->issueAccessToken(array(
'grant_type' => 'password',
'client_id' => 1234,
'client_secret' => 5678,
'username' => 'foo',
'password' => 'bar'
));
}
public function test_issueAccessToken_passwordGrant_defaultScope()
{
$this->scope->shouldReceive('getScope')->andReturn(array(
'id' => 1,
'scope' => 'foo',
'name' => 'Foo Name',
'description' => 'Foo Name Description'
));
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->client->shouldReceive('validateRefreshToken')->andReturn(1);
$this->session->shouldReceive('validateAuthCode')->andReturn(1);
$this->session->shouldReceive('createSession')->andReturn(1);
$this->session->shouldReceive('deleteSession')->andReturn(null);
$this->session->shouldReceive('updateRefreshToken')->andReturn(null);
$this->session->shouldReceive('associateScope')->andReturn(null);
$this->session->shouldReceive('associateAccessToken')->andReturn(1);
$testCredentials = function() { return 1; };
$a = $this->returnDefault();
$pgrant = new League\OAuth2\Server\Grant\Password();
$pgrant->setVerifyCredentialsCallback($testCredentials);
$a->addGrantType($pgrant);
$a->requireScopeParam(false);
$a->setDefaultScope('foobar');
$v = $a->issueAccessToken(array(
'grant_type' => 'password',
'client_id' => 1234,
'client_secret' => 5678,
'username' => 'foo',
'password' => 'bar',
'scope' => ''
));
$this->assertArrayHasKey('access_token', $v);
$this->assertArrayHasKey('token_type', $v);
$this->assertArrayHasKey('expires', $v);
$this->assertArrayHasKey('expires_in', $v);
}
public function test_issueAccessToken_passwordGrant_defaultScopeArray()
{
$this->scope->shouldReceive('getScope')->andReturn(array(
'id' => 1,
'scope' => 'foo',
'name' => 'Foo Name',
'description' => 'Foo Name Description'
));
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->client->shouldReceive('validateRefreshToken')->andReturn(1);
$this->session->shouldReceive('validateAuthCode')->andReturn(1);
$this->session->shouldReceive('createSession')->andReturn(1);
$this->session->shouldReceive('deleteSession')->andReturn(null);
$this->session->shouldReceive('updateRefreshToken')->andReturn(null);
$this->session->shouldReceive('associateScope')->andReturn(null);
$this->session->shouldReceive('associateAccessToken')->andReturn(1);
$testCredentials = function() { return 1; };
$a = $this->returnDefault();
$pgrant = new League\OAuth2\Server\Grant\Password();
$pgrant->setVerifyCredentialsCallback($testCredentials);
$a->addGrantType($pgrant);
$a->requireScopeParam(false);
$a->setDefaultScope(array('foobar', 'barfoo'));
$v = $a->issueAccessToken(array(
'grant_type' => 'password',
'client_id' => 1234,
'client_secret' => 5678,
'username' => 'foo',
'password' => 'bar',
'scope' => ''
));
$this->assertArrayHasKey('access_token', $v);
$this->assertArrayHasKey('token_type', $v);
$this->assertArrayHasKey('expires', $v);
$this->assertArrayHasKey('expires_in', $v);
}
public function test_issueAccessToken_passwordGrant_goodScope()
{
$this->scope->shouldReceive('getScope')->andReturn(array(
'id' => 1,
'scope' => 'foo',
'name' => 'Foo Name',
'description' => 'Foo Name Description'
));
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->client->shouldReceive('validateRefreshToken')->andReturn(1);
$this->session->shouldReceive('validateAuthCode')->andReturn(1);
$this->session->shouldReceive('createSession')->andReturn(1);
$this->session->shouldReceive('deleteSession')->andReturn(null);
$this->session->shouldReceive('updateRefreshToken')->andReturn(null);
$this->session->shouldReceive('associateScope')->andReturn(null);
$this->session->shouldReceive('associateAccessToken')->andReturn(1);
$testCredentials = function() { return 1; };
$a = $this->returnDefault();
$pgrant = new League\OAuth2\Server\Grant\Password();
$pgrant->setVerifyCredentialsCallback($testCredentials);
$a->addGrantType($pgrant);
$v = $a->issueAccessToken(array(
'grant_type' => 'password',
'client_id' => 1234,
'client_secret' => 5678,
'username' => 'foo',
'password' => 'bar',
'scope' => 'blah'
));
$this->assertArrayHasKey('access_token', $v);
$this->assertArrayHasKey('token_type', $v);
$this->assertArrayHasKey('expires', $v);
$this->assertArrayHasKey('expires_in', $v);
}
function test_issueAccessToken_passwordGrant_passedInput()
{
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->client->shouldReceive('validateRefreshToken')->andReturn(1);
$this->session->shouldReceive('validateAuthCode')->andReturn(1);
$this->session->shouldReceive('createSession')->andReturn(1);
$this->session->shouldReceive('deleteSession')->andReturn(null);
$this->session->shouldReceive('updateRefreshToken')->andReturn(null);
$this->session->shouldReceive('associateAccessToken')->andReturn(1);
$testCredentials = function() { return 1; };
$a = $this->returnDefault();
$pgrant = new League\OAuth2\Server\Grant\Password();
$pgrant->setVerifyCredentialsCallback($testCredentials);
$a->addGrantType($pgrant);
$a->requireScopeParam(false);
$v = $a->issueAccessToken(array(
'grant_type' => 'password',
'client_id' => 1234,
'client_secret' => 5678,
'username' => 'foo',
'password' => 'bar'
));
$this->assertArrayHasKey('access_token', $v);
$this->assertArrayHasKey('token_type', $v);
$this->assertArrayHasKey('expires', $v);
$this->assertArrayHasKey('expires_in', $v);
$this->assertEquals($a->getAccessTokenTTL(), $v['expires_in']);
}
function test_issueAccessToken_passwordGrant()
{
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->client->shouldReceive('validateRefreshToken')->andReturn(1);
$this->session->shouldReceive('validateAuthCode')->andReturn(1);
$this->session->shouldReceive('createSession')->andReturn(1);
$this->session->shouldReceive('deleteSession')->andReturn(null);
$this->session->shouldReceive('updateRefreshToken')->andReturn(null);
$this->session->shouldReceive('associateAccessToken')->andReturn(1);
$testCredentials = function() { return 1; };
$a = $this->returnDefault();
$pgrant = new League\OAuth2\Server\Grant\Password();
$pgrant->setVerifyCredentialsCallback($testCredentials);
$a->addGrantType($pgrant);
$a->requireScopeParam(false);
$_POST['grant_type'] = 'password';
$_POST['client_id'] = 1234;
$_POST['client_secret'] = 5678;
$_POST['username'] = 'foo';
$_POST['password'] = 'bar';
$request = new League\OAuth2\Server\Util\Request(array(), $_POST);
$a->setRequest($request);
$v = $a->issueAccessToken();
$this->assertArrayHasKey('access_token', $v);
$this->assertArrayHasKey('token_type', $v);
$this->assertArrayHasKey('expires', $v);
$this->assertArrayHasKey('expires_in', $v);
$this->assertEquals($a->getAccessTokenTTL(), $v['expires_in']);
}
function test_issueAccessToken_passwordGrant_customExpiresIn()
{
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->client->shouldReceive('validateRefreshToken')->andReturn(1);
$this->session->shouldReceive('validateAuthCode')->andReturn(1);
$this->session->shouldReceive('createSession')->andReturn(1);
$this->session->shouldReceive('deleteSession')->andReturn(null);
$this->session->shouldReceive('updateRefreshToken')->andReturn(null);
$this->session->shouldReceive('associateAccessToken')->andReturn(1);
$testCredentials = function() { return 1; };
$a = $this->returnDefault();
$pgrant = new League\OAuth2\Server\Grant\Password();
$pgrant->setVerifyCredentialsCallback($testCredentials);
$pgrant->setAccessTokenTTL(30);
$a->addGrantType($pgrant);
$a->requireScopeParam(false);
$_POST['grant_type'] = 'password';
$_POST['client_id'] = 1234;
$_POST['client_secret'] = 5678;
$_POST['username'] = 'foo';
$_POST['password'] = 'bar';
$request = new League\OAuth2\Server\Util\Request(array(), $_POST);
$a->setRequest($request);
$v = $a->issueAccessToken();
$this->assertArrayHasKey('access_token', $v);
$this->assertArrayHasKey('token_type', $v);
$this->assertArrayHasKey('expires', $v);
$this->assertArrayHasKey('expires_in', $v);
$this->assertNotEquals($a->getAccessTokenTTL(), $v['expires_in']);
$this->assertNotEquals(time()+$a->getAccessTokenTTL(), $v['expires']);
$this->assertEquals(30, $v['expires_in']);
$this->assertEquals(time()+30, $v['expires']);
}
function test_issueAccessToken_passwordGrant_withRefreshToken()
{
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->client->shouldReceive('validateRefreshToken')->andReturn(1);
$this->session->shouldReceive('validateAuthCode')->andReturn(1);
$this->session->shouldReceive('createSession')->andReturn(1);
$this->session->shouldReceive('deleteSession')->andReturn(null);
$this->session->shouldReceive('updateRefreshToken')->andReturn(null);
$this->session->shouldReceive('associateAccessToken')->andReturn(1);
$this->session->shouldReceive('associateRefreshToken')->andReturn(null);
$testCredentials = function() { return 1; };
$a = $this->returnDefault();
$pgrant = new League\OAuth2\Server\Grant\Password();
$pgrant->setVerifyCredentialsCallback($testCredentials);
$a->addGrantType($pgrant);
$a->addGrantType(new League\OAuth2\Server\Grant\RefreshToken());
$a->requireScopeParam(false);
$_POST['grant_type'] = 'password';
$_POST['client_id'] = 1234;
$_POST['client_secret'] = 5678;
$_POST['username'] = 'foo';
$_POST['password'] = 'bar';
$request = new League\OAuth2\Server\Util\Request(array(), $_POST);
$a->setRequest($request);
$v = $a->issueAccessToken();
$this->assertArrayHasKey('access_token', $v);
$this->assertArrayHasKey('token_type', $v);
$this->assertArrayHasKey('expires', $v);
$this->assertArrayHasKey('expires_in', $v);
$this->assertArrayHasKey('refresh_token', $v);
$this->assertEquals($a->getAccessTokenTTL(), $v['expires_in']);
}
}

View File

@@ -0,0 +1,421 @@
<?php
use \Mockery as m;
class Refresh_Token_test extends PHPUnit_Framework_TestCase
{
private $client;
private $session;
private $scope;
public function setUp()
{
$this->client = M::mock('League\OAuth2\Server\Storage\ClientInterface');
$this->session = M::mock('League\OAuth2\Server\Storage\SessionInterface');
$this->scope = M::mock('League\OAuth2\Server\Storage\ScopeInterface');
}
private function returnDefault()
{
return new League\OAuth2\Server\Authorization($this->client, $this->session, $this->scope);
}
public function test_setRefreshTokenTTL()
{
$a = $this->returnDefault();
$rt = new League\OAuth2\Server\Grant\RefreshToken();
$rt->setRefreshTokenTTL(30);
$this->assertEquals(30, $rt->getRefreshTokenTTL());
}
public function test_issueAccessToken_with_refresh_token()
{
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->session->shouldReceive('validateAuthCode')->andReturn(1);
$this->session->shouldReceive('updateSession')->andReturn(null);
$this->session->shouldReceive('removeAuthCode')->andReturn(null);
$this->session->shouldReceive('associateAccessToken')->andReturn(1);
$this->session->shouldReceive('associateRefreshToken')->andReturn(1);
$this->session->shouldReceive('associateScope')->andReturn(null);
$this->session->shouldReceive('getAuthCodeScopes')->andReturn(array('scope_id' => 1));
$a = $this->returnDefault();
$a->addGrantType(new League\OAuth2\Server\Grant\AuthCode());
$a->addGrantType(new League\OAuth2\Server\Grant\RefreshToken());
$_POST['grant_type'] = 'authorization_code';
$_POST['client_id'] = 1234;
$_POST['client_secret'] = 5678;
$_POST['redirect_uri'] = 'http://foo/redirect';
$_POST['code'] = 'foobar';
$request = new League\OAuth2\Server\Util\Request(array(), $_POST);
$a->setRequest($request);
$v = $a->issueAccessToken();
$this->assertArrayHasKey('access_token', $v);
$this->assertArrayHasKey('token_type', $v);
$this->assertArrayHasKey('expires', $v);
$this->assertArrayHasKey('expires_in', $v);
$this->assertArrayHasKey('refresh_token', $v);
$this->assertEquals($a->getAccessTokenTTL(), $v['expires_in']);
}
/**
* @expectedException League\OAuth2\Server\Exception\ClientException
* @expectedExceptionCode 0
*/
public function test_issueAccessToken_refreshTokenGrant_missingClientId()
{
$a = $this->returnDefault();
$a->addGrantType(new League\OAuth2\Server\Grant\RefreshToken());
$request = new League\OAuth2\Server\Util\Request(array(), $_POST);
$a->setRequest($request);
$a->issueAccessToken(array(
'grant_type' => 'refresh_token'
));
}
/**
* @expectedException League\OAuth2\Server\Exception\ClientException
* @expectedExceptionCode 0
*/
public function test_issueAccessToken_refreshTokenGrant_missingClientSecret()
{
$a = $this->returnDefault();
$a->addGrantType(new League\OAuth2\Server\Grant\RefreshToken());
$request = new League\OAuth2\Server\Util\Request(array(), $_POST);
$a->setRequest($request);
$a->issueAccessToken(array(
'grant_type' => 'refresh_token',
'client_id' => 1234
));
}
/**
* @expectedException League\OAuth2\Server\Exception\ClientException
* @expectedExceptionCode 8
*/
public function test_issueAccessToken_refreshTokenGrant_badClient()
{
$this->client->shouldReceive('getClient')->andReturn(false);
$a = $this->returnDefault();
$a->addGrantType(new League\OAuth2\Server\Grant\RefreshToken());
$request = new League\OAuth2\Server\Util\Request(array(), $_POST);
$a->setRequest($request);
$a->issueAccessToken(array(
'grant_type' => 'refresh_token',
'client_id' => 1234,
'client_secret' => 5678
));
}
/**
* @expectedException League\OAuth2\Server\Exception\ClientException
* @expectedExceptionCode 0
*/
public function test_issueAccessToken_refreshTokenGrant_missingRefreshToken()
{
$this->client->shouldReceive('getClient')->andReturn(array());
$a = $this->returnDefault();
$a->addGrantType(new League\OAuth2\Server\Grant\RefreshToken());
$request = new League\OAuth2\Server\Util\Request(array(), $_POST);
$a->setRequest($request);
$a->issueAccessToken(array(
'grant_type' => 'refresh_token',
'client_id' => 1234,
'client_secret' => 5678
));
}
/**
* @expectedException League\OAuth2\Server\Exception\ClientException
* @expectedExceptionCode 0
*/
public function test_issueAccessToken_refreshTokenGrant_badRefreshToken()
{
$this->client->shouldReceive('getClient')->andReturn(array());
$this->session->shouldReceive('validateRefreshToken')->andReturn(false);
$a = $this->returnDefault();
$a->addGrantType(new League\OAuth2\Server\Grant\RefreshToken());
$request = new League\OAuth2\Server\Util\Request(array(), $_POST);
$a->setRequest($request);
$a->issueAccessToken(array(
'grant_type' => 'refresh_token',
'client_id' => 1234,
'client_secret' => 5678,
'refresh_token' => 'abcdef'
));
}
public function test_issueAccessToken_refreshTokenGrant_passedInput()
{
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->session->shouldReceive('validateRefreshToken')->andReturn(1);
$this->session->shouldReceive('validateAuthCode')->andReturn(1);
$this->session->shouldReceive('updateSession')->andReturn(null);
$this->session->shouldReceive('updateRefreshToken')->andReturn(null);
$this->session->shouldReceive('associateAccessToken')->andReturn(1);
$this->session->shouldReceive('associateRefreshToken')->andReturn(1);
$this->session->shouldReceive('removeRefreshToken')->andReturn(1);
$this->session->shouldReceive('getAccessToken')->andReturn(null);
$this->session->shouldReceive('getScopes')->andReturn(array());
$a = $this->returnDefault();
$a->addGrantType(new League\OAuth2\Server\Grant\RefreshToken());
$_POST['grant_type'] = 'refresh_token';
$_POST['client_id'] = 1234;
$_POST['client_secret'] = 5678;
$_POST['refresh_token'] = 'abcdef';
$request = new League\OAuth2\Server\Util\Request(array(), $_POST);
$a->setRequest($request);
$v = $a->issueAccessToken();
$this->assertArrayHasKey('access_token', $v);
$this->assertArrayHasKey('token_type', $v);
$this->assertArrayHasKey('expires', $v);
$this->assertArrayHasKey('expires_in', $v);
$this->assertEquals($a->getAccessTokenTTL(), $v['expires_in']);
}
public function test_issueAccessToken_refreshTokenGrant()
{
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->session->shouldReceive('validateRefreshToken')->andReturn(1);
$this->session->shouldReceive('validateAuthCode')->andReturn(1);
$this->session->shouldReceive('updateSession')->andReturn(null);
$this->session->shouldReceive('updateRefreshToken')->andReturn(null);
$this->session->shouldReceive('getAccessToken')->andReturn(null);
$this->session->shouldReceive('getScopes')->andReturn(array('id' => 1));
$this->session->shouldReceive('associateAccessToken')->andReturn(1);
$this->session->shouldReceive('associateRefreshToken')->andReturn(1);
$this->session->shouldReceive('removeRefreshToken')->andReturn(1);
$this->session->shouldReceive('associateScope')->andReturn(null);
$a = $this->returnDefault();
$a->addGrantType(new League\OAuth2\Server\Grant\RefreshToken());
$v = $a->issueAccessToken(array(
'grant_type' => 'refresh_token',
'client_id' => 1234,
'client_secret' => 5678,
'refresh_token' => 'abcdef',
));
$this->assertArrayHasKey('access_token', $v);
$this->assertArrayHasKey('token_type', $v);
$this->assertArrayHasKey('expires', $v);
$this->assertArrayHasKey('expires_in', $v);
$this->assertEquals($a->getAccessTokenTTL(), $v['expires_in']);
}
public function test_issueAccessToken_refreshTokenGrant_rotateTokens()
{
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->session->shouldReceive('validateRefreshToken')->andReturn(1);
$this->session->shouldReceive('validateAuthCode')->andReturn(1);
$this->session->shouldReceive('updateSession')->andReturn(null);
$this->session->shouldReceive('updateRefreshToken')->andReturn(null);
$this->session->shouldReceive('getAccessToken')->andReturn(null);
$this->session->shouldReceive('getScopes')->andReturn(array('id' => 1));
$this->session->shouldReceive('associateAccessToken')->andReturn(1);
$this->session->shouldReceive('associateRefreshToken')->andReturn(1);
$this->session->shouldReceive('removeRefreshToken')->andReturn(1);
$this->session->shouldReceive('associateScope')->andReturn(null);
$a = $this->returnDefault();
$rt = new League\OAuth2\Server\Grant\RefreshToken();
$rt->rotateRefreshTokens(true);
$a->addGrantType($rt);
$v = $a->issueAccessToken(array(
'grant_type' => 'refresh_token',
'client_id' => 1234,
'client_secret' => 5678,
'refresh_token' => 'abcdef',
));
$this->assertArrayHasKey('access_token', $v);
$this->assertArrayHasKey('token_type', $v);
$this->assertArrayHasKey('expires', $v);
$this->assertArrayHasKey('expires_in', $v);
$this->assertArrayHasKey('refresh_token', $v);
$this->assertEquals($a->getAccessTokenTTL(), $v['expires_in']);
}
public function test_issueAccessToken_refreshTokenGrant_customExpiresIn()
{
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->session->shouldReceive('validateRefreshToken')->andReturn(1);
$this->session->shouldReceive('validateAuthCode')->andReturn(1);
$this->session->shouldReceive('updateSession')->andReturn(null);
$this->session->shouldReceive('updateRefreshToken')->andReturn(null);
$this->session->shouldReceive('getAccessToken')->andReturn(null);
$this->session->shouldReceive('getScopes')->andReturn(array('id' => 1));
$this->session->shouldReceive('associateAccessToken')->andReturn(1);
$this->session->shouldReceive('associateRefreshToken')->andReturn(1);
$this->session->shouldReceive('removeRefreshToken')->andReturn(1);
$this->session->shouldReceive('associateScope')->andReturn(null);
$a = $this->returnDefault();
$grant = new League\OAuth2\Server\Grant\RefreshToken();
$grant->setAccessTokenTTL(30);
$a->addGrantType($grant);
$v = $a->issueAccessToken(array(
'grant_type' => 'refresh_token',
'client_id' => 1234,
'client_secret' => 5678,
'refresh_token' => 'abcdef',
));
$this->assertArrayHasKey('access_token', $v);
$this->assertArrayHasKey('token_type', $v);
$this->assertArrayHasKey('expires', $v);
$this->assertArrayHasKey('expires_in', $v);
$this->assertNotEquals($a->getAccessTokenTTL(), $v['expires_in']);
$this->assertNotEquals(time()+$a->getAccessTokenTTL(), $v['expires']);
$this->assertEquals(30, $v['expires_in']);
$this->assertEquals(time()+30, $v['expires']);
}
public function test_issueAccessToken_refreshTokenGrant_newScopes()
{
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->session->shouldReceive('validateRefreshToken')->andReturn(1);
$this->session->shouldReceive('validateAuthCode')->andReturn(1);
$this->session->shouldReceive('updateSession')->andReturn(null);
$this->session->shouldReceive('updateRefreshToken')->andReturn(null);
$this->session->shouldReceive('getAccessToken')->andReturn(null);
$this->session->shouldReceive('getScopes')->andReturn(array(array('id' => 1, 'scope' => 'foo'), array('id' => 2, 'scope' => 'bar')));
$this->session->shouldReceive('associateAccessToken')->andReturn(1);
$this->session->shouldReceive('associateRefreshToken')->andReturn(1);
$this->session->shouldReceive('removeRefreshToken')->andReturn(1);
$this->session->shouldReceive('associateScope')->andReturn(null);
$this->scope->shouldReceive('getScope')->andReturn(array('id' => 1, 'scope' => 'foo'));
$a = $this->returnDefault();
$grant = new League\OAuth2\Server\Grant\RefreshToken();
$grant->setAccessTokenTTL(30);
$grant->rotateRefreshTokens(true);
$a->addGrantType($grant);
$v = $a->issueAccessToken(array(
'grant_type' => 'refresh_token',
'client_id' => 1234,
'client_secret' => 5678,
'refresh_token' => 'abcdef',
'scope' => 'foo'
));
$this->assertArrayHasKey('access_token', $v);
$this->assertArrayHasKey('token_type', $v);
$this->assertArrayHasKey('expires', $v);
$this->assertArrayHasKey('expires_in', $v);
$this->assertArrayHasKey('refresh_token', $v);
$this->assertNotEquals($a->getAccessTokenTTL(), $v['expires_in']);
$this->assertNotEquals(time()+$a->getAccessTokenTTL(), $v['expires']);
$this->assertEquals(30, $v['expires_in']);
$this->assertEquals(time()+30, $v['expires']);
}
/**
* @expectedException League\OAuth2\Server\Exception\ClientException
* @expectedExceptionCode 0
*/
public function test_issueAccessToken_refreshTokenGrant_badNewScopes()
{
$this->client->shouldReceive('getClient')->andReturn(array(
'client_id' => 1234,
'client_secret' => 5678,
'redirect_uri' => 'http://foo/redirect',
'name' => 'Example Client'
));
$this->session->shouldReceive('validateRefreshToken')->andReturn(1);
$this->session->shouldReceive('validateAuthCode')->andReturn(1);
$this->session->shouldReceive('updateSession')->andReturn(null);
$this->session->shouldReceive('updateRefreshToken')->andReturn(null);
$this->session->shouldReceive('getAccessToken')->andReturn(null);
$this->session->shouldReceive('getScopes')->andReturn(array(array('id' => 1, 'scope' => 'foo'), array('id' => 2, 'scope' => 'bar')));
$this->session->shouldReceive('associateAccessToken')->andReturn(1);
$this->session->shouldReceive('associateRefreshToken')->andReturn(1);
$this->session->shouldReceive('removeRefreshToken')->andReturn(1);
$this->session->shouldReceive('associateScope')->andReturn(null);
$this->scope->shouldReceive('getScope')->andReturn(array('id' => 1, 'scope' => 'foo'));
$a = $this->returnDefault();
$grant = new League\OAuth2\Server\Grant\RefreshToken();
$grant->setAccessTokenTTL(30);
$grant->rotateRefreshTokens(true);
$a->addGrantType($grant);
$a->issueAccessToken(array(
'grant_type' => 'refresh_token',
'client_id' => 1234,
'client_secret' => 5678,
'refresh_token' => 'abcdef',
'scope' => 'foobar'
));
}
}

View File

@@ -0,0 +1,284 @@
<?php
use \Mockery as m;
class Resource_Server_test extends PHPUnit_Framework_TestCase
{
private $session;
public function setUp()
{
$this->session = M::mock('League\OAuth2\Server\Storage\SessionInterface');
}
private function returnDefault()
{
return new League\OAuth2\Server\Resource($this->session);
}
public function test_getExceptionMessage()
{
$m = League\OAuth2\Server\Resource::getExceptionMessage('invalid_request');
$reflector = new ReflectionClass($this->returnDefault());
$exceptionMessages = $reflector->getProperty('exceptionMessages');
$exceptionMessages->setAccessible(true);
$v = $exceptionMessages->getValue();
$this->assertEquals($v['invalid_request'], $m);
}
public function test_getExceptionCode()
{
$this->assertEquals('invalid_request', League\OAuth2\Server\Resource::getExceptionType(0));
$this->assertEquals('invalid_token', League\OAuth2\Server\Resource::getExceptionType(1));
$this->assertEquals('insufficient_scope', League\OAuth2\Server\Resource::getExceptionType(2));
}
public function test_getExceptionHttpHeaders()
{
$this->assertEquals(array('HTTP/1.1 400 Bad Request'), League\OAuth2\Server\Resource::getExceptionHttpHeaders('invalid_request'));
$this->assertEquals(array('HTTP/1.1 401 Unauthorized'), League\OAuth2\Server\Resource::getExceptionHttpHeaders('invalid_token'));
$this->assertContains('HTTP/1.1 403 Forbidden', League\OAuth2\Server\Resource::getExceptionHttpHeaders('insufficient_scope'));
}
public function test_setRequest()
{
$s = $this->returnDefault();
$request = new League\OAuth2\Server\Util\Request();
$s->setRequest($request);
$reflector = new ReflectionClass($s);
$requestProperty = $reflector->getProperty('request');
$requestProperty->setAccessible(true);
$v = $requestProperty->getValue($s);
$this->assertTrue($v instanceof League\OAuth2\Server\Util\RequestInterface);
}
public function test_getRequest()
{
$s = $this->returnDefault();
$request = new League\OAuth2\Server\Util\Request();
$s->setRequest($request);
$v = $s->getRequest();
$this->assertTrue($v instanceof League\OAuth2\Server\Util\RequestInterface);
}
public function test_getTokenKey()
{
$s = $this->returnDefault();
$this->assertEquals('access_token', $s->getTokenKey());
}
public function test_setTokenKey()
{
$s = $this->returnDefault();
$s->setTokenKey('oauth_token');
$reflector = new ReflectionClass($s);
$requestProperty = $reflector->getProperty('tokenKey');
$requestProperty->setAccessible(true);
$v = $requestProperty->getValue($s);
$this->assertEquals('oauth_token', $v);
}
public function test_getScopes()
{
$s = $this->returnDefault();
$this->assertEquals(array(), $s->getScopes());
}
/**
* @expectedException League\OAuth2\Server\Exception\MissingAccessTokenException
*/
public function test_determineAccessToken_missingToken()
{
$_SERVER['HTTP_AUTHORIZATION'] = 'Bearer';
$request = new League\OAuth2\Server\Util\Request(array(), array(), array(), array(), $_SERVER);
$s = $this->returnDefault();
$s->setRequest($request);
$reflector = new ReflectionClass($s);
$method = $reflector->getMethod('determineAccessToken');
$method->setAccessible(true);
$method->invoke($s);
}
/**
* @expectedException League\OAuth2\Server\Exception\MissingAccessTokenException
*/
public function test_determineAccessToken_brokenCurlRequest()
{
$_SERVER['HTTP_AUTHORIZATION'] = 'Bearer, Bearer abcdef';
$request = new League\OAuth2\Server\Util\Request(array(), array(), array(), array(), $_SERVER);
$s = $this->returnDefault();
$s->setRequest($request);
$reflector = new ReflectionClass($s);
$method = $reflector->getMethod('determineAccessToken');
$method->setAccessible(true);
$method->invoke($s);
}
public function test_determineAccessToken_fromHeader()
{
$request = new League\OAuth2\Server\Util\Request();
$requestReflector = new ReflectionClass($request);
$param = $requestReflector->getProperty('headers');
$param->setAccessible(true);
$param->setValue($request, array(
'Authorization' => 'Bearer abcdef'
));
$s = $this->returnDefault();
$s->setRequest($request);
$reflector = new ReflectionClass($s);
$method = $reflector->getMethod('determineAccessToken');
$method->setAccessible(true);
$result = $method->invoke($s);
$this->assertEquals('abcdef', $result);
}
public function test_determineAccessToken_fromBrokenCurlHeader()
{
$request = new League\OAuth2\Server\Util\Request();
$requestReflector = new ReflectionClass($request);
$param = $requestReflector->getProperty('headers');
$param->setAccessible(true);
$param->setValue($request, array(
'Authorization' => 'Bearer abcdef, Bearer abcdef'
));
$s = $this->returnDefault();
$s->setRequest($request);
$reflector = new ReflectionClass($s);
$method = $reflector->getMethod('determineAccessToken');
$method->setAccessible(true);
$result = $method->invoke($s);
$this->assertEquals('abcdef', $result);
}
public function test_determineAccessToken_fromMethod()
{
$s = $this->returnDefault();
$_GET[$s->getTokenKey()] = 'abcdef';
$_SERVER['REQUEST_METHOD'] = 'get';
$request = new League\OAuth2\Server\Util\Request($_GET, array(), array(), array(), $_SERVER);
$s->setRequest($request);
$reflector = new ReflectionClass($s);
$method = $reflector->getMethod('determineAccessToken');
$method->setAccessible(true);
$result = $method->invoke($s);
$this->assertEquals('abcdef', $result);
}
public function test_hasScope_isRequired()
{
$s = $this->returnDefault();
$reflector = new ReflectionClass($s);
$param = $reflector->getProperty('sessionScopes');
$param->setAccessible(true);
$param->setValue($s, array(
'a', 'b', 'c'
));
$result = $s->hasScope(array('a', 'b'), true);
$this->assertEquals(true, $result);
}
/**
* @expectedException League\OAuth2\Server\Exception\InsufficientScopeException
*/
public function test_hasScope_isRequiredFailure()
{
$s = $this->returnDefault();
$reflector = new ReflectionClass($s);
$param = $reflector->getProperty('sessionScopes');
$param->setAccessible(true);
$param->setValue($s, array(
'a', 'b', 'c'
));
$s->hasScope('d', true);
}
/**
* @expectedException League\OAuth2\Server\Exception\InvalidAccessTokenException
*/
public function test_isValid_notValid()
{
$this->session->shouldReceive('validateAccessToken')->andReturn(false);
$request = new League\OAuth2\Server\Util\Request();
$requestReflector = new ReflectionClass($request);
$param = $requestReflector->getProperty('headers');
$param->setAccessible(true);
$param->setValue($request, array(
'Authorization' => 'Bearer abcdef'
));
$s = $this->returnDefault();
$s->setRequest($request);
$s->isValid();
}
public function test_isValid_valid()
{
$this->session->shouldReceive('validateAccessToken')->andReturn(array(
'session_id' => 1,
'owner_type' => 'user',
'owner_id' => 123,
'client_id' => 'testapp'
));
$this->session->shouldReceive('getScopes')->andReturn(array(
array('scope' => 'foo'),
array('scope' => 'bar')
));
$request = new League\OAuth2\Server\Util\Request();
$requestReflector = new ReflectionClass($request);
$param = $requestReflector->getProperty('headers');
$param->setAccessible(true);
$param->setValue($request, array(
'Authorization' => 'Bearer abcdef'
));
$s = $this->returnDefault();
$s->setRequest($request);
$this->assertTrue($s->isValid());
$this->assertEquals(123, $s->getOwnerId());
$this->assertEquals('user', $s->getOwnerType());
$this->assertEquals('abcdef', $s->getAccessToken());
$this->assertEquals('testapp', $s->getClientId());
$this->assertTrue($s->hasScope('foo'));
$this->assertTrue($s->hasScope('bar'));
$this->assertTrue($s->hasScope(array('foo', 'bar')));
$this->assertFalse($s->hasScope(array('foobar')));
$this->assertFalse($s->hasScope('foobar'));
}
}

View File

@@ -1,31 +0,0 @@
<?php
use Oauth2\Resource\Database;
class ResourceDB implements Database
{
private $accessTokens = array(
'test12345' => array(
'id' => 1,
'owner_type' => 'user',
'owner_id' => 123
)
);
private $sessionScopes = array(
1 => array(
'foo',
'bar'
)
);
public function validateAccessToken($accessToken)
{
return (isset($this->accessTokens[$accessToken])) ? $this->accessTokens[$accessToken] : false;
}
public function sessionScopes($sessionId)
{
return (isset($this->sessionScopes[$sessionId])) ? $this->sessionScopes[$sessionId] : array();
}
}

View File

@@ -1,121 +0,0 @@
<?php
class Resource_Server_test extends PHPUnit_Framework_TestCase {
function setUp()
{
require_once('database_mock.php');
$this->server = new Oauth2\Resource\Server();
$this->db = new ResourceDB();
$this->assertInstanceOf('Oauth2\Resource\Database', $this->db);
$this->server->registerDbAbstractor($this->db);
}
function test_init_POST()
{
$_SERVER['REQUEST_METHOD'] = 'POST';
$_POST['oauth_token'] = 'test12345';
$this->server->init();
$reflector = new ReflectionClass($this->server);
$_accessToken = $reflector->getProperty('_accessToken');
$_accessToken->setAccessible(true);
$_type = $reflector->getProperty('_type');
$_type->setAccessible(true);
$_typeId = $reflector->getProperty('_typeId');
$_typeId->setAccessible(true);
$_scopes = $reflector->getProperty('_scopes');
$_scopes->setAccessible(true);
$this->assertEquals($_accessToken->getValue($this->server), $_POST['oauth_token']);
$this->assertEquals($_type->getValue($this->server), 'user');
$this->assertEquals($_typeId->getValue($this->server), 123);
$this->assertEquals($_scopes->getValue($this->server), array('foo', 'bar'));
}
function test_init_GET()
{
$_GET['oauth_token'] = 'test12345';
$this->server->init();
$reflector = new ReflectionClass($this->server);
$_accessToken = $reflector->getProperty('_accessToken');
$_accessToken->setAccessible(true);
$_type = $reflector->getProperty('_type');
$_type->setAccessible(true);
$_typeId = $reflector->getProperty('_typeId');
$_typeId->setAccessible(true);
$_scopes = $reflector->getProperty('_scopes');
$_scopes->setAccessible(true);
$this->assertEquals($_accessToken->getValue($this->server), $_GET['oauth_token']);
$this->assertEquals($_type->getValue($this->server), 'user');
$this->assertEquals($_typeId->getValue($this->server), 123);
$this->assertEquals($_scopes->getValue($this->server), array('foo', 'bar'));
}
function test_init_header()
{
// Test with authorisation header
$this->markTestIncomplete('Authorisation header test has not been implemented yet.');
}
/**
* @expectedException \Oauth2\Resource\ClientException
* @expectedExceptionMessage An access token was not presented with the request
*/
function test_init_missingToken()
{
$this->server->init();
}
/**
* @expectedException \Oauth2\Resource\ClientException
* @expectedExceptionMessage The access token is not registered with the resource server
*/
function test_init_wrongToken()
{
$_POST['oauth_token'] = 'blah';
$_SERVER['REQUEST_METHOD'] = 'POST';
$this->server->init();
}
function test_hasScope()
{
$_POST['oauth_token'] = 'test12345';
$_SERVER['REQUEST_METHOD'] = 'POST';
$this->server->init();
$this->assertEquals(true, $this->server->hasScope('foo'));
$this->assertEquals(true, $this->server->hasScope('bar'));
$this->assertEquals(true, $this->server->hasScope(array('foo', 'bar')));
$this->assertEquals(false, $this->server->hasScope('foobar'));
$this->assertEquals(false, $this->server->hasScope(array('foobar')));
}
function test___call()
{
$_POST['oauth_token'] = 'test12345';
$_SERVER['REQUEST_METHOD'] = 'POST';
$this->server->init();
$this->assertEquals(123, $this->server->isUser());
$this->assertEquals(false, $this->server->isMachine());
}
}

View File

@@ -0,0 +1,15 @@
<?php
class RedirectUri_test extends PHPUnit_Framework_TestCase
{
function test_make()
{
$v1 = League\OAuth2\Server\Util\RedirectUri::make('https://foobar/', array('foo'=>'bar'));
$v2 = League\OAuth2\Server\Util\RedirectUri::make('https://foobar/', array('foo'=>'bar'), '#');
$v3 = League\OAuth2\Server\Util\RedirectUri::make('https://foobar/', array('foo'=>'bar', 'bar' => 'foo'));
$this->assertEquals('https://foobar/?foo=bar', $v1);
$this->assertEquals('https://foobar/#foo=bar', $v2);
$this->assertEquals('https://foobar/?foo=bar&bar=foo', $v3);
}
}

View File

@@ -0,0 +1,87 @@
<?php
class Request_test extends PHPUnit_Framework_TestCase
{
private $request;
function setUp()
{
$this->request = new League\OAuth2\Server\Util\Request(
array('foo' => 'bar'),
array('foo' => 'bar'),
array('foo' => 'bar'),
array('foo' => 'bar'),
array('HTTP_HOST' => 'foobar.com')
);
}
function test_buildFromIndex()
{
$r = new League\OAuth2\Server\Util\Request();
$r->buildFromGlobals();
$this->assertTrue($r instanceof League\OAuth2\Server\Util\Request);
}
function test_get()
{
$this->assertEquals('bar', $this->request->get('foo'));
$this->assertEquals(array('foo' => 'bar'), $this->request->get());
}
function test_post()
{
$this->assertEquals('bar', $this->request->post('foo'));
$this->assertEquals(array('foo' => 'bar'), $this->request->post());
}
function test_file()
{
$this->assertEquals('bar', $this->request->file('foo'));
$this->assertEquals(array('foo' => 'bar'), $this->request->file());
}
function test_cookie()
{
$this->assertEquals('bar', $this->request->cookie('foo'));
$this->assertEquals(array('foo' => 'bar'), $this->request->cookie());
}
function test_server()
{
$this->assertEquals('foobar.com', $this->request->server('HTTP_HOST'));
$this->assertEquals(array('HTTP_HOST' => 'foobar.com'), $this->request->server());
}
function test_header()
{
$this->assertEquals('foobar.com', $this->request->header('Host'));
$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
*/
function test_unknownProperty()
{
$reflector = new ReflectionClass($this->request);
$method = $reflector->getMethod('getPropertyValue');
$method->setAccessible(true);
$method->invoke($this->request, 'blah');
}
}

View File

@@ -0,0 +1,32 @@
<?php
class Secure_Key_test extends PHPUnit_Framework_TestCase
{
function test_make()
{
$v1 = League\OAuth2\Server\Util\SecureKey::make();
$v2 = League\OAuth2\Server\Util\SecureKey::make();
$v3 = League\OAuth2\Server\Util\SecureKey::make(50);
$this->assertEquals(40, strlen($v1));
$this->assertTrue($v1 !== $v2);
$this->assertEquals(50, strlen($v3));
}
public function test_make_with_different_algorithm()
{
$algorithm = $this->getMock('League\OAuth2\Server\Util\KeyAlgorithm\KeyAlgorithmInterface');
$result = 'dasdsdsaads';
$algorithm
->expects($this->once())
->method('make')
->with(11)
->will($this->returnValue($result))
;
League\OAuth2\Server\Util\SecureKey::setAlgorithm($algorithm);
$this->assertSame($algorithm, League\OAuth2\Server\Util\SecureKey::getAlgorithm());
$this->assertEquals($result, League\OAuth2\Server\Util\SecureKey::make(11));
}
}

View File

@@ -0,0 +1,22 @@
<?php
/**
* Created by PhpStorm.
* User: jderay
* Date: 3/11/14
* Time: 12:31 PM
*/
class Default_Algorithm_test extends PHPUnit_Framework_TestCase
{
public function test_make()
{
$algorithm = new League\OAuth2\Server\Util\KeyAlgorithm\DefaultAlgorithm();
$v1 = $algorithm->make();
$v2 = $algorithm->make();
$v3 = $algorithm->make(50);
$this->assertEquals(40, strlen($v1));
$this->assertTrue($v1 !== $v2);
$this->assertEquals(50, strlen($v3));
}
}