devise-token_authenticatable 0.1.0.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.
- data/.gitignore +21 -0
- data/Gemfile +4 -0
- data/LICENSE +20 -0
- data/README.md +31 -0
- data/Rakefile +1 -0
- data/devise-token_authenticatable.gemspec +36 -0
- data/lib/devise-token_authenticatable.rb +1 -0
- data/lib/devise/token_authenticatable.rb +27 -0
- data/lib/devise/token_authenticatable/model.rb +90 -0
- data/lib/devise/token_authenticatable/strategy.rb +102 -0
- data/lib/devise/token_authenticatable/version.rb +5 -0
- data/spec/factories/admin.rb +24 -0
- data/spec/factories/user.rb +25 -0
- data/spec/models/devise/token_authenticatable/model_spec.rb +79 -0
- data/spec/requests/devise/token_authenticatable/strategy_spec.rb +340 -0
- data/spec/spec_helper.rb +42 -0
- data/spec/support/helpers.rb +33 -0
- data/spec/support/integration.rb +8 -0
- data/spec/support/rails_app.rb +19 -0
- data/spec/support/rails_app/Rakefile +6 -0
- data/spec/support/rails_app/app/controllers/admins/sessions_controller.rb +6 -0
- data/spec/support/rails_app/app/controllers/admins_controller.rb +11 -0
- data/spec/support/rails_app/app/controllers/application_controller.rb +9 -0
- data/spec/support/rails_app/app/controllers/home_controller.rb +25 -0
- data/spec/support/rails_app/app/controllers/publisher/registrations_controller.rb +2 -0
- data/spec/support/rails_app/app/controllers/publisher/sessions_controller.rb +2 -0
- data/spec/support/rails_app/app/controllers/users_controller.rb +31 -0
- data/spec/support/rails_app/app/mailers/users/mailer.rb +12 -0
- data/spec/support/rails_app/app/models/admin.rb +9 -0
- data/spec/support/rails_app/app/models/user.rb +25 -0
- data/spec/support/rails_app/app/views/users/index.html.erb +1 -0
- data/spec/support/rails_app/config.ru +4 -0
- data/spec/support/rails_app/config/database.yml +11 -0
- data/spec/support/rails_app/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/support/rails_app/config/initializers/devise.rb +173 -0
- data/spec/support/rails_app/config/initializers/inflections.rb +2 -0
- data/spec/support/rails_app/config/initializers/secret_token.rb +4 -0
- data/spec/support/rails_app/config/routes.rb +104 -0
- data/spec/support/rails_app/db/migrate/20100401102949_create_tables.rb +74 -0
- data/spec/support/rails_app/db/schema.rb +52 -0
- data/spec/support/rails_app/public/404.html +26 -0
- data/spec/support/rails_app/public/422.html +26 -0
- data/spec/support/rails_app/public/500.html +26 -0
- data/spec/support/rails_app/public/favicon.ico +0 -0
- data/spec/support/session_helper.rb +27 -0
- metadata +289 -0
data/.gitignore
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
*.log
|
4
|
+
.bundle
|
5
|
+
.config
|
6
|
+
.rspec
|
7
|
+
.rspec-local
|
8
|
+
.ruby-version
|
9
|
+
.yardoc
|
10
|
+
Gemfile.lock
|
11
|
+
InstalledFiles
|
12
|
+
_yardoc
|
13
|
+
coverage
|
14
|
+
doc/
|
15
|
+
lib/bundler/man
|
16
|
+
pkg
|
17
|
+
rdoc
|
18
|
+
spec/reports
|
19
|
+
test/tmp
|
20
|
+
test/version_tmp
|
21
|
+
tmp
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2013 Sebastian Oelke
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# Devise::TokenAuthenticatable
|
2
|
+
|
3
|
+
**Note that this gem is not ready for usage, yet!**
|
4
|
+
|
5
|
+
TODO: Write a gem description
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'devise-token_authenticatable'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install devise-token_authenticatable
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
TODO: Write usage instructions here
|
24
|
+
|
25
|
+
## Contributing
|
26
|
+
|
27
|
+
1. Fork it
|
28
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
29
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
30
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
31
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'devise/token_authenticatable/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "devise-token_authenticatable"
|
8
|
+
spec.version = Devise::TokenAuthenticatable::VERSION.dup
|
9
|
+
spec.platform = Gem::Platform::RUBY
|
10
|
+
spec.authors = ["Sebastian Oelke"]
|
11
|
+
spec.email = ["dev@sohleeatsworld.de"]
|
12
|
+
spec.description = %q{This gem provides the extracted Token Authenticatable module of devise.
|
13
|
+
It enables the user to sign in via an authentication token. This token
|
14
|
+
can be given via a query string or HTTP Basic Authentication.}
|
15
|
+
spec.summary = %q{Provides authentication based on an authentication token for devise 3.2 and up.}
|
16
|
+
spec.homepage = "https://github.com/baschtl/devise-token_authenticatable"
|
17
|
+
spec.license = "MIT"
|
18
|
+
|
19
|
+
spec.files = `git ls-files`.split($/)
|
20
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
21
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
22
|
+
spec.require_paths = ["lib"]
|
23
|
+
|
24
|
+
|
25
|
+
spec.add_dependency "devise", "~> 3.2.0"
|
26
|
+
|
27
|
+
spec.add_development_dependency "activerecord", ">= 3.2"
|
28
|
+
spec.add_development_dependency "actionmailer", ">= 3.2"
|
29
|
+
spec.add_development_dependency "rspec-rails"
|
30
|
+
spec.add_development_dependency "pry"
|
31
|
+
spec.add_development_dependency "factory_girl_rails"
|
32
|
+
spec.add_development_dependency "timecop"
|
33
|
+
spec.add_development_dependency "sqlite3", "~> 1.3"
|
34
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
35
|
+
spec.add_development_dependency "rake"
|
36
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'devise/token_authenticatable'
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "devise/token_authenticatable/strategy"
|
2
|
+
|
3
|
+
module Devise
|
4
|
+
module TokenAuthenticatable
|
5
|
+
|
6
|
+
# Authentication token params key name of choice. E.g. /users/sign_in?some_key=...
|
7
|
+
mattr_accessor :token_authentication_key
|
8
|
+
@@token_authentication_key = :auth_token
|
9
|
+
|
10
|
+
# Enable the configuration of the TokenAuthenticatable
|
11
|
+
# strategy with a block:
|
12
|
+
#
|
13
|
+
# Devise::TokenAuthenticatable.setup do |config|
|
14
|
+
# config.token_authentication_key = :other_key
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
def self.setup
|
18
|
+
yield self
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Register TokenAuthenticatable module in Devise.
|
24
|
+
Devise::add_module :token_authenticatable,
|
25
|
+
model: 'devise/token_authenticatable/model',
|
26
|
+
strategy: true,
|
27
|
+
no_input: true
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module Devise
|
2
|
+
module Models
|
3
|
+
# The TokenAuthenticatable module is responsible for generating an authentication token and
|
4
|
+
# validating the authenticity of the same while signing in.
|
5
|
+
#
|
6
|
+
# This module only provides a few helpers to help you manage the token, but it is up to you
|
7
|
+
# to choose how to use it. For example, if you want to have a new token every time the user
|
8
|
+
# saves his account, you can do the following:
|
9
|
+
#
|
10
|
+
# before_save :reset_authentication_token
|
11
|
+
#
|
12
|
+
# On the other hand, if you want to generate token unless one exists, you should use instead:
|
13
|
+
#
|
14
|
+
# before_save :ensure_authentication_token
|
15
|
+
#
|
16
|
+
# If you want to delete the token after it is used, you can do so in the
|
17
|
+
# after_token_authentication callback.
|
18
|
+
#
|
19
|
+
# == APIs
|
20
|
+
#
|
21
|
+
# If you are using token authentication with APIs and using trackable. Every
|
22
|
+
# request will be considered as a new sign in (since there is no session in
|
23
|
+
# APIs). You can disable this by creating a before filter as follow:
|
24
|
+
#
|
25
|
+
# before_filter :skip_trackable
|
26
|
+
#
|
27
|
+
# def skip_trackable
|
28
|
+
# request.env['devise.skip_trackable'] = true
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# == Options
|
32
|
+
#
|
33
|
+
# TokenAuthenticatable adds the following options to devise_for:
|
34
|
+
#
|
35
|
+
# * +token_authentication_key+: Defines name of the authentication token params key. E.g. /users/sign_in?some_key=...
|
36
|
+
#
|
37
|
+
module TokenAuthenticatable
|
38
|
+
extend ActiveSupport::Concern
|
39
|
+
|
40
|
+
def self.required_fields(klass)
|
41
|
+
[:authentication_token]
|
42
|
+
end
|
43
|
+
|
44
|
+
# Generate new authentication token (a.k.a. "single access token").
|
45
|
+
def reset_authentication_token
|
46
|
+
self.authentication_token = self.class.authentication_token
|
47
|
+
end
|
48
|
+
|
49
|
+
# Generate new authentication token and save the record.
|
50
|
+
def reset_authentication_token!
|
51
|
+
reset_authentication_token
|
52
|
+
save(:validate => false)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Generate authentication token unless already exists.
|
56
|
+
def ensure_authentication_token
|
57
|
+
reset_authentication_token if authentication_token.blank?
|
58
|
+
end
|
59
|
+
|
60
|
+
# Generate authentication token unless already exists and save the record.
|
61
|
+
def ensure_authentication_token!
|
62
|
+
reset_authentication_token! if authentication_token.blank?
|
63
|
+
end
|
64
|
+
|
65
|
+
# Hook called after token authentication.
|
66
|
+
def after_token_authentication
|
67
|
+
end
|
68
|
+
|
69
|
+
def expire_auth_token_on_timeout
|
70
|
+
self.class.expire_auth_token_on_timeout
|
71
|
+
end
|
72
|
+
|
73
|
+
module ClassMethods
|
74
|
+
def find_for_token_authentication(conditions)
|
75
|
+
find_for_authentication(:authentication_token => conditions[Devise::TokenAuthenticatable.token_authentication_key])
|
76
|
+
end
|
77
|
+
|
78
|
+
# Generate a token checking if one does not already exist in the database.
|
79
|
+
def authentication_token
|
80
|
+
loop do
|
81
|
+
token = Devise.friendly_token
|
82
|
+
break token unless to_adapter.find_first({ :authentication_token => token })
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
Devise::Models.config(self, :token_authentication_key, :expire_auth_token_on_timeout)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'devise/strategies/base'
|
2
|
+
|
3
|
+
module Devise
|
4
|
+
module Strategies
|
5
|
+
#
|
6
|
+
# The +TokenAuthenticatable+ strategy was extracted from Devise 3.1.0. Its purpose is
|
7
|
+
# to provide the deprecated functionality of the +TokenAuthenticatable+ strategy. The
|
8
|
+
# following description was adapted accordingly.
|
9
|
+
#
|
10
|
+
# See: https://github.com/plataformatec/devise/blob/v3.1/lib/devise/strategies/token_authenticatable.rb
|
11
|
+
#
|
12
|
+
#
|
13
|
+
# Strategy for signing in a user, based on a authenticatable token. This works for both params
|
14
|
+
# and http. For the former, all you need to do is to pass the params in the URL:
|
15
|
+
#
|
16
|
+
# http://myapp.example.com/?user_token=SECRET
|
17
|
+
#
|
18
|
+
# For headers, you can use basic authentication passing the token as username and
|
19
|
+
# blank password. Since some clients may require a password, you can pass "X" as
|
20
|
+
# password and it will simply be ignored.
|
21
|
+
#
|
22
|
+
# You may also pass the token using the Token authentication mechanism provided
|
23
|
+
# by Rails: http://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Token.html
|
24
|
+
# The token options are stored in request.env['devise.token_options']
|
25
|
+
#
|
26
|
+
#
|
27
|
+
# Changes regarding the original +TokenAuthenticatable+ implementation:
|
28
|
+
#
|
29
|
+
# The private method +remember_me?+ in +TokenAuthenticatable+ returns +false+.
|
30
|
+
# For +TokenAuthenticatable+ this method was removed. This results in the
|
31
|
+
# usage of the default implementation in +Authenticatable+.
|
32
|
+
#
|
33
|
+
class TokenAuthenticatable < Authenticatable
|
34
|
+
def store?
|
35
|
+
super && !mapping.to.skip_session_storage.include?(:token_auth)
|
36
|
+
end
|
37
|
+
|
38
|
+
def valid?
|
39
|
+
super || valid_for_token_auth?
|
40
|
+
end
|
41
|
+
|
42
|
+
def authenticate!
|
43
|
+
resource = mapping.to.find_for_token_authentication(authentication_hash)
|
44
|
+
return fail(:invalid_token) unless resource
|
45
|
+
|
46
|
+
if validate(resource)
|
47
|
+
resource.after_token_authentication
|
48
|
+
success!(resource)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
# Token Authenticatable can be authenticated with params in any controller and any verb.
|
55
|
+
def valid_params_request?
|
56
|
+
true
|
57
|
+
end
|
58
|
+
|
59
|
+
# Check if the model accepts this strategy as token authenticatable.
|
60
|
+
def token_authenticatable?
|
61
|
+
mapping.to.http_authenticatable?(:token_options)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Check if this is strategy is valid for token authentication by:
|
65
|
+
#
|
66
|
+
# * Validating if the model allows http token authentication;
|
67
|
+
# * If the http auth token exists;
|
68
|
+
# * If all authentication keys are present;
|
69
|
+
#
|
70
|
+
def valid_for_token_auth?
|
71
|
+
token_authenticatable? && auth_token.present? && with_authentication_hash(:token_auth, token_auth_hash)
|
72
|
+
end
|
73
|
+
|
74
|
+
# Extract the auth token from the request
|
75
|
+
def auth_token
|
76
|
+
@auth_token ||= ActionController::HttpAuthentication::Token.token_and_options(request)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Extract a hash with attributes:values from the auth_token
|
80
|
+
def token_auth_hash
|
81
|
+
request.env['devise.token_options'] = auth_token.last
|
82
|
+
{ authentication_keys.first => auth_token.first }
|
83
|
+
end
|
84
|
+
|
85
|
+
# Try both scoped and non scoped keys
|
86
|
+
def params_auth_hash
|
87
|
+
if params[scope].kind_of?(Hash) && params[scope].has_key?(authentication_keys.first)
|
88
|
+
params[scope]
|
89
|
+
else
|
90
|
+
params
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# Overwrite authentication keys to use token_authentication_key.
|
95
|
+
def authentication_keys
|
96
|
+
@authentication_keys ||= [Devise::TokenAuthenticatable.token_authentication_key]
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
Warden::Strategies.add(:token_authenticatable, Devise::Strategies::TokenAuthenticatable)
|
@@ -0,0 +1,24 @@
|
|
1
|
+
FactoryGirl.define do
|
2
|
+
|
3
|
+
factory :admin do
|
4
|
+
sequence(:email) { |n| "admin#{n}@domain.com" }
|
5
|
+
password 'some_password'
|
6
|
+
password_confirmation 'some_password'
|
7
|
+
|
8
|
+
ignore do
|
9
|
+
confirm_account true
|
10
|
+
end
|
11
|
+
|
12
|
+
after(:create) do |u, evaluator|
|
13
|
+
u.confirm! if evaluator.confirm_account
|
14
|
+
end
|
15
|
+
|
16
|
+
trait :with_reset_password_token do
|
17
|
+
reset_password_token { SecureRandom.hex }
|
18
|
+
end
|
19
|
+
|
20
|
+
trait :with_authentication_token do
|
21
|
+
authentication_token { SecureRandom.hex }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
FactoryGirl.define do
|
2
|
+
|
3
|
+
factory :user do
|
4
|
+
username 'testuser'
|
5
|
+
sequence(:email) { |n| "user#{n}@domain.com" }
|
6
|
+
password 'some_password'
|
7
|
+
password_confirmation 'some_password'
|
8
|
+
|
9
|
+
ignore do
|
10
|
+
confirm_account true
|
11
|
+
end
|
12
|
+
|
13
|
+
after(:create) do |u, evaluator|
|
14
|
+
u.confirm! if evaluator.confirm_account
|
15
|
+
end
|
16
|
+
|
17
|
+
trait :with_reset_password_token do
|
18
|
+
reset_password_token { SecureRandom.hex }
|
19
|
+
end
|
20
|
+
|
21
|
+
trait :with_authentication_token do
|
22
|
+
authentication_token { SecureRandom.hex }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
##
|
4
|
+
# If a model that is plain token authenticatable should be tested with
|
5
|
+
# this shared example the corresponding factory has to provide a trait
|
6
|
+
# +:with_authentication_token+ that sets the attribute +authentication_token+.
|
7
|
+
#
|
8
|
+
# See spec/factories/account.rb for an example.
|
9
|
+
#
|
10
|
+
shared_examples "plain token authenticatable" do
|
11
|
+
|
12
|
+
context "instance methods" do
|
13
|
+
|
14
|
+
describe "#reset_authentication_token" do
|
15
|
+
let(:entity) { create(described_class.name.underscore.to_sym, :with_authentication_token) }
|
16
|
+
|
17
|
+
it "should reset authentication token" do
|
18
|
+
expect { entity.reset_authentication_token }.to change { entity.authentication_token }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#ensure_authentication_token" do
|
23
|
+
|
24
|
+
context "with existing authentication token" do
|
25
|
+
let(:entity) { create(described_class.name.underscore.to_sym, :with_authentication_token) }
|
26
|
+
|
27
|
+
it "should not change the authentication token" do
|
28
|
+
expect { entity.ensure_authentication_token }.to_not change { entity.authentication_token }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "without existing authentication token" do
|
33
|
+
let(:entity) { create(described_class.name.underscore.to_sym) }
|
34
|
+
|
35
|
+
it "should create an authentication token" do
|
36
|
+
entity.authentication_token = nil
|
37
|
+
expect { entity.ensure_authentication_token }.to change { entity.authentication_token }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "class methods" do
|
44
|
+
|
45
|
+
describe "#find_for_authentication_token" do
|
46
|
+
let(:entity) { create(described_class.name.underscore.to_sym, :with_authentication_token) }
|
47
|
+
|
48
|
+
it "should authenticate a valid entity with authentication token and return it" do
|
49
|
+
authenticated_entity = described_class.find_for_token_authentication(auth_token: entity.authentication_token)
|
50
|
+
expect(entity.authentication_token).to eq(authenticated_entity.authentication_token)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should return nil when authenticating an invalid entity by authentication token" do
|
54
|
+
authenticated_entity = described_class.find_for_token_authentication(auth_token: entity.authentication_token.reverse)
|
55
|
+
expect(authenticated_entity).to be_nil
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should not be subject to injection" do
|
59
|
+
entity2 = create(described_class.name.underscore.to_sym, :with_authentication_token)
|
60
|
+
|
61
|
+
authenticated_entity = described_class.find_for_token_authentication(auth_token: { '$ne' => entity.authentication_token })
|
62
|
+
expect(authenticated_entity).to be_nil
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "#required_fields" do
|
67
|
+
|
68
|
+
it "should contain the fields that Devise uses" do
|
69
|
+
expect(Devise::Models::TokenAuthenticatable.required_fields(described_class)).to eq([
|
70
|
+
:authentication_token
|
71
|
+
])
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe User do
|
78
|
+
it_behaves_like "plain token authenticatable"
|
79
|
+
end
|