grape_token_auth 0.0.0 → 0.1.0.rc1

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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +1 -1
  3. data/.ruby-version +1 -0
  4. data/CONTRIBUTING.md +46 -0
  5. data/README.md +222 -12
  6. data/Rakefile +11 -1
  7. data/bin/rspec +16 -0
  8. data/circle.yml +6 -0
  9. data/config/database.yml +8 -0
  10. data/grape_token_auth.gemspec +15 -0
  11. data/lib/grape_token_auth/api_helpers.rb +30 -0
  12. data/lib/grape_token_auth/apis/confirmation_api.rb +49 -0
  13. data/lib/grape_token_auth/apis/omniauth_api.rb +149 -0
  14. data/lib/grape_token_auth/apis/password_api.rb +138 -0
  15. data/lib/grape_token_auth/apis/registration_api.rb +88 -0
  16. data/lib/grape_token_auth/apis/session_api.rb +60 -0
  17. data/lib/grape_token_auth/apis/token_validation_api.rb +29 -0
  18. data/lib/grape_token_auth/authentication_header.rb +52 -0
  19. data/lib/grape_token_auth/authorizer_data.rb +58 -0
  20. data/lib/grape_token_auth/configuration.rb +81 -0
  21. data/lib/grape_token_auth/exceptions.rb +29 -0
  22. data/lib/grape_token_auth/key_generator.rb +44 -0
  23. data/lib/grape_token_auth/lookup_token.rb +46 -0
  24. data/lib/grape_token_auth/mail/mail.rb +28 -0
  25. data/lib/grape_token_auth/mail/message_base.rb +34 -0
  26. data/lib/grape_token_auth/mail/messages/confirmation/confirmation.html.erb +16 -0
  27. data/lib/grape_token_auth/mail/messages/confirmation/confirmation.text.erb +8 -0
  28. data/lib/grape_token_auth/mail/messages/confirmation/confirmation_email.rb +27 -0
  29. data/lib/grape_token_auth/mail/messages/password_reset/password_reset.html.erb +18 -0
  30. data/lib/grape_token_auth/mail/messages/password_reset/password_reset.text.erb +9 -0
  31. data/lib/grape_token_auth/mail/messages/password_reset/password_reset_email.rb +27 -0
  32. data/lib/grape_token_auth/mail/smtp_mailer.rb +50 -0
  33. data/lib/grape_token_auth/middleware.rb +42 -0
  34. data/lib/grape_token_auth/mount_helpers.rb +80 -0
  35. data/lib/grape_token_auth/omniauth/omniauth_failure_html.rb +26 -0
  36. data/lib/grape_token_auth/omniauth/omniauth_html_base.rb +23 -0
  37. data/lib/grape_token_auth/omniauth/omniauth_resource.rb +109 -0
  38. data/lib/grape_token_auth/omniauth/omniauth_success_html.rb +61 -0
  39. data/lib/grape_token_auth/omniauth/response_template.html.erb +38 -0
  40. data/lib/grape_token_auth/orm_integrations/active_record_token_auth.rb +310 -0
  41. data/lib/grape_token_auth/resource/resource_creator.rb +48 -0
  42. data/lib/grape_token_auth/resource/resource_crud_base.rb +43 -0
  43. data/lib/grape_token_auth/resource/resource_finder.rb +53 -0
  44. data/lib/grape_token_auth/resource/resource_updater.rb +40 -0
  45. data/lib/grape_token_auth/token.rb +23 -0
  46. data/lib/grape_token_auth/token_authentication.rb +8 -0
  47. data/lib/grape_token_auth/token_authorizer.rb +60 -0
  48. data/lib/grape_token_auth/unauthorized_middleware.rb +20 -0
  49. data/lib/grape_token_auth/version.rb +1 -1
  50. data/lib/grape_token_auth.rb +65 -2
  51. metadata +266 -13
