devise_token_auth 0.1.28 → 0.1.29.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +61 -1
  3. data/app/controllers/devise_token_auth/{auth_controller.rb → omniauth_callbacks_controller.rb} +22 -33
  4. data/app/controllers/devise_token_auth/registrations_controller.rb +2 -0
  5. data/app/controllers/devise_token_auth/sessions_controller.rb +1 -1
  6. data/app/controllers/devise_token_auth/token_validations_controller.rb +23 -0
  7. data/app/models/devise_token_auth/concerns/user.rb +1 -3
  8. data/config/initializers/devise.rb +0 -9
  9. data/config/routes.rb +12 -1
  10. data/lib/devise_token_auth/engine.rb +8 -0
  11. data/lib/devise_token_auth/rails/routes.rb +30 -9
  12. data/lib/devise_token_auth/version.rb +1 -1
  13. data/lib/generators/devise_token_auth/templates/devise_token_auth_create_users.rb.erb +0 -2
  14. data/test/controllers/devise_token_auth/{auth_controller_test.rb → omniauth_callbacks_controller_test.rb} +4 -4
  15. data/test/controllers/devise_token_auth/registrations_controller_test.rb +6 -0
  16. data/test/controllers/overrides/confirmations_controller_test.rb +44 -0
  17. data/test/controllers/overrides/omniauth_callbacks_controller_test.rb +44 -0
  18. data/test/controllers/overrides/passwords_controller_test.rb +62 -0
  19. data/test/controllers/overrides/registrations_controller_test.rb +40 -0
  20. data/test/controllers/overrides/sessions_controller_test.rb +33 -0
  21. data/test/controllers/overrides/token_validations_controller_test.rb +38 -0
  22. data/test/dummy/app/controllers/overrides/confirmations_controller.rb +32 -0
  23. data/test/dummy/app/controllers/overrides/omniauth_callbacks_controller.rb +14 -0
  24. data/test/dummy/app/controllers/overrides/passwords_controller.rb +39 -0
  25. data/test/dummy/app/controllers/overrides/registrations_controller.rb +27 -0
  26. data/test/dummy/app/controllers/overrides/sessions_controller.rb +43 -0
  27. data/test/dummy/app/controllers/overrides/token_validations_controller.rb +23 -0
  28. data/test/dummy/{tmp/generators/app/models/mang.rb → app/models/evil_user.rb} +1 -1
  29. data/test/dummy/config/routes.rb +9 -0
  30. data/test/dummy/db/development.sqlite3 +0 -0
  31. data/test/dummy/{tmp/generators/db/migrate/20140924174608_devise_token_auth_create_mangs.rb → db/migrate/20140928231203_devise_token_auth_create_evil_users.rb} +10 -9
  32. data/test/dummy/db/schema.rb +33 -1
  33. data/test/dummy/db/test.sqlite3 +0 -0
  34. data/test/dummy/log/development.log +437 -0
  35. data/test/dummy/log/test.log +72703 -0
  36. data/test/dummy/tmp/generators/config/routes.rb +0 -5
  37. data/test/dummy/tmp/generators/db/migrate/{20140924174608_devise_token_auth_create_users.rb → 20140930001137_devise_token_auth_create_users.rb} +0 -2
  38. data/test/fixtures/evil_users.yml +29 -0
  39. data/test/fixtures/mangs.yml +0 -2
  40. data/test/fixtures/users.yml +0 -2
  41. metadata +40 -13
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5a97968a706152912c6f7d8357340e0e6885ba6a
4
- data.tar.gz: 476575b95c813c9af74617898a3dee647ced5d76
3
+ metadata.gz: 27aae401ac1cd56896e88990fafd43722ae0874d
4
+ data.tar.gz: 641556555fefe2509adf75b29125a94abb9ca14a
5
5
  SHA512:
