omniauth-identity 3.0.2 → 3.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8e337a130887896ec09b2aa2a66fa1064a87b5aad59d1e068d484a2d2666f691
4
- data.tar.gz: 7cdf49c8f0dc5db0d481233c91f9800932880d243f2c8311dc9336d3830d1296
3
+ metadata.gz: 629d1327cd3aa697de7139825ca429e8829886526da60aa233937643a56caf54
4
+ data.tar.gz: f8fa65f35a26646fcec82b86208da5a511e7639be3388997ede74e0b8df98ca8
5
5
  SHA512:
6
- metadata.gz: 83e043a28067c4e22ce4be6932901eea262846000623626e73f9b6efa3ee2cd8a63263d93240d81173533d8db4e3a86815bf653814b26ced28b16b29e4787762
7
- data.tar.gz: b12161b52c4d4f3b2d5e19d954ad965f0a7c73d4622a50f8004c2659ccd06445f19e20db23c81926f3ff9dc74930739f3f31d69c4da351e1208ea055832700a6
6
+ metadata.gz: 35d08b45518df49d12131b94fdd26110448161809153f782f709369f85488a30dda1bc2fc38121e19beda06c048bf1c8db5b2f901540ab10133bd52925cfe941
7
+ data.tar.gz: dc462e3a8e3733565d2d660bcf6495460e77376469f2cab70d140bff22a07c5f63b0fb3b09b94774956f1c9f47f67f2cbffdcf797e653cc112f31460a26b004a
data/CHANGELOG.md CHANGED
@@ -8,6 +8,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8
8
 
9
9
  ## [Unreleased]
10
10
 
