omniauth-identity 2.0.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,11 +4,8 @@ module OmniAuth
4
4
  module Identity
5
5
  module Models
6
6
  module Mongoid
7
-
8
7
  def self.included(base)
9
-
10
8
  base.class_eval do
11
-
12
9
  include ::OmniAuth::Identity::Model
13
10
  include ::OmniAuth::Identity::SecurePassword
14
11
 
@@ -16,17 +13,14 @@ module OmniAuth
16
13
 
17
14
  def self.auth_key=(key)
18
15
  super
19
- validates_uniqueness_of key, :case_sensitive => false
16
+ validates_uniqueness_of key, case_sensitive: false
20
17
  end
21
18
 
22
19
  def self.locate(search_hash)
23
20
  where(search_hash).first
24
21
  end
25
-
26
22
  end
27
-
28
23
  end
29
-
30
24
  end
31
25
  end
32
26
  end
@@ -9,9 +9,7 @@ module OmniAuth
9
9
  # a has_secure_password method.
10
10
  module SecurePassword
11
11
  def self.included(base)
12
- unless base.respond_to?(:has_secure_password)
13
- base.extend ClassMethods
14
- end
12
+ base.extend ClassMethods unless base.respond_to?(:has_secure_password)
15
13
  end
16
14
 
17
15
  module ClassMethods
@@ -40,7 +38,7 @@ module OmniAuth
40
38
  # User.find_by_name("david").try(:authenticate, "notright") # => nil
41
39
  # User.find_by_name("david").try(:authenticate, "mUc3m00RsqyRe") # => user
42
40
  def has_secure_password
43
- attr_reader :password
41
+ attr_reader :password
44
42
 
45
43
  validates_confirmation_of :password
46
44
  validates_presence_of :password_digest
@@ -6,39 +6,53 @@ module OmniAuth
6
6
  class Identity
7
7
  include OmniAuth::Strategy
8
8
 
9
- option :fields, [:name, :email]
9
+ option :fields, %i[name email]
10
+ option :enable_login, true # See #other_phase documentation
10
11
  option :on_login, nil
11
12
  option :on_registration, nil
12
13
  option :on_failed_registration, nil
13
- option :locate_conditions, lambda{|req| {model.auth_key => req['auth_key']} }
14
+ option :enable_registration, true
15
+ option :locate_conditions, ->(req) { { model.auth_key => req['auth_key'] } }
14
16
 
15
17
  def request_phase
16
18
  if options[:on_login]
17
- options[:on_login].call(self.env)
19
+ options[:on_login].call(env)
18
20
  else
19
21
  OmniAuth::Form.build(
20
- :title => (options[:title] || "Identity Verification"),
21
- :url => callback_path
22
+ title: (options[:title] || 'Identity Verification'),
23
+ url: callback_path
22
24
  ) do |f|
23
25
  f.text_field 'Login', 'auth_key'
24
26
  f.password_field 'Password', 'password'
25
- f.html "<p align='center'><a href='#{registration_path}'>Create an Identity</a></p>"
27
+ if options[:enable_registration]
28
+ f.html "<p align='center'><a href='#{registration_path}'>Create an Identity</a></p>"
29
+ end
26
30
  end.to_response
27
31
  end
28
32
  end
29
33
 
30
34
  def callback_phase
31
35
  return fail!(:invalid_credentials) unless identity
36
+
32
37
  super
33
38
  end
34
39
 
35
40
  def other_phase
36
- if on_registration_path?
41
+ if options[:enable_registration] && on_registration_path?
37
42
  if request.get?
38
43
  registration_form
39
44
  elsif request.post?
40
45
  registration_phase
46
+ else
47
+ call_app!
41
48
  end
49
+ elsif options[:enable_login] && on_request_path?
50
+ # OmniAuth, by default, disables "GET" requests for security reasons.
51
+ # This effectively disables omniauth-identity tool's login form feature.
52
+ # Because it is disabled by default, and because enabling it would desecuritize all the other
53
+ # OmniAuth strategies that may be implemented, we do not ask users to modify that setting.
54
+ # Instead we hook in here in the "other_phase", with a config setting of our own: `enable_login`
55
+ request_phase
42
56
  else
43
57
  call_app!
44
58
  end
@@ -46,9 +60,9 @@ module OmniAuth
46
60
 
