omniauth-identity 3.0.2 → 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 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