omniauth-identity 3.0.6 → 3.0.7
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 +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
|