oauth2_provider_engine 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.rdoc +3 -0
- data/Rakefile +40 -0
- data/app/assets/javascripts/oauth2_provider/application.js +52 -0
- data/app/assets/javascripts/oauth2_provider/highcharts.js +162 -0
- data/app/assets/javascripts/oauth2_provider/jquery.tagsinput.js +218 -0
- data/app/assets/stylesheets/oauth2_provider/gh-buttons.css +388 -0
- data/app/assets/stylesheets/oauth2_provider/gh-icons.png +0 -0
- data/app/assets/stylesheets/oauth2_provider/jquery.tagsinput.css +6 -0
- data/app/assets/stylesheets/oauth2_provider/reset.css +2 -0
- data/app/assets/stylesheets/oauth2_provider/template.css +52 -0
- data/app/controllers/oauth2_provider/accesses_controller.rb +39 -0
- data/app/controllers/oauth2_provider/application_controller.rb +17 -0
- data/app/controllers/oauth2_provider/authorize_controller.rb +141 -0
- data/app/controllers/oauth2_provider/clients_controller.rb +85 -0
- data/app/controllers/oauth2_provider/scopes_controller.rb +63 -0
- data/app/controllers/oauth2_provider/token_controller.rb +187 -0
- data/app/helpers/clients_helper.rb +5 -0
- data/app/helpers/oauth2_provider/application_helper.rb +4 -0
- data/app/models/oauth2_provider/client.rb +129 -0
- data/app/models/oauth2_provider/document.rb +15 -0
- data/app/models/oauth2_provider/oauth_access.rb +80 -0
- data/app/models/oauth2_provider/oauth_authorization.rb +70 -0
- data/app/models/oauth2_provider/oauth_daily_request.rb +54 -0
- data/app/models/oauth2_provider/oauth_refresh_token.rb +20 -0
- data/app/models/oauth2_provider/oauth_token.rb +78 -0
- data/app/models/oauth2_provider/scope.rb +39 -0
- data/app/views/layouts/oauth2_provider/application.html.erb +62 -0
- data/app/views/oauth2_provider/accesses/index.html.erb +25 -0
- data/app/views/oauth2_provider/accesses/show.html.erb +35 -0
- data/app/views/oauth2_provider/clients/_form.html.erb +50 -0
- data/app/views/oauth2_provider/clients/edit.html.erb +9 -0
- data/app/views/oauth2_provider/clients/index.html.erb +43 -0
- data/app/views/oauth2_provider/clients/new.html.erb +8 -0
- data/app/views/oauth2_provider/clients/show.html.erb +49 -0
- data/app/views/oauth2_provider/scopes/_form.html.erb +35 -0
- data/app/views/oauth2_provider/scopes/edit.html.erb +8 -0
- data/app/views/oauth2_provider/scopes/index.html.erb +27 -0
- data/app/views/oauth2_provider/scopes/new.html.erb +7 -0
- data/app/views/oauth2_provider/scopes/show.html.erb +19 -0
- data/app/views/shared/authorize.html.erb +34 -0
- data/app/views/shared/token.json.erb +8 -0
- data/config/locales/en.yml +31 -0
- data/config/oauth.yml +4 -0
- data/config/routes.rb +25 -0
- data/lib/oauth2_provider.rb +38 -0
- data/lib/oauth2_provider/controller_mixin.rb +53 -0
- data/lib/oauth2_provider/engine.rb +4 -0
- data/lib/oauth2_provider_engine.rb +1 -0
- data/lib/oauth2_provider_engine/version.rb +3 -0
- data/test/dummy/CHANGELOG.rdoc +67 -0
- data/test/dummy/Gemfile +53 -0
- data/test/dummy/Gemfile.lock +254 -0
- data/test/dummy/README.rdoc +522 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/VERSION +1 -0
- data/test/dummy/app/assets/stylesheets/reset.css +2 -0
- data/test/dummy/app/assets/stylesheets/template.css +52 -0
- data/test/dummy/app/controllers/application_controller.rb +52 -0
- data/test/dummy/app/controllers/pastas_controller.rb +23 -0
- data/test/dummy/app/controllers/pizzas_controller.rb +23 -0
- data/test/dummy/app/controllers/sessions_controller.rb +26 -0
- data/test/dummy/app/controllers/users_controller.rb +59 -0
- data/test/dummy/app/models/user.rb +50 -0
- data/test/dummy/app/views/layouts/application.html.erb +65 -0
- data/test/dummy/app/views/sessions/new.html.erb +25 -0
- data/test/dummy/app/views/shared/403.json.erb +4 -0
- data/test/dummy/app/views/shared/404.json.erb +6 -0
- data/test/dummy/app/views/shared/422.json.erb +5 -0
- data/test/dummy/app/views/shared/500.json.erb +4 -0
- data/test/dummy/app/views/shared/html/404.html.erb +0 -0
- data/test/dummy/app/views/shared/html/422.html.erb +0 -0
- data/test/dummy/app/views/users/_form.html.erb +27 -0
- data/test/dummy/app/views/users/edit.html.erb +8 -0
- data/test/dummy/app/views/users/index.html.erb +20 -0
- data/test/dummy/app/views/users/new.html.erb +46 -0
- data/test/dummy/app/views/users/show.html.erb +15 -0
- data/test/dummy/app/views/users/show.json.erb +6 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +57 -0
- data/test/dummy/config/boot.rb +13 -0
- data/test/dummy/config/cucumber.yml +8 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +32 -0
- data/test/dummy/config/environments/production.rb +58 -0
- data/test/dummy/config/environments/test.rb +35 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +10 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/test.rb +3 -0
- data/test/dummy/config/locales/en.yml +1 -0
- data/test/dummy/config/mongoid.yml +20 -0
- data/test/dummy/config/routes.rb +22 -0
- data/test/dummy/db/seeds.rb +7 -0
- data/test/dummy/doc/README_FOR_APP +2 -0
- data/test/dummy/lib/tasks/cucumber.rake +53 -0
- data/test/dummy/lib/tasks/watchr.rake +5 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +4 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/public/robots.txt +5 -0
- data/test/dummy/script/cucumber +10 -0
- data/test/dummy/script/rails +6 -0
- data/test/dummy/spec/acceptance/acceptance_helper.rb +5 -0
- data/test/dummy/spec/acceptance/accesses_controller_spec.rb +77 -0
- data/test/dummy/spec/acceptance/clients_controller_spec.rb +218 -0
- data/test/dummy/spec/acceptance/oauth_authorize_controller_spec.rb +241 -0
- data/test/dummy/spec/acceptance/oauth_token_controller_spec.rb +196 -0
- data/test/dummy/spec/acceptance/resource_controller_spec.rb +143 -0
- data/test/dummy/spec/acceptance/scopes_controller_spec.rb +227 -0
- data/test/dummy/spec/acceptance/support/helpers.rb +81 -0
- data/test/dummy/spec/acceptance/support/paths.rb +9 -0
- data/test/dummy/spec/acceptance/support/view_helpers.rb +52 -0
- data/test/dummy/spec/acceptance/users_controller_spec.rb +198 -0
- data/test/dummy/spec/extras/scope_spec.rb +105 -0
- data/test/dummy/spec/factories/oauth.rb +106 -0
- data/test/dummy/spec/models/oauth/client_spec.rb +123 -0
- data/test/dummy/spec/models/oauth/oauth_access_spec.rb +48 -0
- data/test/dummy/spec/models/oauth/oauth_authorization_spec.rb +50 -0
- data/test/dummy/spec/models/oauth/oauth_daily_request_spec.rb +14 -0
- data/test/dummy/spec/models/oauth/oauth_refresh_token_spec.rb +11 -0
- data/test/dummy/spec/models/oauth/oauth_token_spec.rb +55 -0
- data/test/dummy/spec/models/scope_spec.rb +17 -0
- data/test/dummy/spec/spec_helper.rb +39 -0
- data/test/dummy/spec/support/settings_helper.rb +28 -0
- data/test/dummy/test/initializers/capybara_headers_hack.rb +23 -0
- data/test/oauth2_provider_test.rb +7 -0
- data/test/test_helper.rb +15 -0
- metadata +387 -0
@@ -0,0 +1,129 @@
|
|
1
|
+
# Application making protected resource requests on behalf of
|
2
|
+
# the resource owner and with its authorization
|
3
|
+
|
4
|
+
module Oauth2Provider
|
5
|
+
class Client
|
6
|
+
include Mongoid::Document
|
7
|
+
include Mongoid::Timestamps
|
8
|
+
include Document::Base
|
9
|
+
|
10
|
+
field :uri # client identifier (internal)
|
11
|
+
field :name # client name
|
12
|
+
field :created_from # user who created the client
|
13
|
+
field :secret # client secret
|
14
|
+
field :site_uri # client website
|
15
|
+
field :redirect_uri # page called after authorization
|
16
|
+
field :scope, type: Array, default: [] # raw scope with keywords
|
17
|
+
field :scope_values, type: Array, default: [] # scope parsed as array of allowed actions
|
18
|
+
field :info # client additional info
|
19
|
+
field :granted_times, type: Integer, default: 0 # tokens granted in the authorization step
|
20
|
+
field :revoked_times, type: Integer, default: 0 # tokens revoked in the authorization step
|
21
|
+
field :blocked, type: Time, default: nil # blocks any request from the client
|
22
|
+
|
23
|
+
attr_accessible :name, :site_uri, :redirect_uri, :info, :scope
|
24
|
+
|
25
|
+
before_create :random_secret
|
26
|
+
before_destroy :clean
|
27
|
+
|
28
|
+
validates :name, presence: true
|
29
|
+
validates :uri, presence: true, url: true
|
30
|
+
validates :created_from, presence: true, url: true
|
31
|
+
validates :redirect_uri, presence: true, url: true
|
32
|
+
|
33
|
+
|
34
|
+
# Block the client
|
35
|
+
def block!
|
36
|
+
self.blocked = Time.now
|
37
|
+
self.save
|
38
|
+
OauthToken.block_client!(self.uri)
|
39
|
+
OauthAuthorization.block_client!(self.uri)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Unblock the client
|
43
|
+
def unblock!
|
44
|
+
self.blocked = nil
|
45
|
+
self.save
|
46
|
+
end
|
47
|
+
|
48
|
+
# Check if the status is or is not blocked
|
49
|
+
def blocked?
|
50
|
+
!self.blocked.nil?
|
51
|
+
end
|
52
|
+
|
53
|
+
# Increase the counter of resource owners granting the access
|
54
|
+
# to the client
|
55
|
+
def granted!
|
56
|
+
self.granted_times += 1
|
57
|
+
self.save
|
58
|
+
end
|
59
|
+
|
60
|
+
# Increase the counter of resource owners revoking the access
|
61
|
+
# to the client
|
62
|
+
def revoked!
|
63
|
+
self.revoked_times += 1
|
64
|
+
self.save
|
65
|
+
end
|
66
|
+
|
67
|
+
def scope_pretty
|
68
|
+
separator = Oauth2Provider.settings["scope_separator"]
|
69
|
+
scope.join(separator)
|
70
|
+
end
|
71
|
+
|
72
|
+
def scope_values_pretty
|
73
|
+
separator = Oauth2Provider.settings["scope_separator"]
|
74
|
+
scope_values.join(separator)
|
75
|
+
end
|
76
|
+
|
77
|
+
class << self
|
78
|
+
|
79
|
+
# Filter to the client uri (internal identifier) and the
|
80
|
+
# redirect uri
|
81
|
+
def where_uri(client_uri, redirect_uri)
|
82
|
+
where(uri: client_uri, redirect_uri: redirect_uri)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Filter to the client secret and the redirect uri
|
86
|
+
def where_secret(secret, client_uri)
|
87
|
+
where(secret: secret, uri: client_uri)
|
88
|
+
end
|
89
|
+
|
90
|
+
# Filter to the client scope
|
91
|
+
def where_scope(scope)
|
92
|
+
all_in(scope_values: scope)
|
93
|
+
end
|
94
|
+
|
95
|
+
# Sync all clients with the correct exploded scope when a
|
96
|
+
# scope is modified (changed or removed)
|
97
|
+
def sync_clients_with_scope(scope)
|
98
|
+
Client.all.each do |client|
|
99
|
+
scope_string = client.scope.join(Oauth2Provider.settings["scope_separator"])
|
100
|
+
client.scope_values = Oauth2Provider.normalize_scope(scope_string)
|
101
|
+
client.save
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
# TODO: use atomic updates
|
110
|
+
# https://github.com/mongoid/mongoid/commit/aa2c388c71529bf4d987b286acfd861eaac530ce
|
111
|
+
def block_tokens!
|
112
|
+
OauthToken.where(client_uri: uri).map(&:block!)
|
113
|
+
end
|
114
|
+
|
115
|
+
def block_authorizations!
|
116
|
+
OauthAuthorization.where(client_uri: uri).map(&:block!)
|
117
|
+
end
|
118
|
+
|
119
|
+
def random_secret
|
120
|
+
self.secret = SecureRandom.hex(Oauth2Provider.settings["random_length"])
|
121
|
+
end
|
122
|
+
|
123
|
+
def clean
|
124
|
+
OauthToken.where(client_uri: uri).destroy_all
|
125
|
+
OauthAuthorization.where(client_uri: uri).destroy_all
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Oauth2Provider
|
2
|
+
module Document
|
3
|
+
module Base
|
4
|
+
|
5
|
+
def base_uri(request)
|
6
|
+
protocol = request.protocol
|
7
|
+
host = request.host_with_port
|
8
|
+
name = self.class.name.underscore.pluralize.split('/').last
|
9
|
+
id = self.id.as_json
|
10
|
+
uri = protocol + host + "/oauth/" + name + "/" + id
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# Access info related to a resource owner using a specific
|
2
|
+
# client (block and statistics)
|
3
|
+
|
4
|
+
module Oauth2Provider
|
5
|
+
class OauthAccess
|
6
|
+
include Mongoid::Document
|
7
|
+
include Mongoid::Timestamps
|
8
|
+
|
9
|
+
field :client_uri # client identifier (internal)
|
10
|
+
field :resource_owner_uri # resource owner identifier
|
11
|
+
field :blocked, type: Time, default: nil # authorization block (a user block a single client)
|
12
|
+
|
13
|
+
embeds_many :oauth_daily_requests, class_name: 'Oauth2Provider::OauthDailyRequest' # daily requests (one record per day)
|
14
|
+
|
15
|
+
validates :client_uri, presence: true
|
16
|
+
validates :resource_owner_uri, presence: true
|
17
|
+
|
18
|
+
|
19
|
+
# Block the resource owner delegation to a specific client
|
20
|
+
def block!
|
21
|
+
self.blocked = Time.now
|
22
|
+
self.save
|
23
|
+
OauthToken.block_access!(client_uri, resource_owner_uri)
|
24
|
+
OauthAuthorization.block_access!(client_uri, resource_owner_uri)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Unblock the resource owner delegation to a specific client
|
28
|
+
def unblock!
|
29
|
+
self.blocked = nil
|
30
|
+
self.save
|
31
|
+
end
|
32
|
+
|
33
|
+
# Check if the status is or is not blocked
|
34
|
+
def blocked?
|
35
|
+
!self.blocked.nil?
|
36
|
+
end
|
37
|
+
|
38
|
+
# Increment the daily accesses
|
39
|
+
def accessed!
|
40
|
+
daily_requests.increment!
|
41
|
+
end
|
42
|
+
|
43
|
+
# A daily requests record (there is one per day)
|
44
|
+
#
|
45
|
+
# @params [String] time we want to find the requests record
|
46
|
+
# @return [OauthDailyRequest] requests record
|
47
|
+
def daily_requests(time = Time.now)
|
48
|
+
find_or_create_daily_requests(time)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Give back the last days in a friendly format.It is used to
|
52
|
+
# generate graph for statistics
|
53
|
+
def chart_days
|
54
|
+
daily_requests = self.oauth_daily_requests.limit(10)
|
55
|
+
days = daily_requests.map(&:created_at)
|
56
|
+
days.map { |d| d.strftime("%b %e") }
|
57
|
+
end
|
58
|
+
|
59
|
+
# Give the number of accesses for the last days. It is used
|
60
|
+
# to generate graph for statistics
|
61
|
+
def chart_times
|
62
|
+
access_times = self.oauth_daily_requests.limit(10)
|
63
|
+
access_times.map(&:times)
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def find_or_create_daily_requests(time)
|
70
|
+
daily_requests = oauth_daily_requests.find_day(time).first
|
71
|
+
daily_requests = oauth_daily_requests.create(created_at: time) unless daily_requests
|
72
|
+
return daily_requests
|
73
|
+
end
|
74
|
+
|
75
|
+
def daily_id(time)
|
76
|
+
time.year + time.month + time.day
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# Authorization grant which represents the authorization
|
2
|
+
# provided by the resource owner
|
3
|
+
|
4
|
+
module Oauth2Provider
|
5
|
+
class OauthAuthorization
|
6
|
+
include Mongoid::Document
|
7
|
+
include Mongoid::Timestamps
|
8
|
+
|
9
|
+
field :client_uri # client identifier
|
10
|
+
field :resource_owner_uri # resource owner identifier
|
11
|
+
field :code # authorization code
|
12
|
+
field :scope, type: Array # scope accessible with request
|
13
|
+
field :expire_at, type: Time # authorization expiration (security reasons)
|
14
|
+
field :blocked, type: Time, default: nil # authorization block (if client is blocked)
|
15
|
+
|
16
|
+
validates :client_uri, presence: true, url: true
|
17
|
+
validates :resource_owner_uri, presence: true, url: true
|
18
|
+
|
19
|
+
before_create :random_code
|
20
|
+
before_create :create_expiration
|
21
|
+
|
22
|
+
# Block the authorization (when resource owner blocks a client)
|
23
|
+
def block!
|
24
|
+
self.blocked = Time.now
|
25
|
+
self.save
|
26
|
+
end
|
27
|
+
|
28
|
+
# Block tokens used from a client
|
29
|
+
def self.block_client!(client_uri)
|
30
|
+
self.where(client_uri: client_uri).map(&:block!)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Block tokens used from a client in behalf of a resource owner
|
34
|
+
def self.block_access!(client_uri, resource_owner_uri)
|
35
|
+
self.where(client_uri: client_uri, resource_owner_uri: resource_owner_uri).map(&:block!)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Check if the status is or is not blocked
|
39
|
+
def blocked?
|
40
|
+
!self.blocked.nil?
|
41
|
+
end
|
42
|
+
|
43
|
+
# Check if the authorization is expired
|
44
|
+
def expired?
|
45
|
+
self.expire_at < Time.now
|
46
|
+
end
|
47
|
+
|
48
|
+
# Find the authorization based on the client uri and the
|
49
|
+
# authorization code
|
50
|
+
class << self
|
51
|
+
def where_code_and_client_uri(code, client_id)
|
52
|
+
where(code: code).where(client_uri: client_id)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
# random authorization code
|
60
|
+
def random_code
|
61
|
+
self.code = SecureRandom.hex(Oauth2Provider.settings["random_length"])
|
62
|
+
end
|
63
|
+
|
64
|
+
# expiration time
|
65
|
+
def create_expiration
|
66
|
+
self.expire_at = Chronic.parse("in #{Oauth2Provider.settings["authorization_expires_in"]} seconds")
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# Daily requests of a Resource Owner on a specific client
|
2
|
+
|
3
|
+
module Oauth2Provider
|
4
|
+
class OauthDailyRequest
|
5
|
+
|
6
|
+
include Mongoid::Document
|
7
|
+
|
8
|
+
field :created_at, type: Time # creation time
|
9
|
+
field :time_id # unique key for the day
|
10
|
+
field :day # request day
|
11
|
+
field :month # request month
|
12
|
+
field :year # request year
|
13
|
+
field :times, type: Integer, default: 0 # daily request times
|
14
|
+
|
15
|
+
# resource owner's client access
|
16
|
+
embedded_in :oauth_access, inverse_of: :oauth_daily_requests
|
17
|
+
|
18
|
+
after_create :init_times
|
19
|
+
|
20
|
+
# Increment the times counter that track the number of
|
21
|
+
# requests a client have made in behalf of a resource
|
22
|
+
# owner in a specific day
|
23
|
+
def increment!
|
24
|
+
self.times += 1
|
25
|
+
self.save
|
26
|
+
end
|
27
|
+
|
28
|
+
class << self
|
29
|
+
|
30
|
+
# Find a daily requests record
|
31
|
+
def find_day(time)
|
32
|
+
time_id = time_id(time)
|
33
|
+
where(time_id: time_id)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Define an identifier for a specific day
|
37
|
+
def time_id(time)
|
38
|
+
time.strftime("%Y%m%d")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
# Add statistical informations
|
45
|
+
def init_times
|
46
|
+
self.day = self.created_at.strftime("%d")
|
47
|
+
self.month = self.created_at.strftime("%m")
|
48
|
+
self.year = self.created_at.strftime("%Y")
|
49
|
+
self.time_id = self.class.time_id(created_at)
|
50
|
+
self.save
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Oauth2Provider
|
2
|
+
class OauthRefreshToken
|
3
|
+
include Mongoid::Document
|
4
|
+
include Mongoid::Timestamps
|
5
|
+
|
6
|
+
field :refresh_token
|
7
|
+
field :access_token
|
8
|
+
|
9
|
+
validates :access_token, presence: true
|
10
|
+
|
11
|
+
before_create :random_refresh_token
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def random_refresh_token
|
16
|
+
self.refresh_token = SecureRandom.hex(Oauth2Provider.settings["random_length"])
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# Access token used from the client to request resource
|
2
|
+
# owner resouces
|
3
|
+
|
4
|
+
module Oauth2Provider
|
5
|
+
class OauthToken
|
6
|
+
include Mongoid::Document
|
7
|
+
include Mongoid::Timestamps
|
8
|
+
|
9
|
+
field :client_uri # client identifier (internal)
|
10
|
+
field :resource_owner_uri # resource owner identifier
|
11
|
+
field :token # access token
|
12
|
+
field :refresh_token # refresh token
|
13
|
+
field :scope, type: Array # scope accessible with token
|
14
|
+
field :expire_at, type: Time, default: nil # token expiration
|
15
|
+
field :blocked, type: Time, default: nil # access token block (if client is blocked)
|
16
|
+
|
17
|
+
before_create :random_token
|
18
|
+
before_create :random_refresh_token
|
19
|
+
before_create :create_expiration
|
20
|
+
|
21
|
+
validates :client_uri, presence: true, url: true
|
22
|
+
validates :resource_owner_uri, presence: true, url: true
|
23
|
+
|
24
|
+
|
25
|
+
# Block the resource owner delegation to a specific client
|
26
|
+
def block!
|
27
|
+
self.blocked = Time.now
|
28
|
+
self.save
|
29
|
+
end
|
30
|
+
|
31
|
+
# Block tokens used from a client
|
32
|
+
def self.block_client!(client_uri)
|
33
|
+
self.where(client_uri: client_uri).map(&:block!)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Block tokens used from a client in behalf of a resource owner
|
37
|
+
def self.block_access!(client_uri, resource_owner_uri)
|
38
|
+
self.where(client_uri: client_uri, resource_owner_uri: resource_owner_uri).map(&:block!)
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.exist(client_uri, resource_owner_uri, scope)
|
42
|
+
self.where(client_uri: client_uri).
|
43
|
+
where(resource_owner_uri: resource_owner_uri).
|
44
|
+
all_in(scope: scope)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Check if the status is or is not blocked
|
48
|
+
def blocked?
|
49
|
+
!self.blocked.nil?
|
50
|
+
end
|
51
|
+
|
52
|
+
# Last time the resource owner have used the token
|
53
|
+
def last_access
|
54
|
+
self.updated_at
|
55
|
+
end
|
56
|
+
|
57
|
+
# Token is expired or not
|
58
|
+
def expired?
|
59
|
+
self.expire_at < Time.now
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def random_token
|
66
|
+
self.token = SecureRandom.hex(Oauth2Provider.settings["random_length"])
|
67
|
+
end
|
68
|
+
|
69
|
+
def random_refresh_token
|
70
|
+
self.refresh_token = SecureRandom.hex(Oauth2Provider.settings["random_length"])
|
71
|
+
end
|
72
|
+
|
73
|
+
def create_expiration
|
74
|
+
self.expire_at = Chronic.parse("in #{Oauth2Provider.settings["token_expires_in"]} seconds")
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|