slots-jwt 0.0.4 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +121 -6
- data/app/controllers/slots/jwt/sessions_controller.rb +38 -0
- data/app/models/slots/jwt/application_record.rb +9 -0
- data/app/models/slots/jwt/session.rb +44 -0
- data/config/initializers/inflections.rb +3 -0
- data/config/routes.rb +2 -2
- data/lib/generators/slots/install/USAGE +1 -1
- data/lib/generators/slots/install/install_generator.rb +1 -1
- data/lib/generators/slots/install/templates/create_slots_sessions.rb +2 -2
- data/lib/generators/slots/install/templates/slots.rb +1 -1
- data/lib/generators/slots/model/model_generator.rb +1 -1
- data/lib/slots.rb +1 -44
- data/lib/slots/jwt.rb +49 -0
- data/lib/slots/jwt/authentication_helper.rb +147 -0
- data/lib/slots/jwt/configuration.rb +84 -0
- data/lib/slots/jwt/database_authentication.rb +21 -0
- data/lib/slots/jwt/engine.rb +9 -0
- data/lib/slots/jwt/extra_classes.rb +14 -0
- data/lib/slots/jwt/generic_methods.rb +53 -0
- data/lib/slots/jwt/generic_validations.rb +53 -0
- data/lib/slots/jwt/permission_filter.rb +37 -0
- data/lib/slots/jwt/slokens.rb +115 -0
- data/lib/slots/jwt/tests.rb +37 -0
- data/lib/slots/jwt/tokens.rb +104 -0
- data/lib/slots/jwt/type_helper.rb +30 -0
- data/lib/slots/{version.rb → jwt/version.rb} +3 -1
- data/lib/tasks/slots_tasks.rake +5 -5
- metadata +23 -19
- data/app/controllers/slots/sessions_controller.rb +0 -36
- data/app/mailers/slots/application_mailer.rb +0 -8
- data/app/models/slots/application_record.rb +0 -7
- data/app/models/slots/session.rb +0 -42
- data/lib/slots/authentication_helper.rb +0 -144
- data/lib/slots/configuration.rb +0 -82
- data/lib/slots/database_authentication.rb +0 -19
- data/lib/slots/engine.rb +0 -7
- data/lib/slots/extra_classes.rb +0 -12
- data/lib/slots/generic_methods.rb +0 -51
- data/lib/slots/generic_validations.rb +0 -51
- data/lib/slots/slokens.rb +0 -113
- data/lib/slots/tests.rb +0 -35
- data/lib/slots/tokens.rb +0 -102
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Slots
|
4
|
+
module JWT
|
5
|
+
module Tests
|
6
|
+
def authorized_get(current_user, url, headers: {}, **options)
|
7
|
+
authorized_protocal :get, current_user, url, headers: headers, **options
|
8
|
+
end
|
9
|
+
def authorized_post(current_user, url, headers: {}, **options)
|
10
|
+
authorized_protocal :post, current_user, url, headers: headers, **options
|
11
|
+
end
|
12
|
+
def authorized_patch(current_user, url, headers: {}, **options)
|
13
|
+
authorized_protocal :patch, current_user, url, headers: headers, **options
|
14
|
+
end
|
15
|
+
def authorized_put(current_user, url, headers: {}, **options)
|
16
|
+
authorized_protocal :put, current_user, url, headers: headers, **options
|
17
|
+
end
|
18
|
+
def authorized_delete(current_user, url, headers: {}, **options)
|
19
|
+
authorized_protocal :delete, current_user, url, headers: headers, **options
|
20
|
+
end
|
21
|
+
|
22
|
+
def authorized_protocal(type, current_user, url, headers: {}, session: false, **options)
|
23
|
+
@token = current_user&.create_token(session)
|
24
|
+
headers = headers.merge(token_header(@token)) if @token
|
25
|
+
send(type, url, headers: headers, **options)
|
26
|
+
end
|
27
|
+
|
28
|
+
def current_token
|
29
|
+
@token
|
30
|
+
end
|
31
|
+
|
32
|
+
def token_header(token)
|
33
|
+
{'authorization' => %{Bearer token="#{token}"}}
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Slots
|
4
|
+
module JWT
|
5
|
+
module Tokens
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
end
|
10
|
+
|
11
|
+
def jwt_identifier
|
12
|
+
send(self.class.jwt_identifier_column)
|
13
|
+
end
|
14
|
+
|
15
|
+
def create_token(have_session)
|
16
|
+
session = ''
|
17
|
+
if have_session && Slots::JWT.configuration.session_lifetime
|
18
|
+
@new_session = self.sessions.new(jwt_iat: 0)
|
19
|
+
# Session should never be invalid since its all programmed
|
20
|
+
raise 'Session not valid' unless @new_session.valid?
|
21
|
+
session = @new_session.session
|
22
|
+
end
|
23
|
+
@slots_jwt = Slots::JWT::Slokens.encode(self, session, extra_payload)
|
24
|
+
if @new_session
|
25
|
+
@new_session.jwt_iat = @slots_jwt.iat
|
26
|
+
@new_session.save!
|
27
|
+
end
|
28
|
+
@new_token = true
|
29
|
+
run_token_created_callback
|
30
|
+
token
|
31
|
+
end
|
32
|
+
|
33
|
+
def extra_payload
|
34
|
+
@extra_payload || {}
|
35
|
+
end
|
36
|
+
|
37
|
+
def token
|
38
|
+
@slots_jwt&.token
|
39
|
+
end
|
40
|
+
|
41
|
+
def jwt
|
42
|
+
@slots_jwt
|
43
|
+
end
|
44
|
+
def set_token!(slots_jwt)
|
45
|
+
@slots_jwt = slots_jwt
|
46
|
+
self
|
47
|
+
end
|
48
|
+
|
49
|
+
def update_session
|
50
|
+
return false unless valid_in_database?
|
51
|
+
return false unless allowed_new_token?
|
52
|
+
# Need to check if allowed new token after loading
|
53
|
+
session = self.sessions.matches_jwt(jwt)
|
54
|
+
return false unless session
|
55
|
+
old_iat = jwt.iat
|
56
|
+
jwt.update_token(self, extra_payload)
|
57
|
+
if session.jwt_iat == old_iat
|
58
|
+
# if old_iat == previous_jwt_iat dont update and return token
|
59
|
+
session.update(previous_jwt_iat: old_iat, jwt_iat: jwt.iat)
|
60
|
+
@new_token = true
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def update_token
|
65
|
+
# This will only update the data in the token
|
66
|
+
# not the experation data or anything else
|
67
|
+
return false unless valid_in_database?
|
68
|
+
return false unless allowed_new_token?
|
69
|
+
|
70
|
+
session = self.sessions.matches_jwt(jwt)
|
71
|
+
old_iat = jwt.iat
|
72
|
+
jwt.update_token_data(self, extra_payload)
|
73
|
+
# Dont worry if session isnt there because exp not updated
|
74
|
+
session&.update(previous_jwt_iat: old_iat, jwt_iat: jwt.iat)
|
75
|
+
@new_token = true
|
76
|
+
end
|
77
|
+
|
78
|
+
def new_token?
|
79
|
+
@new_token
|
80
|
+
end
|
81
|
+
|
82
|
+
def valid_in_database?
|
83
|
+
begin
|
84
|
+
jwt_identifier_was = self.jwt_identifier
|
85
|
+
self.reload
|
86
|
+
return false if jwt_identifier_was != self.jwt_identifier
|
87
|
+
rescue ActiveRecord::RecordNotFound
|
88
|
+
return false
|
89
|
+
end
|
90
|
+
true
|
91
|
+
end
|
92
|
+
|
93
|
+
module ClassMethods
|
94
|
+
def from_sloken(slots_jwt)
|
95
|
+
self.new(slots_jwt.authentication_model_values).set_token!(slots_jwt)
|
96
|
+
end
|
97
|
+
|
98
|
+
def jwt_identifier_column
|
99
|
+
Slots::JWT.configuration.logins.keys.first
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Slots
|
4
|
+
module JWT
|
5
|
+
module TypeHelper
|
6
|
+
def self.included(mod)
|
7
|
+
mod.module_eval do
|
8
|
+
def initialize(*args, required_permission: nil, **kwargs, &block)
|
9
|
+
required_permission(required_permission)
|
10
|
+
# Pass on the default args:
|
11
|
+
super(*args, **kwargs, &block)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
# Call this method in an Object class to set the permission level:
|
16
|
+
def required_permission(permission_level)
|
17
|
+
@_required_permission = permission_level
|
18
|
+
end
|
19
|
+
|
20
|
+
# This method is overridden to customize object types:
|
21
|
+
def to_graphql
|
22
|
+
type_defn = super # returns a GraphQL::ObjectType
|
23
|
+
# Get a configured value and assign it to metadata
|
24
|
+
type_defn.metadata[:has_required_permission] = true
|
25
|
+
type_defn.metadata[:required_permission] = @_required_permission
|
26
|
+
type_defn
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/tasks/slots_tasks.rake
CHANGED
@@ -3,8 +3,8 @@
|
|
3
3
|
namespace :slots do
|
4
4
|
desc "Creates or prepends secret in config/lots_secrets.yml"
|
5
5
|
task :new_secret do
|
6
|
-
FileUtils.touch(Slots.secret_yaml_file)
|
7
|
-
secret_keys = YAML.load_file(Slots.secret_yaml_file) || []
|
6
|
+
FileUtils.touch(Slots::JWT.secret_yaml_file)
|
7
|
+
secret_keys = YAML.load_file(Slots::JWT.secret_yaml_file) || []
|
8
8
|
# DO 1 minute from now so has time to restart server
|
9
9
|
secret_keys.prepend('SECRET' => SecureRandom.hex(64), 'CREATED_AT' => 1.minute.from_now.to_i)
|
10
10
|
|
@@ -12,16 +12,16 @@ namespace :slots do
|
|
12
12
|
slots_initilizer = Rails.root.join('config', 'initializers', 'slots.rb')
|
13
13
|
require slots_initilizer if File.file?(slots_initilizer)
|
14
14
|
|
15
|
-
remove_old_secrets = Slots.configuration.session_lifetime.ago.to_i
|
15
|
+
remove_old_secrets = Slots::JWT.configuration.session_lifetime.ago.to_i
|
16
16
|
secret_keys.reject! { |value| remove_old_secrets > value['CREATED_AT'] }
|
17
|
-
File.open(Slots.secret_yaml_file, "w") do |file|
|
17
|
+
File.open(Slots::JWT.secret_yaml_file, "w") do |file|
|
18
18
|
file.write secret_keys.to_yaml
|
19
19
|
end
|
20
20
|
Rake::Task["restart"].invoke
|
21
21
|
end
|
22
22
|
desc "Clears config/lots_secrets.yml"
|
23
23
|
task :clear_secrets do
|
24
|
-
File.open(Slots.secret_yaml_file, "w") do |file|
|
24
|
+
File.open(Slots::JWT.secret_yaml_file, "w") do |file|
|
25
25
|
file.write [].to_yaml
|
26
26
|
end
|
27
27
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: slots-jwt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonathon Gardner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-11-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -81,10 +81,10 @@ files:
|
|
81
81
|
- MIT-LICENSE
|
82
82
|
- README.md
|
83
83
|
- Rakefile
|
84
|
-
- app/controllers/slots/sessions_controller.rb
|
85
|
-
- app/
|
86
|
-
- app/models/slots/
|
87
|
-
-
|
84
|
+
- app/controllers/slots/jwt/sessions_controller.rb
|
85
|
+
- app/models/slots/jwt/application_record.rb
|
86
|
+
- app/models/slots/jwt/session.rb
|
87
|
+
- config/initializers/inflections.rb
|
88
88
|
- config/routes.rb
|
89
89
|
- lib/generators/slots/install/USAGE
|
90
90
|
- lib/generators/slots/install/install_generator.rb
|
@@ -96,19 +96,22 @@ files:
|
|
96
96
|
- lib/generators/slots/model/templates/model.rb
|
97
97
|
- lib/generators/slots/model/templates/model_test.rb
|
98
98
|
- lib/slots.rb
|
99
|
-
- lib/slots/
|
100
|
-
- lib/slots/
|
101
|
-
- lib/slots/
|
102
|
-
- lib/slots/
|
103
|
-
- lib/slots/
|
104
|
-
- lib/slots/
|
105
|
-
- lib/slots/
|
106
|
-
- lib/slots/
|
107
|
-
- lib/slots/
|
108
|
-
- lib/slots/
|
109
|
-
- lib/slots/
|
99
|
+
- lib/slots/jwt.rb
|
100
|
+
- lib/slots/jwt/authentication_helper.rb
|
101
|
+
- lib/slots/jwt/configuration.rb
|
102
|
+
- lib/slots/jwt/database_authentication.rb
|
103
|
+
- lib/slots/jwt/engine.rb
|
104
|
+
- lib/slots/jwt/extra_classes.rb
|
105
|
+
- lib/slots/jwt/generic_methods.rb
|
106
|
+
- lib/slots/jwt/generic_validations.rb
|
107
|
+
- lib/slots/jwt/permission_filter.rb
|
108
|
+
- lib/slots/jwt/slokens.rb
|
109
|
+
- lib/slots/jwt/tests.rb
|
110
|
+
- lib/slots/jwt/tokens.rb
|
111
|
+
- lib/slots/jwt/type_helper.rb
|
112
|
+
- lib/slots/jwt/version.rb
|
110
113
|
- lib/tasks/slots_tasks.rake
|
111
|
-
homepage: https://github.com/jonathongardner/slots
|
114
|
+
homepage: https://github.com/jonathongardner/slots-jwt
|
112
115
|
licenses:
|
113
116
|
- MIT
|
114
117
|
metadata: {}
|
@@ -127,7 +130,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
127
130
|
- !ruby/object:Gem::Version
|
128
131
|
version: '0'
|
129
132
|
requirements: []
|
130
|
-
|
133
|
+
rubyforge_project:
|
134
|
+
rubygems_version: 2.7.6
|
131
135
|
signing_key:
|
132
136
|
specification_version: 4
|
133
137
|
summary: Token Authentication for Rails using JWT.
|
@@ -1,36 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Slots
|
4
|
-
class SessionsController < ApplicationController
|
5
|
-
update_expired_session_tokens! only: :update_session_token # needed if token is expired
|
6
|
-
require_user_load! only: :update_session_token
|
7
|
-
require_login! only: [:update_session_token, :sign_out]
|
8
|
-
skip_callback!
|
9
|
-
|
10
|
-
def sign_in
|
11
|
-
@_current_user = _authentication_model.find_for_authentication(params[:login])
|
12
|
-
|
13
|
-
current_user.authenticate!(params[:password])
|
14
|
-
|
15
|
-
new_token!(ActiveModel::Type::Boolean.new.cast(params[:session]))
|
16
|
-
render json: current_user.as_json, status: :accepted
|
17
|
-
end
|
18
|
-
|
19
|
-
def sign_out
|
20
|
-
Slots::Session.find_by(session: jw_token.session)&.delete if jw_token.session.present?
|
21
|
-
head :ok
|
22
|
-
end
|
23
|
-
|
24
|
-
def update_session_token
|
25
|
-
# TODO think about not allowing user to get new token here because then there
|
26
|
-
current_user.update_token unless current_user.new_token?
|
27
|
-
render json: current_user.as_json, status: :accepted
|
28
|
-
end
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
|
-
def _authentication_model
|
33
|
-
Slots.configuration.authentication_model
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
data/app/models/slots/session.rb
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Slots
|
4
|
-
class Session < ApplicationRecord
|
5
|
-
belongs_to :user, session_assocaition
|
6
|
-
before_validation :create_random_session, on: :create
|
7
|
-
validates :session, :jwt_iat, presence: true
|
8
|
-
validates :session, uniqueness: true
|
9
|
-
|
10
|
-
def update_random_session
|
11
|
-
self.session = SecureRandom.hex(32)
|
12
|
-
end
|
13
|
-
|
14
|
-
def self.expired
|
15
|
-
self.where(self.arel_table[:created_at].lte(Slots.configuration.session_lifetime.ago))
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.not_expired
|
19
|
-
self.where(self.arel_table[:created_at].gt(Slots.configuration.session_lifetime.ago))
|
20
|
-
end
|
21
|
-
|
22
|
-
def self.matches_jwt(sloken_jws)
|
23
|
-
jwt_where = self.arel_table[:jwt_iat].eq(sloken_jws.iat)
|
24
|
-
if Slots.configuration.previous_jwt_lifetime
|
25
|
-
jwt_where = jwt_where.or(
|
26
|
-
Arel::Nodes::Grouping.new(
|
27
|
-
self.arel_table[:previous_jwt_iat].eq(sloken_jws.iat)
|
28
|
-
.and(self.arel_table[:jwt_iat].gt(Slots.configuration.previous_jwt_lifetime.ago.to_i))
|
29
|
-
)
|
30
|
-
)
|
31
|
-
end
|
32
|
-
|
33
|
-
self.not_expired
|
34
|
-
.where(jwt_where)
|
35
|
-
.find_by(session: sloken_jws.session)
|
36
|
-
end
|
37
|
-
private
|
38
|
-
def create_random_session
|
39
|
-
update_random_session unless self.session
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
@@ -1,144 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Slots
|
4
|
-
module AuthenticationHelper
|
5
|
-
ALL = Object.new
|
6
|
-
|
7
|
-
extend ActiveSupport::Concern
|
8
|
-
|
9
|
-
included do
|
10
|
-
include ActionController::HttpAuthentication::Token::ControllerMethods
|
11
|
-
end
|
12
|
-
|
13
|
-
def jw_token
|
14
|
-
return @_jw_token if @_jw_token&.valid!
|
15
|
-
@_jw_token = Slots::Slokens.decode(authenticate_with_http_token { |t, _| t })
|
16
|
-
@_jw_token.valid!
|
17
|
-
end
|
18
|
-
|
19
|
-
def update_expired_session_tokens
|
20
|
-
return false unless Slots.configuration.session_lifetime
|
21
|
-
@_jw_token = Slots::Slokens.decode(authenticate_with_http_token { |t, _| t })
|
22
|
-
return false unless @_jw_token.expired? && @_jw_token.session.present?
|
23
|
-
new_session_token
|
24
|
-
end
|
25
|
-
|
26
|
-
def new_session_token
|
27
|
-
_current_user = Slots.configuration.authentication_model.from_sloken(@_jw_token)
|
28
|
-
return false unless _current_user&.update_session
|
29
|
-
@_current_user = _current_user
|
30
|
-
true
|
31
|
-
end
|
32
|
-
|
33
|
-
def current_user
|
34
|
-
return @_current_user if instance_variable_defined?(:@_current_user)
|
35
|
-
current_user = Slots.configuration.authentication_model.from_sloken(jw_token)
|
36
|
-
# So if jw_token initalize current_user if expired
|
37
|
-
@_current_user ||= current_user
|
38
|
-
end
|
39
|
-
def load_user
|
40
|
-
current_user&.valid_in_database? && current_user.allowed_new_token?
|
41
|
-
end
|
42
|
-
|
43
|
-
def set_token_header!
|
44
|
-
# check if current user for logout
|
45
|
-
response.set_header('authorization', "Bearer token=#{current_user.token}") if current_user&.new_token?
|
46
|
-
end
|
47
|
-
|
48
|
-
def require_valid_user
|
49
|
-
# Load user will make sure it is in the database and valid in the database
|
50
|
-
raise Slots::InvalidToken, "User doesnt exist" if @_require_load_user && !load_user
|
51
|
-
access_denied! unless current_user && (@_ignore_callbacks || token_allowed?)
|
52
|
-
end
|
53
|
-
def require_load_user
|
54
|
-
# Use varaible so that if this action is prepended it will still only be called when checking for valid user,
|
55
|
-
# i.e. so its not called before update_expired_session_tokens if set
|
56
|
-
@_require_load_user = true
|
57
|
-
end
|
58
|
-
def ignore_callbacks
|
59
|
-
@_ignore_callbacks = true
|
60
|
-
end
|
61
|
-
|
62
|
-
def access_denied!
|
63
|
-
raise Slots::AccessDenied
|
64
|
-
end
|
65
|
-
|
66
|
-
def token_allowed?
|
67
|
-
!(self.class._reject_token?(self))
|
68
|
-
end
|
69
|
-
|
70
|
-
def new_token!(session)
|
71
|
-
current_user.create_token(session)
|
72
|
-
set_token_header!
|
73
|
-
end
|
74
|
-
|
75
|
-
def update_token!
|
76
|
-
current_user.update_token
|
77
|
-
end
|
78
|
-
|
79
|
-
module ClassMethods
|
80
|
-
def update_expired_session_tokens!(**options)
|
81
|
-
prepend_before_action :update_expired_session_tokens, **options
|
82
|
-
after_action :set_token_header!, **options
|
83
|
-
end
|
84
|
-
|
85
|
-
def require_login!(load_user: false, **options)
|
86
|
-
before_action :require_load_user, **options if load_user
|
87
|
-
before_action :require_valid_user, **options
|
88
|
-
end
|
89
|
-
|
90
|
-
def require_user_load!(**options)
|
91
|
-
prepend_before_action :require_load_user, **options
|
92
|
-
end
|
93
|
-
|
94
|
-
def skip_callback!(**options)
|
95
|
-
prepend_before_action :ignore_callbacks, **options
|
96
|
-
end
|
97
|
-
|
98
|
-
def ignore_login!(**options)
|
99
|
-
skip_before_action :require_valid_user, **options
|
100
|
-
skip_before_action :require_load_user, **options, raise: false
|
101
|
-
skip_before_action :update_expired_session_tokens, **options, raise: false
|
102
|
-
skip_after_action :set_token_header!, **options, raise: false
|
103
|
-
end
|
104
|
-
|
105
|
-
def catch_invalid_login(response: {errors: {authentication: ['login or password is invalid']}}, status: :unauthorized)
|
106
|
-
rescue_from Slots::AuthenticationFailed do |exception|
|
107
|
-
render json: response, status: status
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
def catch_invalid_token(response: {errors: {authentication: ['invalid or missing token']}}, status: :unauthorized)
|
112
|
-
rescue_from Slots::InvalidToken do |exception|
|
113
|
-
render json: response, status: status
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
def catch_access_denied(response: {errors: {authorization: ["can't access"]}}, status: :forbidden)
|
118
|
-
rescue_from Slots::AccessDenied do |exception|
|
119
|
-
render json: response, status: status
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
def reject_token(only: ALL, except: ALL, &block)
|
124
|
-
raise 'Cant pass both only and except' unless only == ALL || except == ALL
|
125
|
-
only = Array(only) if only != ALL
|
126
|
-
except = Array(except) if except != ALL
|
127
|
-
|
128
|
-
(@_reject_token ||= []).push([only, except, block])
|
129
|
-
end
|
130
|
-
def _reject_token?(con)
|
131
|
-
(@_reject_token ||= []).any? { |o, e, b| _check_to_reject?(con, o, e, b) } || _superclass_reject_token?(con)
|
132
|
-
end
|
133
|
-
def _check_to_reject?(con, only, except, block)
|
134
|
-
return false unless only == ALL || only.any? { |o| o.to_sym == con.action_name.to_sym }
|
135
|
-
return false if except != ALL && except.any? { |e| e.to_sym == con.action_name.to_sym }
|
136
|
-
(con.instance_eval &block)
|
137
|
-
end
|
138
|
-
|
139
|
-
def _superclass_reject_token?(con)
|
140
|
-
self.superclass.respond_to?('_reject_token?') && self.superclass._reject_token?(con)
|
141
|
-
end
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|