omniauth-identity 1.1.1 → 3.0.3
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 +5 -5
- data/CHANGELOG.md +81 -0
- data/CODE_OF_CONDUCT.md +133 -0
- data/LICENSE +22 -0
- data/README.md +238 -0
- data/lib/omniauth-identity.rb +2 -0
- data/lib/omniauth-identity/version.rb +3 -1
- data/lib/omniauth/identity.rb +3 -2
- data/lib/omniauth/identity/model.rb +17 -14
- data/lib/omniauth/identity/models/active_record.rb +4 -1
- data/lib/omniauth/identity/models/couch_potato.rb +3 -4
- data/lib/omniauth/identity/models/mongoid.rb +3 -7
- data/lib/omniauth/identity/models/{mongo_mapper.rb → no_brainer.rb} +6 -4
- data/lib/omniauth/identity/secure_password.rb +4 -4
- data/lib/omniauth/strategies/identity.rb +92 -39
- data/spec/omniauth/identity/model_spec.rb +60 -59
- data/spec/omniauth/identity/models/active_record_spec.rb +24 -8
- data/spec/omniauth/identity/models/couch_potato_spec.rb +17 -11
- data/spec/omniauth/identity/models/mongoid_spec.rb +23 -13
- data/spec/omniauth/identity/models/no_brainer_spec.rb +17 -0
- data/spec/omniauth/identity/secure_password_spec.rb +12 -12
- data/spec/omniauth/strategies/identity_spec.rb +178 -67
- data/spec/spec_helper.rb +20 -6
- metadata +75 -128
- data/.gitignore +0 -4
- data/.rspec +0 -2
- data/Gemfile +0 -11
- data/Gemfile.lock +0 -179
- data/Guardfile +0 -10
- data/README.markdown +0 -202
- data/Rakefile +0 -9
- data/lib/omniauth/identity/models/data_mapper.rb +0 -32
- data/omniauth-identity.gemspec +0 -32
- data/spec/omniauth/identity/models/data_mapper_spec.rb +0 -22
- data/spec/omniauth/identity/models/mongo_mapper_spec.rb +0 -15
@@ -1,122 +1,123 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class ExampleModel
|
4
4
|
include OmniAuth::Identity::Model
|
5
5
|
end
|
6
6
|
|
7
|
-
describe OmniAuth::Identity::Model do
|
7
|
+
RSpec.describe OmniAuth::Identity::Model do
|
8
8
|
context 'Class Methods' do
|
9
|
-
subject{ ExampleModel }
|
9
|
+
subject { ExampleModel }
|
10
10
|
|
11
11
|
describe '.locate' do
|
12
|
-
it('
|
12
|
+
it('is abstract') { expect { subject.locate('abc') }.to raise_error(NotImplementedError) }
|
13
13
|
end
|
14
14
|
|
15
15
|
describe '.authenticate' do
|
16
|
-
it '
|
17
|
-
mocked_instance =
|
18
|
-
subject.
|
19
|
-
subject.authenticate({'email' => 'example'},'pass').
|
16
|
+
it 'calls locate and then authenticate' do
|
17
|
+
mocked_instance = double('ExampleModel', authenticate: 'abbadoo')
|
18
|
+
allow(subject).to receive(:locate).with('email' => 'example').and_return(mocked_instance)
|
19
|
+
expect(subject.authenticate({ 'email' => 'example' }, 'pass')).to eq('abbadoo')
|
20
20
|
end
|
21
21
|
|
22
|
-
it '
|
23
|
-
mocked_instance =
|
24
|
-
subject.
|
25
|
-
|
22
|
+
it 'calls locate with additional scopes when provided' do
|
23
|
+
mocked_instance = double('ExampleModel', authenticate: 'abbadoo')
|
24
|
+
allow(subject).to receive(:locate).with('email' => 'example',
|
25
|
+
'user_type' => 'admin').and_return(mocked_instance)
|
26
|
+
expect(subject.authenticate({ 'email' => 'example', 'user_type' => 'admin' }, 'pass')).to eq('abbadoo')
|
26
27
|
end
|
27
28
|
|
28
|
-
it '
|
29
|
-
subject.
|
30
|
-
subject.authenticate('blah','foo').
|
29
|
+
it 'recovers gracefully if locate is nil' do
|
30
|
+
allow(subject).to receive(:locate).and_return(nil)
|
31
|
+
expect(subject.authenticate('blah', 'foo')).to be false
|
31
32
|
end
|
32
33
|
end
|
33
34
|
end
|
34
35
|
|
35
36
|
context 'Instance Methods' do
|
36
|
-
subject{ ExampleModel.new }
|
37
|
+
subject { ExampleModel.new }
|
37
38
|
|
38
39
|
describe '#authenticate' do
|
39
|
-
it('
|
40
|
+
it('is abstract') { expect { subject.authenticate('abc') }.to raise_error(NotImplementedError) }
|
40
41
|
end
|
41
42
|
|
42
43
|
describe '#uid' do
|
43
|
-
it '
|
44
|
-
subject.
|
45
|
-
subject.
|
46
|
-
subject.uid.
|
44
|
+
it 'defaults to #id' do
|
45
|
+
allow(subject).to receive(:respond_to?).with(:id).and_return(true)
|
46
|
+
allow(subject).to receive(:id).and_return 'wakka-do'
|
47
|
+
expect(subject.uid).to eq('wakka-do')
|
47
48
|
end
|
48
49
|
|
49
|
-
it '
|
50
|
-
subject.
|
51
|
-
subject.uid.
|
50
|
+
it 'stringifies it' do
|
51
|
+
allow(subject).to receive(:id).and_return 123
|
52
|
+
expect(subject.uid).to eq('123')
|
52
53
|
end
|
53
54
|
|
54
|
-
it '
|
55
|
-
subject.
|
56
|
-
|
55
|
+
it 'raises NotImplementedError if #id is not defined' do
|
56
|
+
allow(subject).to receive(:respond_to?).with(:id).and_return(false)
|
57
|
+
expect { subject.uid }.to raise_error(NotImplementedError)
|
57
58
|
end
|
58
59
|
end
|
59
60
|
|
60
61
|
describe '#auth_key' do
|
61
|
-
it '
|
62
|
-
subject.
|
63
|
-
subject.
|
64
|
-
subject.auth_key.
|
62
|
+
it 'defaults to #email' do
|
63
|
+
allow(subject).to receive(:respond_to?).with(:email).and_return(true)
|
64
|
+
allow(subject).to receive(:email).and_return('bob@bob.com')
|
65
|
+
expect(subject.auth_key).to eq('bob@bob.com')
|
65
66
|
end
|
66
67
|
|
67
|
-
it '
|
68
|
+
it 'uses the class .auth_key' do
|
68
69
|
subject.class.auth_key 'login'
|
69
|
-
subject.
|
70
|
-
subject.auth_key.
|
70
|
+
allow(subject).to receive(:login).and_return 'bob'
|
71
|
+
expect(subject.auth_key).to eq('bob')
|
71
72
|
subject.class.auth_key nil
|
72
73
|
end
|
73
74
|
|
74
|
-
it '
|
75
|
-
|
75
|
+
it 'raises a NotImplementedError if the auth_key method is not defined' do
|
76
|
+
expect { subject.auth_key }.to raise_error(NotImplementedError)
|
76
77
|
end
|
77
78
|
end
|
78
79
|
|
79
80
|
describe '#auth_key=' do
|
80
|
-
it '
|
81
|
-
subject.
|
82
|
-
subject.
|
83
|
-
|
81
|
+
it 'defaults to setting email' do
|
82
|
+
allow(subject).to receive(:respond_to?).with(:email=).and_return(true)
|
83
|
+
expect(subject).to receive(:email=).with 'abc'
|
84
|
+
|
84
85
|
subject.auth_key = 'abc'
|
85
86
|
end
|
86
87
|
|
87
|
-
it '
|
88
|
+
it 'uses a custom .auth_key if one is provided' do
|
88
89
|
subject.class.auth_key 'login'
|
89
|
-
subject.
|
90
|
-
subject.
|
90
|
+
allow(subject).to receive(:respond_to?).with(:login=).and_return(true)
|
91
|
+
expect(subject).to receive(:login=).with('abc')
|
91
92
|
|
92
93
|
subject.auth_key = 'abc'
|
93
94
|
end
|
94
95
|
|
95
|
-
it '
|
96
|
-
|
96
|
+
it 'raises a NotImplementedError if the autH_key method is not defined' do
|
97
|
+
expect { subject.auth_key = 'broken' }.to raise_error(NotImplementedError)
|
97
98
|
end
|
98
99
|
end
|
99
100
|
|
100
101
|
describe '#info' do
|
101
|
-
it '
|
102
|
-
subject.
|
103
|
-
subject.
|
104
|
-
|
105
|
-
subject.info.
|
106
|
-
|
107
|
-
|
108
|
-
|
102
|
+
it 'includes attributes that are set' do
|
103
|
+
allow(subject).to receive(:name).and_return('Bob Bobson')
|
104
|
+
allow(subject).to receive(:nickname).and_return('bob')
|
105
|
+
|
106
|
+
expect(subject.info).to eq({
|
107
|
+
'name' => 'Bob Bobson',
|
108
|
+
'nickname' => 'bob'
|
109
|
+
})
|
109
110
|
end
|
110
111
|
|
111
|
-
it '
|
112
|
-
subject.
|
112
|
+
it 'automaticallies set name off of nickname' do
|
113
|
+
allow(subject).to receive(:nickname).and_return('bob')
|
113
114
|
subject.info['name'] == 'bob'
|
114
115
|
end
|
115
116
|
|
116
|
-
it '
|
117
|
-
subject.
|
118
|
-
subject.
|
119
|
-
subject.info['name'].
|
117
|
+
it 'does not overwrite a provided name' do
|
118
|
+
allow(subject).to receive(:name).and_return('Awesome Dude')
|
119
|
+
allow(subject).to receive(:first_name).and_return('Frank')
|
120
|
+
expect(subject.info['name']).to eq('Awesome Dude')
|
120
121
|
end
|
121
122
|
end
|
122
123
|
end
|
@@ -1,14 +1,30 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
describe(OmniAuth::Identity::Models::ActiveRecord, :
|
4
|
-
|
3
|
+
RSpec.describe(OmniAuth::Identity::Models::ActiveRecord, db: true) do
|
4
|
+
describe 'model', type: :model do
|
5
|
+
subject(:model_klass) do
|
6
|
+
AnonymousActiveRecord.generate(
|
7
|
+
parent_klass: 'OmniAuth::Identity::Models::ActiveRecord',
|
8
|
+
columns: OmniAuth::Identity::Model::SCHEMA_ATTRIBUTES | %w[provider password_digest],
|
9
|
+
connection_params: { adapter: 'sqlite3', encoding: 'utf8', database: ':memory:' }
|
10
|
+
) do
|
11
|
+
def flower
|
12
|
+
'🌸'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
5
16
|
|
6
|
-
|
7
|
-
|
8
|
-
|
17
|
+
it 'delegates locate to the where query method' do
|
18
|
+
allow(model_klass).to receive(:where).with('ham_sandwich' => 'open faced', 'category' => 'sandwiches',
|
19
|
+
'provider' => 'identity').and_return(['wakka'])
|
20
|
+
expect(model_klass.locate('ham_sandwich' => 'open faced', 'category' => 'sandwiches')).to eq('wakka')
|
21
|
+
end
|
9
22
|
end
|
10
23
|
|
11
|
-
|
12
|
-
TestIdentity
|
24
|
+
describe '#table_name' do
|
25
|
+
class TestIdentity < OmniAuth::Identity::Models::ActiveRecord; end
|
26
|
+
it 'does not use STI rules for its table name' do
|
27
|
+
expect(TestIdentity.table_name).to eq('test_identities')
|
28
|
+
end
|
13
29
|
end
|
14
30
|
end
|
@@ -1,15 +1,21 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
class CouchPotatoTestIdentity
|
5
|
-
include CouchPotato::Persistence
|
6
|
-
include OmniAuth::Identity::Models::CouchPotatoModule
|
7
|
-
auth_key :ham_sandwich
|
8
|
-
end
|
3
|
+
require 'couch_potato'
|
9
4
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
5
|
+
class CouchPotatoTestIdentity
|
6
|
+
include CouchPotato::Persistence
|
7
|
+
include OmniAuth::Identity::Models::CouchPotatoModule
|
8
|
+
auth_key :ham_sandwich
|
9
|
+
end
|
14
10
|
|
11
|
+
RSpec.describe(OmniAuth::Identity::Models::CouchPotatoModule, db: true) do
|
12
|
+
describe 'model', type: :model do
|
13
|
+
subject { CouchPotatoTestIdentity }
|
14
|
+
|
15
|
+
it 'delegates locate to the where query method' do
|
16
|
+
allow(subject).to receive(:where).with('ham_sandwich' => 'open faced',
|
17
|
+
'category' => 'sandwiches').and_return(['wakka'])
|
18
|
+
expect(subject.locate('ham_sandwich' => 'open faced', 'category' => 'sandwiches')).to eq('wakka')
|
19
|
+
end
|
20
|
+
end
|
15
21
|
end
|
@@ -1,18 +1,28 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
class MongoidTestIdentity
|
5
|
-
include Mongoid::Document
|
6
|
-
include OmniAuth::Identity::Models::Mongoid
|
7
|
-
auth_key :ham_sandwich
|
8
|
-
end
|
3
|
+
require 'mongoid'
|
9
4
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
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
|
13
|
+
describe 'model', type: :model do
|
14
|
+
subject { MongoidTestIdentity }
|
15
|
+
|
16
|
+
it { is_expected.to be_mongoid_document }
|
17
|
+
|
18
|
+
it 'does not munge collection name' do
|
19
|
+
expect(subject).to be_stored_in(database: 'db1', collection: 'mongoid_test_identities', client: 'secondary')
|
20
|
+
end
|
14
21
|
|
15
|
-
|
16
|
-
|
22
|
+
it 'delegates locate to the where query method' do
|
23
|
+
allow(subject).to receive(:where).with('ham_sandwich' => 'open faced',
|
24
|
+
'category' => 'sandwiches').and_return(['wakka'])
|
25
|
+
expect(subject.locate('ham_sandwich' => 'open faced', 'category' => 'sandwiches')).to eq('wakka')
|
26
|
+
end
|
17
27
|
end
|
18
28
|
end
|
@@ -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
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class HasTheMethod
|
4
4
|
def self.has_secure_password; end
|
@@ -7,21 +7,21 @@ end
|
|
7
7
|
class DoesNotHaveTheMethod
|
8
8
|
end
|
9
9
|
|
10
|
-
describe OmniAuth::Identity::SecurePassword do
|
11
|
-
it '
|
12
|
-
DoesNotHaveTheMethod.
|
13
|
-
DoesNotHaveTheMethod.
|
10
|
+
RSpec.describe OmniAuth::Identity::SecurePassword do
|
11
|
+
it 'extends with the class methods if it does not have the method' do
|
12
|
+
expect(DoesNotHaveTheMethod).to receive(:extend).with(OmniAuth::Identity::SecurePassword::ClassMethods)
|
13
|
+
DoesNotHaveTheMethod.include described_class
|
14
14
|
end
|
15
15
|
|
16
|
-
it '
|
17
|
-
HasTheMethod.
|
18
|
-
HasTheMethod.
|
16
|
+
it 'does not extend if the method is already defined' do
|
17
|
+
expect(HasTheMethod).not_to receive(:extend)
|
18
|
+
HasTheMethod.include described_class
|
19
19
|
end
|
20
20
|
|
21
|
-
it '
|
22
|
-
[HasTheMethod,DoesNotHaveTheMethod].each do |klass|
|
23
|
-
klass.send(:include,
|
24
|
-
klass.
|
21
|
+
it 'responds to has_secure_password afterwards' do
|
22
|
+
[HasTheMethod, DoesNotHaveTheMethod].each do |klass|
|
23
|
+
klass.send(:include, described_class)
|
24
|
+
expect(klass).to be_respond_to(:has_secure_password)
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
@@ -1,141 +1,252 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
describe OmniAuth::Strategies::Identity do
|
3
|
+
RSpec.describe OmniAuth::Strategies::Identity do
|
6
4
|
attr_accessor :app
|
7
5
|
|
8
|
-
let(:auth_hash){ last_response.headers['env']['omniauth.auth'] }
|
9
|
-
let(:identity_hash){ last_response.headers['env']['omniauth.identity'] }
|
6
|
+
let(:auth_hash) { last_response.headers['env']['omniauth.auth'] }
|
7
|
+
let(:identity_hash) { last_response.headers['env']['omniauth.identity'] }
|
8
|
+
let(:identity_options) { {} }
|
9
|
+
let(:anon_ar) do
|
10
|
+
AnonymousActiveRecord.generate(
|
11
|
+
parent_klass: 'OmniAuth::Identity::Models::ActiveRecord',
|
12
|
+
columns: OmniAuth::Identity::Model::SCHEMA_ATTRIBUTES | %w[provider password_digest],
|
13
|
+
connection_params: { adapter: 'sqlite3', encoding: 'utf8', database: ':memory:' }
|
14
|
+
) do
|
15
|
+
def balloon
|
16
|
+
'🎈'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
10
20
|
|
11
21
|
# customize rack app for testing, if block is given, reverts to default
|
12
22
|
# rack app after testing is done
|
13
23
|
def set_app!(identity_options = {})
|
14
|
-
|
15
|
-
old_app = self.app
|
24
|
+
old_app = app
|
16
25
|
self.app = Rack::Builder.app do
|
17
|
-
use Rack::Session::Cookie
|
26
|
+
use Rack::Session::Cookie, secret: '1234567890qwertyuiop'
|
18
27
|
use OmniAuth::Strategies::Identity, identity_options
|
19
|
-
run
|
28
|
+
run ->(env) { [404, { 'env' => env }, ['HELLO!']] }
|
20
29
|
end
|
21
30
|
if block_given?
|
22
31
|
yield
|
23
32
|
self.app = old_app
|
24
33
|
end
|
25
|
-
|
34
|
+
app
|
26
35
|
end
|
27
36
|
|
28
|
-
before
|
29
|
-
|
37
|
+
before do
|
38
|
+
opts = identity_options.reverse_merge({ model: anon_ar })
|
39
|
+
set_app!(opts)
|
30
40
|
end
|
31
41
|
|
32
42
|
describe '#request_phase' do
|
33
|
-
|
34
|
-
|
35
|
-
|
43
|
+
context 'with default settings' do
|
44
|
+
let(:identity_options) { { model: anon_ar } }
|
45
|
+
|
46
|
+
it 'displays a form' do
|
47
|
+
get '/auth/identity'
|
48
|
+
|
49
|
+
expect(last_response.body).not_to eq('HELLO!')
|
50
|
+
expect(last_response.body).to be_include('<form')
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'when login is enabled' do
|
55
|
+
context 'when registration is enabled' do
|
56
|
+
let(:identity_options) { { model: anon_ar, enable_registration: true, enable_login: true } }
|
57
|
+
|
58
|
+
it 'displays a form with a link to register' do
|
59
|
+
get '/auth/identity'
|
60
|
+
|
61
|
+
expect(last_response.body).not_to eq('HELLO!')
|
62
|
+
expect(last_response.body).to be_include('<form')
|
63
|
+
expect(last_response.body).to be_include('<a')
|
64
|
+
expect(last_response.body).to be_include('Create an Identity')
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context 'when registration is disabled' do
|
69
|
+
let(:identity_options) { { model: anon_ar, enable_registration: false, enable_login: true } }
|
70
|
+
|
71
|
+
it 'displays a form without a link to register' do
|
72
|
+
get '/auth/identity'
|
73
|
+
|
74
|
+
expect(last_response.body).not_to eq('HELLO!')
|
75
|
+
expect(last_response.body).to be_include('<form')
|
76
|
+
expect(last_response.body).not_to be_include('<a')
|
77
|
+
expect(last_response.body).not_to be_include('Create an Identity')
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context 'when login is disabled' do
|
83
|
+
context 'when registration is enabled' do
|
84
|
+
let(:identity_options) { { model: anon_ar, enable_registration: true, enable_login: false } }
|
85
|
+
|
86
|
+
it 'bypasses registration form' do
|
87
|
+
get '/auth/identity'
|
88
|
+
|
89
|
+
expect(last_response.body).to eq('HELLO!')
|
90
|
+
expect(last_response.body).not_to be_include('<form')
|
91
|
+
expect(last_response.body).not_to be_include('<a')
|
92
|
+
expect(last_response.body).not_to be_include('Create an Identity')
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'when registration is disabled' do
|
97
|
+
let(:identity_options) { { model: anon_ar, enable_registration: false, enable_login: false } }
|
98
|
+
|
99
|
+
it 'displays a form without a link to register' do
|
100
|
+
get '/auth/identity'
|
101
|
+
|
102
|
+
expect(last_response.body).to eq('HELLO!')
|
103
|
+
expect(last_response.body).not_to be_include('<form')
|
104
|
+
expect(last_response.body).not_to be_include('<a')
|
105
|
+
expect(last_response.body).not_to be_include('Create an Identity')
|
106
|
+
end
|
107
|
+
end
|
36
108
|
end
|
37
109
|
end
|
38
110
|
|
39
111
|
describe '#callback_phase' do
|
40
|
-
let(:user){
|
112
|
+
let(:user) { double(uid: 'user1', info: { 'name' => 'Rockefeller' }) }
|
41
113
|
|
42
114
|
context 'with valid credentials' do
|
43
115
|
before do
|
44
|
-
|
45
|
-
|
46
|
-
post '/auth/identity/callback', :
|
116
|
+
allow(anon_ar).to receive('auth_key').and_return('email')
|
117
|
+
expect(anon_ar).to receive('authenticate').with({ 'email' => 'john' }, 'awesome').and_return(user)
|
118
|
+
post '/auth/identity/callback', auth_key: 'john', password: 'awesome'
|
47
119
|
end
|
48
120
|
|
49
|
-
it '
|
50
|
-
auth_hash.
|
121
|
+
it 'populates the auth hash' do
|
122
|
+
expect(auth_hash).to be_kind_of(Hash)
|
51
123
|
end
|
52
124
|
|
53
|
-
it '
|
54
|
-
auth_hash['uid'].
|
125
|
+
it 'populates the uid' do
|
126
|
+
expect(auth_hash['uid']).to eq('user1')
|
55
127
|
end
|
56
128
|
|
57
|
-
it '
|
58
|
-
auth_hash['info'].
|
129
|
+
it 'populates the info hash' do
|
130
|
+
expect(auth_hash['info']).to eq({ 'name' => 'Rockefeller' })
|
59
131
|
end
|
60
132
|
end
|
61
133
|
|
62
134
|
context 'with invalid credentials' do
|
63
135
|
before do
|
64
|
-
|
65
|
-
OmniAuth.config.on_failure =
|
66
|
-
|
67
|
-
post '/auth/identity/callback', :
|
136
|
+
allow(anon_ar).to receive('auth_key').and_return('email')
|
137
|
+
OmniAuth.config.on_failure = ->(env) { [401, {}, [env['omniauth.error.type'].inspect]] }
|
138
|
+
expect(anon_ar).to receive(:authenticate).with({ 'email' => 'wrong' }, 'login').and_return(false)
|
139
|
+
post '/auth/identity/callback', auth_key: 'wrong', password: 'login'
|
68
140
|
end
|
69
141
|
|
70
|
-
it '
|
71
|
-
last_response.body.
|
142
|
+
it 'fails with :invalid_credentials' do
|
143
|
+
expect(last_response.body).to eq(':invalid_credentials')
|
72
144
|
end
|
73
145
|
end
|
74
146
|
|
75
147
|
context 'with auth scopes' do
|
148
|
+
let(:identity_options) do
|
149
|
+
{ model: anon_ar, locate_conditions: lambda { |req|
|
150
|
+
{ model.auth_key => req['auth_key'], 'user_type' => 'admin' }
|
151
|
+
} }
|
152
|
+
end
|
76
153
|
|
77
|
-
it '
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
post '/auth/identity/callback', :
|
154
|
+
it 'evaluates and pass through conditions proc' do
|
155
|
+
allow(anon_ar).to receive('auth_key').and_return('email')
|
156
|
+
expect(anon_ar).to receive('authenticate').with({ 'email' => 'john', 'user_type' => 'admin' },
|
157
|
+
'awesome').and_return(user)
|
158
|
+
post '/auth/identity/callback', auth_key: 'john', password: 'awesome'
|
82
159
|
end
|
83
160
|
end
|
84
161
|
end
|
85
162
|
|
86
163
|
describe '#registration_form' do
|
87
|
-
|
88
|
-
|
89
|
-
|
164
|
+
context 'registration is enabled' do
|
165
|
+
it 'triggers from /auth/identity/register by default' do
|
166
|
+
get '/auth/identity/register'
|
167
|
+
expect(last_response.body).to be_include('Register Identity')
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
context 'registration is disabled' do
|
172
|
+
let(:identity_options) { { model: anon_ar, enable_registration: false } }
|
173
|
+
|
174
|
+
it 'calls app' do
|
175
|
+
get '/auth/identity/register'
|
176
|
+
expect(last_response.body).to be_include('HELLO!')
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
it 'supports methods other than GET and POST' do
|
181
|
+
head '/auth/identity/register'
|
182
|
+
expect(last_response.status).to eq(404)
|
90
183
|
end
|
91
184
|
end
|
92
185
|
|
93
186
|
describe '#registration_phase' do
|
94
|
-
context '
|
95
|
-
let(:
|
96
|
-
:name => 'Awesome Dude',
|
97
|
-
:email => 'awesome@example.com',
|
98
|
-
:password => 'face',
|
99
|
-
:password_confirmation => 'face'
|
100
|
-
} }
|
187
|
+
context 'registration is disabled' do
|
188
|
+
let(:identity_options) { { model: anon_ar, enable_registration: false } }
|
101
189
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
MockIdentity.should_receive(:create).with(properties).and_return(m)
|
190
|
+
it 'calls app' do
|
191
|
+
post '/auth/identity/register'
|
192
|
+
expect(last_response.body).to eq('HELLO!')
|
106
193
|
end
|
194
|
+
end
|
107
195
|
|
108
|
-
|
196
|
+
context 'with successful creation' do
|
197
|
+
let(:properties) do
|
198
|
+
{
|
199
|
+
name: 'Awesome Dude',
|
200
|
+
email: 'awesome@example.com',
|
201
|
+
password: 'face',
|
202
|
+
password_confirmation: 'face',
|
203
|
+
provider: 'identity'
|
204
|
+
}
|
205
|
+
end
|
206
|
+
|
207
|
+
it 'sets the auth hash' do
|
109
208
|
post '/auth/identity/register', properties
|
110
|
-
auth_hash['uid'].
|
209
|
+
expect(auth_hash['uid']).to match(/\d+/)
|
210
|
+
expect(auth_hash['provider']).to eq('identity')
|
111
211
|
end
|
112
212
|
end
|
113
213
|
|
114
214
|
context 'with invalid identity' do
|
115
|
-
let(:properties)
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
215
|
+
let(:properties) do
|
216
|
+
{
|
217
|
+
name: 'Awesome Dude',
|
218
|
+
email: 'awesome@example.com',
|
219
|
+
password: 'NOT',
|
220
|
+
password_confirmation: 'MATCHING',
|
221
|
+
provider: 'identity'
|
222
|
+
}
|
223
|
+
end
|
224
|
+
let(:invalid_identity) { double(persisted?: false, save: false) }
|
121
225
|
|
122
226
|
before do
|
123
|
-
|
227
|
+
expect(anon_ar).to receive(:new).with(properties).and_return(invalid_identity)
|
124
228
|
end
|
125
229
|
|
126
230
|
context 'default' do
|
127
|
-
it '
|
231
|
+
it 'shows registration form' do
|
128
232
|
post '/auth/identity/register', properties
|
129
|
-
last_response.body.
|
233
|
+
expect(last_response.body).to be_include('Register Identity')
|
234
|
+
expect(last_response.body).to be_include('One or more fields were invalid')
|
130
235
|
end
|
131
236
|
end
|
132
237
|
|
133
238
|
context 'custom on_failed_registration endpoint' do
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
239
|
+
let(:identity_options) do
|
240
|
+
{ model: anon_ar, on_failed_registration: lambda { |env|
|
241
|
+
[404, { 'env' => env }, ["FAIL'DOH!"]]
|
242
|
+
} }
|
243
|
+
end
|
244
|
+
|
245
|
+
it 'sets the identity hash' do
|
246
|
+
post '/auth/identity/register', properties
|
247
|
+
expect(identity_hash).to eq(invalid_identity)
|
248
|
+
expect(last_response.body).to be_include("FAIL'DOH!")
|
249
|
+
expect(last_response.body).not_to be_include('One or more fields were invalid')
|
139
250
|
end
|
140
251
|
end
|
141
252
|
end
|