47
61
  def registration_form
48
62
  if options[:on_registration]
49
- options[:on_registration].call(self.env)
63
+ options[:on_registration].call(env)
50
64
  else
51
- OmniAuth::Form.build(:title => 'Register Identity') do |f|
65
+ OmniAuth::Form.build(title: 'Register Identity') do |f|
52
66
  options[:fields].each do |field|
53
67
  f.text_field field.to_s.capitalize, field.to_s
54
68
  end
@@ -59,23 +73,26 @@ module OmniAuth
59
73
  end
60
74
 
61
75
  def registration_phase
62
- attributes = (options[:fields] + [:password, :password_confirmation]).inject({}){|h,k| h[k] = request[k.to_s]; h}
76
+ attributes = (options[:fields] + %i[password password_confirmation]).each_with_object({}) do |k, h|
77
+ h[k] = request[k.to_s]
78
+ end
79
+ if model.respond_to?(:column_names) && model.column_names.include?('provider')
80
+ attributes.reverse_merge!(provider: 'identity')
81
+ end
63
82
  @identity = model.create(attributes)
64
83
  if @identity.persisted?
65
84
  env['PATH_INFO'] = callback_path
66
85
  callback_phase
86
+ elsif options[:on_failed_registration]
87
+ env['omniauth.identity'] = @identity
88
+ options[:on_failed_registration].call(env)
67
89
  else
68
- if options[:on_failed_registration]
69
- self.env['omniauth.identity'] = @identity
70
- options[:on_failed_registration].call(self.env)
71
- else
72
- registration_form
73
- end
90
+ registration_form
74
91
  end
75
92
  end
76
93
 
77
- uid{ identity.uid }
78
- info{ identity.info }
94
+ uid { identity.uid }
95
+ info { identity.info }
79
96
 
80
97
  def registration_path
81
98
  options[:registration_path] || "#{path_prefix}/#{name}/register"
@@ -86,13 +103,13 @@ module OmniAuth
86
103
  end
87
104
 
88
105
  def identity
89
- if options.locate_conditions.is_a? Proc
90
- conditions = instance_exec(request, &options.locate_conditions)
106
+ if options[:locate_conditions].is_a? Proc
107
+ conditions = instance_exec(request, &options[:locate_conditions])
91
108
  conditions.to_hash
92
109
  else
93
- conditions = options.locate_conditions.to_hash
110
+ conditions = options[:locate_conditions].to_hash
94
111
  end
95
- @identity ||= model.authenticate(conditions, request['password'] )
112
+ @identity ||= model.authenticate(conditions, request['password'])
96
113
  end
97
114
 
98
115
  def model
@@ -2,87 +2,88 @@ class ExampleModel
2
2
  include OmniAuth::Identity::Model
3
3
  end
4
4
 
5
- describe OmniAuth::Identity::Model do
5
+ RSpec.describe OmniAuth::Identity::Model do
6
6
  context 'Class Methods' do
7
- subject{ ExampleModel }
7
+ subject { ExampleModel }
8
8
 
9
9
  describe '.locate' do
10
- it('should be abstract'){ expect{ subject.locate('abc') }.to raise_error(NotImplementedError) }
10
+ it('is abstract') { expect { subject.locate('abc') }.to raise_error(NotImplementedError) }
11
11
  end
12
12
 
13
13
  describe '.authenticate' do
14
- it 'should call locate and then authenticate' do
15
- mocked_instance = double('ExampleModel', :authenticate => 'abbadoo')
14
+ it 'calls locate and then authenticate' do
15
+ mocked_instance = double('ExampleModel', authenticate: 'abbadoo')
16
16
  allow(subject).to receive(:locate).with('email' => 'example').and_return(mocked_instance)
17
- expect(subject.authenticate({'email' => 'example'},'pass')).to eq('abbadoo')
17
+ expect(subject.authenticate({ 'email' => 'example' }, 'pass')).to eq('abbadoo')
18
18
  end
19
19
 
