rack-oauth2 0.2.3 → 0.3.0.alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +1 -0
- data/README.rdoc +1 -0
- data/VERSION +1 -1
- data/lib/rack/oauth2.rb +1 -7
- data/lib/rack/oauth2/server.rb +0 -1
- data/lib/rack/oauth2/server/abstract.rb +2 -1
- data/lib/rack/oauth2/server/abstract/error.rb +55 -0
- data/lib/rack/oauth2/server/abstract/handler.rb +2 -3
- data/lib/rack/oauth2/server/abstract/request.rb +2 -3
- data/lib/rack/oauth2/server/abstract/response.rb +0 -5
- data/lib/rack/oauth2/server/authorize.rb +19 -14
- data/lib/rack/oauth2/server/authorize/code.rb +8 -19
- data/lib/rack/oauth2/server/authorize/error.rb +60 -0
- data/lib/rack/oauth2/server/authorize/token.rb +15 -24
- data/lib/rack/oauth2/server/resource.rb +1 -79
- data/lib/rack/oauth2/server/resource/bearer.rb +74 -0
- data/lib/rack/oauth2/server/resource/bearer/error.rb +80 -0
- data/lib/rack/oauth2/server/token.rb +12 -19
- data/lib/rack/oauth2/server/token/authorization_code.rb +4 -5
- data/lib/rack/oauth2/server/token/error.rb +54 -0
- data/lib/rack/oauth2/server/token/password.rb +0 -2
- data/lib/rack/oauth2/server/token/refresh_token.rb +1 -1
- data/lib/rack/oauth2/server/util.rb +29 -0
- data/rack-oauth2.gemspec +1 -1
- data/spec/rack/oauth2/server/abstract/error_spec.rb +51 -0
- data/spec/rack/oauth2/server/authorize/code_spec.rb +42 -28
- data/spec/rack/oauth2/server/authorize/error_spec.rb +103 -0
- data/spec/rack/oauth2/server/authorize/token_spec.rb +55 -26
- data/spec/rack/oauth2/server/authorize_spec.rb +24 -68
- data/spec/rack/oauth2/server/resource/bearer/error_spec.rb +118 -0
- data/spec/rack/oauth2/server/resource/bearer_spec.rb +117 -0
- data/spec/rack/oauth2/server/token/authorization_code_spec.rb +26 -109
- data/spec/rack/oauth2/server/token/error_spec.rb +77 -0
- data/spec/rack/oauth2/server/token/password_spec.rb +27 -47
- data/spec/rack/oauth2/server/token/refresh_token_spec.rb +22 -43
- data/spec/rack/oauth2/server/token_spec.rb +77 -116
- data/spec/rack/oauth2/server/util_spec.rb +75 -16
- data/spec/spec_helper.rb +0 -12
- metadata +25 -29
- data/lib/rack/oauth2/server/authorize/code_and_token.rb +0 -62
- data/lib/rack/oauth2/server/error.rb +0 -73
- data/lib/rack/oauth2/server/error/authorize.rb +0 -54
- data/lib/rack/oauth2/server/error/resource.rb +0 -50
- data/lib/rack/oauth2/server/error/token.rb +0 -59
- data/lib/rack/oauth2/server/token/assertion.rb +0 -29
- data/spec/rack/oauth2/server/authorize/code_and_token_spec.rb +0 -53
- data/spec/rack/oauth2/server/error/authorize_spec.rb +0 -102
- data/spec/rack/oauth2/server/error/resource_spec.rb +0 -69
- data/spec/rack/oauth2/server/error/token_spec.rb +0 -115
- data/spec/rack/oauth2/server/error_spec.rb +0 -107
- data/spec/rack/oauth2/server/resource_spec.rb +0 -141
- data/spec/rack/oauth2/server/token/assertion_spec.rb +0 -56
data/Gemfile
CHANGED
data/README.rdoc
CHANGED
@@ -14,6 +14,7 @@ http://tools.ietf.org/html/draft-ietf-oauth-v2-10
|
|
14
14
|
* View RDoc on RDoc.info (http://rdoc.info/github/nov/rack-oauth2)
|
15
15
|
* View Source on GitHub (http://github.com/nov/rack-oauth2)
|
16
16
|
* Report Issues on GitHub (http://github.com/nov/rack-oauth2/issues)
|
17
|
+
* Facebook Page (http://www.facebook.com/pages/RackOAuth2/141477809244105)
|
17
18
|
|
18
19
|
== Usage
|
19
20
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.0.alpha
|
data/lib/rack/oauth2.rb
CHANGED
data/lib/rack/oauth2/server.rb
CHANGED
@@ -0,0 +1,55 @@
|
|
1
|
+
module Rack
|
2
|
+
module OAuth2
|
3
|
+
module Server
|
4
|
+
module Abstract
|
5
|
+
class Error < StandardError
|
6
|
+
attr_accessor :status, :error, :description, :uri
|
7
|
+
|
8
|
+
def initialize(status, error, description = nil, options = {})
|
9
|
+
@status = status
|
10
|
+
@error = error
|
11
|
+
@description = description
|
12
|
+
@uri = options[:uri]
|
13
|
+
end
|
14
|
+
|
15
|
+
def protocol_params
|
16
|
+
{
|
17
|
+
:error => error,
|
18
|
+
:error_description => description,
|
19
|
+
:error_uri => uri
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
def finish
|
24
|
+
response = Rack::Response.new
|
25
|
+
response.status = status
|
26
|
+
yield response if block_given?
|
27
|
+
unless response.redirect?
|
28
|
+
response.header['Content-Type'] = 'application/json'
|
29
|
+
response.write Util.compact_hash(protocol_params).to_json
|
30
|
+
end
|
31
|
+
response.finish
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class BadRequest < Error
|
36
|
+
def initialize(error = :bad_request, description = nil, options = {})
|
37
|
+
super 400, error, description, options
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class Unauthorized < Error
|
42
|
+
def initialize(error = :unauthorized, description = nil, options = {})
|
43
|
+
super 401, error, description, options
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class Forbidden < Error
|
48
|
+
def initialize(error = :forbidden, description = nil, options = {})
|
49
|
+
super 403, error, description, options
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -3,10 +3,9 @@ module Rack
|
|
3
3
|
module Server
|
4
4
|
module Abstract
|
5
5
|
class Handler
|
6
|
-
attr_accessor :
|
6
|
+
attr_accessor :authenticator, :request, :response
|
7
7
|
|
8
|
-
def initialize(
|
9
|
-
@realm = realm
|
8
|
+
def initialize(&authenticator)
|
10
9
|
@authenticator = authenticator
|
11
10
|
end
|
12
11
|
|
@@ -15,14 +15,13 @@ module Rack
|
|
15
15
|
|
16
16
|
def attr_missing_with_error_handling!
|
17
17
|
if params['client_id'].present? && @client_id != params['client_id']
|
18
|
-
|
18
|
+
invalid_request! 'Multiple client credentials are provided.'
|
19
19
|
end
|
20
20
|
attr_missing_without_error_handling!
|
21
21
|
rescue AttrRequired::AttrMissing => e
|
22
|
-
invalid_request!
|
22
|
+
invalid_request! e.message, :state => @state, :redirect_uri => @redirect_uri
|
23
23
|
end
|
24
24
|
alias_method_chain :attr_missing!, :error_handling
|
25
|
-
|
26
25
|
end
|
27
26
|
end
|
28
27
|
end
|
@@ -2,16 +2,14 @@ module Rack
|
|
2
2
|
module OAuth2
|
3
3
|
module Server
|
4
4
|
class Authorize < Abstract::Handler
|
5
|
-
|
6
5
|
def call(env)
|
7
6
|
request = Request.new(env)
|
8
|
-
request.profile.new(
|
9
|
-
rescue Error => e
|
7
|
+
request.profile.new(&@authenticator).call(env).finish
|
8
|
+
rescue Rack::OAuth2::Server::Abstract::Error => e
|
10
9
|
e.finish
|
11
10
|
end
|
12
11
|
|
13
12
|
class Request < Abstract::Request
|
14
|
-
include Error::Authorize
|
15
13
|
attr_required :response_type
|
16
14
|
attr_optional :redirect_uri, :state
|
17
15
|
|
@@ -27,36 +25,43 @@ module Rack
|
|
27
25
|
Code
|
28
26
|
when 'token'
|
29
27
|
Token
|
30
|
-
when 'code_and_token'
|
31
|
-
CodeAndToken
|
32
28
|
when ''
|
33
29
|
attr_missing!
|
34
30
|
else
|
35
|
-
unsupported_response_type!
|
31
|
+
unsupported_response_type! "#{CGI.escape params['response_type']} isn't supported."
|
36
32
|
end
|
37
33
|
end
|
38
|
-
|
39
34
|
end
|
40
35
|
|
41
36
|
class Response < Abstract::Response
|
42
37
|
attr_required :redirect_uri
|
43
|
-
attr_optional :state, :
|
38
|
+
attr_optional :state, :approval
|
44
39
|
|
45
40
|
def initialize(request)
|
46
41
|
@state = request.state
|
47
|
-
@redirect_uri = Util.parse_uri(request.redirect_uri) if request.redirect_uri
|
48
42
|
super
|
49
43
|
end
|
50
44
|
|
51
45
|
def approved?
|
52
|
-
@
|
46
|
+
@approval
|
53
47
|
end
|
54
48
|
|
55
49
|
def approve!
|
56
|
-
@
|
50
|
+
@approval = true
|
51
|
+
end
|
52
|
+
|
53
|
+
def protocol_params
|
54
|
+
{:state => state}
|
57
55
|
end
|
58
|
-
end
|
59
56
|
|
57
|
+
def finish
|
58
|
+
if approved?
|
59
|
+
attr_missing!
|
60
|
+
redirect Util.redirect_uri(redirect_uri, protocol_params_location, protocol_params)
|
61
|
+
end
|
62
|
+
super
|
63
|
+
end
|
64
|
+
end
|
60
65
|
end
|
61
66
|
end
|
62
67
|
end
|
@@ -64,4 +69,4 @@ end
|
|
64
69
|
|
65
70
|
require 'rack/oauth2/server/authorize/code'
|
66
71
|
require 'rack/oauth2/server/authorize/token'
|
67
|
-
require 'rack/oauth2/server/authorize/
|
72
|
+
require 'rack/oauth2/server/authorize/error'
|
@@ -5,8 +5,8 @@ module Rack
|
|
5
5
|
class Code < Abstract::Handler
|
6
6
|
|
7
7
|
def call(env)
|
8
|
-
@request = Request.new
|
9
|
-
@response = Response.new
|
8
|
+
@request = Request.new env
|
9
|
+
@response = Response.new request
|
10
10
|
super
|
11
11
|
end
|
12
12
|
|
@@ -21,25 +21,14 @@ module Rack
|
|
21
21
|
class Response < Authorize::Response
|
22
22
|
attr_required :code
|
23
23
|
|
24
|
-
def
|
25
|
-
|
26
|
-
params = {
|
27
|
-
:code => code,
|
28
|
-
:state => state
|
29
|
-
}.delete_if do |key, value|
|
30
|
-
value.blank?
|
31
|
-
end
|
32
|
-
redirect_uri.query = if redirect_uri.query
|
33
|
-
[redirect_uri.query, params.to_query].join('&')
|
34
|
-
else
|
35
|
-
params.to_query
|
36
|
-
end
|
37
|
-
redirect redirect_uri.to_s
|
38
|
-
end
|
39
|
-
super
|
24
|
+
def protocol_params
|
25
|
+
super.merge(:code => code)
|
40
26
|
end
|
41
|
-
end
|
42
27
|
|
28
|
+
def protocol_params_location
|
29
|
+
:query
|
30
|
+
end
|
31
|
+
end
|
43
32
|
end
|
44
33
|
end
|
45
34
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Rack
|
2
|
+
module OAuth2
|
3
|
+
module Server
|
4
|
+
class Authorize
|
5
|
+
class BadRequest < Abstract::BadRequest
|
6
|
+
attr_accessor :redirect_uri, :state, :protocol_params_location
|
7
|
+
|
8
|
+
def protocol_params
|
9
|
+
super.merge(:state => state)
|
10
|
+
end
|
11
|
+
|
12
|
+
def finish
|
13
|
+
if redirect_uri.present? && protocol_params_location.present?
|
14
|
+
super do |response|
|
15
|
+
response.redirect Util.redirect_uri(redirect_uri, protocol_params_location, protocol_params)
|
16
|
+
end
|
17
|
+
else
|
18
|
+
raise self
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
module ErrorMethods
|
24
|
+
DEFAULT_DESCRIPTION = {
|
25
|
+
:invalid_request => "The request is missing a required parameter, includes an unsupported parameter or parameter value, or is otherwise malformed.",
|
26
|
+
:unauthorized_client => "The client is not authorized to use the requested response type.",
|
27
|
+
:access_denied => "The end-user or authorization server denied the request.",
|
28
|
+
:unsupported_response_type => "The requested response type is not supported by the authorization server.",
|
29
|
+
:invalid_scope => "The requested scope is invalid, unknown, or malformed."
|
30
|
+
}
|
31
|
+
|
32
|
+
def self.included(klass)
|
33
|
+
DEFAULT_DESCRIPTION.each do |error, default_description|
|
34
|
+
klass.class_eval <<-ERROR
|
35
|
+
def #{error}!(description = "#{default_description}", options = {})
|
36
|
+
bad_request! :#{error}, description, options.merge(:redirect => true)
|
37
|
+
end
|
38
|
+
ERROR
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def bad_request!(error = :bad_request, description = nil, options = {})
|
43
|
+
exception = BadRequest.new error, description, options
|
44
|
+
exception.protocol_params_location = case response_type
|
45
|
+
when :code
|
46
|
+
:query
|
47
|
+
when :token
|
48
|
+
:fragment
|
49
|
+
end
|
50
|
+
exception.state = state
|
51
|
+
exception.redirect_uri = redirect_uri if options[:redirect]
|
52
|
+
raise exception
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
Request.send :include, ErrorMethods
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -3,10 +3,9 @@ module Rack
|
|
3
3
|
module Server
|
4
4
|
class Authorize
|
5
5
|
class Token < Abstract::Handler
|
6
|
-
|
7
6
|
def call(env)
|
8
|
-
@request = Request.new
|
9
|
-
@response = Response.new
|
7
|
+
@request = Request.new env
|
8
|
+
@response = Response.new request
|
10
9
|
super
|
11
10
|
end
|
12
11
|
|
@@ -19,30 +18,22 @@ module Rack
|
|
19
18
|
end
|
20
19
|
|
21
20
|
class Response < Authorize::Response
|
22
|
-
attr_required :access_token
|
23
|
-
attr_optional :expires_in, :scope
|
21
|
+
attr_required :access_token, :token_type
|
22
|
+
attr_optional :refresh_token, :expires_in, :scope
|
24
23
|
|
25
|
-
def
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
}.delete_if do |key, value|
|
33
|
-
value.blank?
|
34
|
-
end
|
35
|
-
redirect_uri.fragment = if redirect_uri.fragment
|
36
|
-
[redirect_uri.fragment, params.to_query].join('&')
|
37
|
-
else
|
38
|
-
params.to_query
|
39
|
-
end
|
40
|
-
redirect redirect_uri.to_s
|
41
|
-
end
|
42
|
-
super
|
24
|
+
def protocol_params
|
25
|
+
super.merge(
|
26
|
+
:access_token => access_token,
|
27
|
+
:expires_in => expires_in,
|
28
|
+
:refresh_token => refresh_token,
|
29
|
+
:scope => Array(scope).join(' ')
|
30
|
+
)
|
43
31
|
end
|
44
|
-
end
|
45
32
|
|
33
|
+
def protocol_params_location
|
34
|
+
:fragment
|
35
|
+
end
|
36
|
+
end
|
46
37
|
end
|
47
38
|
end
|
48
39
|
end
|
@@ -1,79 +1 @@
|
|
1
|
-
require 'rack/
|
2
|
-
|
3
|
-
module Rack
|
4
|
-
module OAuth2
|
5
|
-
module Server
|
6
|
-
class Resource < Abstract::Handler
|
7
|
-
|
8
|
-
def initialize(app, realm = nil, &authenticator)
|
9
|
-
@app = app
|
10
|
-
super(realm, &authenticator)
|
11
|
-
end
|
12
|
-
|
13
|
-
def call(env)
|
14
|
-
request = Request.new(env, realm)
|
15
|
-
if request.oauth2?
|
16
|
-
authenticate!(request)
|
17
|
-
env[ACCESS_TOKEN] = request.access_token
|
18
|
-
end
|
19
|
-
@app.call(env)
|
20
|
-
rescue Error => e
|
21
|
-
e.realm = realm
|
22
|
-
e.finish
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
def authenticate!(request)
|
28
|
-
@authenticator.call(request)
|
29
|
-
end
|
30
|
-
|
31
|
-
class Request < Rack::Request
|
32
|
-
include Error::Resource
|
33
|
-
|
34
|
-
attr_accessor :realm
|
35
|
-
|
36
|
-
def initialize(env, realm = nil)
|
37
|
-
@env = env
|
38
|
-
@realm = realm
|
39
|
-
@auth_header = Rack::Auth::AbstractRequest.new(env)
|
40
|
-
end
|
41
|
-
|
42
|
-
def oauth2?
|
43
|
-
access_token.present?
|
44
|
-
end
|
45
|
-
|
46
|
-
def access_token
|
47
|
-
tokens = [access_token_in_haeder, access_token_in_payload].compact
|
48
|
-
case Array(tokens).size
|
49
|
-
when 0
|
50
|
-
nil
|
51
|
-
when 1
|
52
|
-
tokens.first
|
53
|
-
else
|
54
|
-
invalid_request!('Both Authorization header and payload includes oauth_token.', :realm => realm)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
def access_token_in_haeder
|
59
|
-
if @auth_header.provided? && @auth_header.scheme == :oauth && @auth_header.params !~ /oauth_signature_method/
|
60
|
-
@auth_header.params
|
61
|
-
else
|
62
|
-
nil
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def access_token_in_payload
|
67
|
-
if params['oauth_token'] && !params['oauth_signature_method']
|
68
|
-
params['oauth_token']
|
69
|
-
else
|
70
|
-
nil # This is OAuth1 request
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
end
|
75
|
-
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
1
|
+
require 'rack/oauth2/server/resource/bearer'
|