@@ -0,0 +1,310 @@
1
+ require 'bcrypt'
2
+
3
+ module GrapeTokenAuth
4
+ module ActiveRecord
5
+ module TokenAuth
6
+ attr_accessor :password, :password_confirmation
7
+
8
+ def self.included(base)
9
+ base.serialize :tokens, JSON
10
+ base.after_initialize { self.tokens ||= {} }
11
+ base.validates :password, presence: true, on: :create
12
+ base.validate :password_confirmation_matches,
13
+ if: :encrypted_password_changed?
14
+ base.validates :email, uniqueness: { scope: :provider },
15
+ format: { with: Configuration::EMAIL_VALIDATION,
16
+ message: 'invalid email' }, allow_blank: true
17
+ base.before_update :synchronize_email_and_uid
18
+
19
+ class << base
20
+ def exists_in_column?(column, value)
21
+ where(column => value).count > 0
22
+ end
23
+
24
+ def find_with_reset_token(attributes)
25
+ original_token = attributes[:reset_password_token]
26
+ reset_password_token = LookupToken.digest(:reset_password_token,
27
+ original_token)
28
+
29
+ recoverable = find_or_initialize_by(reset_password_token:
30
+ reset_password_token)
31
+
32
+ return nil unless recoverable.persisted?
33
+
34
+ recoverable.reset_password_token = original_token
35
+ recoverable
36
+ end
37
+
38
+ def reset_token_lifespan
39
+ @reset_token_lifespan || 60 * 60 * 6 # 6 hours
40
+ end
41
+
42
+ def confirmation_token_lifespan
43
+ @confirmat_token_lifespan || 60 * 60 * 24 * 3 # 3 days
44
+ end
45
+
46
+ def confirm_by_token(token)
47
+ confirmation_digest = LookupToken.digest(:confirmation_token,
48
+ token)
49
+ confirmable = find_or_initialize_by(confirmation_token:
50
+ confirmation_digest)
51
+
52
+ return nil unless confirmable.persisted?
53
+
54
+ confirmable.confirm
55
+ confirmable
56
+ end
57
+
58
+ def serialize_into_session(record)
59
+ [record.to_key, record.authenticatable_salt]
60
+ end
61
+
62
+ def serialize_from_session(key, salt)
63
+ record = get(key)
64
+ record if record && record.authenticatable_salt == salt
65
+ end
66
+
67
+ def get(key)
68
+ find(key).first
69
+ end
70
+
71
+ attr_writer :reset_token_lifespan
72
+ attr_writer :confirmation_token_lifespan
73
+ attr_accessor :case_insensitive_keys
74
+ end
75
+ end
76
+
77
+ def authenticatable_salt
78
+ end
79
+
80
+ def reset_password_period_valid?
81
+ return false unless reset_password_sent_at
82
+ expiry = reset_password_sent_at.utc + self.class.reset_token_lifespan
83
+ Time.now.utc <= expiry
84
+ end
85
+
86
+ def reset_password(password, password_confirmation)
87
+ self.password = password
88
+ self.password_confirmation = password_confirmation
89
+ save
90
+ end
91
+
92
+ def password_confirmation_matches
93
+ return if password.present? && password_confirmation.present? &&
94
+ password == password_confirmation
95
+ errors.add(:password_confirmation,
96
+ 'password confirmation does not match')
97
+ end
98
+
99
+ def create_new_auth_token(client_id = nil)
100
+ self.tokens = {} if tokens.nil?
101
+ token = Token.new(client_id)
102
+ last_token = tokens.fetch(client_id, {})['token']
103
+ tokens[token.client_id] = token.to_h.merge(last_token: last_token)
104
+ self.save!
105
+
106
+ build_auth_header(token)
107
+ end
108
+
109
+ def valid_token?(token, client_id)
110
+ return false unless tokens && tokens[client_id]
111
+ return true if token_is_current?(token, client_id)
112
+ return true if token_can_be_reused?(token, client_id)
113
+
114
+ false
115
+ end
116
+
117
+ def password=(new_password)
118
+ @password = new_password
119
+ self.encrypted_password = BCrypt::Password.create(new_password)
120
+ end
121
+
122
+ def valid_password?(password)
123
+ BCrypt::Password.new(encrypted_password) == password
124
+ end
125
+
126
+ def while_record_locked(&block)
127
+ with_lock(&block)
128
+ end
129
+
130
+ def extend_batch_buffer(token, client_id)
131
+ token_hash = tokens[client_id]
132
+ token_hash[:updated_at] = Time.now
133
+ expiry = token_hash[:expiry] || token_hash['expiry']
134
+ save!
135
+ build_auth_header(Token.new(client_id, token, expiry))
136
+ end
137
+
138
+ # Copied out of Devise. Excludes the serialization blacklist.
139
+ def serializable_hash(options = nil)
140
+ options ||= {}
141
+ options[:except] = Array(options[:except])
142
+
143
+ if options[:force_except]
144
+ options[:except].concat Array(options[:force_except])
145
+ else
146
+ blacklist = GrapeTokenAuth.configuration.serialization_blacklist
147
+ options[:except].concat blacklist
148
+ end
149
+
150
+ super(options)
151
+ end
152
+
153
+ def send_reset_password_instructions(opts)
154
+ token = set_reset_password_token
155
+
156
+ opts ||= {}
157
+ opts[:client_config] ||= 'default'
158
+ opts[:token] = token
159
+ opts[:to] = email
160
+
161
+ GrapeTokenAuth.send_notification(:reset_password_instructions, opts)
162
+
163
+ token
164
+ end
165
+
166
+ def send_confirmation_instructions(opts)
167
+ opts ||= {}
168
+ token = generate_confirmation_token!
169
+ opts[:token] = token
170
+
171
+ # fall back to "default" config name
172
+ opts[:client_config] ||= 'default'
173
+ opts[:to] = pending_reconfirmation? ? unconfirmed_email : email
174
+
175
+ GrapeTokenAuth.send_notification(:confirmation_instructions, opts)
176
+ token
177
+ end
178
+
179
+ # devise method
180
+ def confirm(args = {})
181
+ pending_any_confirmation do
182
+ if confirmation_period_expired?
183
+ errors.add(:email, :confirmation_period_expired)
184
+ return false
185
+ end
186
+
187
+ self.confirmed_at = Time.now.utc
188
+
189
+ #if self.class.reconfirmable && unconfirmed_email.present?
190
+ # self.email = unconfirmed_email
191
+ # self.unconfirmed_email = nil
192
+
193
+ # # We need to validate in such cases to enforce e-mail uniqueness
194
+ # saved = save(validate: true)
195
+ #else
196
+ saved = save(validate: args[:ensure_valid] == true)
197
+
198
+ after_confirmation if saved
199
+ saved
200
+ end
201
+ end
202
+
203
+ def build_auth_url(url, params)
204
+ url = URI(url)
205
+ expiry = tokens[params[:client_id]][:expiry]
206
+ url.query = params.merge(uid: uid, expiry: expiry).to_query
207
+ url.to_s
208
+ end
209
+
210
+ def pending_reconfirmation?
211
+ unconfirmed_email.present?
212
+ end
213
+
214
+ def confirmed?
215
+ !!confirmed_at
216
+ end
217
+
218
+ def skip_confirmation!
219
+ self.confirmed_at = Time.now.utc
220
+ end
221
+
222
+ def confirmation_period_expired?
223
+ confirmation_sent_at && (Time.now > confirmation_sent_at + self.class.confirmation_token_lifespan)
224
+ end
225
+
226
+ def after_confirmation
227
+ end
228
+
229
+ def token_validation_response
230
+ as_json(except: [:tokens, :created_at, :updated_at])
231
+ end
232
+
233
+ private
234
+
235
+ # devise method
236
+ def pending_any_confirmation
237
+ if (!confirmed? || pending_reconfirmation?)
238
+ yield
239
+ else
240
+ self.errors.add(:email, :already_confirmed)
241
+ false
242
+ end
243
+ end
244
+
245
+ def generate_confirmation_token!
246
+ token, enc = GrapeTokenAuth::LookupToken.generate(self.class,
247
+ :confirmation_token)
248
+ self.confirmation_token = enc
249
+ self.confirmation_sent_at = Time.now.utc
250
+ save(validate: false)
251
+ token
252
+ end
253
+
254
+ def set_reset_password_token
255
+ token, enc = GrapeTokenAuth::LookupToken.generate(self.class,
256
+ :reset_password_token)
257
+
258
+ self.reset_password_token = enc
259
+ self.reset_password_sent_at = Time.now.utc
260
+ save(validate: false)
261
+ token
262
+ end
263
+
264
+ def synchronize_email_and_uid
265
+ self.uid = email if provider == 'email'
266
+ end
267
+
268
+ def token_is_current?(token, client_id)
269
+ client_id_info = tokens[client_id]
270
+ expiry = client_id_info['expiry'] || client_id_info[:expiry]
271
+ token_hash = client_id_info['token'] || client_id_info[:token]
272
+ return false unless expiry && token
273
+ return false unless DateTime.strptime(expiry.to_s, '%s') > Time.now
274
+ return false unless tokens_match?(token_hash, token)
275
+ true
276
+ end
277
+
278
+ def fetch_with_indifference(hash, key)
279
+ hash[key.to_sym] || hash[key.to_s]
280
+ end
281
+
282
+ def token_can_be_reused?(token, client_id)
283
+ updated_at = fetch_with_indifference(tokens[client_id], :updated_at)
284
+ last_token = fetch_with_indifference(tokens[client_id], :last_token)
285
+ return false unless updated_at && last_token
286
+ return false unless within_batch_window?(Time.parse(updated_at))
287
+ return false unless tokens_match?(last_token, token)
288
+ true
289
+ end
290
+
291
+ def tokens_match?(token_hash, token)
292
+ BCrypt::Password.new(token_hash) == token
293
+ end
294
+
295
+ def within_batch_window?(time)
296
+ time > Time.now - GrapeTokenAuth.batch_request_buffer_throttle
297
+ end
298
+
299
+ def build_auth_header(token)
300
+ {
301
+ 'access-token' => token.to_s,
302
+ 'expiry' => token.expiry.to_s,
303
+ 'client' => token.client_id.to_s,
304
+ 'token-type' => 'Bearer',
305
+ 'uid' => uid.to_s
306
+ }
307
+ end
308
+ end
309
+ end
310
+ end
@@ -0,0 +1,48 @@
1
+ require_relative 'resource_crud_base'
2
+
3
+ module GrapeTokenAuth
4
+ class ResourceCreator < ResourceCrudBase
5
+ def create!
6
+ validate_scope!
7
+ validate_params!
8
+ return false unless errors.empty?
9
+ create_resource!
10
+ return false unless errors.empty?
11
+ resource
12
+ end
13
+
14
+ private
15
+
16
+ def create_resource!
17
+ @resource = resource_class.create(permitted_params.merge(provider: 'email'))
18
+ return if @resource.valid?
19
+ pull_validation_messages
20
+ end
21
+
22
+ def permitted_attributes
23
+ white_list = GrapeTokenAuth.configuration.param_white_list || {}
24
+ other_attributes = white_list[scope] || []
25
+ [:email, :password, :password_confirmation] + other_attributes
26
+ end
27
+
28
+ def validate_params!
29
+ unpack_params.each do |label, value|
30
+ errors << validation_message(label, value)
31
+ end
32
+ errors.compact!
33
+ end
34
+
35
+ def unpack_params
36
+ [:email, :password_confirmation, :password]
37
+ .each_with_object({}) do |key, unpacked|
38
+ unpacked[key] = find_with_indifference(params, key)
39
+ end
40
+ end
41
+
42
+ def validation_message(label, value)
43
+ return "#{label} is required" unless value
44
+ return "#{label} must be a string" unless value.is_a? String
45
+ nil
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,43 @@
1
+ module GrapeTokenAuth
2
+ class ResourceCrudBase
3
+ attr_reader :resource, :errors, :scope
4
+
5
+ def initialize(params, configuration, scope = :user)
6
+ @configuration = configuration
7
+ @params = params
8
+ @errors = []
9
+ @scope = scope
10
+ end
11
+
12
+ protected
13
+
14
+ attr_reader :configuration, :params, :resource_class
15
+
16
+ def validate_scope!
17
+ @resource_class = configuration.scope_to_class(scope)
18
+ fail ScopeUndefinedError.new(nil, scope) unless resource_class
19
+ end
20
+
21
+ def pull_validation_messages
22
+ @resource.errors.messages.map do |k, v|
23
+ v.each { |e| errors << "#{k} #{e}" }
24
+ end
25
+ end
26
+
27
+ def permitted_params
28
+ permitted_attributes.each_with_object({}) do |key, permitted|
29
+ value = find_with_indifference(params, key)
30
+ permitted[key] = value if value
31
+ end
32
+ end
33
+
34
+ def find_with_indifference(hash, key)
35
+ if hash.key?(key.to_sym)
36
+ return hash[key.to_sym]
37
+ elsif hash.key?(key.to_s)
38
+ return hash[key.to_s]
39
+ end
40
+ nil
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,53 @@
1
+ module GrapeTokenAuth
2
+ class ResourceFinder
3
+ def initialize(scope, params)
4
+ @scope = scope
5
+ @params = params
6
+ set_resource_class
7
+ set_finder_key
8
+ end
9
+
10
+ def self.find(scope, params)
11
+ new(scope, params).find_resource
12
+ end
13
+
14
+ def find_resource
15
+ return unless finder_key
16
+ find_resource_by_key
17
+ end
18
+
19
+ private
20
+
21
+ attr_reader :scope, :params, :resource_class, :finder_key
22
+
23
+ def set_finder_key
24
+ auth_keys = configuration.authentication_keys
25
+ @finder_key = (params.keys.map(&:to_sym) & auth_keys).first
26
+ end
27
+
28
+ def find_resource_by_key
29
+ query_value = params[finder_key] || params[finder_key.to_s]
30
+ query = "#{finder_key} = ? AND provider='email'"
31
+
32
+ insensitive_keys = resource_class.case_insensitive_keys
33
+ if insensitive_keys && insensitive_keys.include?(finder_key)
34
+ query_value.downcase!
35
+ end
36
+
37
+ resource_class.where(query, query_value).first
38
+
39
+ # if ActiveRecord::Base.connection.adapter_name.downcase.starts_with? 'mysql'
40
+ # q = "BINARY " + q
41
+ # end
42
+ end
43
+
44
+ def configuration
45
+ GrapeTokenAuth.configuration
46
+ end
47
+
48
+ def set_resource_class
49
+ @resource_class = configuration.scope_to_class(scope)
50
+ fail(ScopeUndefinedError.new(scope)) unless resource_class
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,40 @@
1
+ module GrapeTokenAuth
2
+ class ResourceUpdater < ResourceCrudBase
3
+ def initialize(resource, params, configuration, scope = :user)
4
+ @resource = resource
5
+ super(params, configuration, scope)
6
+ end
7
+
8
+ def update!
9
+ validate_scope!
10
+ return false unless errors.empty?
11
+ update_resource!
12
+ return false unless errors.empty?
13
+ resource
14
+ end
15
+
16
+ private
17
+
18
+ def case_fix_params
19
+ insensitive_keys = resource_class.case_insensitive_keys || []
20
+ params = permitted_params
21
+ insensitive_keys.each do |k|
22
+ value = params[k]
23
+ params[k] = value.downcase if value
24
+ end
25
+ params
26
+ end
27
+
28
+ def update_resource!
29
+ resource.update(case_fix_params)
30
+ return if resource.valid?
31
+ pull_validation_messages
32
+ end
33
+
34
+ def permitted_attributes
35
+ white_list = GrapeTokenAuth.configuration.param_white_list || {}
36
+ other_attributes = white_list[scope] || []
37
+ [:email] + other_attributes
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,23 @@
1
+ module GrapeTokenAuth
2
+ class Token
3
+ attr_reader :token, :client_id, :expiry
4
+
5
+ def initialize(client_id = nil, token = nil, expiry = nil)
6
+ @client_id = client_id || SecureRandom.urlsafe_base64(nil, false)
7
+ @token = token || SecureRandom.urlsafe_base64(nil, false)
8
+ @expiry = expiry || (Time.now + GrapeTokenAuth.token_lifespan).to_i
9
+ end
10
+
11
+ def to_s
12
+ @token
13
+ end
14
+
15
+ def to_h
16
+ { expiry: expiry, token: to_password_hash, updated_at: Time.now }
17
+ end
18
+
19
+ def to_password_hash
20
+ @password_hash ||= BCrypt::Password.create(@token)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,8 @@
1
+ module GrapeTokenAuth
2
+ module TokenAuthentication
3
+ def self.included(base)
4
+ base.auth :grape_devise_token_auth
5
+ base.helpers GrapeTokenAuth::ApiHelpers
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,60 @@
1
+ module GrapeTokenAuth
2
+ class TokenAuthorizer
3
+ attr_reader :data
4
+
5
+ def initialize(authorizer_data)
6
+ @data = authorizer_data
7
+ end
8
+
9
+ def authenticate_from_token(scope)
10
+ initialize_resource_class(scope)
11
+ return nil unless resource_class
12
+
13
+ resource_from_existing_warden_user(scope)
14
+ return resource if correct_resource_type_logged_in?
15
+
16
+ find_resource(scope)
17
+ end
18
+
19
+ def find_resource(scope)
20
+ initialize_resource_class(scope)
21
+ return nil unless resource_class
22
+
23
+ return nil unless data.token_prerequisites_present?
24
+
25
+ load_user_from_uid
26
+ return nil unless user_authenticated?
27
+
28
+ user
29
+ end
30
+
31
+ private
32
+
33
+ attr_reader :resource_class, :user, :resource
34
+
35
+ def initialize_resource_class(scope)
36
+ @resource_class = GrapeTokenAuth.configuration.scope_to_class(scope)
37
+ end
38
+
39
+ def load_user_from_uid
40
+ @user = resource_class.find_by_uid(data.uid)
41
+ # TODO: hacky solution to the fact that this statement can fail sporadically
42
+ # with multiple requests. Nil returned from the statement. but
43
+ # re-executing the request causes it to pass?
44
+ rescue ::ActiveRecord::StatementInvalid
45
+ @user = resource_class.find_by_uid(data.uid)
46
+ end
47
+
48
+ def resource_from_existing_warden_user(scope)
49
+ @resource = data.exisiting_warden_user(scope)
50
+ end
51
+
52
+ def correct_resource_type_logged_in?
53
+ resource && resource.class == resource_class
54
+ end
55
+
56
+ def user_authenticated?
57
+ user && user.valid_token?(data.token, data.client_id)
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,20 @@
1
+ module GrapeTokenAuth
2
+ class UnauthorizedMiddleware
3
+ def self.call(env)
4
+ warden_opts = env.fetch('warden.options', {})
5
+ errors = warden_opts['errors'] || warden_opts[:errors]
6
+ [401,
7
+ { 'Content-Type' => 'application/json'
8
+ },
9
+ prepare_errors(errors)
10
+ ]
11
+ end
12
+
13
+ def self.prepare_errors(errors)
14
+ return [] unless errors
15
+ return [errors.to_json] if errors.class == Hash
16
+ return [{ 'errors' => errors }.to_json] if errors.class == String
17
+ []
18
+ end
19
+ end
20
+ end
@@ -1,3 +1,3 @@
1
1
  module GrapeTokenAuth