20
- it 'should call locate with additional scopes when provided' do
21
- mocked_instance = double('ExampleModel', :authenticate => 'abbadoo')
22
- allow(subject).to receive(:locate).with('email' => 'example', 'user_type' => 'admin').and_return(mocked_instance)
23
- expect(subject.authenticate({'email' => 'example', 'user_type' => 'admin'}, 'pass')).to eq('abbadoo')
20
+ it 'calls locate with additional scopes when provided' do
21
+ mocked_instance = double('ExampleModel', authenticate: 'abbadoo')
22
+ allow(subject).to receive(:locate).with('email' => 'example',
23
+ 'user_type' => 'admin').and_return(mocked_instance)
24
+ expect(subject.authenticate({ 'email' => 'example', 'user_type' => 'admin' }, 'pass')).to eq('abbadoo')
24
25
  end
25
26
 
26
- it 'should recover gracefully if locate is nil' do
27
+ it 'recovers gracefully if locate is nil' do
27
28
  allow(subject).to receive(:locate).and_return(nil)
28
- expect(subject.authenticate('blah','foo')).to be false
29
+ expect(subject.authenticate('blah', 'foo')).to be false
29
30
  end
30
31
  end
31
32
  end
32
33
 
33
34
  context 'Instance Methods' do
34
- subject{ ExampleModel.new }
35
+ subject { ExampleModel.new }
35
36
 
36
37
  describe '#authenticate' do
37
- it('should be abstract'){ expect{ subject.authenticate('abc') }.to raise_error(NotImplementedError) }
38
+ it('is abstract') { expect { subject.authenticate('abc') }.to raise_error(NotImplementedError) }
38
39
  end
39
40
 
40
41
  describe '#uid' do
41
- it 'should default to #id' do
42
+ it 'defaults to #id' do
42
43
  allow(subject).to receive(:respond_to?).with(:id).and_return(true)
43
44
  allow(subject).to receive(:id).and_return 'wakka-do'
44
45
  expect(subject.uid).to eq('wakka-do')
45
46
  end
46
47
 
47
- it 'should stringify it' do
48
+ it 'stringifies it' do
48
49
  allow(subject).to receive(:id).and_return 123
49
50
  expect(subject.uid).to eq('123')
50
51
  end
51
52
 
52
- it 'should raise NotImplementedError if #id is not defined' do
53
+ it 'raises NotImplementedError if #id is not defined' do
53
54
  allow(subject).to receive(:respond_to?).with(:id).and_return(false)
54
- expect{ subject.uid }.to raise_error(NotImplementedError)
55
+ expect { subject.uid }.to raise_error(NotImplementedError)
55
56
  end
56
57
  end
57
58
 
58
59
  describe '#auth_key' do
59
- it 'should default to #email' do
60
+ it 'defaults to #email' do
60
61
  allow(subject).to receive(:respond_to?).with(:email).and_return(true)
61
62
  allow(subject).to receive(:email).and_return('bob@bob.com')
62
63
  expect(subject.auth_key).to eq('bob@bob.com')
63
64
  end
64
65
 
65
- it 'should use the class .auth_key' do
66
+ it 'uses the class .auth_key' do
66
67
  subject.class.auth_key 'login'
67
68
  allow(subject).to receive(:login).and_return 'bob'
68
69
  expect(subject.auth_key).to eq('bob')
69
70
  subject.class.auth_key nil
70
71
  end
71
72
 
72
- it 'should raise a NotImplementedError if the auth_key method is not defined' do
73
- expect{ subject.auth_key }.to raise_error(NotImplementedError)
73
+ it 'raises a NotImplementedError if the auth_key method is not defined' do
74
+ expect { subject.auth_key }.to raise_error(NotImplementedError)
74
75
  end
75
76
  end
76
77
 
77
78
  describe '#auth_key=' do
78
- it 'should default to setting email' do
79
+ it 'defaults to setting email' do
79
80
  allow(subject).to receive(:respond_to?).with(:email=).and_return(true)
80
81
  expect(subject).to receive(:email=).with 'abc'
81
-
82
+
82
83
  subject.auth_key = 'abc'
83
84
  end
84
85
 
85
- it 'should use a custom .auth_key if one is provided' do
86
+ it 'uses a custom .auth_key if one is provided' do
86
87
  subject.class.auth_key 'login'
87
88
  allow(subject).to receive(:respond_to?).with(:login=).and_return(true)
88
89
  expect(subject).to receive(:login=).with('abc')
@@ -90,28 +91,28 @@ describe OmniAuth::Identity::Model do
90
91
  subject.auth_key = 'abc'
