devise_token_auth 0.1.34 → 0.1.35

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of devise_token_auth might be problematic. Click here for more details.

Files changed (29) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +73 -2
  3. data/app/controllers/devise_token_auth/application_controller.rb +1 -0
  4. data/app/controllers/devise_token_auth/concerns/set_user_by_token.rb +2 -0
  5. data/app/controllers/devise_token_auth/omniauth_callbacks_controller.rb +135 -136
  6. data/app/controllers/devise_token_auth/passwords_controller.rb +112 -65
  7. data/app/controllers/devise_token_auth/registrations_controller.rb +91 -50
  8. data/app/controllers/devise_token_auth/sessions_controller.rb +53 -26
  9. data/app/controllers/devise_token_auth/token_validations_controller.rb +18 -8
  10. data/app/models/devise_token_auth/concerns/user.rb +5 -3
  11. data/app/views/devise_token_auth/omniauth_external_window.html.erb +1 -1
  12. data/config/locales/pl.yml +30 -0
  13. data/lib/devise_token_auth/rails/routes.rb +5 -2
  14. data/lib/devise_token_auth/version.rb +1 -1
  15. data/lib/generators/devise_token_auth/install_generator.rb +11 -0
  16. data/test/controllers/custom/custom_passwords_controller_test.rb +15 -0
  17. data/test/controllers/custom/custom_registrations_controller_test.rb +9 -0
  18. data/test/controllers/custom/custom_sessions_controller_test.rb +9 -0
  19. data/test/controllers/custom/custom_token_validations_controller_test.rb +9 -0
  20. data/test/controllers/devise_token_auth/omniauth_callbacks_controller_test.rb +4 -4
  21. data/test/dummy/app/controllers/custom/passwords_controller.rb +5 -0
  22. data/test/dummy/app/controllers/custom/registrations_controller.rb +6 -0
  23. data/test/dummy/app/controllers/custom/sessions_controller.rb +6 -0
  24. data/test/dummy/app/controllers/custom/token_validations_controller.rb +6 -0
  25. data/test/dummy/db/test.sqlite3 +0 -0
  26. data/test/dummy/log/test.log +44662 -0
  27. data/test/dummy/tmp/generators/db/migrate/{20150809052321_devise_token_auth_create_users.rb → 20151013023615_devise_token_auth_create_users.rb} +0 -0
  28. metadata +9 -9
  29. data/config/routes.rb +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4fdc74cd5894dae6ce1eae8903c9a30d38fc5827
4
- data.tar.gz: 2c99359cc717c189bb12beb45f80521b340367ca
3
+ metadata.gz: 89fd0f78a201ad5a99dedac0fed3488d7560ed25
4
+ data.tar.gz: 6fd0ffc8d75f18d4c444ae9d6afe8e5e0ad0ea26
5
5
  SHA512:
6
- metadata.gz: b5e79c25c08635fc1c5c7b9afc36d153da02ac003bb0643482b2f83978806c1441155b491987cbe94a664cd1486fa8ab7ed0f212abb3961793388d9b8c097060
7
- data.tar.gz: f967d2e07f376a7fb62d28dddb8d8cd5e6013800bb8e62506938f78099e4ba943a85460fe9ea2aba8e976f8345f260d990a65dd9b71562b81b68c772c6fd9805
6
+ metadata.gz: c3b3be8a1cd2e4ac12bd699c6b3b118045235c40b984a3e733d7676912aa5194454211edbb5c5e22eda77c9637604269dd1d92cca9796ed72e365e0b0f99745e
7
+ data.tar.gz: 98902da7dc896d05ffa0d01dcd30d9a7e297fd4f0725f54756f794907abfb5117d91720d41d0228f45f485242f9b0b203dbe7f092c868acf999e85db4451377d
data/README.md CHANGED
@@ -8,6 +8,8 @@
8
8
 
9
9
  ## Simple, secure token based authentication for Rails.
10
10
 
