devise-tokens 1.0.0 → 1.0.1

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 (64) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/devise_tokens/application_controller.rb +77 -0
  3. data/app/controllers/devise_tokens/concerns/resource_finder.rb +42 -0
  4. data/app/controllers/devise_tokens/concerns/set_user_by_token.rb +160 -0
  5. data/app/controllers/devise_tokens/confirmations_controller.rb +79 -0
  6. data/app/controllers/devise_tokens/omniauth_callbacks_controller.rb +284 -0
  7. data/app/controllers/devise_tokens/passwords_controller.rb +204 -0
  8. data/app/controllers/devise_tokens/registrations_controller.rb +203 -0
  9. data/app/controllers/devise_tokens/sessions_controller.rb +128 -0
  10. data/app/controllers/devise_tokens/token_validations_controller.rb +29 -0
  11. data/app/controllers/devise_tokens/unlocks_controller.rb +87 -0
  12. data/app/models/devise_token_auth/concerns/active_record_support.rb +16 -0
  13. data/app/models/devise_token_auth/concerns/mongoid_support.rb +19 -0
  14. data/app/models/devise_token_auth/concerns/tokens_serialization.rb +19 -0
  15. data/app/models/devise_token_auth/concerns/user.rb +253 -0
  16. data/app/models/devise_token_auth/concerns/user_omniauth_callbacks.rb +28 -0
  17. data/app/validators/devise_token_auth_email_validator.rb +23 -0
  18. data/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
  19. data/app/views/devise/mailer/reset_password_instructions.html.erb +8 -0
  20. data/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
  21. data/app/views/devise_token_auth/omniauth_external_window.html.erb +38 -0
  22. data/config/locales/da-DK.yml +52 -0
  23. data/config/locales/de.yml +51 -0
  24. data/config/locales/en.yml +57 -0
  25. data/config/locales/es.yml +51 -0
  26. data/config/locales/fr.yml +51 -0
  27. data/config/locales/he.yml +52 -0
  28. data/config/locales/it.yml +48 -0
  29. data/config/locales/ja.yml +48 -0
  30. data/config/locales/nl.yml +32 -0
  31. data/config/locales/pl.yml +50 -0
  32. data/config/locales/pt-BR.yml +48 -0
  33. data/config/locales/pt.yml +50 -0
  34. data/config/locales/ro.yml +48 -0
  35. data/config/locales/ru.yml +52 -0
  36. data/config/locales/sq.yml +48 -0
  37. data/config/locales/sv.yml +52 -0
  38. data/config/locales/uk.yml +61 -0
  39. data/config/locales/vi.yml +52 -0
  40. data/config/locales/zh-CN.yml +48 -0
  41. data/config/locales/zh-HK.yml +50 -0
  42. data/config/locales/zh-TW.yml +50 -0
  43. data/lib/devise_tokens.rb +14 -0
  44. data/lib/devise_tokens/blacklist.rb +2 -0
  45. data/lib/devise_tokens/controllers/helpers.rb +161 -0
  46. data/lib/devise_tokens/controllers/url_helpers.rb +10 -0
  47. data/lib/devise_tokens/engine.rb +92 -0
  48. data/lib/devise_tokens/errors.rb +6 -0
  49. data/lib/devise_tokens/rails/routes.rb +116 -0
  50. data/lib/devise_tokens/token_factory.rb +126 -0
  51. data/lib/devise_tokens/url.rb +39 -0
  52. data/lib/devise_tokens/version.rb +3 -0
  53. data/lib/generators/devise_tokens/USAGE +31 -0
  54. data/lib/generators/devise_tokens/install_generator.rb +91 -0
  55. data/lib/generators/devise_tokens/install_generator_helpers.rb +98 -0
  56. data/lib/generators/devise_tokens/install_mongoid_generator.rb +46 -0
  57. data/lib/generators/devise_tokens/install_views_generator.rb +18 -0
  58. data/lib/generators/devise_tokens/templates/devise_tokens.rb +55 -0
  59. data/lib/generators/devise_tokens/templates/devise_tokens_create_users.rb.erb +49 -0
  60. data/lib/generators/devise_tokens/templates/user.rb.erb +9 -0
  61. data/lib/generators/devise_tokens/templates/user_mongoid.rb.erb +56 -0
  62. data/lib/tasks/devise_tokens_tasks.rake +6 -0
  63. metadata +208 -4
  64. data/lib/devise-tokens.rb +0 -5
