slots-jwt 0.0.4 → 0.1.0
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 +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,147 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Slots
|
4
|
+
module JWT
|
5
|
+
module AuthenticationHelper
|
6
|
+
ALL = Object.new
|
7
|
+
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
included do
|
11
|
+
include ActionController::HttpAuthentication::Token::ControllerMethods
|
12
|
+
end
|
13
|
+
|
14
|
+
def jw_token
|
15
|
+
return @_jw_token if instance_variable_defined?(:@_jw_token)
|
16
|
+
token = authenticate_with_http_token { |t, _| t }
|
17
|
+
@_jw_token = token ? Slots::JWT::Slokens.decode(token) : nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def jw_token!
|
21
|
+
jw_token&.valid!
|
22
|
+
end
|
23
|
+
|
24
|
+
def update_expired_session_tokens
|
25
|
+
return false unless Slots::JWT.configuration.session_lifetime
|
26
|
+
return false unless jw_token&.expired? && jw_token.session.present?
|
27
|
+
new_session_token
|
28
|
+
end
|
29
|
+
|
30
|
+
def new_session_token
|
31
|
+
_current_user = Slots::JWT.configuration.authentication_model.from_sloken(@_jw_token)
|
32
|
+
return false unless _current_user&.update_session
|
33
|
+
@_current_user = _current_user
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
def current_user
|
38
|
+
return @_current_user if instance_variable_defined?(:@_current_user)
|
39
|
+
@_current_user = jw_token ? Slots::JWT.configuration.authentication_model.from_sloken(jw_token!) : nil
|
40
|
+
end
|
41
|
+
def load_user
|
42
|
+
current_user&.valid_in_database? && current_user.allowed_new_token?
|
43
|
+
end
|
44
|
+
|
45
|
+
def set_token_header!
|
46
|
+
# check if current user for logout
|
47
|
+
response.set_header('authorization', "Bearer token=#{current_user.token}") if current_user&.new_token?
|
48
|
+
end
|
49
|
+
|
50
|
+
def require_valid_user
|
51
|
+
# Load user will make sure it is in the database and valid in the database
|
52
|
+
raise Slots::JWT::InvalidToken, "User doesnt exist" if @_require_load_user && !load_user
|
53
|
+
access_denied! unless current_user && (@_ignore_callbacks || token_allowed?)
|
54
|
+
end
|
55
|
+
def require_load_user
|
56
|
+
# Use varaible so that if this action is prepended it will still only be called when checking for valid user,
|
57
|
+
# i.e. so its not called before update_expired_session_tokens if set
|
58
|
+
@_require_load_user = true
|
59
|
+
end
|
60
|
+
def ignore_callbacks
|
61
|
+
@_ignore_callbacks = true
|
62
|
+
end
|
63
|
+
|
64
|
+
def access_denied!
|
65
|
+
raise Slots::JWT::AccessDenied
|
66
|
+
end
|
67
|
+
|
68
|
+
def token_allowed?
|
69
|
+
!(self.class._reject_token?(self))
|
70
|
+
end
|
71
|
+
|
72
|
+
def new_token!(session)
|
73
|
+
current_user.create_token(session)
|
74
|
+
set_token_header!
|
75
|
+
end
|
76
|
+
|
77
|
+
def update_token!
|
78
|
+
current_user.update_token
|
79
|
+
end
|
80
|
+
|
81
|
+
module ClassMethods
|
82
|
+
def update_expired_session_tokens!(**options)
|
83
|
+
prepend_before_action :update_expired_session_tokens, **options
|
84
|
+
after_action :set_token_header!, **options
|
85
|
+
end
|
86
|
+
|
87
|
+
def require_login!(load_user: false, **options)
|
88
|
+
before_action :require_load_user, **options if load_user
|
89
|
+
before_action :require_valid_user, **options
|
90
|
+
end
|
91
|
+
|
92
|
+
def require_user_load!(**options)
|
93
|
+
prepend_before_action :require_load_user, **options
|
94
|
+
end
|
95
|
+
|
96
|
+
def skip_callback!(**options)
|
97
|
+
prepend_before_action :ignore_callbacks, **options
|
98
|
+
end
|
99
|
+
|
100
|
+
def ignore_login!(**options)
|
101
|
+
skip_before_action :require_valid_user, **options
|
102
|
+
skip_before_action :require_load_user, **options, raise: false
|
103
|
+
skip_before_action :update_expired_session_tokens, **options, raise: false
|
104
|
+
skip_after_action :set_token_header!, **options, raise: false
|
105
|
+
end
|
106
|
+
|
107
|
+
def catch_invalid_login(response: {errors: {authentication: ['login or password is invalid']}}, status: :unauthorized)
|
108
|
+
rescue_from Slots::JWT::AuthenticationFailed do |exception|
|
109
|
+
render json: response, status: status
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def catch_invalid_token(response: {errors: {authentication: ['invalid or missing token']}}, status: :unauthorized)
|
114
|
+
rescue_from Slots::JWT::InvalidToken do |exception|
|
115
|
+
render json: response, status: status
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def catch_access_denied(response: {errors: {authorization: ["can't access"]}}, status: :forbidden)
|
120
|
+
rescue_from Slots::JWT::AccessDenied do |exception|
|
121
|
+
render json: response, status: status
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def reject_token(only: ALL, except: ALL, &block)
|
126
|
+
raise 'Cant pass both only and except' unless only == ALL || except == ALL
|
127
|
+
only = Array(only) if only != ALL
|
128
|
+
except = Array(except) if except != ALL
|
129
|
+
|
130
|
+
(@_reject_token ||= []).push([only, except, block])
|
131
|
+
end
|
132
|
+
def _reject_token?(con)
|
133
|
+
(@_reject_token ||= []).any? { |o, e, b| _check_to_reject?(con, o, e, b) } || _superclass_reject_token?(con)
|
134
|
+
end
|
135
|
+
def _check_to_reject?(con, only, except, block)
|
136
|
+
return false unless only == ALL || only.any? { |o| o.to_sym == con.action_name.to_sym }
|
137
|
+
return false if except != ALL && except.any? { |e| e.to_sym == con.action_name.to_sym }
|
138
|
+
con.instance_eval(&block)
|
139
|
+
end
|
140
|
+
|
141
|
+
def _superclass_reject_token?(con)
|
142
|
+
self.superclass.respond_to?('_reject_token?') && self.superclass._reject_token?(con)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
module Slots
|
6
|
+
module JWT
|
7
|
+
class Configuration
|
8
|
+
attr_accessor :login_regex_validations, :token_lifetime, :session_lifetime, :previous_jwt_lifetime
|
9
|
+
attr_reader :logins
|
10
|
+
attr_writer :authentication_model
|
11
|
+
|
12
|
+
# raise_no_error is used for rake to load
|
13
|
+
def initialize
|
14
|
+
@logins = {email: //}
|
15
|
+
@login_regex_validations = true
|
16
|
+
@authentication_model = 'User'
|
17
|
+
@secret_keys = [{created_at: 0, secret: ENV['SLOT_SECRET']}]
|
18
|
+
@token_lifetime = 1.hour
|
19
|
+
@session_lifetime = 2.weeks # Set to nil if you dont want sessions
|
20
|
+
@previous_jwt_lifetime = 5.seconds # Set to nil if you dont want sessions
|
21
|
+
@manage_callbacks = Proc.new { }
|
22
|
+
end
|
23
|
+
|
24
|
+
def logins=(value)
|
25
|
+
if value.is_a? Symbol
|
26
|
+
@logins = {value => //}
|
27
|
+
elsif value.is_a?(Hash)
|
28
|
+
# Should do most inclusive regex last
|
29
|
+
raise 'must be hash of symbols => regex' unless value.length > 0 && value.all? { |k, v| k.is_a?(Symbol) && v.is_a?(Regexp) }
|
30
|
+
@logins = value
|
31
|
+
else
|
32
|
+
raise 'must be a symbol or hash'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def authentication_model
|
37
|
+
@authentication_model.to_s.constantize rescue nil
|
38
|
+
end
|
39
|
+
|
40
|
+
def secret=(v)
|
41
|
+
@secret_keys = [{created_at: 0, secret: v}]
|
42
|
+
end
|
43
|
+
|
44
|
+
def secret_yaml=(file_path_string)
|
45
|
+
secret_keys = YAML.load_file(Slots::JWT.secret_yaml_file)
|
46
|
+
@secret_keys = []
|
47
|
+
secret_keys.each do |secret_key|
|
48
|
+
raise ArgumentError, 'Need CREATED_AT' unless (created_at = secret_key['CREATED_AT']&.to_i)
|
49
|
+
raise ArgumentError, 'Need SECRET' unless (secret = secret_key['SECRET'])
|
50
|
+
previous_created_at = @secret_keys[-1]&.dig(:created_at) || Time.now.to_i
|
51
|
+
|
52
|
+
raise ArgumentError, 'CREATED_AT must be newest to latest' unless previous_created_at > created_at
|
53
|
+
@secret_keys.push(
|
54
|
+
created_at: created_at,
|
55
|
+
secret: secret
|
56
|
+
)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def secret(at = Time.now.to_i)
|
61
|
+
@secret_keys.each do |secret_hash|
|
62
|
+
return secret_hash[:secret] if at > secret_hash[:created_at]
|
63
|
+
end
|
64
|
+
raise InvalidSecret, 'Invalid Secret'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class << self
|
69
|
+
attr_writer :configuration
|
70
|
+
|
71
|
+
def configuration
|
72
|
+
@configuration ||= Configuration.new
|
73
|
+
end
|
74
|
+
|
75
|
+
def configure
|
76
|
+
yield configuration
|
77
|
+
end
|
78
|
+
|
79
|
+
def secret_yaml_file
|
80
|
+
Rails.root.join('config', 'slots_secrets.yml')
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Slots
|
4
|
+
module JWT
|
5
|
+
module DatabaseAuthentication
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
has_secure_password
|
10
|
+
end
|
11
|
+
|
12
|
+
# TODO allow super
|
13
|
+
def as_json(*)
|
14
|
+
super.except('password_digest')
|
15
|
+
end
|
16
|
+
|
17
|
+
module ClassMethods
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Slots
|
4
|
+
module JWT
|
5
|
+
class AuthenticationFailed < StandardError
|
6
|
+
end
|
7
|
+
class InvalidToken < StandardError
|
8
|
+
end
|
9
|
+
class AccessDenied < StandardError
|
10
|
+
end
|
11
|
+
class InvalidSecret < StandardError
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Slots
|
4
|
+
module JWT
|
5
|
+
module GenericMethods
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
end
|
10
|
+
|
11
|
+
def allowed_new_token?
|
12
|
+
!(self.class._reject_new_token?(self))
|
13
|
+
end
|
14
|
+
|
15
|
+
def run_token_created_callback
|
16
|
+
self.class._token_created_callback(self)
|
17
|
+
end
|
18
|
+
|
19
|
+
def authenticate?(password)
|
20
|
+
password.present? && persisted? && respond_to?(:authenticate) && authenticate(password) && allowed_new_token?
|
21
|
+
end
|
22
|
+
|
23
|
+
def authenticate!(password)
|
24
|
+
raise Slots::JWT::AuthenticationFailed unless self.authenticate?(password)
|
25
|
+
true
|
26
|
+
end
|
27
|
+
|
28
|
+
module ClassMethods
|
29
|
+
def find_for_authentication(login)
|
30
|
+
Slots::JWT.configuration.logins.each do |k, v|
|
31
|
+
next unless login&.match(v)
|
32
|
+
return find_by(arel_table[k].lower.eq(login.downcase)) || new
|
33
|
+
end
|
34
|
+
new
|
35
|
+
end
|
36
|
+
|
37
|
+
def reject_new_token(&block)
|
38
|
+
(@_reject_new_token ||= []).push(block)
|
39
|
+
end
|
40
|
+
def _reject_new_token?(user)
|
41
|
+
(@_reject_new_token ||= []).any? { |b| user.instance_eval(&b) }
|
42
|
+
end
|
43
|
+
|
44
|
+
def token_created_callback(&block)
|
45
|
+
(@_token_created_callback ||= []).push(block)
|
46
|
+
end
|
47
|
+
def _token_created_callback(user)
|
48
|
+
(@_token_created_callback ||= []).each { |b| user.instance_eval(&b) }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Slots
|
4
|
+
module JWT
|
5
|
+
module GenericValidations
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
validate :unique_and_present, :logins_meets_criteria
|
10
|
+
end
|
11
|
+
|
12
|
+
def logins_meets_criteria
|
13
|
+
return if self.errors.any?
|
14
|
+
return unless Slots::JWT.configuration.login_regex_validations
|
15
|
+
logins = Slots::JWT.configuration.logins
|
16
|
+
login_c = logins.keys
|
17
|
+
logins.each do |col, reg|
|
18
|
+
login_c.delete(col) # Login columns left
|
19
|
+
column_match(reg, col)
|
20
|
+
column_dont_match(reg, col, login_c)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def unique_and_present
|
25
|
+
# Use this rather than validates because logins in configure might not be set yet on include
|
26
|
+
Slots::JWT.configuration.logins.each do |column, _|
|
27
|
+
value = self.send(column)
|
28
|
+
next self.errors.add(column, "can't be blank") unless value.present?
|
29
|
+
|
30
|
+
pk_value = self.send(self.class.primary_key)
|
31
|
+
lower_case = self.class.arel_table[column].lower.eq(value.downcase)
|
32
|
+
next unless self.class.where.not(self.class.primary_key => pk_value).where(lower_case).exists?
|
33
|
+
self.errors.add(column, "has already been taken")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def column_match(regex, column)
|
38
|
+
# TODO change error message to use locals? or something configurable
|
39
|
+
self.errors.add(column, "didn't match login criteria") unless self.send(column).match(regex)
|
40
|
+
end
|
41
|
+
|
42
|
+
def column_dont_match(regex, column_not_to_match, columns)
|
43
|
+
columns.each do |c|
|
44
|
+
# Since we check if any errors should be present
|
45
|
+
self.errors.add(c, "matched #{column_not_to_match} login criteria") if self.send(c).match(regex)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
module ClassMethods
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Slots
|
4
|
+
module JWT
|
5
|
+
class PermissionFilter
|
6
|
+
def initialize(current_user)
|
7
|
+
@current_user = current_user
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(schema_member, ctx)
|
11
|
+
@schema_member = schema_member
|
12
|
+
return true if _dont_check?
|
13
|
+
allowed?
|
14
|
+
end
|
15
|
+
protected
|
16
|
+
attr_reader :schema_member, :current_user
|
17
|
+
|
18
|
+
private
|
19
|
+
def _dont_check?
|
20
|
+
!schema_member.metadata[:has_required_permission]
|
21
|
+
end
|
22
|
+
|
23
|
+
def required_permission
|
24
|
+
schema_member.metadata[:required_permission]
|
25
|
+
end
|
26
|
+
|
27
|
+
def valid_loaded_user
|
28
|
+
return @valid_loaded_user if instance_variable_defined?(:@valid_loaded_user)
|
29
|
+
@valid_loaded_user = current_user&.valid_in_database? && current_user.allowed_new_token?
|
30
|
+
end
|
31
|
+
|
32
|
+
def is_admin
|
33
|
+
valid_loaded_user && current_user.admin
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'jwt'
|
4
|
+
module Slots
|
5
|
+
module JWT
|
6
|
+
class Slokens
|
7
|
+
attr_reader :token, :exp, :iat, :extra_payload, :authentication_model_values, :session
|
8
|
+
def initialize(decode: false, encode: false, token: nil, authentication_record: nil, extra_payload: nil, session: nil)
|
9
|
+
if decode
|
10
|
+
@token = token
|
11
|
+
decode()
|
12
|
+
elsif encode
|
13
|
+
@authentication_model_values = authentication_record.as_json
|
14
|
+
@extra_payload = extra_payload.as_json
|
15
|
+
@session = session
|
16
|
+
update_iat
|
17
|
+
update_exp
|
18
|
+
encode()
|
19
|
+
@valid = true
|
20
|
+
else
|
21
|
+
raise 'must encode or decode'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
def self.decode(token)
|
25
|
+
self.new(decode: true, token: token)
|
26
|
+
end
|
27
|
+
def self.encode(authentication_record, session = '', extra_payload)
|
28
|
+
self.new(encode: true, authentication_record: authentication_record, session: session, extra_payload: extra_payload)
|
29
|
+
end
|
30
|
+
|
31
|
+
def expired?
|
32
|
+
@expired
|
33
|
+
end
|
34
|
+
|
35
|
+
def valid?
|
36
|
+
@valid
|
37
|
+
end
|
38
|
+
|
39
|
+
def valid!
|
40
|
+
raise InvalidToken, "Invalid Token" unless valid?
|
41
|
+
self
|
42
|
+
end
|
43
|
+
|
44
|
+
def update_token_data(authentication_record, extra_payload)
|
45
|
+
@authentication_model_values = authentication_record.as_json
|
46
|
+
@extra_payload = extra_payload.as_json
|
47
|
+
update_iat
|
48
|
+
encode
|
49
|
+
end
|
50
|
+
|
51
|
+
def update_token(authentication_record, extra_payload)
|
52
|
+
update_exp
|
53
|
+
update_token_data(authentication_record, extra_payload)
|
54
|
+
end
|
55
|
+
|
56
|
+
def payload
|
57
|
+
{
|
58
|
+
authentication_model_key => @authentication_model_values,
|
59
|
+
'exp' => @exp,
|
60
|
+
'iat' => @iat,
|
61
|
+
'session' => @session,
|
62
|
+
'extra_payload' => @extra_payload,
|
63
|
+
}
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
def authentication_model_key
|
68
|
+
Slots::JWT.configuration.authentication_model.name.underscore
|
69
|
+
end
|
70
|
+
|
71
|
+
def default_expected_keys
|
72
|
+
['exp', 'iat', 'session', authentication_model_key]
|
73
|
+
end
|
74
|
+
def secret
|
75
|
+
Slots::JWT.configuration.secret(@iat)
|
76
|
+
end
|
77
|
+
def update_iat
|
78
|
+
@iat = Time.now.to_i
|
79
|
+
end
|
80
|
+
def update_exp
|
81
|
+
@exp = Slots::JWT.configuration.token_lifetime.from_now.to_i
|
82
|
+
end
|
83
|
+
def encode
|
84
|
+
@token = ::JWT.encode self.payload, secret, 'HS256'
|
85
|
+
@expired = false
|
86
|
+
@valid = true
|
87
|
+
end
|
88
|
+
|
89
|
+
def decode
|
90
|
+
begin
|
91
|
+
set_payload
|
92
|
+
::JWT.decode @token, secret, true, verify_iat: true, algorithm: 'HS256'
|
93
|
+
rescue ::JWT::ExpiredSignature
|
94
|
+
@expired = true
|
95
|
+
rescue ::JWT::InvalidIatError, ::JWT::VerificationError, ::JWT::DecodeError, NoMethodError, JSON::ParserError, Slots::JWT::InvalidSecret
|
96
|
+
@valid = false
|
97
|
+
else
|
98
|
+
@valid = payload.slice(*default_expected_keys).compact.length == default_expected_keys.length
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def set_payload
|
103
|
+
encoded64 = @token.split('.')[1] || ''
|
104
|
+
string_payload = Base64.decode64(encoded64)
|
105
|
+
local_payload = JSON.parse(string_payload)
|
106
|
+
raise JSON::ParserError unless local_payload.is_a?(Hash)
|
107
|
+
@exp = local_payload['exp']&.to_i
|
108
|
+
@iat = local_payload['iat']&.to_i
|
109
|
+
@session = local_payload['session']
|
110
|
+
@authentication_model_values = local_payload[authentication_model_key]
|
111
|
+
@extra_payload = local_payload['extra_payload']
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|