2
- VERSION = '0.0.0'
2
+ VERSION = '0.1.0.rc1'
3
3
  end
@@ -1,5 +1,68 @@
1
- require "grape_token_auth/version"
1
+ require 'grape_token_auth/version'
2
+ require 'forwardable'
3
+ require 'grape'
4
+ Dir.glob(File.expand_path('../**/*.rb', __FILE__)).each { |path| require path }
2
5
 
3
6
  module GrapeTokenAuth
4
- # Your code goes here...
7
+ class << self
8
+ extend Forwardable
9
+
10
+ attr_writer :configuration
11
+
12
+ def configure
13
+ yield configuration if block_given?
14
+ end
15
+
16
+ def configuration
17
+ @configuration ||= Configuration.new
18
+ end
19
+
20
+ def_delegators :configuration, :token_lifespan,
21
+ :batch_request_buffer_throttle,
22
+ :change_headers_on_each_request
23
+
24
+ def setup!(&block)
25
+ add_auth_strategy
26
+ configure(&block) if block_given?
27
+ end
28
+
29
+ def configure_warden(warden_manager)
30
+ configuration.mappings.each do |scope, klass|
31
+ warden_manager.serialize_into_session(scope) do |record|
32
+ klass.serialize_into_session(record)
33
+ end
34
+
35
+ warden_manager.serialize_from_session(scope) do |key|
36
+ klass.serialize_from_session(*key)
37
+ end
38
+ end
39
+ end
40
+
41
+ def setup_warden!(builder)
42
+ builder.use Warden::Manager do |manager|
43
+ manager.failure_app = GrapeTokenAuth::UnauthorizedMiddleware
44
+ manager.default_scope = :user
45
+ GrapeTokenAuth.configure_warden(manager)
46
+ end
47
+ end
48
+
49
+ def set_omniauth_path_prefix!
50
+ ::OmniAuth.config.path_prefix = configuration.omniauth_prefix
51
+ end
52
+
53
+ def send_notification(notification_type, opts)
54
+ message = GrapeTokenAuth::Mail.initialize_message(notification_type, opts)
55
+ configuration.mailer.send!(message, opts)
56
+ end
57
+
58
+ private
59
+
60
+ def add_auth_strategy
61
+ Grape::Middleware::Auth::Strategies.add(
62
+ :grape_devise_token_auth,
63
+ GrapeTokenAuth::Middleware,
64
+ ->(options) { [options] }
65
+ )
66
+ end
67
+ end
5
68
  end