11
+ [![Join the chat at https://gitter.im/lynndylanhurley/devise_token_auth](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/lynndylanhurley/devise_token_auth?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
12
+
11
13
  This gem provides the following features:
12
14
 
13
15
  * Seamless integration with both the the venerable [ng-token-auth](https://github.com/lynndylanhurley/ng-token-auth) module for [angular.js](https://github.com/angular/angular.js) and the outstanding [jToker](https://github.com/lynndylanhurley/j-toker) plugin for [jQuery](https://jquery.com/).
@@ -42,6 +44,7 @@ Please read the [issue reporting guidelines](#issue-reporting) before posting is
42
44
  * [OmniAuth Authentication](#omniauth-authentication)
43
45
  * [OmniAuth Provider Settings](#omniauth-provider-settings)
44
46
  * [Email Authentication](#email-authentication)
47
+ * [Customizing Devise Verbiage](#customizing-devise-verbiage)
45
48
  * [Cross Origin Requests (CORS)](#cors)
46
49
  * [Usage Continued](#usage-cont)
47
50
  * [Mounting Routes](#mounting-routes)
@@ -162,6 +165,20 @@ The following settings are available for configuration in `config/initializers/d
162
165
  | **`default_password_reset_url`** | `nil` | By default this value is expected to be sent by the client so that the API knows where to redirect users after successful password resets. If this param is set, the API will redirect to this value when no value is provided by the cilent. |
163
166
  | **`redirect_whitelist`** | `nil` | As an added security measure, you can limit the URLs to which the API will redirect after email token validation (password reset, email confirmation, etc.). This value should be an array containing exact matches to the client URLs to be visited after validation. |
164
167
 
168
+ Additionally, you can configure other aspects of devise by manually creating the traditional devise.rb file at `config/initializers/devise.rb`. Here are some examples of what you can do in this file:
169
+
170
+ ~~~ruby
171
+ Devise.setup do |config|
172
+ # The e-mail address that mail will appear to be sent from
173
+ # If absent, mail is sent from "please-change-me-at-config-initializers-devise@example.com"
174
+ config.mailer_sender = "support@myapp.com"
175
+
176
+ # If using rails-api, you may want to tell devise to not use ActionDispatch::Flash
177
+ # middleware b/c rails-api does not include it.
178
+ # See: http://stackoverflow.com/q/19600905/806956
179
+ config.navigational_formats = [:json]
180
+ end
181
+ ~~~
165
182
 
166
183
  ## OmniAuth authentication
167
184
 
@@ -271,6 +288,21 @@ Rails.application.configure do
271
288
  end
272
289
  ~~~
273
290
 
291
+ If you wish to send custom e-mails instead of using the default devise templates, you can [do that too](#email-template-overrides).
292
+
293
+ ## Customizing Devise Verbiage
294
+ Devise Token Auth ships with intelligent default wording for everything you need. But that doesn't mean you can't make it more awesome. You can override the [devise defaults](https://github.com/plataformatec/devise/blob/master/config/locales/en.yml) by creating a YAML file at `config/locales/devise.en.yml` and assigning whatever custom values you want. For example, to customize the subject line of your devise e-mails, you could do this:
295
+
296
+ ~~~yaml
297
+ en:
298
+ devise:
299
+ mailer:
300
+ confirmation_instructions:
301
+ subject: "Please confirm your e-mail address"
302
+ reset_password_instructions:
303
+ subject: "Reset password request"
304
+ ~~~
305
+
274
306
  ## CORS
275
307
 
276
308
  If your API and client live on different domains, you will need to configure your Rails API to allow [cross origin requests](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing). The [rack-cors](https://github.com/cyu/rack-cors) gem can be used to accomplish this.
@@ -635,6 +667,45 @@ module Overrides
635
667
  end
636
668
  ~~~
637
669
 
670
+ ## Overriding rendering methods
671
+ To customize json rendering, implement the following protected controller methods, for success methods, assume that the @resource object is available:
672
+
673
+ ### Registrations Controller
674
+ * render_create_error_missing_confirm_success_url
675
+ * render_create_error_redirect_url_not_allowed
676
+ * render_create_success
677
+ * render_create_error
678
+ * render_create_error_email_already_exists
679
+ * render_update_success
680
+ * render_update_error
681
+ * render_update_error_user_not_found
682
+
683
+
684
+ ### Sessions Controller
685
+ * render_new_error
686
+ * render_create_success
687
+ * render_create_error_not_confirmed
688
+ * render_create_error_bad_credentials
689
+ * render_destroy_success
690
+ * render_destroy_error
691
+
692
+
693
+ ### Passwords Controller
694
+ * render_create_error_missing_email
695
+ * render_create_error_missing_redirect_url
696
+ * render_create_error_not_allowed_redirect_url
697
+ * render_create_success
698
+ * render_create_error
699
+ * render_update_error_unauthorized
700
+ * render_update_error_password_not_required
701
+ * render_update_error_missing_password
702
+ * render_update_success
703
+ * render_update_error
704
+
705
+ ### Token Validations Controller
706
+ * render_validate_token_success
707
+ * render_validate_token_error
708
+
638
709
  ##### Example: all :controller options with default settings:
639
710
 
640
711
  ~~~ruby
@@ -681,7 +752,7 @@ This will create two new files:
681
752
  * `app/views/devise/mailer/reset_password_instructions.html.erb`
682
753
  * `app/views/devise/mailer/confirmation_instructions.html.erb`
683
754
 
684
- These files may be edited to suit your taste.
755
+ These files may be edited to suit your taste. You can customize the e-mail subjects like [this](#customizing-devise-verbiage).
685
756
 
686
757
  **Note:** if you choose to modify these templates, do not modify the `link_to` blocks unless you absolutely know what you are doing.
687
758
 
@@ -851,7 +922,7 @@ To run just one test:
851
922
  2. Run `bundle install`
852
923
  3. Run `rake db:migrate`
853
924
  4. Run `RAILS_ENV=test rake db:migrate`
854
- 5. See this link for various ways to run a single file or a single test: http://flavio.castelli.name/2010/05/28/rails_execute_single_test/
925
+ 5. See this link for various ways to run a single file or a single test: http://flavio.castelli.name/2010/05/28/rails_execute_single_test/
855
926
 
856
927
  # License
857
928
  This project uses the WTFPL
@@ -2,6 +2,7 @@ module DeviseTokenAuth
2
2
  class ApplicationController < DeviseController
3
3
  include DeviseTokenAuth::Concerns::SetUserByToken
4
4
 
5
+ protected
5
6
 
6
7
  def resource_class(m=nil)
7
8
  if m
@@ -7,6 +7,8 @@ module DeviseTokenAuth::Concerns::SetUserByToken
7
7
  after_action :update_auth_header
8
8
  end
9
9
 
10
+ protected
11
+
10
12
  # keep track of request duration
11
13
  def set_request_start
12
14
  @request_started_at = Time.now
@@ -12,7 +12,7 @@ module DeviseTokenAuth
12
12
  # derive target redirect route from 'resource_class' param, which was set
13
13
  # before authentication.
14
14
  devise_mapping = request.env['omniauth.params']['resource_class'].underscore.to_sym
15
- redirect_route = "/#{Devise.mappings[devise_mapping].as_json["path"]}/#{params[:provider]}/callback"
15
+ redirect_route = "#{request.protocol}#{request.host_with_port}/#{Devise.mappings[devise_mapping].as_json["path"]}/#{params[:provider]}/callback"
16
16
 
17
17
  # preserve omniauth info for success route. ignore 'extra' in twitter
18
18
  # auth response to avoid CookieOverflow.
@@ -22,108 +22,6 @@ module DeviseTokenAuth
22
22
  redirect_to redirect_route
23
23
  end
24
24
 
25
- def get_resource_from_auth_hash
26
- # find or create user by provider and provider uid
27
- @resource = resource_class.where({
28
- uid: auth_hash['uid'],
29
- provider: auth_hash['provider']
30
- }).first_or_initialize
31
-
32
- if @resource.new_record?
33
- @oauth_registration = true
34
- set_random_password
35
- end
36
-
37
- # sync user info with provider, update/generate auth token
38
- assign_provider_attrs(@resource, auth_hash)
39
-
40
- # assign any additional (whitelisted) attributes
41
- extra_params = whitelisted_params
42
- @resource.assign_attributes(extra_params) if extra_params
43
-
44
- @resource
45
- end
46
-
47
- def set_random_password
48
- # set crazy password for new oauth users. this is only used to prevent
49
- # access via email sign-in.
50
- p = SecureRandom.urlsafe_base64(nil, false)
51
- @resource.password = p
52
- @resource.password_confirmation = p
53
- end
54
-
55
- def create_token_info
56
- # create token info
57
- @client_id = SecureRandom.urlsafe_base64(nil, false)
58
- @token = SecureRandom.urlsafe_base64(nil, false)
59
- @expiry = (Time.now + DeviseTokenAuth.token_lifespan).to_i
60
- @config = omniauth_params['config_name']
61
- end
62
-
63
- def create_auth_params
64
- @auth_params = {
65
- auth_token: @token,
66
- client_id: @client_id,
67
- uid: @resource.uid,
68
- expiry: @expiry,
69
- config: @config
70
- }
71
- @auth_params.merge!(oauth_registration: true) if @oauth_registration
72
- @auth_params
73
- end
74
-
75
- def set_token_on_resource
76
- @resource.tokens[@client_id] = {
77
- token: BCrypt::Password.create(@token),
78
- expiry: @expiry
79
- }
80
- end
81
-
82
- def render_data(message, data)
83
- @data = data.merge({
84
- message: message
85
- })
86
- render :layout => nil, :template => "devise_token_auth/omniauth_external_window"
87
- end
88
-
89
- def render_data_or_redirect(message, data)
90
-
91
- # We handle inAppBrowser and newWindow the same, but it is nice
92
- # to support values in case people need custom implementations for each case
93
- # (For example, nbrustein does not allow new users to be created if logging in with
94
- # an inAppBrowser)
95
- #
96
- # See app/views/devise_token_auth/omniauth_external_window.html.erb to understand
97
- # why we can handle these both the same. The view is setup to handle both cases
98
- # at the same time.
99
- if ['inAppBrowser', 'newWindow'].include?(omniauth_window_type)
100
- render_data(message, data)
101
-
102
- elsif auth_origin_url # default to same-window implementation, which forwards back to auth_origin_url
103
-
104
- # build and redirect to destination url
105
- redirect_to DeviseTokenAuth::Url.generate(auth_origin_url, data)
106
- else
107
-
108
- # there SHOULD always be an auth_origin_url, but if someone does something silly
109
- # like coming straight to this url or refreshing the page at the wrong time, there may not be one.
110
- # In that case, just render in plain text the error message if there is one or otherwise
111
- # a generic message.
112
- fallback_render data[:error] || 'An error occurred'
113
- end
114
- end
115
-
116
- def fallback_render(text)
117
- render inline: %Q|
118
-
119
- <html>
120
- <head></head>
121
- <body>
122
- #{text}
123
- </body>
124
- </html>|
125
- end
126
-
127
25
  def omniauth_success
128
26
  get_resource_from_auth_hash
129
27
  create_token_info
@@ -141,9 +39,40 @@ module DeviseTokenAuth
141
39
 
142
40
  yield if block_given?
143
41
 
144
- render_data_or_redirect('deliverCredentials', @resource.as_json.merge(@auth_params.as_json))
42
+ render_data_or_redirect('deliverCredentials', @auth_params.as_json, @resource.as_json)
43
+ end
44
+
45
+ def omniauth_failure
46
+ @error = params[:message]
47
+ render_data_or_redirect('authFailure', {error: @error})
145
48
  end
146
49
 
50
+ protected
51
+
52
+ # this will be determined differently depending on the action that calls
53
+ # it. redirect_callbacks is called upon returning from successful omniauth
54
+ # authentication, and the target params live in an omniauth-specific
55
+ # request.env variable. this variable is then persisted thru the redirect
56
+ # using our own dta.omniauth.params session var. the omniauth_success
57
+ # method will access that session var and then destroy it immediately
58
+ # after use. In the failure case, finally, the omniauth params
59
+ # are added as query params in our monkey patch to OmniAuth in engine.rb
60
+ def omniauth_params
61
+ if !defined?(@_omniauth_params)
62
+ if request.env['omniauth.params'] && request.env['omniauth.params'].any?
63
+ @_omniauth_params = request.env['omniauth.params']
64
+ elsif session['dta.omniauth.params'] && session['dta.omniauth.params'].any?
65
+ @_omniauth_params ||= session.delete('dta.omniauth.params')
66
+ @_omniauth_params
67
+ elsif params['omniauth_window_type']
68
+ @_omniauth_params = params.slice('omniauth_window_type', 'auth_origin_url', 'resource_class', 'origin')
69
+ else
70
+ @_omniauth_params = {}
71
+ end
72
+ end
73
+ @_omniauth_params
74
+
75
+ end
147
76
 
148
77
  # break out provider attribute assignment for easy method extension
149
78
  def assign_provider_attrs(user, auth_hash)
@@ -155,13 +84,6 @@ module DeviseTokenAuth
155
84
  })
156
85
  end
157
86
 
158
-
159
- def omniauth_failure
160
- @error = params[:message]
161
- render_data_or_redirect('authFailure', {error: @error})
162
- end
163
-
164
-
165
87
  # derive allowed params from the standard devise parameter sanitizer
166
88
  def whitelisted_params
167
89
  whitelist = devise_parameter_sanitizer.for(:sign_up)
@@ -189,31 +111,6 @@ module DeviseTokenAuth
189
111
  resource_class
190
112
  end
191
113
 
192
- # this will be determined differently depending on the action that calls
193
- # it. redirect_callbacks is called upon returning from successful omniauth
194
- # authentication, and the target params live in an omniauth-specific
195
- # request.env variable. this variable is then persisted thru the redirect
196
- # using our own dta.omniauth.params session var. the omniauth_success
197
- # method will access that session var and then destroy it immediately
198
- # after use. In the failure case, finally, the omniauth params
199
- # are added as query params in our monkey patch to OmniAuth in engine.rb
200
- def omniauth_params
201
- if !defined?(@_omniauth_params)
202
- if request.env['omniauth.params'] && request.env['omniauth.params'].any?
203
- @_omniauth_params = request.env['omniauth.params']
204
- elsif session['dta.omniauth.params'] && session['dta.omniauth.params'].any?
205
- @_omniauth_params ||= session.delete('dta.omniauth.params')
206
- @_omniauth_params
207
- elsif params['omniauth_window_type']
208
- @_omniauth_params = params.slice('omniauth_window_type', 'auth_origin_url', 'resource_class', 'origin')
209
- else
210
- @_omniauth_params = {}
211
- end
212
- end
213
- @_omniauth_params
214
-
215
- end
216
-
217
114
  def omniauth_window_type
218
115
  omniauth_params['omniauth_window_type']
219
116
  end
@@ -251,5 +148,107 @@ module DeviseTokenAuth
251
148
  end
252
149
  end
253
150
 
151
+ def set_random_password
152
+ # set crazy password for new oauth users. this is only used to prevent
153
+ # access via email sign-in.
154
+ p = SecureRandom.urlsafe_base64(nil, false)
155
+ @resource.password = p
156
+ @resource.password_confirmation = p
157
+ end
158
+
159
+ def create_token_info
160
+ # create token info
161
+ @client_id = SecureRandom.urlsafe_base64(nil, false)
162
+ @token = SecureRandom.urlsafe_base64(nil, false)
163
+ @expiry = (Time.now + DeviseTokenAuth.token_lifespan).to_i
164
+ @config = omniauth_params['config_name']
165
+ end
166
+
167
+ def create_auth_params
168
+ @auth_params = {
169
+ auth_token: @token,
170
+ client_id: @client_id,
171
+ uid: @resource.uid,
172
+ expiry: @expiry,
173
+ config: @config
174
+ }
175
+ @auth_params.merge!(oauth_registration: true) if @oauth_registration
176
+ @auth_params
177
+ end
178
+
179
+ def set_token_on_resource
180
+ @resource.tokens[@client_id] = {
181
+ token: BCrypt::Password.create(@token),
182
+ expiry: @expiry
183
+ }
184
+ end
185
+
186
+ def render_data(message, data)
187
+ @data = data.merge({
188
+ message: message
189
+ })
190
+ render :layout => nil, :template => "devise_token_auth/omniauth_external_window"
191
+ end
192
+
193
+ def render_data_or_redirect(message, data, user_data = {})
194
+
195
+ # We handle inAppBrowser and newWindow the same, but it is nice
196
+ # to support values in case people need custom implementations for each case
197
+ # (For example, nbrustein does not allow new users to be created if logging in with
198
+ # an inAppBrowser)
199
+ #
200
+ # See app/views/devise_token_auth/omniauth_external_window.html.erb to understand
201
+ # why we can handle these both the same. The view is setup to handle both cases
202
+ # at the same time.
203
+ if ['inAppBrowser', 'newWindow'].include?(omniauth_window_type)
204
+ render_data(message, user_data.merge(data))
205
+
206
+ elsif auth_origin_url # default to same-window implementation, which forwards back to auth_origin_url
207
+
208
+ # build and redirect to destination url
209
+ redirect_to DeviseTokenAuth::Url.generate(auth_origin_url, data)
210
+ else
211
+
212
+ # there SHOULD always be an auth_origin_url, but if someone does something silly
213
+ # like coming straight to this url or refreshing the page at the wrong time, there may not be one.
214
+ # In that case, just render in plain text the error message if there is one or otherwise
215
+ # a generic message.
216
+ fallback_render data[:error] || 'An error occurred'
217
+ end
218
+ end
219
+
220
+ def fallback_render(text)
221
+ render inline: %Q|
222
+
223
+ <html>
224
+ <head></head>
225
+ <body>
226
+ #{text}
227
+ </body>
228
+ </html>|
229
+ end
230
+
231
+ def get_resource_from_auth_hash
232
+ # find or create user by provider and provider uid
233
+ @resource = resource_class.where({
234
+ uid: auth_hash['uid'],
235
+ provider: auth_hash['provider']
236
+ }).first_or_initialize
237
+
238
+ if @resource.new_record?
239
+ @oauth_registration = true
240
+ set_random_password
241
+ end
242
+
243
+ # sync user info with provider, update/generate auth token
244
+ assign_provider_attrs(@resource, auth_hash)
245
+
246
+ # assign any additional (whitelisted) attributes
247
+ extra_params = whitelisted_params
248
+ @resource.assign_attributes(extra_params) if extra_params
249
+
250
+ @resource
251
+ end
252
+
254
253
  end
255
254
  end