91
92
  end
92
93
 
93
- it 'should raise a NotImplementedError if the autH_key method is not defined' do
94
- expect{ subject.auth_key = 'broken' }.to raise_error(NotImplementedError)
94
+ it 'raises a NotImplementedError if the autH_key method is not defined' do
95
+ expect { subject.auth_key = 'broken' }.to raise_error(NotImplementedError)
95
96
  end
96
97
  end
97
98
 
98
99
  describe '#info' do
99
- it 'should include attributes that are set' do
100
+ it 'includes attributes that are set' do
100
101
  allow(subject).to receive(:name).and_return('Bob Bobson')
101
102
  allow(subject).to receive(:nickname).and_return('bob')
102
103
 
103
104
  expect(subject.info).to eq({
104
- 'name' => 'Bob Bobson',
105
- 'nickname' => 'bob'
106
- })
105
+ 'name' => 'Bob Bobson',
106
+ 'nickname' => 'bob'
107
+ })
107
108
  end
108
109
 
109
- it 'should automatically set name off of nickname' do
110
+ it 'automaticallies set name off of nickname' do
110
111
  allow(subject).to receive(:nickname).and_return('bob')
111
112
  subject.info['name'] == 'bob'
112
113
  end
113
114
 
114
- it 'should not overwrite a provided name' do
115
+ it 'does not overwrite a provided name' do
115
116
  allow(subject).to receive(:name).and_return('Awesome Dude')
116
117
  allow(subject).to receive(:first_name).and_return('Frank')
117
118
  expect(subject.info['name']).to eq('Awesome Dude')
@@ -1,16 +1,28 @@
1
- describe(OmniAuth::Identity::Models::ActiveRecord, :db => true) do
2
- class TestIdentity < OmniAuth::Identity::Models::ActiveRecord; end
3
-
4
- describe "model", type: :model do
5
- subject { TestIdentity }
1
+ RSpec.describe(OmniAuth::Identity::Models::ActiveRecord, db: true) do
2
+ describe 'model', type: :model do
3
+ subject(:model_klass) do
4
+ AnonymousActiveRecord.generate(
5
+ parent_klass: 'OmniAuth::Identity::Models::ActiveRecord',
6
+ columns: %w[name provider],
7
+ connection_params: { adapter: 'sqlite3', encoding: 'utf8', database: ':memory:' }
8
+ ) do
9
+ def flower
10
+ '🌸'
11
+ end
12
+ end
13
+ end
6
14
 
7
- it 'should delegate locate to the where query method' do
8
- allow(subject).to receive(:where).with('ham_sandwich' => 'open faced', 'category' => 'sandwiches').and_return(['wakka'])
9
- expect(subject.locate('ham_sandwich' => 'open faced', 'category' => 'sandwiches')).to eq('wakka')
15
+ it 'delegates locate to the where query method' do
16
+ allow(model_klass).to receive(:where).with('ham_sandwich' => 'open faced', 'category' => 'sandwiches',
17
+ 'provider' => 'identity').and_return(['wakka'])
18
+ expect(model_klass.locate('ham_sandwich' => 'open faced', 'category' => 'sandwiches')).to eq('wakka')
10
19
  end
20
+ end
11
21
 
12
- it 'should not use STI rules for its table name' do
13
- expect(subject.table_name).to eq('test_identities')
22
+ describe '#table_name' do
23
+ class TestIdentity < OmniAuth::Identity::Models::ActiveRecord; end
24
+ it 'does not use STI rules for its table name' do
25
+ expect(TestIdentity.table_name).to eq('test_identities')
14
26
  end
15
27
  end
16
28
  end
@@ -1,4 +1,4 @@
1
- describe(OmniAuth::Identity::Models::CouchPotatoModule, :db => true) do
1
+ RSpec.describe(OmniAuth::Identity::Models::CouchPotatoModule, db: true) do
2
2
  class CouchPotatoTestIdentity
3
3
  include CouchPotato::Persistence
4
4
  include OmniAuth::Identity::Models::CouchPotatoModule
@@ -8,8 +8,9 @@ describe(OmniAuth::Identity::Models::CouchPotatoModule, :db => true) do
8
8
  describe 'model', type: :model do
9
9
  subject { CouchPotatoTestIdentity }
