sidecar_token_auth 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (175) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +13 -0
  3. data/README.md +12 -0
  4. data/Rakefile +42 -0
  5. data/app/controllers/devise_token_auth/application_controller.rb +79 -0
  6. data/app/controllers/devise_token_auth/concerns/resource_finder.rb +44 -0
  7. data/app/controllers/devise_token_auth/concerns/set_user_by_token.rb +162 -0
  8. data/app/controllers/devise_token_auth/confirmations_controller.rb +90 -0
  9. data/app/controllers/devise_token_auth/omniauth_callbacks_controller.rb +287 -0
  10. data/app/controllers/devise_token_auth/passwords_controller.rb +206 -0
  11. data/app/controllers/devise_token_auth/registrations_controller.rb +283 -0
  12. data/app/controllers/devise_token_auth/sessions_controller.rb +245 -0
  13. data/app/controllers/devise_token_auth/token_validations_controller.rb +31 -0
  14. data/app/controllers/devise_token_auth/unlocks_controller.rb +89 -0
  15. data/app/models/devise_token_auth/concerns/active_record_support.rb +16 -0
  16. data/app/models/devise_token_auth/concerns/confirmable_support.rb +28 -0
  17. data/app/models/devise_token_auth/concerns/mongoid_support.rb +19 -0
  18. data/app/models/devise_token_auth/concerns/tokens_serialization.rb +19 -0
  19. data/app/models/devise_token_auth/concerns/user.rb +257 -0
  20. data/app/models/devise_token_auth/concerns/user_omniauth_callbacks.rb +31 -0
  21. data/app/validators/devise_token_auth_email_validator.rb +23 -0
  22. data/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
  23. data/app/views/devise/mailer/reset_password_instructions.html.erb +8 -0
  24. data/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
  25. data/app/views/devise_token_auth/omniauth_external_window.html.erb +38 -0
  26. data/config/locales/da-DK.yml +52 -0
  27. data/config/locales/de.yml +51 -0
  28. data/config/locales/en.yml +60 -0
  29. data/config/locales/es.yml +51 -0
  30. data/config/locales/fr.yml +51 -0
  31. data/config/locales/he.yml +52 -0
  32. data/config/locales/it.yml +48 -0
  33. data/config/locales/ja.yml +48 -0
  34. data/config/locales/ko.yml +51 -0
  35. data/config/locales/nl.yml +32 -0
  36. data/config/locales/pl.yml +51 -0
  37. data/config/locales/pt-BR.yml +48 -0
  38. data/config/locales/pt.yml +51 -0
  39. data/config/locales/ro.yml +48 -0
  40. data/config/locales/ru.yml +52 -0
  41. data/config/locales/sq.yml +48 -0
  42. data/config/locales/sv.yml +52 -0
  43. data/config/locales/uk.yml +61 -0
  44. data/config/locales/vi.yml +52 -0
  45. data/config/locales/zh-CN.yml +48 -0
  46. data/config/locales/zh-HK.yml +50 -0
  47. data/config/locales/zh-TW.yml +50 -0
  48. data/lib/devise_token_auth.rb +14 -0
  49. data/lib/devise_token_auth/blacklist.rb +2 -0
  50. data/lib/devise_token_auth/controllers/helpers.rb +157 -0
  51. data/lib/devise_token_auth/controllers/url_helpers.rb +10 -0
  52. data/lib/devise_token_auth/engine.rb +96 -0
  53. data/lib/devise_token_auth/errors.rb +8 -0
  54. data/lib/devise_token_auth/rails/routes.rb +116 -0
  55. data/lib/devise_token_auth/token_factory.rb +126 -0
  56. data/lib/devise_token_auth/url.rb +44 -0
  57. data/lib/devise_token_auth/version.rb +5 -0
  58. data/lib/generators/devise_token_auth/USAGE +31 -0
  59. data/lib/generators/devise_token_auth/install_generator.rb +91 -0
  60. data/lib/generators/devise_token_auth/install_generator_helpers.rb +98 -0
  61. data/lib/generators/devise_token_auth/install_mongoid_generator.rb +46 -0
  62. data/lib/generators/devise_token_auth/install_views_generator.rb +18 -0
  63. data/lib/generators/devise_token_auth/templates/devise_token_auth.rb +60 -0
  64. data/lib/generators/devise_token_auth/templates/devise_token_auth_create_users.rb.erb +49 -0
  65. data/lib/generators/devise_token_auth/templates/user.rb.erb +9 -0
  66. data/lib/generators/devise_token_auth/templates/user_mongoid.rb.erb +56 -0
  67. data/lib/tasks/devise_token_auth_tasks.rake +6 -0
  68. data/test/controllers/custom/custom_confirmations_controller_test.rb +25 -0
  69. data/test/controllers/custom/custom_omniauth_callbacks_controller_test.rb +33 -0
  70. data/test/controllers/custom/custom_passwords_controller_test.rb +79 -0
  71. data/test/controllers/custom/custom_registrations_controller_test.rb +63 -0
  72. data/test/controllers/custom/custom_sessions_controller_test.rb +39 -0
  73. data/test/controllers/custom/custom_token_validations_controller_test.rb +42 -0
  74. data/test/controllers/demo_group_controller_test.rb +151 -0
  75. data/test/controllers/demo_mang_controller_test.rb +284 -0
  76. data/test/controllers/demo_user_controller_test.rb +629 -0
  77. data/test/controllers/devise_token_auth/confirmations_controller_test.rb +191 -0
  78. data/test/controllers/devise_token_auth/omniauth_callbacks_controller_test.rb +441 -0
  79. data/test/controllers/devise_token_auth/passwords_controller_test.rb +780 -0
  80. data/test/controllers/devise_token_auth/registrations_controller_test.rb +907 -0
  81. data/test/controllers/devise_token_auth/sessions_controller_test.rb +503 -0
  82. data/test/controllers/devise_token_auth/token_validations_controller_test.rb +102 -0
  83. data/test/controllers/devise_token_auth/unlocks_controller_test.rb +196 -0
  84. data/test/controllers/overrides/confirmations_controller_test.rb +47 -0
  85. data/test/controllers/overrides/omniauth_callbacks_controller_test.rb +53 -0
  86. data/test/controllers/overrides/passwords_controller_test.rb +64 -0
  87. data/test/controllers/overrides/registrations_controller_test.rb +46 -0
  88. data/test/controllers/overrides/sessions_controller_test.rb +35 -0
  89. data/test/controllers/overrides/token_validations_controller_test.rb +43 -0
  90. data/test/dummy/README.rdoc +28 -0
  91. data/test/dummy/app/active_record/confirmable_user.rb +11 -0
  92. data/test/dummy/app/active_record/lockable_user.rb +7 -0
  93. data/test/dummy/app/active_record/mang.rb +5 -0
  94. data/test/dummy/app/active_record/only_email_user.rb +7 -0
  95. data/test/dummy/app/active_record/scoped_user.rb +9 -0
  96. data/test/dummy/app/active_record/unconfirmable_user.rb +9 -0
  97. data/test/dummy/app/active_record/unregisterable_user.rb +9 -0
  98. data/test/dummy/app/active_record/user.rb +6 -0
  99. data/test/dummy/app/controllers/application_controller.rb +18 -0
  100. data/test/dummy/app/controllers/auth_origin_controller.rb +7 -0
  101. data/test/dummy/app/controllers/custom/confirmations_controller.rb +13 -0
  102. data/test/dummy/app/controllers/custom/omniauth_callbacks_controller.rb +13 -0
  103. data/test/dummy/app/controllers/custom/passwords_controller.rb +39 -0
  104. data/test/dummy/app/controllers/custom/registrations_controller.rb +39 -0
  105. data/test/dummy/app/controllers/custom/sessions_controller.rb +29 -0
  106. data/test/dummy/app/controllers/custom/token_validations_controller.rb +19 -0
  107. data/test/dummy/app/controllers/demo_group_controller.rb +15 -0
  108. data/test/dummy/app/controllers/demo_mang_controller.rb +14 -0
  109. data/test/dummy/app/controllers/demo_user_controller.rb +27 -0
  110. data/test/dummy/app/controllers/overrides/confirmations_controller.rb +28 -0
  111. data/test/dummy/app/controllers/overrides/omniauth_callbacks_controller.rb +16 -0
  112. data/test/dummy/app/controllers/overrides/passwords_controller.rb +35 -0
  113. data/test/dummy/app/controllers/overrides/registrations_controller.rb +29 -0
  114. data/test/dummy/app/controllers/overrides/sessions_controller.rb +36 -0
  115. data/test/dummy/app/controllers/overrides/token_validations_controller.rb +23 -0
  116. data/test/dummy/app/helpers/application_helper.rb +1058 -0
  117. data/test/dummy/app/models/concerns/favorite_color.rb +19 -0
  118. data/test/dummy/app/mongoid/confirmable_user.rb +52 -0
  119. data/test/dummy/app/mongoid/lockable_user.rb +38 -0
  120. data/test/dummy/app/mongoid/mang.rb +46 -0
  121. data/test/dummy/app/mongoid/only_email_user.rb +33 -0
  122. data/test/dummy/app/mongoid/scoped_user.rb +50 -0
  123. data/test/dummy/app/mongoid/unconfirmable_user.rb +44 -0
  124. data/test/dummy/app/mongoid/unregisterable_user.rb +47 -0
  125. data/test/dummy/app/mongoid/user.rb +49 -0
  126. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  127. data/test/dummy/config.ru +18 -0
  128. data/test/dummy/config/application.rb +48 -0
  129. data/test/dummy/config/application.yml.bk +0 -0
  130. data/test/dummy/config/boot.rb +11 -0
  131. data/test/dummy/config/environment.rb +7 -0
  132. data/test/dummy/config/environments/development.rb +46 -0
  133. data/test/dummy/config/environments/production.rb +84 -0
  134. data/test/dummy/config/environments/test.rb +50 -0
  135. data/test/dummy/config/initializers/assets.rb +10 -0
  136. data/test/dummy/config/initializers/backtrace_silencers.rb +9 -0
  137. data/test/dummy/config/initializers/cookies_serializer.rb +5 -0
  138. data/test/dummy/config/initializers/devise.rb +290 -0
  139. data/test/dummy/config/initializers/devise_token_auth.rb +55 -0
  140. data/test/dummy/config/initializers/figaro.rb +3 -0
  141. data/test/dummy/config/initializers/filter_parameter_logging.rb +6 -0
  142. data/test/dummy/config/initializers/inflections.rb +18 -0
  143. data/test/dummy/config/initializers/mime_types.rb +6 -0
  144. data/test/dummy/config/initializers/omniauth.rb +11 -0
  145. data/test/dummy/config/initializers/session_store.rb +5 -0
  146. data/test/dummy/config/initializers/wrap_parameters.rb +16 -0
  147. data/test/dummy/config/routes.rb +57 -0
  148. data/test/dummy/config/spring.rb +3 -0
  149. data/test/dummy/db/migrate/20140715061447_devise_token_auth_create_users.rb +58 -0
  150. data/test/dummy/db/migrate/20140715061805_devise_token_auth_create_mangs.rb +57 -0
  151. data/test/dummy/db/migrate/20140829044006_add_operating_thetan_to_user.rb +8 -0
  152. data/test/dummy/db/migrate/20140916224624_add_favorite_color_to_mangs.rb +7 -0
  153. data/test/dummy/db/migrate/20141222035835_devise_token_auth_create_only_email_users.rb +55 -0
  154. data/test/dummy/db/migrate/20141222053502_devise_token_auth_create_unregisterable_users.rb +56 -0
  155. data/test/dummy/db/migrate/20150708104536_devise_token_auth_create_unconfirmable_users.rb +56 -0
  156. data/test/dummy/db/migrate/20160103235141_devise_token_auth_create_scoped_users.rb +56 -0
  157. data/test/dummy/db/migrate/20160629184441_devise_token_auth_create_lockable_users.rb +56 -0
  158. data/test/dummy/db/migrate/20190924101113_devise_token_auth_create_confirmable_users.rb +49 -0
  159. data/test/dummy/db/schema.rb +198 -0
  160. data/test/dummy/lib/migration_database_helper.rb +43 -0
  161. data/test/factories/users.rb +41 -0
  162. data/test/lib/devise_token_auth/blacklist_test.rb +11 -0
  163. data/test/lib/devise_token_auth/token_factory_test.rb +191 -0
  164. data/test/lib/devise_token_auth/url_test.rb +26 -0
  165. data/test/lib/generators/devise_token_auth/install_generator_test.rb +217 -0
  166. data/test/lib/generators/devise_token_auth/install_generator_with_namespace_test.rb +222 -0
  167. data/test/lib/generators/devise_token_auth/install_views_generator_test.rb +25 -0
  168. data/test/models/concerns/mongoid_support_test.rb +31 -0
  169. data/test/models/concerns/tokens_serialization_test.rb +70 -0
  170. data/test/models/confirmable_user_test.rb +35 -0
  171. data/test/models/only_email_user_test.rb +29 -0
  172. data/test/models/user_test.rb +108 -0
  173. data/test/support/controllers/routes.rb +43 -0
  174. data/test/test_helper.rb +103 -0
  175. metadata +481 -0
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'devise_token_auth/rails/routes'
4
+
5
+ module DeviseTokenAuth
6
+ class Engine < ::Rails::Engine
7
+ isolate_namespace DeviseTokenAuth
8
+
9
+ initializer 'devise_token_auth.url_helpers' do
10
+ Devise.helpers << DeviseTokenAuth::Controllers::Helpers
11
+ end
12
+ end
13
+
14
+ mattr_accessor :change_headers_on_each_request,
15
+ :max_number_of_devices,
16
+ :token_lifespan,
17
+ :token_cost,
18
+ :batch_request_buffer_throttle,
19
+ :omniauth_prefix,
20
+ :default_confirm_success_url,
21
+ :default_password_reset_url,
22
+ :redirect_whitelist,
23
+ :check_current_password_before_update,
24
+ :enable_standard_devise_support,
25
+ :remove_tokens_after_password_reset,
26
+ :default_callbacks,
27
+ :headers_names,
28
+ :bypass_sign_in,
29
+ :send_confirmation_email,
30
+ :require_client_password_reset_token
31
+
32
+ self.change_headers_on_each_request = true
33
+ self.max_number_of_devices = 10
34
+ self.token_lifespan = 2.weeks
35
+ self.token_cost = 10
36
+ self.batch_request_buffer_throttle = 5.seconds
37
+ self.omniauth_prefix = '/omniauth'
38
+ self.default_confirm_success_url = nil
39
+ self.default_password_reset_url = nil
40
+ self.redirect_whitelist = nil
41
+ self.check_current_password_before_update = false
42
+ self.enable_standard_devise_support = false
43
+ self.remove_tokens_after_password_reset = false
44
+ self.default_callbacks = true
45
+ self.headers_names = { 'access-token': 'access-token',
46
+ 'client': 'client',
47
+ 'expiry': 'expiry',
48
+ 'uid': 'uid',
49
+ 'token-type': 'token-type' }
50
+ self.bypass_sign_in = true
51
+ self.send_confirmation_email = false
52
+ self.require_client_password_reset_token = false
53
+
54
+ def self.setup(&block)
55
+ yield self
56
+
57
+ Rails.application.config.after_initialize do
58
+ if defined?(::OmniAuth)
59
+ ::OmniAuth::config.path_prefix = Devise.omniauth_path_prefix = omniauth_prefix
60
+
61
+ # Omniauth currently does not pass along omniauth.params upon failure redirect
62
+ # see also: https://github.com/intridea/omniauth/issues/626
63
+ OmniAuth::FailureEndpoint.class_eval do
64
+ def redirect_to_failure
65
+ message_key = env['omniauth.error.type']
66
+ origin_query_param = env['omniauth.origin'] ? "&origin=#{CGI.escape(env['omniauth.origin'])}" : ''
67
+ strategy_name_query_param = env['omniauth.error.strategy'] ? "&strategy=#{env['omniauth.error.strategy'].name}" : ''
68
+ extra_params = env['omniauth.params'] ? "&#{env['omniauth.params'].to_query}" : ''
69
+ new_path = "#{env['SCRIPT_NAME']}#{OmniAuth.config.path_prefix}/failure?message=#{message_key}#{origin_query_param}#{strategy_name_query_param}#{extra_params}"
70
+ Rack::Response.new(['302 Moved'], 302, 'Location' => new_path).finish
71
+ end
72
+ end
73
+
74
+ # Omniauth currently removes omniauth.params during mocked requests
75
+ # see also: https://github.com/intridea/omniauth/pull/812
76
+ OmniAuth::Strategy.class_eval do
77
+ def mock_callback_call
78
+ setup_phase
79
+ @env['omniauth.origin'] = session.delete('omniauth.origin')
80
+ @env['omniauth.origin'] = nil if env['omniauth.origin'] == ''
81
+ @env['omniauth.params'] = session.delete('omniauth.params') || {}
82
+ mocked_auth = OmniAuth.mock_auth_for(name.to_s)
83
+ if mocked_auth.is_a?(Symbol)
84
+ fail!(mocked_auth)
85
+ else
86
+ @env['omniauth.auth'] = mocked_auth
87
+ OmniAuth.config.before_callback_phase.call(@env) if OmniAuth.config.before_callback_phase
88
+ call_app!
89
+ end
90
+ end
91
+ end
92
+
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DeviseTokenAuth
4
+ module Errors
5
+ class NoResourceDefinedError < StandardError; end
6
+ class InvalidModel < StandardError; end
7
+ end
8
+ end
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionDispatch::Routing
4
+ class Mapper
5
+ def mount_devise_token_auth_for(resource, opts)
6
+ # ensure objects exist to simplify attr checks
7
+ opts[:controllers] ||= {}
8
+ opts[:skip] ||= []
9
+
10
+ # check for ctrl overrides, fall back to defaults
11
+ sessions_ctrl = opts[:controllers][:sessions] || 'devise_token_auth/sessions'
12
+ registrations_ctrl = opts[:controllers][:registrations] || 'devise_token_auth/registrations'
13
+ passwords_ctrl = opts[:controllers][:passwords] || 'devise_token_auth/passwords'
14
+ confirmations_ctrl = opts[:controllers][:confirmations] || 'devise_token_auth/confirmations'
15
+ token_validations_ctrl = opts[:controllers][:token_validations] || 'devise_token_auth/token_validations'
16
+ omniauth_ctrl = opts[:controllers][:omniauth_callbacks] || 'devise_token_auth/omniauth_callbacks'
17
+ unlocks_ctrl = opts[:controllers][:unlocks] || 'devise_token_auth/unlocks'
18
+
19
+ # define devise controller mappings
20
+ controllers = { sessions: sessions_ctrl,
21
+ registrations: registrations_ctrl,
22
+ passwords: passwords_ctrl,
23
+ confirmations: confirmations_ctrl }
24
+
25
+ controllers[:unlocks] = unlocks_ctrl if unlocks_ctrl
26
+
27
+ # remove any unwanted devise modules
28
+ opts[:skip].each{ |item| controllers.delete(item) }
29
+
30
+ devise_for resource.pluralize.underscore.gsub('/', '_').to_sym,
31
+ class_name: resource,
32
+ module: :devise,
33
+ path: opts[:at].to_s,
34
+ controllers: controllers,
35
+ skip: opts[:skip] + [:omniauth_callbacks]
36
+
37
+ unnest_namespace do
38
+ # get full url path as if it were namespaced
39
+ full_path = "#{@scope[:path]}/#{opts[:at]}"
40
+
41
+ # get namespace name
42
+ namespace_name = @scope[:as]
43
+
44
+ # clear scope so controller routes aren't namespaced
45
+ @scope = ActionDispatch::Routing::Mapper::Scope.new(
46
+ path: '',
47
+ shallow_path: '',
48
+ constraints: {},
49
+ defaults: {},
50
+ options: {},
51
+ parent: nil
52
+ )
53
+
54
+ mapping_name = resource.underscore.gsub('/', '_')
55
+ mapping_name = "#{namespace_name}_#{mapping_name}" if namespace_name
56
+
57
+ devise_scope mapping_name.to_sym do
58
+ # path to verify token validity
59
+ get "#{full_path}/validate_token", controller: token_validations_ctrl.to_s, action: 'validate_token' if !opts[:skip].include?(:token_validations)
60
+
61
+ # omniauth routes. only define if omniauth is installed and not skipped.
62
+ if defined?(::OmniAuth) && !opts[:skip].include?(:omniauth_callbacks)
63
+ match "#{full_path}/failure", controller: omniauth_ctrl, action: 'omniauth_failure', via: [:get]
64
+ match "#{full_path}/:provider/callback", controller: omniauth_ctrl, action: 'omniauth_success', via: [:get]
65
+
66
+ match "#{DeviseTokenAuth.omniauth_prefix}/:provider/callback", controller: omniauth_ctrl, action: 'redirect_callbacks', via: [:get, :post]
67
+ match "#{DeviseTokenAuth.omniauth_prefix}/failure", controller: omniauth_ctrl, action: 'omniauth_failure', via: [:get, :post]
68
+
69
+ # preserve the resource class thru oauth authentication by setting name of
70
+ # resource as "resource_class" param
71
+ match "#{full_path}/:provider", to: redirect{ |params, request|
72
+ # get the current querystring
73
+ qs = CGI::parse(request.env['QUERY_STRING'])
74
+
75
+ # append name of current resource
76
+ qs['resource_class'] = [resource]
77
+ qs['namespace_name'] = [namespace_name] if namespace_name
78
+
79
+ set_omniauth_path_prefix!(DeviseTokenAuth.omniauth_prefix)
80
+
81
+ redirect_params = {}.tap { |hash| qs.each{ |k, v| hash[k] = v.first } }
82
+
83
+ if DeviseTokenAuth.redirect_whitelist
84
+ redirect_url = request.params['auth_origin_url']
85
+ unless DeviseTokenAuth::Url.whitelisted?(redirect_url)
86
+ message = I18n.t(
87
+ 'devise_token_auth.registrations.redirect_url_not_allowed',
88
+ redirect_url: redirect_url
89
+ )
90
+ redirect_params['message'] = message
91
+ next "#{::OmniAuth.config.path_prefix}/failure?#{redirect_params.to_param}"
92
+ end
93
+ end
94
+
95
+ # re-construct the path for omniauth
96
+ "#{::OmniAuth.config.path_prefix}/#{params[:provider]}?#{redirect_params.to_param}"
97
+ }, via: [:get]
98
+ end
99
+ end
100
+ end
101
+ end
102
+
103
+ # this allows us to use namespaced paths without namespacing the routes
104
+ def unnest_namespace
105
+ current_scope = @scope.dup
106
+ yield
107
+ ensure
108
+ @scope = current_scope
109
+ end
110
+
111
+ # ignore error about omniauth/multiple model support
112
+ def set_omniauth_path_prefix!(path_prefix)
113
+ ::OmniAuth.config.path_prefix = path_prefix
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,126 @@
1
+ require 'bcrypt'
2
+
3
+ module DeviseTokenAuth
4
+ # A token management factory which allow generate token objects and check them.
5
+ module TokenFactory
6
+ # For BCrypt::Password class see:
7
+ # https://github.com/codahale/bcrypt-ruby/blob/master/lib/bcrypt/password.rb
8
+
9
+ # Creates a token instance. Takes an optional client, lifespan and cost options.
10
+ # Example:
11
+ # DeviseTokenAuth::TokenFactory.create
12
+ # => #<struct DeviseTokenAuth::TokenFactory::Token client="tElcgkdZ7f9XEa0unZhrYQ", token="rAMcWOs0-mGHFMnIgJD2cA", token_hash="$2a$10$wrsdlHVRGlYW11wfImxU..jr0Ux3bHo/qbXcSfgp8zmvVUNHosita", expiry=1518982690>
13
+ #
14
+ # DeviseTokenAuth::TokenFactory.create(lifespan: 10, cost: 4)
15
+ # => #<struct DeviseTokenAuth::TokenFactory::Token client="5qleT7_t9JPVcX9xmxkVYA", token="RBXX43u4xXNSO-fr2N_4pA", token_hash="$2a$04$9gpCaoFbu2dUKxU3qiTgluHX7jj9UzS.jq1QW0EkQmoaxARo1WxTy", expiry=1517773268>
16
+ def self.create(client: nil, lifespan: nil, cost: nil)
17
+ # obj_client = client.nil? ? client() : client
18
+ obj_client = client || client()
19
+ obj_token = token
20
+ obj_token_hash = token_hash(obj_token, cost)
21
+ obj_expiry = expiry(lifespan)
22
+
23
+ Token.new(obj_client, obj_token, obj_token_hash, obj_expiry)
24
+ end
25
+
26
+ # Generates a random URL-safe client.
27
+ # Example:
28
+ # DeviseTokenAuth::TokenFactory.client
29
+ # => "zNf0pNP5iGfuBItZJGCseQ"
30
+ def self.client
31
+ secure_string
32
+ end
33
+
34
+ # Generates a random URL-safe token.
35
+ # Example:
36
+ # DeviseTokenAuth::TokenFactory.token
37
+ # => "6Bqs4K9x8ChLmZogvruF3A"
38
+ def self.token
39
+ secure_string
40
+ end
41
+
42
+ # Returns token hash for a token with given cost. If no cost value is specified,
43
+ # the default value is used. The possible cost value is within range from 4 to 31.
44
+ # It is recommended to not use a value more than 10.
45
+ # Example:
46
+ # DeviseTokenAuth::TokenFactory.token_hash("_qxAxmc-biQLiYRHsmwd5Q")
47
+ # => "$2a$10$6/cTAtQ3CBLfpkeHW7dlt.PD2aVCbFRN5vDDJUUhGsZ6pzYFlh4Me"
48
+ #
49
+ # DeviseTokenAuth::TokenFactory.token_hash("_qxAxmc-biQLiYRHsmwd5Q", 4)
50
+ # => "$2a$04$RkIrosbdRtuet2eUk3si8eS4ufeNpiPc/rSSsfpniRK8ogM5YFOWS"
51
+ def self.token_hash(token, cost = nil)
52
+ cost ||= DeviseTokenAuth.token_cost
53
+ BCrypt::Password.create(token, cost: cost)
54
+ end
55
+
56
+ # Returns the value of time as an integer number of seconds. Takes one argument.
57
+ # Example:
58
+ # DeviseTokenAuth::TokenFactory.expiry
59
+ # => 1518983359
60
+ # DeviseTokenAuth::TokenFactory.expiry(10)
61
+ # => 1517773781
62
+ def self.expiry(lifespan = nil)
63
+ lifespan ||= DeviseTokenAuth.token_lifespan
64
+ (Time.zone.now + lifespan).to_i
65
+ end
66
+
67
+ # Generates a random URL-safe string.
68
+ # Example:
69
+ # DeviseTokenAuth::TokenFactory.secure_string
70
+ # => "ADBoIaqXsEDnxIpOuumrTA"
71
+ def self.secure_string
72
+ # https://ruby-doc.org/stdlib-2.5.0/libdoc/securerandom/rdoc/Random/Formatter.html#method-i-urlsafe_base64
73
+ SecureRandom.urlsafe_base64
74
+ end
75
+
76
+ # Returns true if token hash is a valid token hash.
77
+ # Example:
78
+ # token_hash = "$2a$10$ArjX0tskRIa5Z/Tmapy59OCiAXLStfhrCiaDz.8fCb6hnX1gJ0p/2"
79
+ # DeviseTokenAuth::TokenFactory.valid_token_hash?(token_hash)
80
+ # => true
81
+ def self.valid_token_hash?(token_hash)
82
+ !!BCrypt::Password.valid_hash?(token_hash)
83
+ end
84
+
85
+ # Compares a potential token against the token hash. Returns true if the token is the original token, false otherwise.
86
+ # Example:
87
+ # token = "4wZ9gcc900rMQD1McpcSNA"
88
+ # token_hash = "$2a$10$ArjX0tskRIa5Z/Tmapy59OCiAXLStfhrCiaDz.8fCb6hnX1gJ0p/2"
89
+ # DeviseTokenAuth::TokenFactory.token_hash_is_token?(token_hash, token)
90
+ # => true
91
+ def self.token_hash_is_token?(token_hash, token)
92
+ BCrypt::Password.new(token_hash).is_password?(token)
93
+ rescue StandardError
94
+ false
95
+ end
96
+
97
+ # Creates a token instance with instance variables equal nil.
98
+ # Example:
99
+ # DeviseTokenAuth::TokenFactory.new
100
+ # => #<struct DeviseTokenAuth::TokenFactory::Token client=nil, token=nil, token_hash=nil, expiry=nil>
101
+ def self.new
102
+ Token.new
103
+ end
104
+
105
+ Token = Struct.new(:client, :token, :token_hash, :expiry) do
106
+ # Sets all instance variables of the token to nil. It is faster than creating new empty token.
107
+ # Example:
108
+ # token.clear!
109
+ # => true
110
+ # token
111
+ # => #<struct DeviseTokenAuth::TokenFactory::Token client=nil, token=nil, token_hash=nil, expiry=nil>
112
+ def clear!
113
+ size.times { |i| self[i] = nil }
114
+ true
115
+ end
116
+
117
+ # Checks token attribute presence
118
+ # Example:
119
+ # token.present?
120
+ # => true
121
+ def present?
122
+ token.present?
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DeviseTokenAuth::Url
4
+
5
+ def self.generate(url, params = {})
6
+ uri = URI(url)
7
+
8
+ res = "#{uri.scheme}://#{uri.host}"
9
+ res += ":#{uri.port}" if (uri.port && uri.port != 80 && uri.port != 443)
10
+ res += uri.path.to_s if uri.path
11
+ query = [uri.query, params.to_query].reject(&:blank?).join('&')
12
+ res += "?#{query}"
13
+ res += "##{uri.fragment}" if uri.fragment
14
+ # repeat any query params after the fragment to deal with Angular eating any pre fragment query params, used
15
+ # in the reset password redirect url
16
+ res += "?#{query}" if uri.fragment
17
+
18
+ res
19
+ end
20
+
21
+ def self.whitelisted?(url)
22
+ url.nil? || \
23
+ !!DeviseTokenAuth.redirect_whitelist.find do |pattern|
24
+ !!Wildcat.new(pattern).match(url)
25
+ end
26
+ end
27
+
28
+ # wildcard convenience class
29
+ class Wildcat
30
+ def self.parse_to_regex(str)
31
+ escaped = Regexp.escape(str).gsub('\*','.*?')
32
+ Regexp.new("^#{escaped}$", Regexp::IGNORECASE)
33
+ end
34
+
35
+ def initialize(str)
36
+ @regex = self.class.parse_to_regex(str)
37
+ end
38
+
39
+ def match(str)
40
+ !!@regex.match(str)
41
+ end
42
+ end
43
+
44
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DeviseTokenAuth
4
+ VERSION = '1.1.4'.freeze
5
+ end
@@ -0,0 +1,31 @@
1
+ Description:
2
+ This generator will install all the necessary configuration and migration
3
+ files for the devise_token_auth gem. See
4
+ https://github.com/lynndylanhurley/devise_token_auth for more information.
5
+
6
+ Arguments:
7
+ USER_CLASS # The name of the class to use for user authentication. Default is
8
+ # 'User'
9
+ MOUNT_PATH # The path at which to mount the authentication routes. Default is
10
+ # 'auth'. More detail documentation is here:
11
+ # https://devise-token-auth.gitbook.io/devise-token-auth/usage
12
+
13
+ Example:
14
+ rails generate devise_token_auth:install User auth
15
+
16
+ This will create:
17
+ config/initializers/devise_token_auth.rb
18
+ db/migrate/<%= Time.zone.now.utc.strftime("%Y%m%d%H%M%S") %>_create_devise_token_auth_create_users.rb
19
+ app/models/user.rb
20
+
21
+ If 'app/models/user.rb' already exists, the following line will be inserted
22
+ after the class definition:
23
+ include DeviseTokenAuth::Concerns::User
24
+
25
+ The following line will be inserted into your application controller at
26
+ app/controllers/application_controller.rb:
27
+ include DeviseTokenAuth::Concerns::SetUserByToken
28
+
29
+ The following line will be inserted at the top of 'config/routes.rb' if it
30
+ does not already exist:
31
+ mount_devise_token_auth_for "User", at: 'auth'
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'install_generator_helpers'
4
+
5
+ module DeviseTokenAuth
6
+ class InstallGenerator < Rails::Generators::Base
7
+ include Rails::Generators::Migration
8
+ include DeviseTokenAuth::InstallGeneratorHelpers
9
+
10
+ class_option :primary_key_type, type: :string, desc: 'The type for primary key'
11
+
12
+ def copy_migrations
13
+ if self.class.migration_exists?('db/migrate', "devise_token_auth_create_#{user_class.pluralize.gsub('::','').underscore}")
14
+ say_status('skipped', "Migration 'devise_token_auth_create_#{user_class.pluralize.gsub('::','').underscore}' already exists")
15
+ else
16
+ migration_template(
17
+ 'devise_token_auth_create_users.rb.erb',
18
+ "db/migrate/devise_token_auth_create_#{user_class.pluralize.gsub('::','').underscore}.rb"
19
+ )
20
+ end
21
+ end
22
+
23
+ def create_user_model
24
+ fname = "app/models/#{user_class.underscore}.rb"
25
+ if File.exist?(File.join(destination_root, fname))
26
+ inclusion = 'include DeviseTokenAuth::Concerns::User'
27
+ unless parse_file_for_line(fname, inclusion)
28
+
29
+ active_record_needle = (Rails::VERSION::MAJOR >= 5) ? 'ApplicationRecord' : 'ActiveRecord::Base'
30
+ inject_into_file fname, after: "class #{user_class} < #{active_record_needle}\n" do <<-'RUBY'
31
+ # Include default devise modules.
32
+ devise :database_authenticatable, :registerable,
33
+ :recoverable, :rememberable, :trackable, :validatable,
34
+ :confirmable, :omniauthable
35
+ include DeviseTokenAuth::Concerns::User
36
+ RUBY
37
+ end
38
+ end
39
+ else
40
+ template('user.rb.erb', fname)
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ def self.next_migration_number(path)
47
+ Time.zone.now.utc.strftime('%Y%m%d%H%M%S')
48
+ end
49
+
50
+ def json_supported_database?
51
+ (postgres? && postgres_correct_version?) || (mysql? && mysql_correct_version?)
52
+ end
53
+
54
+ def postgres?
55
+ database_name == 'ActiveRecord::ConnectionAdapters::PostgreSQLAdapter'
56
+ end
57
+
58
+ def postgres_correct_version?
59
+ database_version > '9.3'
60
+ end
61
+
62
+ def mysql?
63
+ database_name == 'ActiveRecord::ConnectionAdapters::MysqlAdapter'
64
+ end
65
+
66
+ def mysql_correct_version?
67
+ database_version > '5.7.7'
68
+ end
69
+
70
+ def database_name
71
+ ActiveRecord::Base.connection.class.name
72
+ end
73
+
74
+ def database_version
75
+ ActiveRecord::Base.connection.select_value('SELECT VERSION()')
76
+ end
77
+
78
+ def rails_5_or_newer?
79
+ Rails::VERSION::MAJOR >= 5
80
+ end
81
+
82
+ def primary_key_type
83
+ primary_key_string if rails_5_or_newer?
84
+ end
85
+
86
+ def primary_key_string
87
+ key_string = options[:primary_key_type]
88
+ ", id: :#{key_string}" if key_string
89
+ end
90
+ end
91
+ end