@@ -0,0 +1,204 @@
1
+ module DeviseTokens
2
+ class PasswordsController < DeviseTokens::ApplicationController
3
+ before_action :validate_redirect_url_param, only: [:create, :edit]
4
+ skip_after_action :update_auth_header, only: [:create, :edit]
5
+
6
+ # this action is responsible for generating password reset tokens and sending emails
7
+ def create
8
+ return render_create_error_missing_email unless resource_params[:email]
9
+
10
+ @email = get_case_insensitive_field_from_resource_params(:email)
11
+ @resource = find_resource(:uid, @email)
12
+
13
+ if @resource
14
+ yield @resource if block_given?
15
+ @resource.send_reset_password_instructions(
16
+ email: @email,
17
+ provider: 'email',
18
+ redirect_url: @redirect_url,
19
+ client_config: params[:config_name]
20
+ )
21
+
22
+ if @resource.errors.empty?
23
+ return render_create_success
24
+ else
25
+ render_create_error @resource.errors
26
+ end
27
+ else
28
+ render_not_found_error
29
+ end
30
+ end
31
+
32
+ # this is where users arrive after visiting the password reset confirmation link
33
+ def edit
34
+ # if a user is not found, return nil
35
+ @resource = resource_class.with_reset_password_token(resource_params[:reset_password_token])
36
+
37
+ if @resource && @resource.reset_password_period_valid?
38
+ token = @resource.create_token unless require_client_password_reset_token?
39
+
40
+ # ensure that user is confirmed
41
+ @resource.skip_confirmation! if confirmable_enabled? && !@resource.confirmed_at
42
+ # allow user to change password once without current_password
43
+ @resource.allow_password_change = true if recoverable_enabled?
44
+
45
+ @resource.save!
46
+
47
+ yield @resource if block_given?
48
+
49
+ if require_client_password_reset_token?
50
+ redirect_to DeviseTokens::Url.generate(@redirect_url, reset_password_token: resource_params[:reset_password_token])
51
+ else
52
+ redirect_header_options = { reset_password: true }
53
+ redirect_headers = build_redirect_headers(token.token,
54
+ token.client,
55
+ redirect_header_options)
56
+ redirect_to(@resource.build_auth_url(@redirect_url,
57
+ redirect_headers))
58
+ end
59
+ else
60
+ render_edit_error
61
+ end
62
+ end
63
+
64
+ def update
65
+ # make sure user is authorized
66
+ if require_client_password_reset_token? && resource_params[:reset_password_token]
67
+ @resource = resource_class.with_reset_password_token(resource_params[:reset_password_token])
68
+ return render_update_error_unauthorized unless @resource
69
+
70
+ @token = @resource.create_token
71
+ else
72
+ @resource = set_user_by_token
73
+ end
74
+
75
+ return render_update_error_unauthorized unless @resource
76
+
77
+ # make sure account doesn't use oauth2 provider
78
+ unless @resource.provider == 'email'
79
+ return render_update_error_password_not_required
80
+ end
81
+
82
+ # ensure that password params were sent
83
+ unless password_resource_params[:password] && password_resource_params[:password_confirmation]
84
+ return render_update_error_missing_password
85
+ end
86
+
87
+ if @resource.send(resource_update_method, password_resource_params)
88
+ @resource.allow_password_change = false if recoverable_enabled?
89
+ @resource.save!
90
+
91
+ yield @resource if block_given?
92
+ return render_update_success
93
+ else
94
+ return render_update_error
95
+ end
96
+ end
97
+
98
+ protected
99
+
100
+ def resource_update_method
101
+ allow_password_change = recoverable_enabled? && @resource.allow_password_change == true || require_client_password_reset_token?
102
+ if DeviseTokens.check_current_password_before_update == false || allow_password_change
103
+ 'update'
104
+ else
105
+ 'update_with_password'
106
+ end
107
+ end
108
+
109
+ def render_create_error_missing_email
110
+ render_error(401, I18n.t('devise_tokens.passwords.missing_email'))
111
+ end
112
+
113
+ def render_create_error_missing_redirect_url
114
+ render_error(401, I18n.t('devise_tokens.passwords.missing_redirect_url'))
115
+ end
116
+
117
+ def render_error_not_allowed_redirect_url
118
+ response = {
119
+ status: 'error',
120
+ data: resource_data
121
+ }
122
+ message = I18n.t('devise_tokens.passwords.not_allowed_redirect_url', redirect_url: @redirect_url)
123
+ render_error(422, message, response)
124
+ end
125
+
126
+ def render_create_success
127
+ render json: {
128
+ success: true,
129
+ message: I18n.t('devise_tokens.passwords.sended', email: @email)
130
+ }
131
+ end
132
+
133
+ def render_create_error(errors)
134
+ render json: {
135
+ success: false,
136
+ errors: errors
137
+ }, status: 400
138
+ end
139
+
140
+ def render_edit_error
141
+ raise ActionController::RoutingError, 'Not Found'
142
+ end
143
+
144
+ def render_update_error_unauthorized
145
+ render_error(401, 'Unauthorized')
146
+ end
147
+
148
+ def render_update_error_password_not_required
149
+ render_error(422, I18n.t('devise_tokens.passwords.password_not_required', provider: @resource.provider.humanize))
150
+ end
151
+
152
+ def render_update_error_missing_password
153
+ render_error(422, I18n.t('devise_tokens.passwords.missing_passwords'))
154
+ end
155
+
156
+ def render_update_success
157
+ render json: {
158
+ success: true,
159
+ data: resource_data,
160
+ message: I18n.t('devise_tokens.passwords.successfully_updated')
161
+ }
162
+ end
163
+
164
+ def render_update_error
165
+ render json: {
166
+ success: false,
167
+ errors: resource_errors
168
+ }, status: 422
169
+ end
170
+
171
+ private
172
+
173
+ def resource_params
174
+ params.permit(:email, :reset_password_token)
175
+ end
176
+
177
+ def password_resource_params
178
+ params.permit(*params_for_resource(:account_update))
179
+ end
180
+
181
+ def render_not_found_error
182
+ render_error(404, I18n.t('devise_tokens.passwords.user_not_found', email: @email))
183
+ end
184
+
185
+ def validate_redirect_url_param
186
+ # give redirect value from params priority
187
+ @redirect_url = params.fetch(
188
+ :redirect_url,
189
+ DeviseTokens.default_password_reset_url
190
+ )
191
+
192
+ return render_create_error_missing_redirect_url unless @redirect_url
193
+ return render_error_not_allowed_redirect_url if blacklisted_redirect_url?(@redirect_url)
194
+ end
195
+
196
+ def reset_password_token_as_raw?(recoverable)
197
+ recoverable && recoverable.reset_password_token.present? && !require_client_password_reset_token?
198
+ end
199
+
200
+ def require_client_password_reset_token?
201
+ DeviseTokens.require_client_password_reset_token
202
+ end
203
+ end
204
+ end
@@ -0,0 +1,203 @@
1
+ module DeviseTokens
2
+ class RegistrationsController < DeviseTokens::ApplicationController
3
+ before_action :set_user_by_token, only: [:destroy, :update]
4
+ before_action :validate_sign_up_params, only: :create
5
+ before_action :validate_account_update_params, only: :update
6
+ skip_after_action :update_auth_header, only: [:create, :destroy]
7
+
8
+ def create
9
+ build_resource
10
+
11
+ unless @resource.present?
12
+ raise DeviseTokens::Errors::NoResourceDefinedError,
13
+ "#{self.class.name} #build_resource does not define @resource,"\
14
+ ' execution stopped.'
15
+ end
16
+
17
+ # give redirect value from params priority
18
+ @redirect_url = params.fetch(
19
+ :confirm_success_url,
20
+ DeviseTokens.default_confirm_success_url
21
+ )
22
+
23
+ # success redirect url is required
24
+ if confirmable_enabled? && !@redirect_url
25
+ return render_create_error_missing_confirm_success_url
26
+ end
27
+
28
+ # if whitelist is set, validate redirect_url against whitelist
29
+ return render_create_error_redirect_url_not_allowed if blacklisted_redirect_url?(@redirect_url)
30
+
31
+ # override email confirmation, must be sent manually from ctrl
32
+ callback_name = defined?(ActiveRecord) && resource_class < ActiveRecord::Base ? :commit : :create
33
+ resource_class.set_callback(callback_name, :after, :send_on_create_confirmation_instructions)
34
+ resource_class.skip_callback(callback_name, :after, :send_on_create_confirmation_instructions)
35
+
36
+ if @resource.respond_to? :skip_confirmation_notification!
37
+ # Fix duplicate e-mails by disabling Devise confirmation e-mail
38
+ @resource.skip_confirmation_notification!
39
+ end
40
+
41
+ if @resource.save
42
+ yield @resource if block_given?
43
+
44
+ unless @resource.confirmed?
45
+ # user will require email authentication
46
+ @resource.send_confirmation_instructions({
47
+ client_config: params[:config_name],
48
+ redirect_url: @redirect_url
49
+ })
50
+ end
51
+
52
+ if active_for_authentication?
53
+ # email auth has been bypassed, authenticate user
54
+ @token = @resource.create_token
55
+ @resource.save!
56
+ update_auth_header
57
+ end
58
+
59
+ render_create_success
60
+ else
61
+ clean_up_passwords @resource
62
+ render_create_error
63
+ end
64
+ end
65
+
66
+ def update
67
+ if @resource
68
+ if @resource.send(resource_update_method, account_update_params)
69
+ yield @resource if block_given?
70
+ render_update_success
71
+ else
72
+ render_update_error
73
+ end
74
+ else
75
+ render_update_error_user_not_found
76
+ end
77
+ end
78
+
79
+ def destroy
80
+ if @resource
81
+ @resource.destroy
82
+ yield @resource if block_given?
83
+ render_destroy_success
84
+ else
85
+ render_destroy_error
86
+ end
87
+ end
88
+
89
+ def sign_up_params
90
+ params.permit(*params_for_resource(:sign_up))
91
+ end
92
+
93
+ def account_update_params
94
+ params.permit(*params_for_resource(:account_update))
95
+ end
96
+
97
+ protected
98
+
99
+ def build_resource
100
+ @resource = resource_class.new(sign_up_params)
101
+ @resource.provider = provider
102
+
103
+ # honor devise configuration for case_insensitive_keys
104
+ if resource_class.case_insensitive_keys.include?(:email)
105
+ @resource.email = sign_up_params[:email].try(:downcase)
106
+ else
107
+ @resource.email = sign_up_params[:email]
108
+ end
109
+ end
110
+
111
+ def render_create_error_missing_confirm_success_url
112
+ response = {
113
+ status: 'error',
114
+ data: resource_data
115
+ }
116
+ message = I18n.t('devise_tokens.registrations.missing_confirm_success_url')
117
+ render_error(422, message, response)
118
+ end
119
+
120
+ def render_create_error_redirect_url_not_allowed
121
+ response = {
122
+ status: 'error',
123
+ data: resource_data
124
+ }
125
+ message = I18n.t('devise_tokens.registrations.redirect_url_not_allowed', redirect_url: @redirect_url)
126
+ render_error(422, message, response)
127
+ end
128
+
129
+ def render_create_success
130
+ render json: {
131
+ status: 'success',
132
+ data: resource_data
133
+ }
134
+ end
135
+
136
+ def render_create_error
137
+ render json: {
138
+ status: 'error',
139
+ data: resource_data,
140
+ errors: resource_errors
141
+ }, status: 422
142
+ end
143
+
144
+ def render_update_success
145
+ render json: {
146
+ status: 'success',
147
+ data: resource_data
148
+ }
149
+ end
150
+
151
+ def render_update_error
152
+ render json: {
153
+ status: 'error',
154
+ errors: resource_errors
155
+ }, status: 422
156
+ end
157
+
158
+ def render_update_error_user_not_found
159
+ render_error(404, I18n.t('devise_tokens.registrations.user_not_found'), status: 'error')
160
+ end
161
+
162
+ def render_destroy_success
163
+ render json: {
164
+ status: 'success',
165
+ message: I18n.t('devise_tokens.registrations.account_with_uid_destroyed', uid: @resource.uid)
166
+ }
167
+ end
168
+
169
+ def render_destroy_error
170
+ render_error(404, I18n.t('devise_tokens.registrations.account_to_destroy_not_found'), status: 'error')
171
+ end
172
+
173
+ private
174
+
175
+ def resource_update_method
176
+ if DeviseTokens.check_current_password_before_update == :attributes
177
+ 'update_with_password'
178
+ elsif DeviseTokens.check_current_password_before_update == :password && account_update_params.key?(:password)
179
+ 'update_with_password'
180
+ elsif account_update_params.key?(:current_password)
181
+ 'update_with_password'
182
+ else
183
+ 'update'
184
+ end
185
+ end
186
+
187
+ def validate_sign_up_params
188
+ validate_post_data sign_up_params, I18n.t('errors.messages.validate_sign_up_params')
189
+ end
190
+
191
+ def validate_account_update_params
192
+ validate_post_data account_update_params, I18n.t('errors.messages.validate_account_update_params')
193
+ end
194
+
195
+ def validate_post_data which, message
196
+ render_error(:unprocessable_entity, message, status: 'error') if which.empty?
197
+ end
198
+
199
+ def active_for_authentication?
200
+ !@resource.respond_to?(:active_for_authentication?) || @resource.active_for_authentication?
201
+ end
202
+ end
203
+ end
@@ -0,0 +1,128 @@
1
+ module DeviseTokens
2
+ class SessionsController < DeviseTokens::ApplicationController
3
+ before_action :set_user_by_token, only: [:destroy]
4
+ after_action :reset_session, only: [:destroy]
5
+
6
+ def new
7
+ render_new_error
8
+ end
9
+
10
+ def create
11
+ # Check
12
+ field = (resource_params.keys.map(&:to_sym) & resource_class.authentication_keys).first
13
+
14
+ @resource = nil
15
+ if field
16
+ q_value = get_case_insensitive_field_from_resource_params(field)
17
+
18
+ @resource = find_resource(field, q_value)
19
+ end
20
+
21
+ if @resource && valid_params?(field, q_value) && (!@resource.respond_to?(:active_for_authentication?) || @resource.active_for_authentication?)
22
+ valid_password = @resource.valid_password?(resource_params[:password])
23
+ if (@resource.respond_to?(:valid_for_authentication?) && !@resource.valid_for_authentication? { valid_password }) || !valid_password
24
+ return render_create_error_bad_credentials
25
+ end
26
+ @token = @resource.create_token
27
+ @resource.save
28
+
29
+ sign_in(:user, @resource, store: false, bypass: false)
30
+
31
+ yield @resource if block_given?
32
+
33
+ render_create_success
34
+ elsif @resource && !(!@resource.respond_to?(:active_for_authentication?) || @resource.active_for_authentication?)
35
+ if @resource.respond_to?(:locked_at) && @resource.locked_at
36
+ render_create_error_account_locked
37
+ else
38
+ render_create_error_not_confirmed
39
+ end
40
+ else
41
+ render_create_error_bad_credentials
42
+ end
43
+ end
44
+
45
+ def destroy
46
+ # remove auth instance variables so that after_action does not run
47
+ user = remove_instance_variable(:@resource) if @resource
48
+ client = @token.client if @token.client
49
+ @token.clear!
50
+
51
+ if user && client && user.tokens[client]
52
+ user.tokens.delete(client)
53
+ user.save!
54
+
55
+ yield user if block_given?
56
+
57
+ render_destroy_success
58
+ else
59
+ render_destroy_error
60
+ end
61
+ end
62
+
63
+ protected
64
+
65
+ def valid_params?(key, val)
66
+ resource_params[:password] && key && val
67
+ end
68
+
69
+ def get_auth_params
70
+ auth_key = nil
71
+ auth_val = nil
72
+
73
+ # iterate thru allowed auth keys, use first found
74
+ resource_class.authentication_keys.each do |k|
75
+ if resource_params[k]
76
+ auth_val = resource_params[k]
77
+ auth_key = k
78
+ break
79
+ end
80
+ end
81
+
82
+ # honor devise configuration for case_insensitive_keys
83
+ if resource_class.case_insensitive_keys.include?(auth_key)
84
+ auth_val.downcase!
85
+ end
86
+
87
+ { key: auth_key, val: auth_val }
88
+ end
89
+
90
+ def render_new_error
91
+ render_error(405, I18n.t('devise_tokens.sessions.not_supported'))
92
+ end
93
+
94
+ def render_create_success
95
+ render json: {
96
+ data: resource_data(resource_json: @resource.token_validation_response)
97
+ }
98
+ end
99
+
100
+ def render_create_error_not_confirmed
101
+ render_error(401, I18n.t('devise_tokens.sessions.not_confirmed', email: @resource.email))
102
+ end
103
+
104
+ def render_create_error_account_locked
105
+ render_error(401, I18n.t('devise.mailer.unlock_instructions.account_lock_msg'))
106
+ end
107
+
108
+ def render_create_error_bad_credentials
109
+ render_error(401, I18n.t('devise_tokens.sessions.bad_credentials'))
110
+ end
111
+
112
+ def render_destroy_success
113
+ render json: {
114
+ success:true
115
+ }, status: 200
116
+ end
117
+
118
+ def render_destroy_error
119
+ render_error(404, I18n.t('devise_tokens.sessions.user_not_found'))
120
+ end
121
+
122
+ private
123
+
124
+ def resource_params
125
+ params.permit(*params_for_resource(:sign_in))
126
+ end
127
+ end
128
+ end