10
10
 
11
- it 'should delegate locate to the where query method' do
12
- allow(subject).to receive(:where).with('ham_sandwich' => 'open faced', 'category' => 'sandwiches').and_return(['wakka'])
11
+ it 'delegates locate to the where query method' do
12
+ allow(subject).to receive(:where).with('ham_sandwich' => 'open faced',
13
+ 'category' => 'sandwiches').and_return(['wakka'])
13
14
  expect(subject.locate('ham_sandwich' => 'open faced', 'category' => 'sandwiches')).to eq('wakka')
14
15
  end
15
16
  end
@@ -1,4 +1,4 @@
1
- describe(OmniAuth::Identity::Models::Mongoid, :db => true) do
1
+ RSpec.describe(OmniAuth::Identity::Models::Mongoid, db: true) do
2
2
  class MongoidTestIdentity
3
3
  include Mongoid::Document
4
4
  include OmniAuth::Identity::Models::Mongoid
@@ -6,17 +6,18 @@ describe(OmniAuth::Identity::Models::Mongoid, :db => true) do
6
6
  store_in database: 'db1', collection: 'mongoid_test_identities', client: 'secondary'
7
7
  end
8
8
 
9
- describe "model", type: :model do
9
+ describe 'model', type: :model do
10
10
  subject { MongoidTestIdentity }
11
11
 
12
12
  it { is_expected.to be_mongoid_document }
13
13
 
14
14
  it 'does not munge collection name' do
15
- is_expected.to be_stored_in(database: 'db1', collection: 'mongoid_test_identities', client: 'secondary')
15
+ expect(subject).to be_stored_in(database: 'db1', collection: 'mongoid_test_identities', client: 'secondary')
16
16
  end
17
17
 
18
- it 'should delegate locate to the where query method' do
19
- allow(subject).to receive(:where).with('ham_sandwich' => 'open faced', 'category' => 'sandwiches').and_return(['wakka'])
18
+ it 'delegates locate to the where query method' do
19
+ allow(subject).to receive(:where).with('ham_sandwich' => 'open faced',
20
+ 'category' => 'sandwiches').and_return(['wakka'])
20
21
  expect(subject.locate('ham_sandwich' => 'open faced', 'category' => 'sandwiches')).to eq('wakka')
21
22
  end
22
23
  end
@@ -5,19 +5,19 @@ end
5
5
  class DoesNotHaveTheMethod
6
6
  end
7
7
 
8
- describe OmniAuth::Identity::SecurePassword do
9
- it 'should extend with the class methods if it does not have the method' do
8
+ RSpec.describe OmniAuth::Identity::SecurePassword do
9
+ it 'extends with the class methods if it does not have the method' do
10
10
  expect(DoesNotHaveTheMethod).to receive(:extend).with(OmniAuth::Identity::SecurePassword::ClassMethods)
11
- DoesNotHaveTheMethod.send(:include, OmniAuth::Identity::SecurePassword)
11
+ DoesNotHaveTheMethod.include OmniAuth::Identity::SecurePassword
12
12
  end
13
13
 
14
- it 'should not extend if the method is already defined' do
14
+ it 'does not extend if the method is already defined' do
15
15
  expect(HasTheMethod).not_to receive(:extend)
16
- HasTheMethod.send(:include, OmniAuth::Identity::SecurePassword)
16
+ HasTheMethod.include OmniAuth::Identity::SecurePassword
17
17
  end
18
18
 
19
- it 'should respond to has_secure_password afterwards' do
20
- [HasTheMethod,DoesNotHaveTheMethod].each do |klass|
19
+ it 'responds to has_secure_password afterwards' do
20
+ [HasTheMethod, DoesNotHaveTheMethod].each do |klass|
21
21
  klass.send(:include, OmniAuth::Identity::SecurePassword)
22
22
  expect(klass).to be_respond_to(:has_secure_password)
23
23
  end
@@ -1,139 +1,253 @@
1
- class MockIdentity; end
2
-
3
- describe OmniAuth::Strategies::Identity do
1
+ RSpec.describe OmniAuth::Strategies::Identity do
4
2
  attr_accessor :app
5
3
 