6
- metadata.gz: 3a5344cdc51f5691c5711463e865acf2ff53e18588a9ae99d0c244b15c5addf3267ef32cc68368778da8aca27aeaea5a2b79dab67ba7973317ba0264d84b290d
7
- data.tar.gz: ba19c67607c5d8b06e5695ecf60763bdcd6c012e7b1183f8bae309e5dcddc6193cbfc5d37e97a2dbc9c2d1b630e559e51a11612de6909024f7e0114027a0a3fd
6
+ metadata.gz: a439fc3a695c0aeec35b4a15b9c5da795fa66ceffe917d03a3b9da79ebe713b59a742af02911f0bd0d301a79f6c5785c101dda0ea15fc93dc44b7614e556fb76
7
+ data.tar.gz: f6e51f041bee6233ffa21a92888fc62fcd1be9fd871bc233c946e2735b3745e3f0a0d640ba7eb26ab486eea759d49acdf8ab108e6b268412bcbf73b10826d581
data/README.md CHANGED
@@ -42,6 +42,7 @@ The fully configured api used in the demo can be found [here](https://github.com
42
42
  * [Controller Integration](#controller-concerns)
43
43
  * [Model Integration](#model-concerns)
44
44
  * [Using Multiple User Classes](#using-multiple-models)
45
+ * [Custom Controller Overrides](#custom-controller-overrides)
45
46
  * [Conceptual Diagrams](#conceptual)
46
47
  * [Token Management](#about-token-management)
47
48
  * [Batch Requests](#about-batch-requests)
@@ -75,12 +76,18 @@ You will need to create a [user model](#model-concerns), [define routes](#mounti
75
76
  rails g devise_token_auth:install [USER_CLASS] [MOUNT_PATH]
76
77
  ~~~
77
78
 
79
+ **Example**:
80
+
81
+ ~~~bash
82
+ rails g devise_token_auth:install User /auth
83
+ ~~~
84
+
78
85
  This generator accepts the following optional arguments:
79
86
 
80
87
  | Argument | Default | Description |
81
88
  |---|---|---|
82
89
  | USER_CLASS | `User` | The name of the class to use for user authentication. |
83
- | MOUNT_PATH | `auth` | The path at which to mount the authentication routes. [Read more](#usage). |
90
+ | MOUNT_PATH | `/auth` | The path at which to mount the authentication routes. [Read more](#usage). |
84
91
 
85
92
  The following events will take place when using the install generator:
86
93
 
@@ -498,6 +505,59 @@ In the above example, the following methods will be available (in addition to `c
498
505
  * `current_member`
499
506
  * `member_signed_in?`
500
507
 
508
+ ## Custom Controller Overrides
509
+
510
+ The built-in controllers can be overridden with your own custom controllers.
511
+
512
+ For example, the default behavior of the [`validate_token`](https://github.com/lynndylanhurley/devise_token_auth/blob/8a33d25deaedb4809b219e557e82ec7ec61bf940/app/controllers/devise_token_auth/token_validations_controller.rb#L6) method of the [`TokenValidationController`](https://github.com/lynndylanhurley/devise_token_auth/blob/8a33d25deaedb4809b219e557e82ec7ec61bf940/app/controllers/devise_token_auth/token_validations_controller.rb) is to return the `User` object as json (sans password and token data). The following example shows how to override the `validate_token` action to include a model method as well.
513
+
514
+ ##### Example: controller overrides
515
+
516
+ ~~~ruby
517
+ # config/routes.rb
518
+ Rails.application.routes.draw do
519
+ ...
520
+ mount_devise_token_auth_for 'User', at: '/auth', controllers: {
521
+ token_validations: 'overrides/token_validations'
522
+ }
523
+ end
524
+
525
+ # app/controllers/overrides/token_validations_controller.rb
526
+ module Overrides
527
+ class TokenValidationsController < DeviseTokenAuth::TokenValidationsController
528
+
529
+ def validate_token
530
+ # @user will have been set by set_user_by_token concern
531
+ if @user
532
+ render json: {
533
+ data: @user.as_json(methods: :calculate_operating_thetan)
534
+ }
535
+ else
536
+ render json: {
537
+ success: false,
538
+ errors: ["Invalid login credentials"]
539
+ }, status: 401
540
+ end
541
+ end
542
+ end
543
+ end
544
+ ~~~
545
+
546
+ ##### Example: all :controller options with default settings:
547
+
548
+ ~~~ruby
549
+ mount_devise_token_auth_for 'User', at: '/auth', controllers: {
550
+ confirmations: 'devise_token_auth/confirmations',
551
+ passwords: 'devise_token_auth/passwords',
552
+ omniauth_callbacks: 'devise_token_auth/omniauth_callbacks',
553
+ registrations: 'devise_token_auth/registrations',
554
+ sessions: 'devise_token_auth/sessions',
555
+ token_validations: 'devise_token_auth/token_validations'
556
+ }
557
+ ~~~
558
+
559
+ **Note:** Controller overrides must implement the expected actions of the controllers that they replace.
560
+
501
561
  # Conceptual
502
562
 
503
563
  None of the following information is required to use this gem, but read on if you're curious.
@@ -1,25 +1,6 @@
1
1
  module DeviseTokenAuth
2
- class AuthController < DeviseTokenAuth::ApplicationController
2
+ class OmniauthCallbacksController < DeviseTokenAuth::ApplicationController
3
3
  skip_after_filter :update_auth_header, :only => [:omniauth_success, :omniauth_failure]
4
- skip_before_filter :assert_is_devise_resource!, :only => [:validate_token]
5
- before_filter :set_user_by_token, :only => [:validate_token]
6
-
7
- def validate_token
8
- # @user will have been set by set_user_token concern
9
- if @user
10
- render json: {
11
- success: true,
12
- data: @user.as_json(except: [
13
- :tokens, :confirm_success_url, :reset_password_redirect_url, :created_at, :updated_at
14
- ])
15
- }
16
- else
17
- render json: {
18
- success: false,
19
- errors: ["Invalid login credentials"]
20
- }, status: 401
21
- end
22
- end
23
4
 
24
5
  def omniauth_success
25
6
  # find or create user by provider and provider uid
@@ -32,7 +13,7 @@ module DeviseTokenAuth
32
13
  @client_id = SecureRandom.urlsafe_base64(nil, false)
33
14
  @token = SecureRandom.urlsafe_base64(nil, false)
34
15
 
35
- @auth_origin_url = generate_url(request.env['omniauth.params']['auth_origin_url'], {
16
+ @auth_origin_url = generate_url(auth_params['auth_origin_url'], {
36
17
  token: @token,
37
18
  client_id: @client_id,
38
19
  uid: @user.uid
@@ -52,12 +33,7 @@ module DeviseTokenAuth
52
33
  }
53
34
 
54
35
  # sync user info with provider, update/generate auth token
55
- @user.assign_attributes({
56
- nickname: auth_hash['info']['nickname'],
57
- name: auth_hash['info']['name'],
58
- image: auth_hash['info']['image'],
59
- email: auth_hash['info']['email']
60
- })
36
+ assign_provider_attrs(@user, auth_hash)
61
37
 
62
38
  # assign any additional (whitelisted) attributes
63
39
  extra_params = whitelisted_params
@@ -74,6 +50,15 @@ module DeviseTokenAuth
74
50
  end
75
51
  end
76
52
 
53
+ def assign_provider_attrs(user, auth_hash)
54
+ user.assign_attributes({
55
+ nickname: auth_hash['info']['nickname'],
56
+ name: auth_hash['info']['name'],
57
+ image: auth_hash['info']['image'],
58
+ email: auth_hash['info']['email']
59
+ })
60
+ end
61
+
77
62
  def omniauth_failure
78
63
  @error = params[:message]
79
64
 
@@ -83,14 +68,18 @@ module DeviseTokenAuth
83
68
  end
84
69
 
85
70
  def auth_hash
86
- request.env['omniauth.auth']
71
+ params["auth_hash"]
72
+ end
73
+
74
+ def auth_params
75
+ params["auth_params"]
87
76
  end
88
77
 
89
78
  def whitelisted_params
90
79
  whitelist = devise_parameter_sanitizer.for(:sign_up)
91
80
 
92
81
  whitelist.inject({}){|coll, key|
93
- param = request.env['omniauth.params'][key.to_s]
82
+ param = auth_params[key.to_s]
94
83
  if param
95
84
  coll[key] = param
96
85
  end
@@ -104,8 +93,8 @@ module DeviseTokenAuth
104
93
 
105
94
  # pull resource class from omniauth return
106
95
  def resource_name
107
- if request.env['omniauth.params']
108
- request.env['omniauth.params']['resource_class'].constantize
96
+ if auth_params
97
+ auth_params['resource_class'].constantize
109
98
  else
110
99
  super
111
100
  end
@@ -113,8 +102,8 @@ module DeviseTokenAuth
113
102
 
114
103
  # necessary for access to devise_parameter_sanitizers
115
104
  def devise_mapping
116
- if request.env['omniauth.params']
117
- Devise.mappings[request.env['omniauth.params']['resource_class'].underscore.to_sym]
105
+ if auth_params
106
+ Devise.mappings[auth_params['resource_class'].underscore.to_sym]
118
107
  else
119
108
  request.env['devise.mapping']
120
109
  end
@@ -20,6 +20,8 @@ module DeviseTokenAuth
20
20
  end
21
21
 
22
22
  begin
23
+ # override email confirmation, must be sent manually from ctrl
24
+ User.skip_callback("create", :after, :send_on_create_confirmation_instructions)
23
25
  if @resource.save
24
26
  @resource.send_confirmation_instructions({
25
27
  client_config: params[:config_name],
@@ -19,7 +19,7 @@ module DeviseTokenAuth
19
19
 
20
20
  render json: {
21
21
  data: @user.as_json(except: [
22
- :tokens, :confirm_success_url, :reset_password_redirect_url, :created_at, :updated_at
22
+ :tokens, :created_at, :updated_at
23
23
  ])
24
24
  }
25
25
 
@@ -0,0 +1,23 @@
1
+ module DeviseTokenAuth
2
+ class TokenValidationsController < DeviseTokenAuth::ApplicationController
3
+ skip_before_filter :assert_is_devise_resource!, :only => [:validate_token]
4
+ before_filter :set_user_by_token, :only => [:validate_token]
5
+
6
+ def validate_token
7
+ # @user will have been set by set_user_token concern
8
+ if @user
9
+ render json: {
10
+ success: true,
11
+ data: @user.as_json(except: [
12
+ :tokens, :created_at, :updated_at
13
+ ])
14
+ }
15
+ else
16
+ render json: {
17
+ success: false,
18
+ errors: ["Invalid login credentials"]
19
+ }, status: 401
20
+ end
21
+ end
22
+ end
23
+ end
@@ -6,7 +6,7 @@ module DeviseTokenAuth::Concerns::User
6
6
  # :confirmable, :lockable, :timeoutable and :omniauthable
7
7
  devise :database_authenticatable, :registerable,
8
8
  :recoverable, :rememberable, :trackable, :validatable,
9
- :confirmable
9
+ :confirmable, :omniauthable
10
10
 
11
11
  serialize :tokens, JSON
12
12
 
@@ -48,7 +48,6 @@ module DeviseTokenAuth::Concerns::User
48
48
  send_devise_notification(:confirmation_instructions, @raw_confirmation_token, opts)
49
49
  end
50
50
 
51
-
52
51
  # override devise method to include additional info as opts hash
53
52
  def send_reset_password_instructions(opts=nil)
54
53
  token = set_reset_password_token
@@ -71,7 +70,6 @@ module DeviseTokenAuth::Concerns::User
71
70
  end
72
71
 
73
72
 
74
-
75
73
  def valid_token?(token, client_id='default')
76
74
  client_id ||= 'default'
77
75
 
@@ -201,12 +201,3 @@ Devise.setup do |config|
201
201
  end
202
202
  end
203
203
  end
204
-
205
-
206
- #module Devise::Mailers::Helpers
207
- #protected
208
-
209
- #def headers_for
210
-
211
- #end
212
- #end
data/config/routes.rb CHANGED
@@ -1,5 +1,16 @@
1
1
  Rails.application.routes.draw do
2
2
  if defined?(::OmniAuth)
3
- get "#{::OmniAuth::config.path_prefix}/:provider/callback", to: 'devise_token_auth/auth#omniauth_success'
3
+ match "#{::OmniAuth::config.path_prefix}/:provider/callback", to: redirect {|params, request|
4
+ devise_mapping = request.env['omniauth.params']['resource_class'].underscore.to_sym
5
+ mount_point = Devise.mappings[devise_mapping].as_json["path_prefix"]
6
+
7
+ qs = {
8
+ auth_hash: request.env['omniauth.auth'],
9
+ auth_params: request.env['omniauth.params']
10
+ }.to_query
11
+
12
+ "#{mount_point}/#{params[:provider]}/callback?#{qs}"
13
+ }, via: :all
4
14
  end
15
+
5
16
  end
@@ -7,6 +7,14 @@ module DeviseTokenAuth
7
7
  initializer "devise_token_auth.url_helpers" do
8
8
  Devise.helpers << DeviseTokenAuth::Controllers::Helpers
9
9
  end
10
+
11
+ initializer "devise_token_auth.omniauth_strategy" do
12
+ if defined?(::OmniAuth)
13
+ Devise.with_options model: true do |d|
14
+ d.add_module(:dta_omniauthable, controller: :omniauth_callbacks, route: :omniauth_callbacks)
15
+ end
16
+ end
17
+ end
10
18
  end
11
19
 
12
20
  mattr_accessor :change_headers_on_each_request,
@@ -1,22 +1,43 @@
1
1
  module ActionDispatch::Routing
2
2
  class Mapper
3
3
  def mount_devise_token_auth_for(resource, opts)
4
+ # ensure objects exist to simplify attr checks
5
+ opts[:controllers] ||= {}
6
+ opts[:skip] ||= []
7
+
8
+ # check for ctrl overrides, fall back to defaults
9
+ sessions_ctrl = opts[:controllers][:sessions] || "devise_token_auth/sessions"
10
+ registrations_ctrl = opts[:controllers][:registrations] || "devise_token_auth/registrations"
11
+ passwords_ctrl = opts[:controllers][:passwords] || "devise_token_auth/passwords"
12
+ confirmations_ctrl = opts[:controllers][:confirmations] || "devise_token_auth/confirmations"
13
+ token_validations_ctrl = opts[:controllers][:token_validations] || "devise_token_auth/token_validations"
14
+ omniauth_ctrl = opts[:controllers][:omniauth_callbacks] || "devise_token_auth/omniauth_callbacks"
15
+
16
+ # define devise controller mappings
17
+ controllers = {:sessions => sessions_ctrl,
18
+ :registrations => registrations_ctrl,
19
+ :passwords => passwords_ctrl,
20
+ :confirmations => confirmations_ctrl,
21
+ :omniauth_callbacks => omniauth_ctrl}
22
+
23
+ # remove any unwanted devise modules
24
+ opts[:skip].each{|item| controllers.delete(item)}
25
+
4
26
  scope opts[:at] do
5
27
  devise_for resource.pluralize.underscore.to_sym,
6
28
  :class_name => resource,
7
29
  :module => :devise,
8
30
  :path => "",
9
- :controllers => {:sessions => "devise_token_auth/sessions",
10
- :registrations => "devise_token_auth/registrations",
11
- :passwords => "devise_token_auth/passwords",
12
- :confirmations => "devise_token_auth/confirmations"}
31
+ :controllers => controllers
13
32
 
14
33
  devise_scope resource.underscore.to_sym do
15
- get "validate_token", to: "devise_token_auth/auth#validate_token"
16
- if defined?(::OmniAuth)
17
- get "failure", to: "devise_token_auth/auth#omniauth_failure"
18
- get ":provider/callback", to: "devise_token_auth/auth#omniauth_success"
19
- post ":provider/callback", to: "devise_token_auth/auth#omniauth_success"
34
+ # path to verify token validity
35
+ get "validate_token", to: "#{token_validations_ctrl}#validate_token"
36
+
37
+ # omniauth routes. only define if omniauth is installed and not skipped.
38
+ if defined?(::OmniAuth) and not opts[:skip].include?(:omniauth_callbacks)
39
+ get "failure", to: "#{omniauth_ctrl}#omniauth_failure"
40
+ get ":provider/callback", to: "#{omniauth_ctrl}#omniauth_success"
20
41
 
21
42
  # preserve the resource class thru oauth authentication by setting name of
22
43
  # resource as "resource_class" param
@@ -1,3 +1,3 @@
1
1
  module DeviseTokenAuth
2
- VERSION = "0.1.28"
2
+ VERSION = "0.1.29.beta1"
3
3
  end
@@ -8,7 +8,6 @@ class DeviseTokenAuthCreate<%= user_class.pluralize %> < ActiveRecord::Migration
8
8
  ## Recoverable
9
9
  t.string :reset_password_token
10
10
  t.datetime :reset_password_sent_at
11
- t.string :reset_password_redirect_url
12
11
 
13
12
  ## Rememberable
14
13
  t.datetime :remember_created_at
@@ -24,7 +23,6 @@ class DeviseTokenAuthCreate<%= user_class.pluralize %> < ActiveRecord::Migration
24
23
  t.string :confirmation_token
25
24
  t.datetime :confirmed_at
26
25
  t.datetime :confirmation_sent_at
27
- t.string :confirm_success_url
28
26
  t.string :unconfirmed_email # Only if using reconfirmable
29
27
 
30
28
  ## Lockable
@@ -38,11 +38,11 @@ class OmniauthTest < ActionDispatch::IntegrationTest
38
38
  end
39
39
 
40
40
  test 'request should determine the correct resource_class' do
41
- assert_equal 'User', request.env['omniauth.params']['resource_class']
41
+ assert_equal 'User', controller.auth_params['resource_class']
42
42
  end
43
43
 
44
44
  test 'request should pass correct redirect_url' do
45
- assert_equal @redirect_url, request.env['omniauth.params']['auth_origin_url']
45
+ assert_equal @redirect_url, controller.auth_params['auth_origin_url']
46
46
  end
47
47
 
48
48
  test 'user should have been created' do
@@ -116,11 +116,11 @@ class OmniauthTest < ActionDispatch::IntegrationTest
116
116
  end
117
117
 
118
118
  test 'request should determine the correct resource_class' do
119
- assert_equal 'Mang', request.env['omniauth.params']['resource_class']
119
+ assert_equal 'Mang', controller.auth_params['resource_class']
120
120
  end
121
121
 
122
122
  test 'request should pass correct redirect_url' do
123
- assert_equal @redirect_url, request.env['omniauth.params']['auth_origin_url']
123
+ assert_equal @redirect_url, controller.auth_params['auth_origin_url']
124
124
  end
125
125
 
126
126
  test 'user should have been created' do
@@ -10,6 +10,8 @@ class DeviseTokenAuth::RegistrationsControllerTest < ActionController::TestCase
10
10
  describe DeviseTokenAuth::RegistrationsController do
11
11
  describe "Successful registration" do
12
12
  before do
13
+ @mails_sent = ActionMailer::Base.deliveries.count
14
+
13
15
  xhr :post, :create, {
14
16
  email: Faker::Internet.email,
15
17
  password: "secret123",
@@ -46,6 +48,10 @@ class DeviseTokenAuth::RegistrationsControllerTest < ActionController::TestCase
46
48
  test "new user password should not be returned" do
47
49
  assert_nil @data['data']['password']
48
50
  end
51
+
52
+ test "only one email was sent" do
53
+ assert_equal @mails_sent + 1, ActionMailer::Base.deliveries.count
54
+ end
49
55
  end
50
56
 
51
57
  describe "Adding extra params" do