omniauth-identity 2.0.0 → 3.0.0

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.
@@ -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