grape_oauth2 0.1.1
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.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rspec +2 -0
- data/.rubocop.yml +18 -0
- data/.travis.yml +42 -0
- data/Gemfile +23 -0
- data/README.md +820 -0
- data/Rakefile +11 -0
- data/gemfiles/active_record.rb +25 -0
- data/gemfiles/mongoid.rb +14 -0
- data/gemfiles/sequel.rb +24 -0
- data/grape_oauth2.gemspec +27 -0
- data/grape_oauth2.png +0 -0
- data/lib/grape_oauth2.rb +129 -0
- data/lib/grape_oauth2/configuration.rb +143 -0
- data/lib/grape_oauth2/configuration/class_accessors.rb +36 -0
- data/lib/grape_oauth2/configuration/validation.rb +71 -0
- data/lib/grape_oauth2/endpoints/authorize.rb +34 -0
- data/lib/grape_oauth2/endpoints/token.rb +72 -0
- data/lib/grape_oauth2/gem_version.rb +24 -0
- data/lib/grape_oauth2/generators/authorization.rb +44 -0
- data/lib/grape_oauth2/generators/base.rb +26 -0
- data/lib/grape_oauth2/generators/token.rb +62 -0
- data/lib/grape_oauth2/helpers/access_token_helpers.rb +54 -0
- data/lib/grape_oauth2/helpers/oauth_params.rb +41 -0
- data/lib/grape_oauth2/mixins/active_record/access_grant.rb +47 -0
- data/lib/grape_oauth2/mixins/active_record/access_token.rb +75 -0
- data/lib/grape_oauth2/mixins/active_record/client.rb +35 -0
- data/lib/grape_oauth2/mixins/mongoid/access_grant.rb +58 -0
- data/lib/grape_oauth2/mixins/mongoid/access_token.rb +88 -0
- data/lib/grape_oauth2/mixins/mongoid/client.rb +41 -0
- data/lib/grape_oauth2/mixins/sequel/access_grant.rb +68 -0
- data/lib/grape_oauth2/mixins/sequel/access_token.rb +86 -0
- data/lib/grape_oauth2/mixins/sequel/client.rb +46 -0
- data/lib/grape_oauth2/responses/authorization.rb +10 -0
- data/lib/grape_oauth2/responses/base.rb +56 -0
- data/lib/grape_oauth2/responses/token.rb +10 -0
- data/lib/grape_oauth2/scopes.rb +74 -0
- data/lib/grape_oauth2/strategies/authorization_code.rb +38 -0
- data/lib/grape_oauth2/strategies/base.rb +47 -0
- data/lib/grape_oauth2/strategies/client_credentials.rb +20 -0
- data/lib/grape_oauth2/strategies/password.rb +22 -0
- data/lib/grape_oauth2/strategies/refresh_token.rb +47 -0
- data/lib/grape_oauth2/unique_token.rb +20 -0
- data/lib/grape_oauth2/version.rb +14 -0
- data/spec/configuration/config_spec.rb +231 -0
- data/spec/configuration/version_spec.rb +12 -0
- data/spec/dummy/endpoints/custom_authorization.rb +25 -0
- data/spec/dummy/endpoints/custom_token.rb +35 -0
- data/spec/dummy/endpoints/status.rb +25 -0
- data/spec/dummy/grape_oauth2_config.rb +11 -0
- data/spec/dummy/orm/active_record/app/config/db.rb +7 -0
- data/spec/dummy/orm/active_record/app/models/access_code.rb +3 -0
- data/spec/dummy/orm/active_record/app/models/access_token.rb +3 -0
- data/spec/dummy/orm/active_record/app/models/application.rb +3 -0
- data/spec/dummy/orm/active_record/app/models/application_record.rb +3 -0
- data/spec/dummy/orm/active_record/app/models/user.rb +10 -0
- data/spec/dummy/orm/active_record/app/twitter.rb +36 -0
- data/spec/dummy/orm/active_record/config.ru +7 -0
- data/spec/dummy/orm/active_record/db/schema.rb +53 -0
- data/spec/dummy/orm/mongoid/app/config/db.rb +6 -0
- data/spec/dummy/orm/mongoid/app/config/mongoid.yml +21 -0
- data/spec/dummy/orm/mongoid/app/models/access_code.rb +3 -0
- data/spec/dummy/orm/mongoid/app/models/access_token.rb +3 -0
- data/spec/dummy/orm/mongoid/app/models/application.rb +3 -0
- data/spec/dummy/orm/mongoid/app/models/user.rb +11 -0
- data/spec/dummy/orm/mongoid/app/twitter.rb +34 -0
- data/spec/dummy/orm/mongoid/config.ru +5 -0
- data/spec/dummy/orm/sequel/app/config/db.rb +1 -0
- data/spec/dummy/orm/sequel/app/models/access_code.rb +4 -0
- data/spec/dummy/orm/sequel/app/models/access_token.rb +4 -0
- data/spec/dummy/orm/sequel/app/models/application.rb +4 -0
- data/spec/dummy/orm/sequel/app/models/application_record.rb +2 -0
- data/spec/dummy/orm/sequel/app/models/user.rb +11 -0
- data/spec/dummy/orm/sequel/app/twitter.rb +47 -0
- data/spec/dummy/orm/sequel/config.ru +5 -0
- data/spec/dummy/orm/sequel/db/schema.rb +50 -0
- data/spec/lib/scopes_spec.rb +50 -0
- data/spec/mixins/active_record/access_token_spec.rb +185 -0
- data/spec/mixins/active_record/client_spec.rb +95 -0
- data/spec/mixins/mongoid/access_token_spec.rb +185 -0
- data/spec/mixins/mongoid/client_spec.rb +95 -0
- data/spec/mixins/sequel/access_token_spec.rb +185 -0
- data/spec/mixins/sequel/client_spec.rb +96 -0
- data/spec/requests/flows/authorization_code_spec.rb +67 -0
- data/spec/requests/flows/client_credentials_spec.rb +101 -0
- data/spec/requests/flows/password_spec.rb +210 -0
- data/spec/requests/flows/refresh_token_spec.rb +222 -0
- data/spec/requests/flows/revoke_token_spec.rb +103 -0
- data/spec/requests/protected_resources_spec.rb +64 -0
- data/spec/spec_helper.rb +60 -0
- data/spec/support/api_helper.rb +11 -0
- metadata +257 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Grape
|
|
2
|
+
module OAuth2
|
|
3
|
+
module ActiveRecord
|
|
4
|
+
# Grape::OAuth2 Client role mixin for ActiveRecord.
|
|
5
|
+
# Includes all the required API, associations, validations and callbacks.
|
|
6
|
+
module Client
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
included do
|
|
10
|
+
has_many :access_tokens, class_name: Grape::OAuth2.config.access_token_class_name, foreign_key: :client_id
|
|
11
|
+
|
|
12
|
+
validates :key, :secret, presence: true
|
|
13
|
+
validates :key, uniqueness: true
|
|
14
|
+
|
|
15
|
+
before_validation :generate_keys, on: :create
|
|
16
|
+
|
|
17
|
+
def self.authenticate(key, secret = nil)
|
|
18
|
+
if secret.nil?
|
|
19
|
+
find_by(key: key)
|
|
20
|
+
else
|
|
21
|
+
find_by(key: key, secret: secret)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
protected
|
|
26
|
+
|
|
27
|
+
def generate_keys
|
|
28
|
+
self.key = Grape::OAuth2::UniqueToken.generate if key.blank?
|
|
29
|
+
self.secret = Grape::OAuth2::UniqueToken.generate if secret.blank?
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
module Grape
|
|
2
|
+
module OAuth2
|
|
3
|
+
module Mongoid
|
|
4
|
+
# Grape::OAuth2 Authorization Grant role mixin for Mongoid ORM.
|
|
5
|
+
# Includes all the required API, associations, validations and callbacks.
|
|
6
|
+
module AccessGrant
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
included do
|
|
10
|
+
include ::Mongoid::Document
|
|
11
|
+
include ::Mongoid::Timestamps
|
|
12
|
+
|
|
13
|
+
field :resource_owner_id, type: BSON::ObjectId
|
|
14
|
+
field :client_id, type: BSON::ObjectId
|
|
15
|
+
|
|
16
|
+
field :token, type: String
|
|
17
|
+
field :scopes, type: String
|
|
18
|
+
field :redirect_uri, type: String
|
|
19
|
+
|
|
20
|
+
field :expires_at, type: DateTime
|
|
21
|
+
|
|
22
|
+
belongs_to :client, class_name: Grape::OAuth2.config.client_class_name,
|
|
23
|
+
foreign_key: :client_id
|
|
24
|
+
|
|
25
|
+
belongs_to :resource_owner, class_name: Grape::OAuth2.config.resource_owner_class_name,
|
|
26
|
+
foreign_key: :resource_owner_id, optional: true # required!
|
|
27
|
+
|
|
28
|
+
before_validation :generate_token, on: :create
|
|
29
|
+
before_validation :setup_expiration, on: :create
|
|
30
|
+
|
|
31
|
+
index({ token: 1 }, unique: true)
|
|
32
|
+
index({ refresh_token: 1 }, unique: true, sparse: true)
|
|
33
|
+
|
|
34
|
+
class << self
|
|
35
|
+
def create_for(client, resource_owner, redirect_uri, scopes = nil)
|
|
36
|
+
create(
|
|
37
|
+
client_id: client.id,
|
|
38
|
+
resource_owner_id: resource_owner && resource_owner.id,
|
|
39
|
+
redirect_uri: redirect_uri,
|
|
40
|
+
scopes: scopes.to_s
|
|
41
|
+
)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
protected
|
|
46
|
+
|
|
47
|
+
def generate_token
|
|
48
|
+
self.token = Grape::OAuth2.config.token_generator.generate(attributes)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def setup_expiration
|
|
52
|
+
self.expires_at = Time.now.utc + Grape::OAuth2.config.authorization_code_lifetime if expires_at.nil?
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
module Grape
|
|
2
|
+
module OAuth2
|
|
3
|
+
module Mongoid
|
|
4
|
+
# Grape::OAuth2 Access Token role mixin for Mongoid ORM.
|
|
5
|
+
# Includes all the required API, associations, validations and callbacks.
|
|
6
|
+
module AccessToken
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
included do
|
|
10
|
+
include ::Mongoid::Document
|
|
11
|
+
include ::Mongoid::Timestamps
|
|
12
|
+
|
|
13
|
+
field :resource_owner_id, type: BSON::ObjectId
|
|
14
|
+
field :client_id, type: BSON::ObjectId
|
|
15
|
+
|
|
16
|
+
belongs_to :client, class_name: 'Application', foreign_key: :client_id, optional: true
|
|
17
|
+
belongs_to :resource_owner, class_name: 'User', foreign_key: :resource_owner_id, optional: true
|
|
18
|
+
|
|
19
|
+
field :token, type: String
|
|
20
|
+
field :refresh_token, type: String
|
|
21
|
+
field :scopes, type: String
|
|
22
|
+
|
|
23
|
+
field :expires_at, type: DateTime
|
|
24
|
+
field :revoked_at, type: DateTime
|
|
25
|
+
|
|
26
|
+
index({ token: 1 }, unique: true)
|
|
27
|
+
index({ refresh_token: 1 }, unique: true, sparse: true)
|
|
28
|
+
|
|
29
|
+
before_validation :setup_expiration, on: :create
|
|
30
|
+
before_validation :generate_tokens, on: :create
|
|
31
|
+
|
|
32
|
+
validates :token, presence: true, uniqueness: true
|
|
33
|
+
|
|
34
|
+
class << self
|
|
35
|
+
def create_for(client, resource_owner, scopes = nil)
|
|
36
|
+
create(
|
|
37
|
+
client: client,
|
|
38
|
+
resource_owner: resource_owner,
|
|
39
|
+
scopes: scopes.to_s
|
|
40
|
+
)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def authenticate(token, type: :access_token)
|
|
44
|
+
if type && type.to_sym == :refresh_token
|
|
45
|
+
find_by(refresh_token: token.to_s)
|
|
46
|
+
else
|
|
47
|
+
find_by(token: token.to_s)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def expired?
|
|
53
|
+
!expires_at.nil? && Time.now.utc > expires_at
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def revoked?
|
|
57
|
+
!revoked_at.nil? && revoked_at <= Time.now.utc
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def revoke!(revoked_at = Time.now)
|
|
61
|
+
update_attribute :revoked_at, revoked_at.utc
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def to_bearer_token
|
|
65
|
+
{
|
|
66
|
+
access_token: token,
|
|
67
|
+
expires_in: expires_at && Grape::OAuth2.config.access_token_lifetime.to_i,
|
|
68
|
+
refresh_token: refresh_token,
|
|
69
|
+
scope: scopes
|
|
70
|
+
}
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
protected
|
|
74
|
+
|
|
75
|
+
def generate_tokens
|
|
76
|
+
self.token = Grape::OAuth2.config.token_generator.generate(attributes) if token.blank?
|
|
77
|
+
self.refresh_token = Grape::OAuth2::UniqueToken.generate if Grape::OAuth2.config.issue_refresh_token
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def setup_expiration
|
|
81
|
+
expires_in = Grape::OAuth2.config.access_token_lifetime
|
|
82
|
+
self.expires_at = Time.now + expires_in if expires_at.nil? && !expires_in.nil?
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module Grape
|
|
2
|
+
module OAuth2
|
|
3
|
+
module Mongoid
|
|
4
|
+
# Grape::OAuth2 Client role mixin for Mongoid ORM.
|
|
5
|
+
# Includes all the required API, associations, validations and callbacks.
|
|
6
|
+
module Client
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
included do
|
|
10
|
+
include ::Mongoid::Document
|
|
11
|
+
include ::Mongoid::Timestamps
|
|
12
|
+
|
|
13
|
+
field :name, type: String
|
|
14
|
+
field :key, type: String
|
|
15
|
+
field :secret, type: String
|
|
16
|
+
field :redirect_uri, type: String
|
|
17
|
+
|
|
18
|
+
before_validation :generate_keys, on: :create
|
|
19
|
+
|
|
20
|
+
validates :key, :secret, presence: true
|
|
21
|
+
validates :key, uniqueness: true
|
|
22
|
+
|
|
23
|
+
def self.authenticate(key, secret = nil)
|
|
24
|
+
if secret.nil?
|
|
25
|
+
Application.find_by(key: key)
|
|
26
|
+
else
|
|
27
|
+
Application.find_by(key: key, secret: secret)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
protected
|
|
32
|
+
|
|
33
|
+
def generate_keys
|
|
34
|
+
self.key = Grape::OAuth2::UniqueToken.generate if key.blank?
|
|
35
|
+
self.secret = Grape::OAuth2::UniqueToken.generate if secret.blank?
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
module Grape
|
|
2
|
+
module OAuth2
|
|
3
|
+
module Sequel
|
|
4
|
+
# Grape::OAuth2 Authorization Grant role mixin for Sequel toolkit.
|
|
5
|
+
# Includes all the required API, associations, validations and callbacks.
|
|
6
|
+
module AccessGrant
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
included do
|
|
10
|
+
plugin :validation_helpers
|
|
11
|
+
plugin :timestamps
|
|
12
|
+
|
|
13
|
+
many_to_one :client, class: Grape::OAuth2.config.client_class_name, key: :client_id
|
|
14
|
+
many_to_one :resource_owner, class: Grape::OAuth2.config.resource_owner_class_name, key: :resource_owner_id
|
|
15
|
+
|
|
16
|
+
def before_validation
|
|
17
|
+
if new?
|
|
18
|
+
generate_token
|
|
19
|
+
setup_expiration
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
super
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
class << self
|
|
26
|
+
def create_for(client, resource_owner, redirect_uri, scopes = nil)
|
|
27
|
+
create(
|
|
28
|
+
client_id: client.id,
|
|
29
|
+
resource_owner_id: resource_owner && resource_owner.id,
|
|
30
|
+
redirect_uri: redirect_uri,
|
|
31
|
+
scopes: scopes.to_s
|
|
32
|
+
)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def validate
|
|
37
|
+
super
|
|
38
|
+
validates_presence [:token, :client_id]
|
|
39
|
+
validates_unique [:token]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def expired?
|
|
43
|
+
expires_at && Time.now.utc > expires_at
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def revoked?
|
|
47
|
+
revoked_at && revoked_at <= Time.now.utc
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def revoke!(revoked_at = Time.now)
|
|
51
|
+
set(revoked_at: revoked_at.utc)
|
|
52
|
+
save(columns: [:revoked_at], validate: false)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
protected
|
|
56
|
+
|
|
57
|
+
def generate_token
|
|
58
|
+
self.token = Grape::OAuth2.config.token_generator.generate(values)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def setup_expiration
|
|
62
|
+
self.expires_at = Time.now.utc + Grape::OAuth2.config.authorization_code_lifetime if expires_at.nil?
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
module Grape
|
|
2
|
+
module OAuth2
|
|
3
|
+
module Sequel
|
|
4
|
+
# Grape::OAuth2 Access Token role mixin for Sequel toolkit.
|
|
5
|
+
# Includes all the required API, associations, validations and callbacks.
|
|
6
|
+
module AccessToken
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
included do
|
|
10
|
+
plugin :validation_helpers
|
|
11
|
+
plugin :timestamps
|
|
12
|
+
|
|
13
|
+
many_to_one :client, class: Grape::OAuth2.config.client_class_name, key: :client_id
|
|
14
|
+
many_to_one :resource_owner, class: Grape::OAuth2.config.resource_owner_class_name, key: :resource_owner_id
|
|
15
|
+
|
|
16
|
+
def before_validation
|
|
17
|
+
if new?
|
|
18
|
+
setup_expiration
|
|
19
|
+
generate_tokens
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
super
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def validate
|
|
26
|
+
super
|
|
27
|
+
validates_presence :token
|
|
28
|
+
validates_unique :token
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class << self
|
|
32
|
+
def create_for(client, resource_owner, scopes = nil)
|
|
33
|
+
create(
|
|
34
|
+
client: client,
|
|
35
|
+
resource_owner: resource_owner,
|
|
36
|
+
scopes: scopes.to_s
|
|
37
|
+
)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def authenticate(token, type: :access_token)
|
|
41
|
+
if type && type.to_sym == :refresh_token
|
|
42
|
+
first(refresh_token: token.to_s)
|
|
43
|
+
else
|
|
44
|
+
first(token: token.to_s)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def expired?
|
|
50
|
+
!expires_at.nil? && Time.now.utc > expires_at.utc
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def revoked?
|
|
54
|
+
!revoked_at.nil? && revoked_at <= Time.now.utc
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def revoke!(revoked_at = Time.now)
|
|
58
|
+
set(revoked_at: revoked_at.utc)
|
|
59
|
+
save(columns: [:revoked_at], validate: false)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def to_bearer_token
|
|
63
|
+
{
|
|
64
|
+
access_token: token,
|
|
65
|
+
expires_in: expires_at && Grape::OAuth2.config.access_token_lifetime.to_i,
|
|
66
|
+
refresh_token: refresh_token,
|
|
67
|
+
scope: scopes
|
|
68
|
+
}
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
protected
|
|
72
|
+
|
|
73
|
+
def generate_tokens
|
|
74
|
+
self.token = Grape::OAuth2.config.token_generator.generate(values) if token.blank?
|
|
75
|
+
self.refresh_token = Grape::OAuth2::UniqueToken.generate if Grape::OAuth2.config.issue_refresh_token
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def setup_expiration
|
|
79
|
+
expires_in = Grape::OAuth2.config.access_token_lifetime
|
|
80
|
+
self.expires_at = Time.now + expires_in if expires_at.nil? && !expires_in.nil?
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
module Grape
|
|
2
|
+
module OAuth2
|
|
3
|
+
module Sequel
|
|
4
|
+
# Grape::OAuth2 Client role mixin for Sequel toolkit.
|
|
5
|
+
# Includes all the required API, associations, validations and callbacks.
|
|
6
|
+
module Client
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
included do
|
|
10
|
+
plugin :validation_helpers
|
|
11
|
+
plugin :timestamps
|
|
12
|
+
|
|
13
|
+
set_allowed_columns :name, :redirect_uri
|
|
14
|
+
|
|
15
|
+
one_to_many :access_tokens, class: Grape::OAuth2.config.access_token_class_name, key: :client_id
|
|
16
|
+
|
|
17
|
+
def before_validation
|
|
18
|
+
generate_keys if new?
|
|
19
|
+
super
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def validate
|
|
23
|
+
super
|
|
24
|
+
validates_presence [:key, :secret]
|
|
25
|
+
validates_unique :key
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def self.authenticate(key, secret = nil)
|
|
29
|
+
if secret.nil?
|
|
30
|
+
find(key: key)
|
|
31
|
+
else
|
|
32
|
+
find(key: key, secret: secret)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
protected
|
|
37
|
+
|
|
38
|
+
def generate_keys
|
|
39
|
+
self.key = Grape::OAuth2::UniqueToken.generate if key.blank?
|
|
40
|
+
self.secret = Grape::OAuth2::UniqueToken.generate if secret.blank?
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
module Grape
|
|
2
|
+
module OAuth2
|
|
3
|
+
# Grape::OAuth2 responses namespace.
|
|
4
|
+
module Responses
|
|
5
|
+
# Base class for Grape::OAuth2 endpoints responses.
|
|
6
|
+
# Processes raw Rack Responses and contains helper methods.
|
|
7
|
+
class Base
|
|
8
|
+
# Raw Rack::Response to process
|
|
9
|
+
#
|
|
10
|
+
# @return [Array] Rack response
|
|
11
|
+
#
|
|
12
|
+
# @example
|
|
13
|
+
# response = Grape::OAuth2::Responses::Base.new([200, {}, Rack::BodyProxy.new('Test')])
|
|
14
|
+
# response.rack_response
|
|
15
|
+
#
|
|
16
|
+
# #=> [200, {}, Rack::BodyProxy.new('Test')]
|
|
17
|
+
#
|
|
18
|
+
attr_reader :rack_response
|
|
19
|
+
|
|
20
|
+
# OAuth2 response class.
|
|
21
|
+
#
|
|
22
|
+
# @param rack_response [Array]
|
|
23
|
+
# raw Rack::Response object
|
|
24
|
+
#
|
|
25
|
+
def initialize(rack_response)
|
|
26
|
+
# Rack Body:
|
|
27
|
+
# [Status Code, Headers, Body]
|
|
28
|
+
@rack_response = rack_response
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Response status
|
|
32
|
+
def status
|
|
33
|
+
@rack_response[0]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Response headers
|
|
37
|
+
def headers
|
|
38
|
+
@rack_response[1]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Raw Rack body
|
|
42
|
+
def raw_body
|
|
43
|
+
@rack_response[2].body
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# JSON-parsed body
|
|
47
|
+
def body
|
|
48
|
+
response_body = raw_body.first
|
|
49
|
+
return {} if response_body.nil? || response_body.empty?
|
|
50
|
+
|
|
51
|
+
JSON.parse(response_body)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|