omniauth-identity 3.0.1 → 3.0.6
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +55 -0
- data/LICENSE +2 -1
- data/README.md +81 -42
- data/lib/omniauth-identity.rb +2 -0
- data/lib/omniauth-identity/version.rb +3 -1
- data/lib/omniauth/identity.rb +4 -0
- data/lib/omniauth/identity/model.rb +85 -29
- data/lib/omniauth/identity/models/active_record.rb +2 -0
- data/lib/omniauth/identity/models/couch_potato.rb +3 -0
- data/lib/omniauth/identity/models/mongoid.rb +3 -0
- data/lib/omniauth/identity/models/no_brainer.rb +31 -0
- data/lib/omniauth/identity/models/sequel.rb +48 -0
- data/lib/omniauth/identity/secure_password.rb +2 -0
- data/lib/omniauth/strategies/identity.rb +105 -32
- data/spec/omniauth/identity/model_spec.rb +2 -0
- data/spec/omniauth/identity/models/active_record_spec.rb +3 -1
- data/spec/omniauth/identity/models/couch_potato_spec.rb +10 -6
- data/spec/omniauth/identity/models/mongoid_spec.rb +11 -7
- data/spec/omniauth/identity/models/no_brainer_spec.rb +17 -0
- data/spec/omniauth/identity/models/sequel_spec.rb +23 -0
- data/spec/omniauth/identity/secure_password_spec.rb +5 -3
- data/spec/omniauth/strategies/identity_spec.rb +128 -15
- data/spec/spec_helper.rb +1 -0
- metadata +29 -129
@@ -1,9 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'couch_potato'
|
2
4
|
|
3
5
|
module OmniAuth
|
4
6
|
module Identity
|
5
7
|
module Models
|
6
8
|
# can not be named CouchPotato since there is a class with that name
|
9
|
+
# NOTE: CouchPotato is based on ActiveModel.
|
7
10
|
module CouchPotatoModule
|
8
11
|
def self.included(base)
|
9
12
|
base.class_eval do
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'nobrainer'
|
4
|
+
|
5
|
+
module OmniAuth
|
6
|
+
module Identity
|
7
|
+
module Models
|
8
|
+
# http://nobrainer.io/ an ORM for RethinkDB
|
9
|
+
# NOTE: NoBrainer is based on ActiveModel.
|
10
|
+
module NoBrainer
|
11
|
+
def self.included(base)
|
12
|
+
base.class_eval do
|
13
|
+
include ::OmniAuth::Identity::Model
|
14
|
+
include ::OmniAuth::Identity::SecurePassword
|
15
|
+
|
16
|
+
has_secure_password
|
17
|
+
|
18
|
+
def self.auth_key=(key)
|
19
|
+
super
|
20
|
+
validates_uniqueness_of key, case_sensitive: false
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.locate(search_hash)
|
24
|
+
where(search_hash).first
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'nobrainer'
|
4
|
+
|
5
|
+
module OmniAuth
|
6
|
+
module Identity
|
7
|
+
module Models
|
8
|
+
# http://sequel.jeremyevans.net/ an SQL ORM
|
9
|
+
# NOTE: Sequel is *not* based on ActiveModel, but supports the API we need, except for `persisted`:
|
10
|
+
# * create
|
11
|
+
# * save, but save is deprecated in favor of `save_changes`
|
12
|
+
module Sequel
|
13
|
+
def self.included(base)
|
14
|
+
base.class_eval do
|
15
|
+
# NOTE: Using the deprecated :validations_class_methods because it defines
|
16
|
+
# validates_confirmation_of, while current :validation_helpers does not.
|
17
|
+
# plugin :validation_helpers
|
18
|
+
plugin :validation_class_methods
|
19
|
+
|
20
|
+
include OmniAuth::Identity::Model
|
21
|
+
include ::OmniAuth::Identity::SecurePassword
|
22
|
+
|
23
|
+
has_secure_password
|
24
|
+
|
25
|
+
alias_method :persisted?, :valid?
|
26
|
+
|
27
|
+
def self.auth_key=(key)
|
28
|
+
super
|
29
|
+
validates_uniqueness_of :key, case_sensitive: false
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.locate(search_hash)
|
33
|
+
where(search_hash).first
|
34
|
+
end
|
35
|
+
|
36
|
+
def persisted?
|
37
|
+
exists?
|
38
|
+
end
|
39
|
+
|
40
|
+
def save
|
41
|
+
save_changes
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -1,33 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module OmniAuth
|
2
4
|
module Strategies
|
3
5
|
# The identity strategy allows you to provide simple internal
|
4
6
|
# user authentication using the same process flow that you
|
5
7
|
# use for external OmniAuth providers.
|
6
8
|
class Identity
|
9
|
+
DEFAULT_REGISTRATION_FIELDS = %i[password password_confirmation].freeze
|
7
10
|
include OmniAuth::Strategy
|
8
|
-
|
9
11
|
option :fields, %i[name email]
|
10
|
-
|
11
|
-
|
12
|
-
option :
|
13
|
-
option :
|
14
|
-
|
12
|
+
|
13
|
+
# Primary Feature Switches:
|
14
|
+
option :enable_registration, true # See #other_phase and #request_phase
|
15
|
+
option :enable_login, true # See #other_phase
|
16
|
+
|
17
|
+
# Customization Options:
|
18
|
+
option :on_login, nil # See #request_phase
|
19
|
+
option :on_validation, nil # See #registration_phase
|
20
|
+
option :on_registration, nil # See #registration_phase
|
21
|
+
option :on_failed_registration, nil # See #registration_phase
|
15
22
|
option :locate_conditions, ->(req) { { model.auth_key => req['auth_key'] } }
|
23
|
+
option :create_identity_link_text, 'Create an Identity'
|
24
|
+
option :registration_failure_message, 'One or more fields were invalid'
|
25
|
+
option :validation_failure_message, 'Validation failed'
|
26
|
+
option :title, 'Identity Verification' # Title for Login Form
|
27
|
+
option :registration_form_title, 'Register Identity' # Title for Registration Form
|
16
28
|
|
17
29
|
def request_phase
|
18
30
|
if options[:on_login]
|
19
31
|
options[:on_login].call(env)
|
20
32
|
else
|
21
|
-
|
22
|
-
title: (options[:title] || 'Identity Verification'),
|
23
|
-
url: callback_path
|
24
|
-
) do |f|
|
25
|
-
f.text_field 'Login', 'auth_key'
|
26
|
-
f.password_field 'Password', 'password'
|
27
|
-
if options[:enable_registration]
|
28
|
-
f.html "<p align='center'><a href='#{registration_path}'>Create an Identity</a></p>"
|
29
|
-
end
|
30
|
-
end.to_response
|
33
|
+
build_omniauth_login_form.to_response
|
31
34
|
end
|
32
35
|
end
|
33
36
|
|
@@ -58,36 +61,32 @@ module OmniAuth
|
|
58
61
|
end
|
59
62
|
end
|
60
63
|
|
61
|
-
def registration_form
|
64
|
+
def registration_form(validation_message = nil)
|
62
65
|
if options[:on_registration]
|
63
66
|
options[:on_registration].call(env)
|
64
67
|
else
|
65
|
-
|
66
|
-
options[:fields].each do |field|
|
67
|
-
f.text_field field.to_s.capitalize, field.to_s
|
68
|
-
end
|
69
|
-
f.password_field 'Password', 'password'
|
70
|
-
f.password_field 'Confirm Password', 'password_confirmation'
|
71
|
-
end.to_response
|
68
|
+
build_omniauth_registration_form(validation_message).to_response
|
72
69
|
end
|
73
70
|
end
|
74
71
|
|
75
72
|
def registration_phase
|
76
|
-
attributes = (options[:fields] +
|
73
|
+
attributes = (options[:fields] + DEFAULT_REGISTRATION_FIELDS).each_with_object({}) do |k, h|
|
77
74
|
h[k] = request[k.to_s]
|
78
75
|
end
|
79
76
|
if model.respond_to?(:column_names) && model.column_names.include?('provider')
|
80
77
|
attributes.reverse_merge!(provider: 'identity')
|
81
78
|
end
|
82
|
-
@identity = model.
|
83
|
-
if
|
84
|
-
env['PATH_INFO'] = callback_path
|
85
|
-
callback_phase
|
86
|
-
elsif options[:on_failed_registration]
|
79
|
+
@identity = model.new(attributes)
|
80
|
+
if saving_instead_of_creating?
|
87
81
|
env['omniauth.identity'] = @identity
|
88
|
-
|
82
|
+
if !validating? || valid?
|
83
|
+
@identity.save
|
84
|
+
registration_result
|
85
|
+
else
|
86
|
+
registration_failure(options[:validation_failure_message])
|
87
|
+
end
|
89
88
|
else
|
90
|
-
|
89
|
+
deprecated_registration(attributes)
|
91
90
|
end
|
92
91
|
end
|
93
92
|
|
@@ -115,6 +114,80 @@ module OmniAuth
|
|
115
114
|
def model
|
116
115
|
options[:model] || ::Identity
|
117
116
|
end
|
117
|
+
|
118
|
+
private
|
119
|
+
|
120
|
+
def build_omniauth_login_form
|
121
|
+
OmniAuth::Form.build(
|
122
|
+
title: options[:title],
|
123
|
+
url: callback_path
|
124
|
+
) do |f|
|
125
|
+
f.text_field 'Login', 'auth_key'
|
126
|
+
f.password_field 'Password', 'password'
|
127
|
+
if options[:enable_registration]
|
128
|
+
f.html "<p align='center'><a href='#{registration_path}'>#{options[:create_identity_link_text]}</a></p>"
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def build_omniauth_registration_form(validation_message)
|
134
|
+
OmniAuth::Form.build(title: options[:registration_form_title]) do |f|
|
135
|
+
f.html "<p style='color:red'>#{validation_message}</p>" if validation_message
|
136
|
+
options[:fields].each do |field|
|
137
|
+
f.text_field field.to_s.capitalize, field.to_s
|
138
|
+
end
|
139
|
+
f.password_field 'Password', 'password'
|
140
|
+
f.password_field 'Confirm Password', 'password_confirmation'
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def saving_instead_of_creating?
|
145
|
+
@identity.respond_to?(:save) && @identity.respond_to?(:persisted?)
|
146
|
+
end
|
147
|
+
|
148
|
+
# Validates the model before it is persisted
|
149
|
+
#
|
150
|
+
# @return [truthy or falsey] :on_validation option is truthy or falsey
|
151
|
+
def validating?
|
152
|
+
!!options[:on_validation]
|
153
|
+
end
|
154
|
+
|
155
|
+
# Validates the model before it is persisted
|
156
|
+
#
|
157
|
+
# @return [true or false] result of :on_validation call
|
158
|
+
def valid?
|
159
|
+
# on_validation may run a Captcha or other validation mechanism
|
160
|
+
# Must return true when validation passes, false otherwise
|
161
|
+
!!options[:on_validation].call(env: env)
|
162
|
+
end
|
163
|
+
|
164
|
+
def registration_failure(message)
|
165
|
+
if options[:on_failed_registration]
|
166
|
+
options[:on_failed_registration].call(env)
|
167
|
+
else
|
168
|
+
registration_form(message)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def registration_result
|
173
|
+
if @identity.persisted?
|
174
|
+
env['PATH_INFO'] = callback_path
|
175
|
+
callback_phase
|
176
|
+
else
|
177
|
+
registration_failure(options[:registration_failure_message])
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def deprecated_registration(attributes)
|
182
|
+
warn <<~CREATEDEP
|
183
|
+
[DEPRECATION] Please define '#{model.class}#save'.
|
184
|
+
Behavior based on '#{model.class}.create' will be removed in omniauth-identity v4.0.
|
185
|
+
See lib/omniauth/identity/model.rb
|
186
|
+
CREATEDEP
|
187
|
+
@identity = model.create(attributes)
|
188
|
+
env['omniauth.identity'] = @identity
|
189
|
+
registration_result
|
190
|
+
end
|
118
191
|
end
|
119
192
|
end
|
120
193
|
end
|
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
RSpec.describe(OmniAuth::Identity::Models::ActiveRecord, db: true) do
|
2
4
|
describe 'model', type: :model do
|
3
5
|
subject(:model_klass) do
|
4
6
|
AnonymousActiveRecord.generate(
|
5
7
|
parent_klass: 'OmniAuth::Identity::Models::ActiveRecord',
|
6
|
-
columns: %w[
|
8
|
+
columns: OmniAuth::Identity::Model::SCHEMA_ATTRIBUTES | %w[provider password_digest],
|
7
9
|
connection_params: { adapter: 'sqlite3', encoding: 'utf8', database: ':memory:' }
|
8
10
|
) do
|
9
11
|
def flower
|
@@ -1,10 +1,14 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
include OmniAuth::Identity::Models::CouchPotatoModule
|
5
|
-
auth_key :ham_sandwich
|
6
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'couch_potato'
|
7
4
|
|
5
|
+
class CouchPotatoTestIdentity
|
6
|
+
include CouchPotato::Persistence
|
7
|
+
include OmniAuth::Identity::Models::CouchPotatoModule
|
8
|
+
auth_key :ham_sandwich
|
9
|
+
end
|
10
|
+
|
11
|
+
RSpec.describe(OmniAuth::Identity::Models::CouchPotatoModule, db: true) do
|
8
12
|
describe 'model', type: :model do
|
9
13
|
subject { CouchPotatoTestIdentity }
|
10
14
|
|
@@ -1,11 +1,15 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
include OmniAuth::Identity::Models::Mongoid
|
5
|
-
auth_key :ham_sandwich
|
6
|
-
store_in database: 'db1', collection: 'mongoid_test_identities', client: 'secondary'
|
7
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'mongoid'
|
8
4
|
|
5
|
+
class MongoidTestIdentity
|
6
|
+
include Mongoid::Document
|
7
|
+
include OmniAuth::Identity::Models::Mongoid
|
8
|
+
auth_key :ham_sandwich
|
9
|
+
store_in database: 'db1', collection: 'mongoid_test_identities', client: 'secondary'
|
10
|
+
end
|
11
|
+
|
12
|
+
RSpec.describe(OmniAuth::Identity::Models::Mongoid, db: true) do
|
9
13
|
describe 'model', type: :model do
|
10
14
|
subject { MongoidTestIdentity }
|
11
15
|
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'nobrainer'
|
4
|
+
|
5
|
+
class NobrainerTestIdentity
|
6
|
+
include NoBrainer::Document
|
7
|
+
include OmniAuth::Identity::Models::NoBrainer
|
8
|
+
auth_key :ham_sandwich
|
9
|
+
end
|
10
|
+
|
11
|
+
RSpec.describe(OmniAuth::Identity::Models::NoBrainer, db: true) do
|
12
|
+
it 'delegates locate to the where query method' do
|
13
|
+
allow(NobrainerTestIdentity).to receive(:where).with('ham_sandwich' => 'open faced',
|
14
|
+
'category' => 'sandwiches').and_return(['wakka'])
|
15
|
+
expect(NobrainerTestIdentity.locate('ham_sandwich' => 'open faced', 'category' => 'sandwiches')).to eq('wakka')
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'sequel'
|
4
|
+
# Connect to an in-memory sqlite3 database.
|
5
|
+
DB = Sequel.sqlite
|
6
|
+
DB.create_table :sequel_test_identities do
|
7
|
+
primary_key :id
|
8
|
+
String :ham_sandwich, null: false
|
9
|
+
String :password_digest, null: false
|
10
|
+
end
|
11
|
+
|
12
|
+
class SequelTestIdentity < Sequel::Model
|
13
|
+
include OmniAuth::Identity::Models::Sequel
|
14
|
+
auth_key :ham_sandwich
|
15
|
+
end
|
16
|
+
|
17
|
+
RSpec.describe(OmniAuth::Identity::Models::Sequel, db: true) do
|
18
|
+
it 'delegates locate to the where query method' do
|
19
|
+
allow(SequelTestIdentity).to receive(:where).with('ham_sandwich' => 'open faced',
|
20
|
+
'category' => 'sandwiches').and_return(['wakka'])
|
21
|
+
expect(SequelTestIdentity.locate('ham_sandwich' => 'open faced', 'category' => 'sandwiches')).to eq('wakka')
|
22
|
+
end
|
23
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class HasTheMethod
|
2
4
|
def self.has_secure_password; end
|
3
5
|
end
|
@@ -8,17 +10,17 @@ end
|
|
8
10
|
RSpec.describe OmniAuth::Identity::SecurePassword do
|
9
11
|
it 'extends with the class methods if it does not have the method' do
|
10
12
|
expect(DoesNotHaveTheMethod).to receive(:extend).with(OmniAuth::Identity::SecurePassword::ClassMethods)
|
11
|
-
DoesNotHaveTheMethod.include
|
13
|
+
DoesNotHaveTheMethod.include described_class
|
12
14
|
end
|
13
15
|
|
14
16
|
it 'does not extend if the method is already defined' do
|
15
17
|
expect(HasTheMethod).not_to receive(:extend)
|
16
|
-
HasTheMethod.include
|
18
|
+
HasTheMethod.include described_class
|
17
19
|
end
|
18
20
|
|
19
21
|
it 'responds to has_secure_password afterwards' do
|
20
22
|
[HasTheMethod, DoesNotHaveTheMethod].each do |klass|
|
21
|
-
klass.send(:include,
|
23
|
+
klass.send(:include, described_class)
|
22
24
|
expect(klass).to be_respond_to(:has_secure_password)
|
23
25
|
end
|
24
26
|
end
|
@@ -1,12 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
RSpec.describe OmniAuth::Strategies::Identity do
|
2
4
|
attr_accessor :app
|
3
5
|
|
4
|
-
let(:
|
5
|
-
let(:
|
6
|
+
let(:env_hash) { last_response.headers['env'] }
|
7
|
+
let(:auth_hash) { env_hash['omniauth.auth'] }
|
8
|
+
let(:identity_hash) { env_hash['omniauth.identity'] }
|
6
9
|
let(:identity_options) { {} }
|
7
10
|
let(:anon_ar) do
|
8
11
|
AnonymousActiveRecord.generate(
|
9
|
-
|
12
|
+
parent_klass: 'OmniAuth::Identity::Models::ActiveRecord',
|
13
|
+
columns: OmniAuth::Identity::Model::SCHEMA_ATTRIBUTES | %w[provider password_digest],
|
10
14
|
connection_params: { adapter: 'sqlite3', encoding: 'utf8', database: ':memory:' }
|
11
15
|
) do
|
12
16
|
def balloon
|
@@ -190,7 +194,7 @@ RSpec.describe OmniAuth::Strategies::Identity do
|
|
190
194
|
end
|
191
195
|
end
|
192
196
|
|
193
|
-
context 'with
|
197
|
+
context 'with good identity' do
|
194
198
|
let(:properties) do
|
195
199
|
{
|
196
200
|
name: 'Awesome Dude',
|
@@ -201,20 +205,71 @@ RSpec.describe OmniAuth::Strategies::Identity do
|
|
201
205
|
}
|
202
206
|
end
|
203
207
|
|
204
|
-
before do
|
205
|
-
allow(anon_ar).to receive('auth_key').and_return('email')
|
206
|
-
m = double(uid: 'abc', name: 'Awesome Dude', email: 'awesome@example.com',
|
207
|
-
info: { name: 'DUUUUDE!' }, persisted?: true)
|
208
|
-
expect(anon_ar).to receive(:create).with(properties).and_return(m)
|
209
|
-
end
|
210
|
-
|
211
208
|
it 'sets the auth hash' do
|
212
209
|
post '/auth/identity/register', properties
|
213
|
-
expect(auth_hash['uid']).to
|
210
|
+
expect(auth_hash['uid']).to match(/\d+/)
|
211
|
+
expect(auth_hash['provider']).to eq('identity')
|
212
|
+
end
|
213
|
+
|
214
|
+
context 'with on_validation proc' do
|
215
|
+
let(:identity_options) do
|
216
|
+
{ model: anon_ar, on_validation: on_validation_proc }
|
217
|
+
end
|
218
|
+
let(:on_validation_proc) do
|
219
|
+
lambda { |_env|
|
220
|
+
false
|
221
|
+
}
|
222
|
+
end
|
223
|
+
|
224
|
+
context 'when validation fails' do
|
225
|
+
it 'does not set the env hash' do
|
226
|
+
post '/auth/identity/register', properties
|
227
|
+
expect(env_hash).to eq(nil)
|
228
|
+
end
|
229
|
+
|
230
|
+
it 'renders registration form' do
|
231
|
+
post '/auth/identity/register', properties
|
232
|
+
expect(last_response.body).to be_include(described_class.default_options[:registration_form_title])
|
233
|
+
end
|
234
|
+
|
235
|
+
it 'displays validation failure message' do
|
236
|
+
post '/auth/identity/register', properties
|
237
|
+
expect(last_response.body).to be_include(described_class.default_options[:validation_failure_message])
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
context 'when validation succeeds' do
|
242
|
+
let(:on_validation_proc) do
|
243
|
+
lambda { |_env|
|
244
|
+
true
|
245
|
+
}
|
246
|
+
end
|
247
|
+
|
248
|
+
it 'sets the auth hash' do
|
249
|
+
post '/auth/identity/register', properties
|
250
|
+
expect(auth_hash['uid']).to match(/\d+/)
|
251
|
+
expect(auth_hash['provider']).to eq('identity')
|
252
|
+
end
|
253
|
+
|
254
|
+
it 'does not render registration form' do
|
255
|
+
post '/auth/identity/register', properties
|
256
|
+
expect(last_response.body).not_to be_include(described_class.default_options[:registration_form_title])
|
257
|
+
end
|
258
|
+
|
259
|
+
it 'does not display validation failure message' do
|
260
|
+
post '/auth/identity/register', properties
|
261
|
+
expect(last_response.body).not_to be_include(described_class.default_options[:validation_failure_message])
|
262
|
+
end
|
263
|
+
|
264
|
+
it 'does not display registration failure message' do
|
265
|
+
post '/auth/identity/register', properties
|
266
|
+
expect(last_response.body).not_to be_include(described_class.default_options[:registration_failure_message])
|
267
|
+
end
|
268
|
+
end
|
214
269
|
end
|
215
270
|
end
|
216
271
|
|
217
|
-
context 'with
|
272
|
+
context 'with bad identity' do
|
218
273
|
let(:properties) do
|
219
274
|
{
|
220
275
|
name: 'Awesome Dude',
|
@@ -224,16 +279,17 @@ RSpec.describe OmniAuth::Strategies::Identity do
|
|
224
279
|
provider: 'identity'
|
225
280
|
}
|
226
281
|
end
|
227
|
-
let(:invalid_identity) { double(persisted?: false) }
|
282
|
+
let(:invalid_identity) { double(persisted?: false, save: false) }
|
228
283
|
|
229
284
|
before do
|
230
|
-
expect(anon_ar).to receive(:
|
285
|
+
expect(anon_ar).to receive(:new).with(properties).and_return(invalid_identity)
|
231
286
|
end
|
232
287
|
|
233
288
|
context 'default' do
|
234
289
|
it 'shows registration form' do
|
235
290
|
post '/auth/identity/register', properties
|
236
291
|
expect(last_response.body).to be_include('Register Identity')
|
292
|
+
expect(last_response.body).to be_include('One or more fields were invalid')
|
237
293
|
end
|
238
294
|
end
|
239
295
|
|
@@ -248,6 +304,63 @@ RSpec.describe OmniAuth::Strategies::Identity do
|
|
248
304
|
post '/auth/identity/register', properties
|
249
305
|
expect(identity_hash).to eq(invalid_identity)
|
250
306
|
expect(last_response.body).to be_include("FAIL'DOH!")
|
307
|
+
expect(last_response.body).not_to be_include('One or more fields were invalid')
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
context 'with on_validation proc' do
|
312
|
+
let(:identity_options) do
|
313
|
+
{ model: anon_ar, on_validation: on_validation_proc }
|
314
|
+
end
|
315
|
+
let(:on_validation_proc) do
|
316
|
+
lambda { |_env|
|
317
|
+
false
|
318
|
+
}
|
319
|
+
end
|
320
|
+
|
321
|
+
context 'when validation fails' do
|
322
|
+
it 'does not set the env hash' do
|
323
|
+
post '/auth/identity/register', properties
|
324
|
+
expect(env_hash).to eq(nil)
|
325
|
+
end
|
326
|
+
|
327
|
+
it 'renders registration form' do
|
328
|
+
post '/auth/identity/register', properties
|
329
|
+
expect(last_response.body).to be_include(described_class.default_options[:registration_form_title])
|
330
|
+
end
|
331
|
+
|
332
|
+
it 'displays validation failure message' do
|
333
|
+
post '/auth/identity/register', properties
|
334
|
+
expect(last_response.body).to be_include(described_class.default_options[:validation_failure_message])
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
context 'when validation succeeds' do
|
339
|
+
let(:on_validation_proc) do
|
340
|
+
lambda { |_env|
|
341
|
+
true
|
342
|
+
}
|
343
|
+
end
|
344
|
+
|
345
|
+
it 'does not set the env hash' do
|
346
|
+
post '/auth/identity/register', properties
|
347
|
+
expect(env_hash).to eq(nil)
|
348
|
+
end
|
349
|
+
|
350
|
+
it 'renders registration form' do
|
351
|
+
post '/auth/identity/register', properties
|
352
|
+
expect(last_response.body).to be_include(described_class.default_options[:registration_form_title])
|
353
|
+
end
|
354
|
+
|
355
|
+
it 'does not display validation failure message' do
|
356
|
+
post '/auth/identity/register', properties
|
357
|
+
expect(last_response.body).not_to be_include(described_class.default_options[:validation_failure_message])
|
358
|
+
end
|
359
|
+
|
360
|
+
it 'display registration failure message' do
|
361
|
+
post '/auth/identity/register', properties
|
362
|
+
expect(last_response.body).to be_include(described_class.default_options[:registration_failure_message])
|
363
|
+
end
|
251
364
|
end
|
252
365
|
end
|
253
366
|
end
|