6
- let(:auth_hash){ last_response.headers['env']['omniauth.auth'] }
7
- let(:identity_hash){ last_response.headers['env']['omniauth.identity'] }
4
+ let(:auth_hash) { last_response.headers['env']['omniauth.auth'] }
5
+ let(:identity_hash) { last_response.headers['env']['omniauth.identity'] }
6
+ let(:identity_options) { {} }
7
+ let(:anon_ar) do
8
+ AnonymousActiveRecord.generate(
9
+ columns: %w[name provider],
10
+ connection_params: { adapter: 'sqlite3', encoding: 'utf8', database: ':memory:' }
11
+ ) do
12
+ def balloon
13
+ '🎈'
14
+ end
15
+ end
16
+ end
8
17
 
9
18
  # customize rack app for testing, if block is given, reverts to default
10
19
  # rack app after testing is done
11
20
  def set_app!(identity_options = {})
12
- identity_options = {:model => MockIdentity}.merge(identity_options)
13
- old_app = self.app
21
+ old_app = app
14
22
  self.app = Rack::Builder.app do
15
23
  use Rack::Session::Cookie, secret: '1234567890qwertyuiop'
16
24
  use OmniAuth::Strategies::Identity, identity_options
17
- run lambda{|env| [404, {'env' => env}, ["HELLO!"]]}
25
+ run ->(env) { [404, { 'env' => env }, ['HELLO!']] }
18
26
  end
19
27
  if block_given?
20
28
  yield
21
29
  self.app = old_app
22
30
  end
23
- self.app
31
+ app
24
32
  end
25
33
 
26
- before(:all) do
27
- set_app!
34
+ before do
35
+ opts = identity_options.reverse_merge({ model: anon_ar })
36
+ set_app!(opts)
28
37
  end
29
38
 
30
39
  describe '#request_phase' do
31
- it 'should display a form' do
32
- get '/auth/identity'
33
- expect(last_response.body).to be_include("<form")
40
+ context 'with default settings' do
41
+ let(:identity_options) { { model: anon_ar } }
42
+
43
+ it 'displays a form' do
44
+ get '/auth/identity'
45
+
46
+ expect(last_response.body).not_to eq('HELLO!')
47
+ expect(last_response.body).to be_include('<form')
48
+ end
49
+ end
50
+
51
+ context 'when login is enabled' do
52
+ context 'when registration is enabled' do
53
+ let(:identity_options) { { model: anon_ar, enable_registration: true, enable_login: true } }
54
+
55
+ it 'displays a form with a link to register' do
56
+ get '/auth/identity'
57
+
58
+ expect(last_response.body).not_to eq('HELLO!')
59
+ expect(last_response.body).to be_include('<form')
60
+ expect(last_response.body).to be_include('<a')
61
+ expect(last_response.body).to be_include('Create an Identity')
62
+ end
63
+ end
64
+
65
+ context 'when registration is disabled' do
66
+ let(:identity_options) { { model: anon_ar, enable_registration: false, enable_login: true } }
67
+
68
+ it 'displays a form without a link to register' do
69
+ get '/auth/identity'
70
+
71
+ expect(last_response.body).not_to eq('HELLO!')
72
+ expect(last_response.body).to be_include('<form')
73
+ expect(last_response.body).not_to be_include('<a')
74
+ expect(last_response.body).not_to be_include('Create an Identity')
75
+ end
76
+ end
77
+ end
78
+
79
+ context 'when login is disabled' do
80
+ context 'when registration is enabled' do
81
+ let(:identity_options) { { model: anon_ar, enable_registration: true, enable_login: false } }
82
+
83
+ it 'bypasses registration form' do
84
+ get '/auth/identity'
85
+
86
+ expect(last_response.body).to eq('HELLO!')
87
+ expect(last_response.body).not_to be_include('<form')
88
+ expect(last_response.body).not_to be_include('<a')
89
+ expect(last_response.body).not_to be_include('Create an Identity')
90
+ end
91
+ end
92
+
93
+ context 'when registration is disabled' do
94
+ let(:identity_options) { { model: anon_ar, enable_registration: false, enable_login: false } }
95
+
96
+ it 'displays a form without a link to register' do
97
+ get '/auth/identity'
98
+
99
+ expect(last_response.body).to eq('HELLO!')
100
+ expect(last_response.body).not_to be_include('<form')
101
+ expect(last_response.body).not_to be_include('<a')
102
+ expect(last_response.body).not_to be_include('Create an Identity')
103
+ end
104
+ end
34
105
  end