11
+ ## [3.0.3] - 2021-02-14
12
+
13
+ ### Added
14
+
15
+ - Add option `:on_validation`, which can be used to add a Captcha
16
+ - See [example here](https://github.com/omniauth/omniauth-identity/pull/86#issue-63225122)
17
+ - Add support for nobrainer, an ORM for RethinkDB
18
+ - Validation error message on invalid registration form submission
19
+
20
+ ### Removed
21
+
22
+ - ruby-head build... simply too slow
23
+
11
24
  ## [3.0.2] - 2021-02-14
12
25
 
13
26
  ### Fixed
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # OmniAuth Identity
2
2
 
3
+ [![Version](https://img.shields.io/gem/v/omniauth-identity.svg)](https://rubygems.org/gems/omniauth-identity)
4
+ [![Depfu](https://badges.depfu.com/badges/6c9b45362951b872127f9e46d39bed76/count.svg)](https://depfu.com/github/omniauth/omniauth-identity?project_id=22381)
3
5
  [![Build Status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2Fomniauth%2Fomniauth-identity%2Fbadge&style=flat)](https://actions-badge.atrox.dev/omniauth/omniauth-identity/goto)
4
6
  [![Maintainability](https://api.codeclimate.com/v1/badges/621d6211cb2e0959ce00/maintainability)](https://codeclimate.com/github/omniauth/omniauth-identity/maintainability)
5
7
  [![Test Coverage](https://api.codeclimate.com/v1/badges/621d6211cb2e0959ce00/test_coverage)](https://codeclimate.com/github/omniauth/omniauth-identity/test_coverage)
@@ -17,7 +19,7 @@ basic construct for user management and then gets out of the way.
17
19
 
18
20
  This gem is compatible with, as of Feb 2021, version 3:
19
21
 
20
- * Latest released version of omniauth, v2.0.2
22
+ * Latest released version of omniauth, v2.0.2
21
23
  * Ruby 2.4, 2.5, 2.6, 2.7, 3.0, ruby-head
22
24
 
23
25
  ## Installation
@@ -56,6 +58,13 @@ with `:model` argument above) that will be able to persist the information
56
58
  provided by the user. Luckily for you, there are pre-built models for popular
57
59
  ORMs that make this dead simple.
58
60
 
61
+ Once you've got an `Identity` persistence model and the strategy up and
62
+ running, you can point users to `/auth/identity` and it will request
63
+ that they log in or give them the opportunity to sign up for an account.
64
+ Once they have authenticated with their identity, OmniAuth will call
65
+ through to `/auth/identity/callback` with the same kinds of information
66
+ it would had the user authenticated through an external provider.
67
+
59
68
  **Note:** OmniAuth Identity is different from many other user authentication
60
69
  systems in that it is *not* built to store authentication information in your primary
61
70
  `User` model. Instead, the `Identity` model should be **associated** with your
@@ -92,33 +101,6 @@ class Identity
92
101
  end
93
102
  ```
94
103
 
95
- ### MongoMapper
96
-
97
- Unfortunately MongoMapper is **not supported** in `omniauth-identity` from >= v2.0 as a result of it
98
- not being maintained for several years.
99
-
100
- It wasn't possible to include Mongoid *and* MongoMapper due to incompatible gem version
101
- requirements. Therefore precedence was given to Mongoid as it is significantly more
102
- popular and actively maintained.
103
-
104
- ### DataMapper
105
-
106
- Include the `OmniAuth::Identity::Models::DataMapper` mixin and specify
107
- fields that you will need.
108
-
109
- ```ruby
110
- class Identity
111
- include DataMapper::Resource
112
- include OmniAuth::Identity::Models::DataMapper
113
-
114
- property :id, Serial
115
- property :email, String
116
- property :password_digest, Text
117
-
118
- attr_accessor :password_confirmation
119
- end
120
- ```
121
-
122
104
  ### CouchPotato
123
105
 
124
106
  Include the `OmniAuth::Identity::Models::CouchPotatoModule` mixin and specify fields that you will need.
@@ -139,13 +121,24 @@ class Identity
139
121
  end
140
122
  ```
141
123
 
142
- Once you've got an `Identity` persistence model and the strategy up and
143
- running, you can point users to `/auth/identity` and it will request
144
- that they log in or give them the opportunity to sign up for an account.
145
- Once they have authenticated with their identity, OmniAuth will call
146
- through to `/auth/identity/callback` with the same kinds of information
147
- it would had the user authenticated through an external provider.
148
- Simple!
124
+ ### NoBrainer
125
+
126
+ [NoBrainer](http://nobrainer.io/) is an ORM for [RethinkDB](https://rethinkdb.com/).
127
+
128
+ Include the `OmniAuth::Identity::Models::NoBrainer` mixin and specify fields that you will need.
129
+
130
+ ```ruby
131
+ class Identity
132
+ include NoBrainer::Document
133
+ include OmniAuth::Identity::Models::NoBrainer
134
+
135
+ auth_key :email
136
+ end
137
+ ```
138
+
139
+ ### Ruby Object Mapper
140
+
141
+ Would love to add a mixin for the [Ruby Object Mapper (ROM)](https://rom-rb.org/) if anyone wants to work on it!
149
142
 
150
143
  ## Custom Auth Model
151
144
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module OmniAuth
4
4
  module Identity
5
- VERSION = '3.0.2'
5
+ VERSION = '3.0.3'
6
6
  end
7
7
  end
@@ -14,6 +14,7 @@ module OmniAuth
14
14
  autoload :ActiveRecord, 'omniauth/identity/models/active_record'
15
15
  autoload :Mongoid, 'omniauth/identity/models/mongoid'
16
16
  autoload :CouchPotatoModule, 'omniauth/identity/models/couch_potato'
17
+ autoload :NoBrainer, 'omniauth/identity/models/no_brainer'
17
18
  end
18
19
  end
19
20
  end
@@ -39,7 +39,7 @@ module OmniAuth
39
39
  # @return [String] The method name.
40
40
  def auth_key(method = false)
41
41
  @auth_key = method.to_s unless method == false
42
- @auth_key = nil if @auth_key == ''
42
+ @auth_key = nil if !defined?(@auth_key) || @auth_key == ''
43
43
 
44
44
  @auth_key || 'email'
45
45
  end
@@ -0,0 +1,30 @@
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
+ module NoBrainer
10
+ def self.included(base)
11
+ base.class_eval do
12
+ include ::OmniAuth::Identity::Model
13
+ include ::OmniAuth::Identity::SecurePassword
14
+
15
+ has_secure_password
16
+
17
+ def self.auth_key=(key)
18
+ super
19
+ validates_uniqueness_of key, case_sensitive: false
20
+ end
21
+
22
+ def self.locate(search_hash)
23
+ where(search_hash).first
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -9,27 +9,23 @@ module OmniAuth
9
9
  include OmniAuth::Strategy
10
10
 
11
11
  option :fields, %i[name email]
12
- option :enable_login, true # See #other_phase documentation
13
- option :on_login, nil
14
- option :on_registration, nil
15
- option :on_failed_registration, nil
16
- option :enable_registration, true
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
17
22
  option :locate_conditions, ->(req) { { model.auth_key => req['auth_key'] } }
18
23
 
19
24
  def request_phase
20
25
  if options[:on_login]
21
26
  options[:on_login].call(env)
22
27
  else
23
- OmniAuth::Form.build(
24
- title: (options[:title] || 'Identity Verification'),
25
- url: callback_path
26
- ) do |f|
27
- f.text_field 'Login', 'auth_key'
28
- f.password_field 'Password', 'password'
29
- if options[:enable_registration]
30
- f.html "<p align='center'><a href='#{registration_path}'>Create an Identity</a></p>"
31
- end
32
- end.to_response
28
+ build_omniauth_login_form.to_response
33
29
  end
34
30
  end
35
31
 
@@ -60,17 +56,11 @@ module OmniAuth
60
56
  end
61
57
  end
62
58
 
63
- def registration_form
59
+ def registration_form(validation_message = nil)
64
60
  if options[:on_registration]
65
61
  options[:on_registration].call(env)
66
62
  else
67
- OmniAuth::Form.build(title: 'Register Identity') do |f|
68
- options[:fields].each do |field|
69
- f.text_field field.to_s.capitalize, field.to_s
70
- end
71
- f.password_field 'Password', 'password'
72
- f.password_field 'Confirm Password', 'password_confirmation'
73
- end.to_response
63
+ build_omniauth_registration_form(validation_message).to_response
74
64
  end
75
65
  end
76
66
 
@@ -81,15 +71,23 @@ module OmniAuth
81
71
  if model.respond_to?(:column_names) && model.column_names.include?('provider')
82
72
  attributes.reverse_merge!(provider: 'identity')
83
73
  end
84
- @identity = model.create(attributes)
85
- if @identity.persisted?
74
+ @identity = model.new(attributes)
75
+
76
+ # on_validation may run a Captcha or other validation mechanism
77
+ # Must return true when validation passes, false otherwise
78
+ if options[:on_validation] && !options[:on_validation].call(env: env)
79
+ if options[:on_failed_registration]
80
+ env['omniauth.identity'] = @identity
81
+ options[:on_failed_registration].call(env)
82
+ else
83
+ validation_message = 'Validation failed'
84
+ registration_form(validation_message)
85
+ end
86
+ elsif @identity.save && @identity.persisted?
86
87
  env['PATH_INFO'] = callback_path
87
88
  callback_phase
88
- elsif options[:on_failed_registration]
89
- env['omniauth.identity'] = @identity
90
- options[:on_failed_registration].call(env)
91
89
  else
92
- registration_form
90
+ show_custom_options_or_default
93
91
  end
94
92
  end
95
93
 
@@ -117,6 +115,42 @@ module OmniAuth
117
115
  def model
118
116
  options[:model] || ::Identity
119
117
  end
118
+
119
+ private
120
+
121
+ def build_omniauth_login_form
122
+ OmniAuth::Form.build(
123
+ title: (options[:title] || 'Identity Verification'),
124
+ url: callback_path
125
+ ) do |f|
126
+ f.text_field 'Login', 'auth_key'
127
+ f.password_field 'Password', 'password'
128
+ if options[:enable_registration]
129
+ f.html "<p align='center'><a href='#{registration_path}'>Create an Identity</a></p>"
130
+ end
131
+ end
132
+ end
133
+
134
+ def build_omniauth_registration_form(validation_message)
135
+ OmniAuth::Form.build(title: 'Register Identity') do |f|
136
+ f.html "<p style='color:red'>#{validation_message}</p>" if validation_message
137
+ options[:fields].each do |field|
138
+ f.text_field field.to_s.capitalize, field.to_s
139
+ end
140
+ f.password_field 'Password', 'password'
141
+ f.password_field 'Confirm Password', 'password_confirmation'
142
+ end
143
+ end
144
+
145
+ def show_custom_options_or_default
146
+ if options[:on_failed_registration]
147
+ env['omniauth.identity'] = @identity
148
+ options[:on_failed_registration].call(env)
149
+ else
150
+ validation_message = 'One or more fields were invalid'
151
+ registration_form(validation_message)
152
+ end
153
+ end
120
154
  end
121
155
  end
122
156
  end
@@ -5,7 +5,7 @@ RSpec.describe(OmniAuth::Identity::Models::ActiveRecord, db: true) do
5
5
  subject(:model_klass) do
6
6
  AnonymousActiveRecord.generate(
7
7
  parent_klass: 'OmniAuth::Identity::Models::ActiveRecord',
8
- columns: %w[name provider],
8
+ columns: OmniAuth::Identity::Model::SCHEMA_ATTRIBUTES | %w[provider password_digest],
9
9
  connection_params: { adapter: 'sqlite3', encoding: 'utf8', database: ':memory:' }
10
10
  ) do
11
11
  def flower
@@ -1,12 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- RSpec.describe(OmniAuth::Identity::Models::CouchPotatoModule, db: true) do
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
 
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
10
12
  describe 'model', type: :model do
11
13
  subject { CouchPotatoTestIdentity }
12
14
 
@@ -1,13 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- RSpec.describe(OmniAuth::Identity::Models::Mongoid, db: true) do
4
- class MongoidTestIdentity
5
- include Mongoid::Document
6
- include OmniAuth::Identity::Models::Mongoid
7
- auth_key :ham_sandwich
8
- store_in database: 'db1', collection: 'mongoid_test_identities', client: 'secondary'
9
- end
3
+ require 'mongoid'
10
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
11
13
  describe 'model', type: :model do
12
14
  subject { MongoidTestIdentity }
13
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
@@ -8,7 +8,8 @@ RSpec.describe OmniAuth::Strategies::Identity do
8
8
  let(:identity_options) { {} }
9
9
  let(:anon_ar) do
10
10
  AnonymousActiveRecord.generate(
11
- columns: %w[name provider],
11
+ parent_klass: 'OmniAuth::Identity::Models::ActiveRecord',
12
+ columns: OmniAuth::Identity::Model::SCHEMA_ATTRIBUTES | %w[provider password_digest],
12
13
  connection_params: { adapter: 'sqlite3', encoding: 'utf8', database: ':memory:' }
13
14
  ) do
14
15
  def balloon
@@ -203,16 +204,10 @@ RSpec.describe OmniAuth::Strategies::Identity do
203
204
  }
204
205
  end
205
206
 
206
- before do
207
- allow(anon_ar).to receive('auth_key').and_return('email')
208
- m = double(uid: 'abc', name: 'Awesome Dude', email: 'awesome@example.com',
209
- info: { name: 'DUUUUDE!' }, persisted?: true)
210
- expect(anon_ar).to receive(:create).with(properties).and_return(m)
211
- end
212
-
213
207
  it 'sets the auth hash' do
214
208
  post '/auth/identity/register', properties
215
- expect(auth_hash['uid']).to eq('abc')
209
+ expect(auth_hash['uid']).to match(/\d+/)
210
+ expect(auth_hash['provider']).to eq('identity')
216
211
  end
217
212
  end
218
213
 
@@ -226,16 +221,17 @@ RSpec.describe OmniAuth::Strategies::Identity do
226
221
  provider: 'identity'
227
222
  }
228
223
  end
229
- let(:invalid_identity) { double(persisted?: false) }
224
+ let(:invalid_identity) { double(persisted?: false, save: false) }
230
225
 
231
226
  before do
232
- expect(anon_ar).to receive(:create).with(properties).and_return(invalid_identity)
227
+ expect(anon_ar).to receive(:new).with(properties).and_return(invalid_identity)
233
228
  end
234
229
 
235
230
  context 'default' do
236
231
  it 'shows registration form' do
237
232
  post '/auth/identity/register', properties
238
233
  expect(last_response.body).to be_include('Register Identity')
234
+ expect(last_response.body).to be_include('One or more fields were invalid')
239
235
  end
240
236
  end
241
237
 
@@ -250,6 +246,7 @@ RSpec.describe OmniAuth::Strategies::Identity do
250
246
  post '/auth/identity/register', properties
251
247
  expect(identity_hash).to eq(invalid_identity)
252
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')
253
250
  end
254
251
  end
255
252
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omniauth-identity
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.2
4
+ version: 3.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Boling
@@ -68,6 +68,20 @@ dependencies:
68
68
  - - "~>"
69
69
  - !ruby/object:Gem::Version
70
70
  version: '7'
71
+ - !ruby/object:Gem::Dependency
72
+ name: nobrainer
73
+ requirement: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ type: :development
79
+ prerelease: false
80
+ version_requirements: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
71
85
  - !ruby/object:Gem::Dependency
72
86
  name: rack-test
73
87
  requirement: !ruby/object:Gem::Requirement
@@ -141,12 +155,14 @@ files:
141
155
  - lib/omniauth/identity/models/active_record.rb
142
156
  - lib/omniauth/identity/models/couch_potato.rb
143
157
  - lib/omniauth/identity/models/mongoid.rb
158
+ - lib/omniauth/identity/models/no_brainer.rb
144
159
  - lib/omniauth/identity/secure_password.rb
145
160
  - lib/omniauth/strategies/identity.rb
146
161
  - spec/omniauth/identity/model_spec.rb
147
162
  - spec/omniauth/identity/models/active_record_spec.rb
148
163
  - spec/omniauth/identity/models/couch_potato_spec.rb
149
164
  - spec/omniauth/identity/models/mongoid_spec.rb
165
+ - spec/omniauth/identity/models/no_brainer_spec.rb
150
166
  - spec/omniauth/identity/secure_password_spec.rb
151
167
  - spec/omniauth/strategies/identity_spec.rb
152
168
  - spec/spec_helper.rb
@@ -179,6 +195,7 @@ test_files:
179
195
  - spec/omniauth/identity/models/active_record_spec.rb
180
196
  - spec/omniauth/identity/models/couch_potato_spec.rb
181
197
  - spec/omniauth/identity/models/mongoid_spec.rb
198
+ - spec/omniauth/identity/models/no_brainer_spec.rb
182
199
  - spec/omniauth/identity/secure_password_spec.rb
183
200
  - spec/omniauth/strategies/identity_spec.rb
184
201
  - spec/spec_helper.rb