omniauth-identity 3.0.6 → 3.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +42 -0
- data/README.md +52 -8
- data/lib/omniauth-identity/version.rb +1 -1
- data/lib/omniauth/identity.rb +1 -1
- data/lib/omniauth/identity/model.rb +43 -34
- data/lib/omniauth/identity/models/active_record.rb +2 -2
- data/lib/omniauth/identity/models/couch_potato.rb +5 -0
- data/lib/omniauth/identity/models/{no_brainer.rb → nobrainer.rb} +0 -0
- data/lib/omniauth/identity/models/sequel.rb +4 -4
- data/lib/omniauth/identity/secure_password.rb +98 -37
- data/spec/omniauth/identity/model_spec.rb +19 -99
- data/spec/omniauth/identity/models/active_record_spec.rb +19 -10
- data/spec/omniauth/identity/models/sequel_spec.rb +30 -15
- data/spec/omniauth/strategies/identity_spec.rb +5 -1
- data/spec/spec_helper.rb +16 -5
- data/spec/support/shared_contexts/instance_with_instance_methods.rb +89 -0
- data/spec/support/shared_contexts/model_with_class_methods.rb +29 -0
- data/spec/support/shared_contexts/persistable_model.rb +24 -0
- metadata +15 -63
- data/spec/omniauth/identity/models/couch_potato_spec.rb +0 -21
- data/spec/omniauth/identity/models/mongoid_spec.rb +0 -28
- data/spec/omniauth/identity/models/no_brainer_spec.rb +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 89bd05bb3cf63c0a47e41c8f955f9b076d5c6b4ae0704eda10819f801eaa6059
|
4
|
+
data.tar.gz: a272f35f9bcc0de8937279904e2bde912865b50ac3a7752dada19f0ec7d6868c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 26286ae10ba06b45b815bd21892ac27378eb338e446f0dcbe96037a8aa51d4097b55243ae12f5feef133577b1d793ce4732f636f930a6773c6b7e154e6256b4c
|
7
|
+
data.tar.gz: 11fc92beba0b8b849c1ce15784870bf4318aeaea14e5c7172f9c26b1891e357ba9603106765a5b2554c20d177a17c5e820bdb01733de169f3e67ec192f8d42e4
|
data/CHANGELOG.md
CHANGED
@@ -8,6 +8,48 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
8
8
|
|
9
9
|
## [Unreleased]
|
10
10
|
|
11
|
+
## [3.0.7] - 2021-03-23
|
12
|
+
|
13
|
+
### Fixed
|
14
|
+
|
15
|
+
- \[ActiveRecord\] Fixed [#110](https://github.com/omniauth/omniauth-identity/issues/110) which prevented `OmniAuth::Identity::Models::ActiveRecord`-based records from saving.
|
16
|
+
- \[CouchPotato\] Fixed `OmniAuth::Identity::Models::CouchPotato`'s `#save`.
|
17
|
+
- \[Sequel\] Fixed `OmniAuth::Identity::Models::Sequel`'s `#save`.
|
18
|
+
- \[Model\] Only define `::create`, `#save`, and `#persisted?` when not already defined.
|
19
|
+
- \[Model\] Restore original `info` functionality which set `name` based on `first_name`, `last_name`, or `nickname`
|
20
|
+
|
21
|
+
### Changed
|
22
|
+
|
23
|
+
- Upgraded to a newer `OmniAuth::Identity::SecurePassword` ripped from [Rails 6-1-stable](https://github.com/rails/rails/blob/6-1-stable/activemodel/lib/active_model/secure_password.rb)
|
24
|
+
- Aeons ago the original was ripped from Rails 3.1, and frozen in time.
|
25
|
+
While writing specs, it was discovered to be incompatible with this gem's Sequel adapter.
|
26
|
+
- Specs validate that the new version does work.
|
27
|
+
In any case, the ripped version is only used when the `has_secure_password` macro is not yet defined in the class.
|
28
|
+
|
29
|
+
### Added
|
30
|
+
|
31
|
+
- New specs to cover real use cases and implementations of each ORM model adapter that ships with the gem:
|
32
|
+
- ActiveRecord (Polyglot - Many Relational Databases)
|
33
|
+
- Sequel (Polyglot - Many Relational Databases)
|
34
|
+
- CouchPotato (CouchDB)
|
35
|
+
- Mongoid (MongoDB)
|
36
|
+
- NoBrainer (RethinkDB)
|
37
|
+
|
38
|
+
## [3.0.6] - 2021-03-20
|
39
|
+
|
40
|
+
### Fixed
|
41
|
+
|
42
|
+
- Fix breaking changes introduced by [#108](https://github.com/omniauth/omniauth-identity/pull/108) which prevented `:on_validation` from firing
|
43
|
+
|
44
|
+
### Added
|
45
|
+
|
46
|
+
- New (or finally documented) options:
|
47
|
+
- `:create_identity_link_text` defaults to `'Create an Identity'`
|
48
|
+
- `:registration_failure_message` defaults to `'One or more fields were invalid'`
|
49
|
+
- `:validation_failure_message` defaults to `'Validation failed'`
|
50
|
+
- `:title` defaults to `'Identity Verification'`
|
51
|
+
- `:registration_form_title` defaults to `'Register Identity'`
|
52
|
+
|
11
53
|
## [3.0.5] - 2021-03-19
|
12
54
|
|
13
55
|
### Fixed
|
data/README.md
CHANGED
@@ -93,8 +93,8 @@ Just include `OmniAuth::Identity::Models::Sequel` mixin, and specify
|
|
93
93
|
whatever else you will need.
|
94
94
|
|
95
95
|
```ruby
|
96
|
-
class SequelTestIdentity < Sequel::Model
|
97
|
-
include OmniAuth::Identity::Models::Sequel
|
96
|
+
class SequelTestIdentity < Sequel::Model(:identities)
|
97
|
+
include ::OmniAuth::Identity::Models::Sequel
|
98
98
|
auth_key :email
|
99
99
|
# whatever else you want!
|
100
100
|
end
|
@@ -108,8 +108,8 @@ fields that you will need.
|
|
108
108
|
|
109
109
|
```ruby
|
110
110
|
class Identity
|
111
|
-
include Mongoid::Document
|
112
|
-
include OmniAuth::Identity::Models::Mongoid
|
111
|
+
include ::Mongoid::Document
|
112
|
+
include ::OmniAuth::Identity::Models::Mongoid
|
113
113
|
|
114
114
|
field :email, type: String
|
115
115
|
field :name, type: String
|
@@ -124,8 +124,9 @@ fields that you will need.
|
|
124
124
|
|
125
125
|
```ruby
|
126
126
|
class Identity
|
127
|
-
|
128
|
-
include
|
127
|
+
# NOTE: CouchPotato::Persistence must be included before OmniAuth::Identity::Models::CouchPotatoModule
|
128
|
+
include ::CouchPotato::Persistence
|
129
|
+
include ::OmniAuth::Identity::Models::CouchPotatoModule
|
129
130
|
|
130
131
|
property :email
|
131
132
|
property :password_digest
|
@@ -147,8 +148,8 @@ fields that you will need.
|
|
147
148
|
|
148
149
|
```ruby
|
149
150
|
class Identity
|
150
|
-
include NoBrainer::Document
|
151
|
-
include OmniAuth::Identity::Models::NoBrainer
|
151
|
+
include ::NoBrainer::Document
|
152
|
+
include ::OmniAuth::Identity::Models::NoBrainer
|
152
153
|
|
153
154
|
auth_key :email
|
154
155
|
end
|
@@ -265,6 +266,49 @@ option :locate_conditions, ->(req) { { model.auth_key => req['auth_key'] } }
|
|
265
266
|
|
266
267
|
Please contribute some documentation if you have the gumption! The maintainer's time is limited, and sometimes the authors of PRs with new options don't update the _this_ readme. 😭
|
267
268
|
|
269
|
+
## Contributing
|
270
|
+
|
271
|
+
1. Fork it
|
272
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
273
|
+
3. Commit your changes (`git commit -am ‘Added some feature’`)
|
274
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
275
|
+
5. Make sure to add tests for it. This is important so I don’t break it in a future version unintentionally.
|
276
|
+
- NOTE: In order to run *all* the tests you will need to have the following databases installed, configured, and running.
|
277
|
+
1. [RethinkDB](https://rethinkdb.com), an open source, real-time, web database, [installed](https://rethinkdb.com/docs/install/) and [running](https://rethinkdb.com/docs/start-a-server/), e.g.
|
278
|
+
```bash
|
279
|
+
brew install rethinkdb
|
280
|
+
rethinkdb
|
281
|
+
```
|
282
|
+
2. [MongoDB](https://docs.mongodb.com/manual/administration/install-community/)
|
283
|
+
```bash
|
284
|
+
brew tap mongodb/brew
|
285
|
+
brew install mongodb-community@4.4
|
286
|
+
mongod --config /usr/local/etc/mongod.conf
|
287
|
+
```
|
288
|
+
3. [CouchDB](https://couchdb.apache.org) (download the .app)
|
289
|
+
To run all tests on all databases:
|
290
|
+
```bash
|
291
|
+
bundle exec rake
|
292
|
+
```
|
293
|
+
To run a specific DB:
|
294
|
+
```bash
|
295
|
+
# CouchDB / CouchPotato
|
296
|
+
bundle exec rspec spec spec_orms --tag 'couchdb'
|
297
|
+
|
298
|
+
# ActiveRecord and Sequel, as they both use the in-memory SQLite driver.
|
299
|
+
bundle exec rspec spec spec_orms --tag 'sqlite3'
|
300
|
+
|
301
|
+
# NOTE - mongoid and nobrainer specs can't be isolated with "tag" because it still loads everything,
|
302
|
+
# and the two libraries are fundamentally incompatible.
|
303
|
+
|
304
|
+
# MongoDB / Mongoid
|
305
|
+
bundle exec rspec spec_orms/mongoid_spec.rb
|
306
|
+
|
307
|
+
# RethinkDB / NoBrainer
|
308
|
+
bundle exec rspec spec_orms/nobrainer_spec.rb
|
309
|
+
```
|
310
|
+
6. Create new Pull Request
|
311
|
+
|
268
312
|
## License
|
269
313
|
|
270
314
|
MIT License. See LICENSE for details.
|
data/lib/omniauth/identity.rb
CHANGED
@@ -14,7 +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/
|
17
|
+
autoload :NoBrainer, 'omniauth/identity/models/nobrainer'
|
18
18
|
autoload :Sequel, 'omniauth/identity/models/sequel'
|
19
19
|
end
|
20
20
|
end
|
@@ -25,11 +25,13 @@ module OmniAuth
|
|
25
25
|
|
26
26
|
def self.included(base)
|
27
27
|
base.extend ClassMethods
|
28
|
+
base.extend ClassCreateApi unless base.respond_to?(:create)
|
29
|
+
im = base.instance_methods
|
30
|
+
base.include InstanceSaveApi unless im.include?(:save)
|
31
|
+
base.include InstancePersistedApi unless im.include?(:persisted?)
|
28
32
|
end
|
29
33
|
|
30
34
|
module ClassMethods
|
31
|
-
extend Gem::Deprecate
|
32
|
-
|
33
35
|
# Authenticate a user with the given key and password.
|
34
36
|
#
|
35
37
|
# @param [String] key The unique login key provided for a given identity.
|
@@ -52,52 +54,55 @@ module OmniAuth
|
|
52
54
|
@auth_key || 'email'
|
53
55
|
end
|
54
56
|
|
57
|
+
# Locate an identity given its unique login key.
|
58
|
+
#
|
59
|
+
# @abstract
|
60
|
+
# @param [String] key The unique login key.
|
61
|
+
# @return [Model] An instance of the identity model class.
|
62
|
+
def locate(_key)
|
63
|
+
raise NotImplementedError
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
module ClassCreateApi
|
55
68
|
# Persists a new Identity object to the ORM.
|
56
|
-
#
|
69
|
+
# Only included if the class doesn't define create, as a reminder to define create.
|
70
|
+
# Override as needed per ORM.
|
57
71
|
#
|
58
72
|
# @deprecated v4.0 will begin using {#new} with {#save} instead.
|
59
73
|
# @abstract
|
60
74
|
# @param [Hash] args Attributes of the new instance.
|
61
75
|
# @return [Model] An instance of the identity model class.
|
62
76
|
# @since 3.0.5
|
63
|
-
def create(*
|
64
|
-
raise NotImplementedError
|
65
|
-
|
66
|
-
super
|
77
|
+
def create(*_args)
|
78
|
+
raise NotImplementedError
|
67
79
|
end
|
80
|
+
end
|
68
81
|
|
69
|
-
|
82
|
+
module InstanceSaveApi
|
83
|
+
# Persists a new Identity object to the ORM.
|
84
|
+
# Default raises an error. Override as needed per ORM.
|
85
|
+
# This base version's arguments are modeled after ActiveModel
|
86
|
+
# since it is a pattern many ORMs follow
|
70
87
|
#
|
71
88
|
# @abstract
|
72
|
-
# @param [String] key The unique login key.
|
73
89
|
# @return [Model] An instance of the identity model class.
|
74
|
-
|
90
|
+
# @since 3.0.5
|
91
|
+
def save(**_options, &_block)
|
75
92
|
raise NotImplementedError
|
76
93
|
end
|
77
94
|
end
|
78
95
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
end
|
90
|
-
|
91
|
-
# Checks if the Identity object is persisted in the ORM.
|
92
|
-
# Defaults to calling super. Override as needed per ORM.
|
93
|
-
#
|
94
|
-
# @abstract
|
95
|
-
# @return [true or false] true if object exists, false if not.
|
96
|
-
# @since 3.0.5
|
97
|
-
def persisted?
|
98
|
-
raise NotImplementedError unless defined?(super)
|
99
|
-
|
100
|
-
super
|
96
|
+
module InstancePersistedApi
|
97
|
+
# Checks if the Identity object is persisted in the ORM.
|
98
|
+
# Default raises an error. Override as needed per ORM.
|
99
|
+
#
|
100
|
+
# @abstract
|
101
|
+
# @return [true or false] true if object exists, false if not.
|
102
|
+
# @since 3.0.5
|
103
|
+
def persisted?
|
104
|
+
raise NotImplementedError
|
105
|
+
end
|
101
106
|
end
|
102
107
|
|
103
108
|
# Returns self if the provided password is correct, false
|
@@ -106,7 +111,7 @@ module OmniAuth
|
|
106
111
|
# @abstract
|
107
112
|
# @param [String] password The password to check.
|
108
113
|
# @return [self or false] Self if authenticated, false if not.
|
109
|
-
def authenticate(
|
114
|
+
def authenticate(_password)
|
110
115
|
raise NotImplementedError
|
111
116
|
end
|
112
117
|
|
@@ -163,9 +168,13 @@ module OmniAuth
|
|
163
168
|
#
|
164
169
|
# @return [Hash] A string-keyed hash of user information.
|
165
170
|
def info
|
166
|
-
|
171
|
+
info = {}
|
172
|
+
SCHEMA_ATTRIBUTES.each_with_object(info) do |attribute, hash|
|
167
173
|
hash[attribute] = send(attribute) if respond_to?(attribute)
|
168
174
|
end
|
175
|
+
info['name'] ||= [info['first_name'], info['last_name']].join(' ').strip if info['first_name'] || info['last_name']
|
176
|
+
info['name'] ||= info['nickname']
|
177
|
+
info
|
169
178
|
end
|
170
179
|
end
|
171
180
|
end
|
@@ -6,8 +6,8 @@ module OmniAuth
|
|
6
6
|
module Identity
|
7
7
|
module Models
|
8
8
|
class ActiveRecord < ::ActiveRecord::Base
|
9
|
-
include OmniAuth::Identity::Model
|
10
|
-
include OmniAuth::Identity::SecurePassword
|
9
|
+
include ::OmniAuth::Identity::Model
|
10
|
+
include ::OmniAuth::Identity::SecurePassword
|
11
11
|
|
12
12
|
self.abstract_class = true
|
13
13
|
has_secure_password
|
@@ -7,6 +7,7 @@ module OmniAuth
|
|
7
7
|
module Models
|
8
8
|
# can not be named CouchPotato since there is a class with that name
|
9
9
|
# NOTE: CouchPotato is based on ActiveModel.
|
10
|
+
# NOTE: CouchPotato::Persistence must be included before OmniAuth::Identity::Models::CouchPotatoModule
|
10
11
|
module CouchPotatoModule
|
11
12
|
def self.included(base)
|
12
13
|
base.class_eval do
|
@@ -23,6 +24,10 @@ module OmniAuth
|
|
23
24
|
def self.locate(search_hash)
|
24
25
|
where(search_hash).first
|
25
26
|
end
|
27
|
+
|
28
|
+
def save
|
29
|
+
CouchPotato.database.save(self)
|
30
|
+
end
|
26
31
|
end
|
27
32
|
end
|
28
33
|
end
|
File without changes
|
@@ -6,9 +6,9 @@ module OmniAuth
|
|
6
6
|
module Identity
|
7
7
|
module Models
|
8
8
|
# http://sequel.jeremyevans.net/ an SQL ORM
|
9
|
-
# NOTE: Sequel is *not* based on ActiveModel, but supports the API we need, except for `persisted
|
9
|
+
# NOTE: Sequel is *not* based on ActiveModel, but supports the API we need, except for `persisted?`:
|
10
10
|
# * create
|
11
|
-
# * save
|
11
|
+
# * save
|
12
12
|
module Sequel
|
13
13
|
def self.included(base)
|
14
14
|
base.class_eval do
|
@@ -17,7 +17,7 @@ module OmniAuth
|
|
17
17
|
# plugin :validation_helpers
|
18
18
|
plugin :validation_class_methods
|
19
19
|
|
20
|
-
include OmniAuth::Identity::Model
|
20
|
+
include ::OmniAuth::Identity::Model
|
21
21
|
include ::OmniAuth::Identity::SecurePassword
|
22
22
|
|
23
23
|
has_secure_password
|
@@ -38,7 +38,7 @@ module OmniAuth
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def save
|
41
|
-
|
41
|
+
super
|
42
42
|
end
|
43
43
|
end
|
44
44
|
end
|
@@ -4,7 +4,7 @@ require 'bcrypt'
|
|
4
4
|
|
5
5
|
module OmniAuth
|
6
6
|
module Identity
|
7
|
-
# This is
|
7
|
+
# This is lightly edited from Rails 6.1 code and is used if
|
8
8
|
# the version of ActiveModel that's being used does not
|
9
9
|
# include SecurePassword. The only difference is that instead of
|
10
10
|
# using ActiveSupport::Concern, it checks to see if there is already
|
@@ -14,63 +14,124 @@ module OmniAuth
|
|
14
14
|
base.extend ClassMethods unless base.respond_to?(:has_secure_password)
|
15
15
|
end
|
16
16
|
|
17
|
+
# BCrypt hash function can handle maximum 72 bytes, and if we pass
|
18
|
+
# password of length more than 72 bytes it ignores extra characters.
|
19
|
+
# Hence need to put a restriction on password length.
|
20
|
+
MAX_PASSWORD_LENGTH_ALLOWED = 72
|
21
|
+
|
22
|
+
class << self
|
23
|
+
attr_accessor :min_cost # :nodoc:
|
24
|
+
end
|
25
|
+
self.min_cost = false
|
26
|
+
|
17
27
|
module ClassMethods
|
18
28
|
# Adds methods to set and authenticate against a BCrypt password.
|
19
|
-
# This mechanism requires you to have a
|
29
|
+
# This mechanism requires you to have a +XXX_digest+ attribute.
|
30
|
+
# Where +XXX+ is the attribute name of your desired password.
|
31
|
+
#
|
32
|
+
# The following validations are added automatically:
|
33
|
+
# * Password must be present on creation
|
34
|
+
# * Password length should be less than or equal to 72 bytes
|
35
|
+
# * Confirmation of password (using a +XXX_confirmation+ attribute)
|
20
36
|
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
37
|
+
# If confirmation validation is not needed, simply leave out the
|
38
|
+
# value for +XXX_confirmation+ (i.e. don't provide a form field for
|
39
|
+
# it). When this attribute has a +nil+ value, the validation will not be
|
40
|
+
# triggered.
|
41
|
+
#
|
42
|
+
# For further customizability, it is possible to suppress the default
|
43
|
+
# validations by passing <tt>validations: false</tt> as an argument.
|
44
|
+
#
|
45
|
+
# Add bcrypt (~> 3.1.7) to Gemfile to use #has_secure_password:
|
46
|
+
#
|
47
|
+
# gem 'bcrypt', '~> 3.1.7'
|
24
48
|
#
|
25
49
|
# Example using Active Record (which automatically includes ActiveModel::SecurePassword):
|
26
50
|
#
|
27
|
-
# # Schema: User(name:string, password_digest:string)
|
51
|
+
# # Schema: User(name:string, password_digest:string, recovery_password_digest:string)
|
28
52
|
# class User < ActiveRecord::Base
|
29
53
|
# has_secure_password
|
54
|
+
# has_secure_password :recovery_password, validations: false
|
30
55
|
# end
|
31
56
|
#
|
32
|
-
# user = User.new(:
|
33
|
-
# user.save
|
34
|
-
# user.password =
|
35
|
-
# user.save
|
36
|
-
# user.password_confirmation =
|
37
|
-
# user.save
|
38
|
-
# user.
|
39
|
-
# user.
|
40
|
-
#
|
41
|
-
#
|
42
|
-
|
43
|
-
|
57
|
+
# user = User.new(name: 'david', password: '', password_confirmation: 'nomatch')
|
58
|
+
# user.save # => false, password required
|
59
|
+
# user.password = 'mUc3m00RsqyRe'
|
60
|
+
# user.save # => false, confirmation doesn't match
|
61
|
+
# user.password_confirmation = 'mUc3m00RsqyRe'
|
62
|
+
# user.save # => true
|
63
|
+
# user.recovery_password = "42password"
|
64
|
+
# user.recovery_password_digest # => "$2a$04$iOfhwahFymCs5weB3BNH/uXkTG65HR.qpW.bNhEjFP3ftli3o5DQC"
|
65
|
+
# user.save # => true
|
66
|
+
# user.authenticate('notright') # => false
|
67
|
+
# user.authenticate('mUc3m00RsqyRe') # => user
|
68
|
+
# user.authenticate_recovery_password('42password') # => user
|
69
|
+
# User.find_by(name: 'david')&.authenticate('notright') # => false
|
70
|
+
# User.find_by(name: 'david')&.authenticate('mUc3m00RsqyRe') # => user
|
71
|
+
def has_secure_password(attribute = :password, validations: true)
|
72
|
+
# Load bcrypt gem only when has_secure_password is used.
|
73
|
+
# This is to avoid ActiveModel (and by extension the entire framework)
|
74
|
+
# being dependent on a binary library.
|
75
|
+
begin
|
76
|
+
require 'bcrypt'
|
77
|
+
rescue LoadError
|
78
|
+
warn "You don't have bcrypt installed in your application. Please add it to your Gemfile and run bundle install"
|
79
|
+
raise
|
80
|
+
end
|
44
81
|
|
45
|
-
|
46
|
-
validates_presence_of :password_digest
|
82
|
+
include InstanceMethodsOnActivation.new(attribute)
|
47
83
|
|
48
|
-
|
84
|
+
if validations
|
85
|
+
include ActiveModel::Validations
|
49
86
|
|
50
|
-
|
51
|
-
|
52
|
-
|
87
|
+
# This ensures the model has a password by checking whether the password_digest
|
88
|
+
# is present, so that this works with both new and existing records. However,
|
89
|
+
# when there is an error, the message is added to the password attribute instead
|
90
|
+
# so that the error message will make sense to the end-user.
|
91
|
+
validate do |record|
|
92
|
+
record.errors.add(attribute, :blank) unless record.public_send("#{attribute}_digest").present?
|
53
93
|
end
|
94
|
+
|
95
|
+
validates_length_of attribute, maximum: ActiveModel::SecurePassword::MAX_PASSWORD_LENGTH_ALLOWED
|
96
|
+
validates_confirmation_of attribute, allow_blank: true
|
54
97
|
end
|
55
98
|
end
|
56
99
|
end
|
57
100
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
101
|
+
class InstanceMethodsOnActivation < Module
|
102
|
+
def initialize(attribute)
|
103
|
+
attr_reader attribute
|
104
|
+
|
105
|
+
define_method("#{attribute}=") do |unencrypted_password|
|
106
|
+
if unencrypted_password.nil?
|
107
|
+
public_send("#{attribute}_digest=", nil)
|
108
|
+
elsif !unencrypted_password.empty?
|
109
|
+
instance_variable_set("@#{attribute}", unencrypted_password)
|
110
|
+
cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine.cost
|
111
|
+
public_send("#{attribute}_digest=", BCrypt::Password.create(unencrypted_password, cost: cost))
|
112
|
+
end
|
65
113
|
end
|
66
|
-
end
|
67
114
|
|
68
|
-
|
69
|
-
|
70
|
-
@password = unencrypted_password
|
71
|
-
if unencrypted_password && !unencrypted_password.empty?
|
72
|
-
self.password_digest = BCrypt::Password.create(unencrypted_password)
|
115
|
+
define_method("#{attribute}_confirmation=") do |unencrypted_password|
|
116
|
+
instance_variable_set("@#{attribute}_confirmation", unencrypted_password)
|
73
117
|
end
|
118
|
+
|
119
|
+
# Returns +self+ if the password is correct, otherwise +false+.
|
120
|
+
#
|
121
|
+
# class User < ActiveRecord::Base
|
122
|
+
# has_secure_password validations: false
|
123
|
+
# end
|
124
|
+
#
|
125
|
+
# user = User.new(name: 'david', password: 'mUc3m00RsqyRe')
|
126
|
+
# user.save
|
127
|
+
# user.authenticate_password('notright') # => false
|
128
|
+
# user.authenticate_password('mUc3m00RsqyRe') # => user
|
129
|
+
define_method("authenticate_#{attribute}") do |unencrypted_password|
|
130
|
+
attribute_digest = public_send("#{attribute}_digest")
|
131
|
+
BCrypt::Password.new(attribute_digest).is_password?(unencrypted_password) && self
|
132
|
+
end
|
133
|
+
|
134
|
+
alias_method :authenticate, :authenticate_password if attribute == :password
|
74
135
|
end
|
75
136
|
end
|
76
137
|
end
|
@@ -1,123 +1,43 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
class ExampleModel
|
4
|
-
include OmniAuth::Identity::Model
|
5
|
-
end
|
6
|
-
|
7
3
|
RSpec.describe OmniAuth::Identity::Model do
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
describe '.locate' do
|
12
|
-
it('is abstract') { expect { subject.locate('abc') }.to raise_error(NotImplementedError) }
|
4
|
+
before do
|
5
|
+
identity_test_klass = Class.new do
|
6
|
+
include OmniAuth::Identity::Model
|
13
7
|
end
|
8
|
+
stub_const('IdentityTestClass', identity_test_klass)
|
9
|
+
end
|
14
10
|
|
15
|
-
|
16
|
-
|
17
|
-
mocked_instance = double('ExampleModel', authenticate: 'abbadoo')
|
18
|
-
allow(subject).to receive(:locate).with('email' => 'example').and_return(mocked_instance)
|
19
|
-
expect(subject.authenticate({ 'email' => 'example' }, 'pass')).to eq('abbadoo')
|
20
|
-
end
|
11
|
+
describe 'Class Methods' do
|
12
|
+
subject(:model_klass) { IdentityTestClass }
|
21
13
|
|
22
|
-
|
23
|
-
mocked_instance = double('ExampleModel', authenticate: 'abbadoo')
|
24
|
-
allow(subject).to receive(:locate).with('email' => 'example',
|
25
|
-
'user_type' => 'admin').and_return(mocked_instance)
|
26
|
-
expect(subject.authenticate({ 'email' => 'example', 'user_type' => 'admin' }, 'pass')).to eq('abbadoo')
|
27
|
-
end
|
14
|
+
include_context 'model with class methods'
|
28
15
|
|
29
|
-
|
30
|
-
|
31
|
-
expect
|
16
|
+
describe '::locate' do
|
17
|
+
it('is abstract') do
|
18
|
+
expect { model_klass.locate('email' => 'example') }.to raise_error(NotImplementedError)
|
32
19
|
end
|
33
20
|
end
|
34
21
|
end
|
35
22
|
|
36
|
-
|
37
|
-
subject {
|
23
|
+
describe 'Instance Methods' do
|
24
|
+
subject(:instance) { IdentityTestClass.new }
|
38
25
|
|
39
|
-
|
40
|
-
it('is abstract') { expect { subject.authenticate('abc') }.to raise_error(NotImplementedError) }
|
41
|
-
end
|
26
|
+
include_context 'instance with instance methods'
|
42
27
|
|
43
|
-
describe '#
|
44
|
-
it '
|
45
|
-
allow(subject).to receive(:respond_to?).with(:id).and_return(true)
|
46
|
-
allow(subject).to receive(:id).and_return 'wakka-do'
|
47
|
-
expect(subject.uid).to eq('wakka-do')
|
48
|
-
end
|
49
|
-
|
50
|
-
it 'stringifies it' do
|
51
|
-
allow(subject).to receive(:id).and_return 123
|
52
|
-
expect(subject.uid).to eq('123')
|
53
|
-
end
|
54
|
-
|
55
|
-
it 'raises NotImplementedError if #id is not defined' do
|
56
|
-
allow(subject).to receive(:respond_to?).with(:id).and_return(false)
|
57
|
-
expect { subject.uid }.to raise_error(NotImplementedError)
|
58
|
-
end
|
28
|
+
describe '#authenticate' do
|
29
|
+
it('is abstract') { expect { instance.authenticate('my-password') }.to raise_error(NotImplementedError) }
|
59
30
|
end
|
60
31
|
|
61
32
|
describe '#auth_key' do
|
62
|
-
it 'defaults to #email' do
|
63
|
-
allow(subject).to receive(:respond_to?).with(:email).and_return(true)
|
64
|
-
allow(subject).to receive(:email).and_return('bob@bob.com')
|
65
|
-
expect(subject.auth_key).to eq('bob@bob.com')
|
66
|
-
end
|
67
|
-
|
68
|
-
it 'uses the class .auth_key' do
|
69
|
-
subject.class.auth_key 'login'
|
70
|
-
allow(subject).to receive(:login).and_return 'bob'
|
71
|
-
expect(subject.auth_key).to eq('bob')
|
72
|
-
subject.class.auth_key nil
|
73
|
-
end
|
74
|
-
|
75
33
|
it 'raises a NotImplementedError if the auth_key method is not defined' do
|
76
|
-
expect {
|
34
|
+
expect { instance.auth_key }.to raise_error(NotImplementedError)
|
77
35
|
end
|
78
36
|
end
|
79
37
|
|
80
38
|
describe '#auth_key=' do
|
81
|
-
it '
|
82
|
-
|
83
|
-
expect(subject).to receive(:email=).with 'abc'
|
84
|
-
|
85
|
-
subject.auth_key = 'abc'
|
86
|
-
end
|
87
|
-
|
88
|
-
it 'uses a custom .auth_key if one is provided' do
|
89
|
-
subject.class.auth_key 'login'
|
90
|
-
allow(subject).to receive(:respond_to?).with(:login=).and_return(true)
|
91
|
-
expect(subject).to receive(:login=).with('abc')
|
92
|
-
|
93
|
-
subject.auth_key = 'abc'
|
94
|
-
end
|
95
|
-
|
96
|
-
it 'raises a NotImplementedError if the autH_key method is not defined' do
|
97
|
-
expect { subject.auth_key = 'broken' }.to raise_error(NotImplementedError)
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
describe '#info' do
|
102
|
-
it 'includes attributes that are set' do
|
103
|
-
allow(subject).to receive(:name).and_return('Bob Bobson')
|
104
|
-
allow(subject).to receive(:nickname).and_return('bob')
|
105
|
-
|
106
|
-
expect(subject.info).to eq({
|
107
|
-
'name' => 'Bob Bobson',
|
108
|
-
'nickname' => 'bob'
|
109
|
-
})
|
110
|
-
end
|
111
|
-
|
112
|
-
it 'automaticallies set name off of nickname' do
|
113
|
-
allow(subject).to receive(:nickname).and_return('bob')
|
114
|
-
subject.info['name'] == 'bob'
|
115
|
-
end
|
116
|
-
|
117
|
-
it 'does not overwrite a provided name' do
|
118
|
-
allow(subject).to receive(:name).and_return('Awesome Dude')
|
119
|
-
allow(subject).to receive(:first_name).and_return('Frank')
|
120
|
-
expect(subject.info['name']).to eq('Awesome Dude')
|
39
|
+
it 'raises a NotImplementedError if the auth_key method is not defined' do
|
40
|
+
expect { instance.auth_key = 'broken' }.to raise_error(NotImplementedError)
|
121
41
|
end
|
122
42
|
end
|
123
43
|
end
|
@@ -1,6 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require 'sqlite3'
|
4
|
+
require 'active_record'
|
5
|
+
require 'anonymous_active_record'
|
6
|
+
|
7
|
+
class TestIdentity < OmniAuth::Identity::Models::ActiveRecord; end
|
8
|
+
|
9
|
+
RSpec.describe(OmniAuth::Identity::Models::ActiveRecord, sqlite3: true) do
|
4
10
|
describe 'model', type: :model do
|
5
11
|
subject(:model_klass) do
|
6
12
|
AnonymousActiveRecord.generate(
|
@@ -14,17 +20,20 @@ RSpec.describe(OmniAuth::Identity::Models::ActiveRecord, db: true) do
|
|
14
20
|
end
|
15
21
|
end
|
16
22
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
23
|
+
include_context 'persistable model'
|
24
|
+
|
25
|
+
describe '::table_name' do
|
26
|
+
it 'does not use STI rules for its table name' do
|
27
|
+
expect(TestIdentity.table_name).to eq('test_identities')
|
28
|
+
end
|
21
29
|
end
|
22
|
-
end
|
23
30
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
31
|
+
describe '::locate' do
|
32
|
+
it 'delegates locate to the where query method' do
|
33
|
+
allow(model_klass).to receive(:where).with('email' => 'open faced', 'category' => 'sandwiches',
|
34
|
+
'provider' => 'identity').and_return(['wakka'])
|
35
|
+
expect(model_klass.locate('email' => 'open faced', 'category' => 'sandwiches')).to eq('wakka')
|
36
|
+
end
|
28
37
|
end
|
29
38
|
end
|
30
39
|
end
|
@@ -1,23 +1,38 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'sqlite3'
|
3
4
|
require 'sequel'
|
4
|
-
|
5
|
+
|
5
6
|
DB = Sequel.sqlite
|
6
|
-
DB.create_table :sequel_test_identities do
|
7
|
-
primary_key :id
|
8
|
-
String :ham_sandwich, null: false
|
9
|
-
String :password_digest, null: false
|
10
|
-
end
|
11
7
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
8
|
+
RSpec.describe(OmniAuth::Identity::Models::Sequel, sqlite3: true) do
|
9
|
+
before(:all) do
|
10
|
+
# Connect to an in-memory sqlite3 database.
|
11
|
+
DB.create_table :sequel_test_identities do
|
12
|
+
primary_key :id
|
13
|
+
String :email, null: false
|
14
|
+
String :password_digest, null: false
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
before do
|
19
|
+
sequel_test_identity = Class.new(Sequel::Model(:sequel_test_identities)) do
|
20
|
+
include ::OmniAuth::Identity::Models::Sequel
|
21
|
+
end
|
22
|
+
stub_const('SequelTestIdentity', sequel_test_identity)
|
23
|
+
end
|
24
|
+
|
25
|
+
describe 'model', type: :model do
|
26
|
+
subject(:model_klass) { SequelTestIdentity }
|
27
|
+
|
28
|
+
include_context 'persistable model'
|
16
29
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
30
|
+
describe '::locate' do
|
31
|
+
it 'delegates to the where query method' do
|
32
|
+
allow(model_klass).to receive(:where).with('email' => 'open faced',
|
33
|
+
'category' => 'sandwiches').and_return(['wakka'])
|
34
|
+
expect(model_klass.locate('email' => 'open faced', 'category' => 'sandwiches')).to eq('wakka')
|
35
|
+
end
|
36
|
+
end
|
22
37
|
end
|
23
38
|
end
|
@@ -1,6 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require 'sqlite3'
|
4
|
+
require 'active_record'
|
5
|
+
require 'anonymous_active_record'
|
6
|
+
|
7
|
+
RSpec.describe OmniAuth::Strategies::Identity, sqlite3: true do
|
4
8
|
attr_accessor :app
|
5
9
|
|
6
10
|
let(:env_hash) { last_response.headers['env'] }
|
data/spec/spec_helper.rb
CHANGED
@@ -1,21 +1,32 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# NOTE: mongoid and no_brainer can't be loaded at the same time.
|
4
|
+
# If you try it, one or both of them will not work.
|
5
|
+
# This is why the ORM specs are split into a separate directory and run in separate threads.
|
6
|
+
|
7
|
+
ENV['RUBY_ENV'] = 'test' # Used by NoBrainer
|
8
|
+
ENV['MONGOID_ENV'] = 'test' # Used by Mongoid
|
9
|
+
|
3
10
|
ruby_version = Gem::Version.new(RUBY_VERSION)
|
4
11
|
require 'simplecov' if ruby_version >= Gem::Version.new('2.7') && RUBY_ENGINE == 'ruby'
|
5
12
|
|
6
13
|
require 'rack/test'
|
7
|
-
require '
|
8
|
-
require 'sqlite3'
|
9
|
-
require 'sequel'
|
10
|
-
require 'anonymous_active_record'
|
14
|
+
require 'rspec/block_is_expected'
|
11
15
|
require 'byebug' if RUBY_ENGINE == 'ruby'
|
12
16
|
|
13
17
|
# This gem
|
14
18
|
require 'omniauth/identity'
|
15
19
|
|
20
|
+
spec_root_matcher = %r{#{__dir__}/(.+)\.rb\Z}
|
21
|
+
Dir.glob(Pathname.new(__dir__).join('support/**/', '*.rb')).each { |f| require f.match(spec_root_matcher)[1] }
|
22
|
+
|
23
|
+
DEFAULT_PASSWORD = 'hang-a-left-at-the-diner'
|
24
|
+
DEFAULT_EMAIL = 'mojo@example.com'
|
25
|
+
|
16
26
|
RSpec.configure do |config|
|
17
27
|
config.include Rack::Test::Methods
|
18
|
-
|
28
|
+
|
29
|
+
# config.include ::Mongoid::Matchers, db: :mongodb
|
19
30
|
|
20
31
|
# Enable flags like --only-failures and --next-failure
|
21
32
|
config.example_status_persistence_file_path = '.rspec_status'
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.shared_examples 'instance with instance methods' do
|
4
|
+
describe '#initialize' do
|
5
|
+
it 'does not raise an error' do
|
6
|
+
block_is_expected.not_to raise_error
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#uid' do
|
11
|
+
it 'defaults to #id' do
|
12
|
+
allow(instance).to receive(:respond_to?).with(:id).and_return(true)
|
13
|
+
allow(instance).to receive(:id).and_return 'wakka-do'
|
14
|
+
expect(instance.uid).to eq('wakka-do')
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'stringifies it' do
|
18
|
+
allow(instance).to receive(:id).and_return 123
|
19
|
+
expect(instance.uid).to eq('123')
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'raises NotImplementedError if #id is not defined' do
|
23
|
+
allow(instance).to receive(:respond_to?).with(:id).and_return(false)
|
24
|
+
expect { instance.uid }.to raise_error(NotImplementedError)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#auth_key' do
|
29
|
+
it 'defaults to #email' do
|
30
|
+
allow(instance).to receive(:respond_to?).with(:email).and_return(true)
|
31
|
+
allow(instance).to receive(:email).and_return('bob@bob.com')
|
32
|
+
expect(instance.auth_key).to eq('bob@bob.com')
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'uses the class .auth_key' do
|
36
|
+
instance.class.auth_key 'login'
|
37
|
+
allow(instance).to receive(:login).and_return 'bob'
|
38
|
+
expect(instance.auth_key).to eq('bob')
|
39
|
+
instance.class.auth_key nil
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '#auth_key=' do
|
44
|
+
it 'defaults to setting email' do
|
45
|
+
allow(instance).to receive(:respond_to?).with(:email=).and_return(true)
|
46
|
+
expect(instance).to receive(:email=).with 'abc'
|
47
|
+
|
48
|
+
instance.auth_key = 'abc'
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'uses a custom .auth_key if one is provided' do
|
52
|
+
instance.class.auth_key 'login'
|
53
|
+
allow(instance).to receive(:respond_to?).with(:login=).and_return(true)
|
54
|
+
expect(instance).to receive(:login=).with('abc')
|
55
|
+
|
56
|
+
instance.auth_key = 'abc'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe '#info' do
|
61
|
+
it 'includes all attributes as they have been set' do
|
62
|
+
allow(instance).to receive(:name).and_return('Bob Bobson')
|
63
|
+
allow(instance).to receive(:nickname).and_return('bob')
|
64
|
+
|
65
|
+
expect(instance.info).to include({
|
66
|
+
'name' => 'Bob Bobson',
|
67
|
+
'nickname' => 'bob'
|
68
|
+
})
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'uses firstname and lastname, over nickname, to set missing name' do
|
72
|
+
allow(instance).to receive(:first_name).and_return('shoeless')
|
73
|
+
allow(instance).to receive(:last_name).and_return('joe')
|
74
|
+
allow(instance).to receive(:nickname).and_return('george')
|
75
|
+
instance.info['name'] == 'shoeless joe'
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'uses nickname to set missing name when first and last are not set' do
|
79
|
+
allow(instance).to receive(:nickname).and_return('bob')
|
80
|
+
instance.info['name'] == 'bob'
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'does not overwrite a provided name' do
|
84
|
+
allow(instance).to receive(:name).and_return('Awesome Dude')
|
85
|
+
allow(instance).to receive(:first_name).and_return('Frank')
|
86
|
+
expect(instance.info['name']).to eq('Awesome Dude')
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.shared_examples 'model with class methods' do
|
4
|
+
describe 'class definition' do
|
5
|
+
it 'does not raise an error' do
|
6
|
+
block_is_expected.not_to raise_error
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '::authenticate' do
|
11
|
+
it 'calls locate and then authenticate' do
|
12
|
+
mocked_instance = double('ExampleModel', authenticate: 'abbadoo')
|
13
|
+
allow(model_klass).to receive(:locate).with('email' => 'example').and_return(mocked_instance)
|
14
|
+
expect(model_klass.authenticate({ 'email' => 'example' }, 'pass')).to eq('abbadoo')
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'calls locate with additional scopes when provided' do
|
18
|
+
mocked_instance = double('ExampleModel', authenticate: 'abbadoo')
|
19
|
+
allow(model_klass).to receive(:locate).with('email' => 'example',
|
20
|
+
'user_type' => 'admin').and_return(mocked_instance)
|
21
|
+
expect(model_klass.authenticate({ 'email' => 'example', 'user_type' => 'admin' }, 'pass')).to eq('abbadoo')
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'recovers gracefully if locate is nil' do
|
25
|
+
allow(model_klass).to receive(:locate).and_return(nil)
|
26
|
+
expect(model_klass.authenticate('blah', 'foo')).to be false
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.shared_context 'persistable model' do
|
4
|
+
include_context 'model with class methods'
|
5
|
+
|
6
|
+
describe 'instance methods' do
|
7
|
+
subject(:instance) { model_klass.new }
|
8
|
+
|
9
|
+
include_context 'instance with instance methods'
|
10
|
+
|
11
|
+
describe '#save' do
|
12
|
+
subject(:save) do
|
13
|
+
instance.email = DEFAULT_EMAIL
|
14
|
+
instance.password = DEFAULT_PASSWORD
|
15
|
+
instance.password_confirmation = DEFAULT_PASSWORD
|
16
|
+
instance.save
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'does not raise an error' do
|
20
|
+
save
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
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.
|
4
|
+
version: 3.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Boling
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date: 2021-03-
|
13
|
+
date: 2021-03-24 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bcrypt
|
@@ -40,54 +40,6 @@ dependencies:
|
|
40
40
|
- - ">="
|
41
41
|
- !ruby/object:Gem::Version
|
42
42
|
version: '0'
|
43
|
-
- !ruby/object:Gem::Dependency
|
44
|
-
name: anonymous_active_record
|
45
|
-
requirement: !ruby/object:Gem::Requirement
|
46
|
-
requirements:
|
47
|
-
- - "~>"
|
48
|
-
- !ruby/object:Gem::Version
|
49
|
-
version: '1.0'
|
50
|
-
- - ">="
|
51
|
-
- !ruby/object:Gem::Version
|
52
|
-
version: 1.0.8
|
53
|
-
type: :development
|
54
|
-
prerelease: false
|
55
|
-
version_requirements: !ruby/object:Gem::Requirement
|
56
|
-
requirements:
|
57
|
-
- - "~>"
|
58
|
-
- !ruby/object:Gem::Version
|
59
|
-
version: '1.0'
|
60
|
-
- - ">="
|
61
|
-
- !ruby/object:Gem::Version
|
62
|
-
version: 1.0.8
|
63
|
-
- !ruby/object:Gem::Dependency
|
64
|
-
name: mongoid
|
65
|
-
requirement: !ruby/object:Gem::Requirement
|
66
|
-
requirements:
|
67
|
-
- - "~>"
|
68
|
-
- !ruby/object:Gem::Version
|
69
|
-
version: '7'
|
70
|
-
type: :development
|
71
|
-
prerelease: false
|
72
|
-
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
requirements:
|
74
|
-
- - "~>"
|
75
|
-
- !ruby/object:Gem::Version
|
76
|
-
version: '7'
|
77
|
-
- !ruby/object:Gem::Dependency
|
78
|
-
name: nobrainer
|
79
|
-
requirement: !ruby/object:Gem::Requirement
|
80
|
-
requirements:
|
81
|
-
- - "~>"
|
82
|
-
- !ruby/object:Gem::Version
|
83
|
-
version: '0'
|
84
|
-
type: :development
|
85
|
-
prerelease: false
|
86
|
-
version_requirements: !ruby/object:Gem::Requirement
|
87
|
-
requirements:
|
88
|
-
- - "~>"
|
89
|
-
- !ruby/object:Gem::Version
|
90
|
-
version: '0'
|
91
43
|
- !ruby/object:Gem::Dependency
|
92
44
|
name: rack-test
|
93
45
|
requirement: !ruby/object:Gem::Requirement
|
@@ -131,19 +83,19 @@ dependencies:
|
|
131
83
|
- !ruby/object:Gem::Version
|
132
84
|
version: '3'
|
133
85
|
- !ruby/object:Gem::Dependency
|
134
|
-
name:
|
86
|
+
name: rspec-block_is_expected
|
135
87
|
requirement: !ruby/object:Gem::Requirement
|
136
88
|
requirements:
|
137
89
|
- - "~>"
|
138
90
|
- !ruby/object:Gem::Version
|
139
|
-
version: '
|
91
|
+
version: '1.0'
|
140
92
|
type: :development
|
141
93
|
prerelease: false
|
142
94
|
version_requirements: !ruby/object:Gem::Requirement
|
143
95
|
requirements:
|
144
96
|
- - "~>"
|
145
97
|
- !ruby/object:Gem::Version
|
146
|
-
version: '
|
98
|
+
version: '1.0'
|
147
99
|
- !ruby/object:Gem::Dependency
|
148
100
|
name: sqlite3
|
149
101
|
requirement: !ruby/object:Gem::Requirement
|
@@ -175,19 +127,19 @@ files:
|
|
175
127
|
- lib/omniauth/identity/models/active_record.rb
|
176
128
|
- lib/omniauth/identity/models/couch_potato.rb
|
177
129
|
- lib/omniauth/identity/models/mongoid.rb
|
178
|
-
- lib/omniauth/identity/models/
|
130
|
+
- lib/omniauth/identity/models/nobrainer.rb
|
179
131
|
- lib/omniauth/identity/models/sequel.rb
|
180
132
|
- lib/omniauth/identity/secure_password.rb
|
181
133
|
- lib/omniauth/strategies/identity.rb
|
182
134
|
- spec/omniauth/identity/model_spec.rb
|
183
135
|
- spec/omniauth/identity/models/active_record_spec.rb
|
184
|
-
- spec/omniauth/identity/models/couch_potato_spec.rb
|
185
|
-
- spec/omniauth/identity/models/mongoid_spec.rb
|
186
|
-
- spec/omniauth/identity/models/no_brainer_spec.rb
|
187
136
|
- spec/omniauth/identity/models/sequel_spec.rb
|
188
137
|
- spec/omniauth/identity/secure_password_spec.rb
|
189
138
|
- spec/omniauth/strategies/identity_spec.rb
|
190
139
|
- spec/spec_helper.rb
|
140
|
+
- spec/support/shared_contexts/instance_with_instance_methods.rb
|
141
|
+
- spec/support/shared_contexts/model_with_class_methods.rb
|
142
|
+
- spec/support/shared_contexts/persistable_model.rb
|
191
143
|
homepage: http://github.com/omniauth/omniauth-identity
|
192
144
|
licenses:
|
193
145
|
- MIT
|
@@ -208,17 +160,17 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
208
160
|
- !ruby/object:Gem::Version
|
209
161
|
version: 1.3.6
|
210
162
|
requirements: []
|
211
|
-
rubygems_version: 3.2.
|
163
|
+
rubygems_version: 3.2.9
|
212
164
|
signing_key:
|
213
165
|
specification_version: 4
|
214
166
|
summary: Traditional username/password based authentication system for OmniAuth
|
215
167
|
test_files:
|
216
|
-
- spec/
|
168
|
+
- spec/spec_helper.rb
|
169
|
+
- spec/support/shared_contexts/persistable_model.rb
|
170
|
+
- spec/support/shared_contexts/model_with_class_methods.rb
|
171
|
+
- spec/support/shared_contexts/instance_with_instance_methods.rb
|
217
172
|
- spec/omniauth/identity/models/active_record_spec.rb
|
218
|
-
- spec/omniauth/identity/models/couch_potato_spec.rb
|
219
|
-
- spec/omniauth/identity/models/mongoid_spec.rb
|
220
|
-
- spec/omniauth/identity/models/no_brainer_spec.rb
|
221
173
|
- spec/omniauth/identity/models/sequel_spec.rb
|
222
174
|
- spec/omniauth/identity/secure_password_spec.rb
|
175
|
+
- spec/omniauth/identity/model_spec.rb
|
223
176
|
- spec/omniauth/strategies/identity_spec.rb
|
224
|
-
- spec/spec_helper.rb
|
@@ -1,21 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'couch_potato'
|
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
|
12
|
-
describe 'model', type: :model do
|
13
|
-
subject { CouchPotatoTestIdentity }
|
14
|
-
|
15
|
-
it 'delegates locate to the where query method' do
|
16
|
-
allow(subject).to receive(:where).with('ham_sandwich' => 'open faced',
|
17
|
-
'category' => 'sandwiches').and_return(['wakka'])
|
18
|
-
expect(subject.locate('ham_sandwich' => 'open faced', 'category' => 'sandwiches')).to eq('wakka')
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'mongoid'
|
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
|
13
|
-
describe 'model', type: :model do
|
14
|
-
subject { MongoidTestIdentity }
|
15
|
-
|
16
|
-
it { is_expected.to be_mongoid_document }
|
17
|
-
|
18
|
-
it 'does not munge collection name' do
|
19
|
-
expect(subject).to be_stored_in(database: 'db1', collection: 'mongoid_test_identities', client: 'secondary')
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'delegates locate to the where query method' do
|
23
|
-
allow(subject).to receive(:where).with('ham_sandwich' => 'open faced',
|
24
|
-
'category' => 'sandwiches').and_return(['wakka'])
|
25
|
-
expect(subject.locate('ham_sandwich' => 'open faced', 'category' => 'sandwiches')).to eq('wakka')
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
@@ -1,17 +0,0 @@
|
|
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
|