35
106
  end
36
107
 
37
108
  describe '#callback_phase' do
38
- let(:user){ double(:uid => 'user1', :info => {'name' => 'Rockefeller'})}
109
+ let(:user) { double(uid: 'user1', info: { 'name' => 'Rockefeller' }) }
39
110
 
40
111
  context 'with valid credentials' do
41
112
  before do
42
- allow(MockIdentity).to receive('auth_key').and_return('email')
43
- expect(MockIdentity).to receive('authenticate').with({'email' => 'john'},'awesome').and_return(user)
44
- post '/auth/identity/callback', :auth_key => 'john', :password => 'awesome'
113
+ allow(anon_ar).to receive('auth_key').and_return('email')
114
+ expect(anon_ar).to receive('authenticate').with({ 'email' => 'john' }, 'awesome').and_return(user)
115
+ post '/auth/identity/callback', auth_key: 'john', password: 'awesome'
45
116
  end
46
117
 
47
- it 'should populate the auth hash' do
118
+ it 'populates the auth hash' do
48
119
  expect(auth_hash).to be_kind_of(Hash)
49
120
  end
50
121
 
51
- it 'should populate the uid' do
122
+ it 'populates the uid' do
52
123
  expect(auth_hash['uid']).to eq('user1')
53
124
  end
54
125
 
55
- it 'should populate the info hash' do
56
- expect(auth_hash['info']).to eq({'name' => 'Rockefeller'})
126
+ it 'populates the info hash' do
127
+ expect(auth_hash['info']).to eq({ 'name' => 'Rockefeller' })
57
128
  end
58
129
  end
59
130
 
60
131
  context 'with invalid credentials' do
61
132
  before do
62
- allow(MockIdentity).to receive('auth_key').and_return('email')
63
- OmniAuth.config.on_failure = lambda{|env| [401, {}, [env['omniauth.error.type'].inspect]]}
64
- expect(MockIdentity).to receive(:authenticate).with({'email' => 'wrong'},'login').and_return(false)
65
- post '/auth/identity/callback', :auth_key => 'wrong', :password => 'login'
133
+ allow(anon_ar).to receive('auth_key').and_return('email')
134
+ OmniAuth.config.on_failure = ->(env) { [401, {}, [env['omniauth.error.type'].inspect]] }
135
+ expect(anon_ar).to receive(:authenticate).with({ 'email' => 'wrong' }, 'login').and_return(false)
136
+ post '/auth/identity/callback', auth_key: 'wrong', password: 'login'
66
137
  end
67
138
 
68
- it 'should fail with :invalid_credentials' do
139
+ it 'fails with :invalid_credentials' do
69
140
  expect(last_response.body).to eq(':invalid_credentials')
70
141
  end
71
142
  end
72
143
 
73
144
  context 'with auth scopes' do
145
+ let(:identity_options) do
146
+ { model: anon_ar, locate_conditions: lambda { |req|
147
+ { model.auth_key => req['auth_key'], 'user_type' => 'admin' }
148
+ } }
149
+ end
74
150
 
75
- it 'should evaluate and pass through conditions proc' do
76
- allow(MockIdentity).to receive('auth_key').and_return('email')
77
- set_app!( :locate_conditions => lambda{|req| {model.auth_key => req['auth_key'], 'user_type' => 'admin'} } )
78
- expect(MockIdentity).to receive('authenticate').with( {'email' => 'john', 'user_type' => 'admin'}, 'awesome' ).and_return(user)
79
- post '/auth/identity/callback', :auth_key => 'john', :password => 'awesome'
151
+ it 'evaluates and pass through conditions proc' do
152
+ allow(anon_ar).to receive('auth_key').and_return('email')
153
+ expect(anon_ar).to receive('authenticate').with({ 'email' => 'john', 'user_type' => 'admin' },
154
+ 'awesome').and_return(user)
155
+ post '/auth/identity/callback', auth_key: 'john', password: 'awesome'
80
156
  end
81
157
  end
82
158
  end
83
159
 
84
160
  describe '#registration_form' do
