devise_token_auth 0.1.28 → 0.1.29.beta1

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 (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