85
- it 'should trigger from /auth/identity/register by default' do
86
- get '/auth/identity/register'
87
- expect(last_response.body).to be_include("Register Identity")
161
+ context 'registration is enabled' do
162
+ it 'triggers from /auth/identity/register by default' do
163
+ get '/auth/identity/register'
164
+ expect(last_response.body).to be_include('Register Identity')
165
+ end
166
+ end
167
+
168
+ context 'registration is disabled' do
169
+ let(:identity_options) { { model: anon_ar, enable_registration: false } }
170
+
171
+ it 'calls app' do
172
+ get '/auth/identity/register'
173
+ expect(last_response.body).to be_include('HELLO!')
174
+ end
175
+ end
176
+
177
+ it 'supports methods other than GET and POST' do
178
+ head '/auth/identity/register'
179
+ expect(last_response.status).to eq(404)
88
180
  end
89
181
  end
90
182
 
91
183
  describe '#registration_phase' do
184
+ context 'registration is disabled' do
185
+ let(:identity_options) { { model: anon_ar, enable_registration: false } }
186
+
187
+ it 'calls app' do
188
+ post '/auth/identity/register'
189
+ expect(last_response.body).to eq('HELLO!')
190
+ end
191
+ end
192
+
92
193
  context 'with successful creation' do
93
- let(:properties){ {
94
- :name => 'Awesome Dude',
95
- :email => 'awesome@example.com',
96
- :password => 'face',
97
- :password_confirmation => 'face'
98
- } }
194
+ let(:properties) do
195
+ {
196
+ name: 'Awesome Dude',
197
+ email: 'awesome@example.com',
198
+ password: 'face',
199
+ password_confirmation: 'face',
200
+ provider: 'identity'
201
+ }
202
+ end
99
203
 
100
204
  before do
101
- allow(MockIdentity).to receive('auth_key').and_return('email')
102
- m = double(:uid => 'abc', :name => 'Awesome Dude', :email => 'awesome@example.com', :info => {:name => 'DUUUUDE!'}, :persisted? => true)
103
- expect(MockIdentity).to receive(:create).with(properties).and_return(m)
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)
104
209
  end
105
210
 
106
- it 'should set the auth hash' do
211
+ it 'sets the auth hash' do
107
212
  post '/auth/identity/register', properties
108
213
  expect(auth_hash['uid']).to eq('abc')
109
214
  end
110
215
  end
111
216
 
112
217
  context 'with invalid identity' do
113
- let(:properties) { {
114
- :name => 'Awesome Dude',
115
- :email => 'awesome@example.com',
116
- :password => 'NOT',
117
- :password_confirmation => 'MATCHING'
118
- } }
218
+ let(:properties) do
219
+ {
220
+ name: 'Awesome Dude',
221
+ email: 'awesome@example.com',
222
+ password: 'NOT',
223
+ password_confirmation: 'MATCHING',
224
+ provider: 'identity'
225
+ }
226
+ end
227
+ let(:invalid_identity) { double(persisted?: false) }
119
228
 
120
229
  before do
121
- expect(MockIdentity).to receive(:create).with(properties).and_return(double(:persisted? => false))
230
+ expect(anon_ar).to receive(:create).with(properties).and_return(invalid_identity)
122
231
  end
123
232
 
124
233
  context 'default' do
125
- it 'should show registration form' do
234
+ it 'shows registration form' do
126
235
  post '/auth/identity/register', properties
127
- expect(last_response.body).to be_include("Register Identity")
236
+ expect(last_response.body).to be_include('Register Identity')
128
237
  end
129
238
  end
130
239
 
131
240
  context 'custom on_failed_registration endpoint' do
132
- it 'should set the identity hash' do
133
- set_app!(:on_failed_registration => lambda{|env| [404, {'env' => env}, ["HELLO!"]]}) do
134
- post '/auth/identity/register', properties
135
- expect(identity_hash).not_to be_nil
136
- end
241
+ let(:identity_options) do
242
+ { model: anon_ar, on_failed_registration: lambda { |env|
243
+ [404, { 'env' => env }, ["FAIL'DOH!"]]
244
+ } }
245
+ end
246
+
247
+ it 'sets the identity hash' do
248
+ post '/auth/identity/register', properties
249
+ expect(identity_hash).to eq(invalid_identity)
250
+ expect(last_response.body).to be_include("FAIL'DOH!")
137
251
  end
138
252
  end
139
253
  end