omniauth-identity2 2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: bb5929b5167f886ce7506dab9ce452f408531e223bb7e9725dc62bd8347aaf01
4
+ data.tar.gz: 0377e7d4165f313242b861522fbc091c0c40cd071494057ed8a19dd83dc356cc
5
+ SHA512:
6
+ metadata.gz: 3e1b5bfb087f5f8ec49cfb742db648147d2314efe5c0681cddc17145c0d4fa42b7a622da0da75e7326648b8fac6a4875517f9ec665e617f4825ab68413d88d18
7
+ data.tar.gz: cc5c59485b9c5c19d2d1e7213c90a55776705a3cb10c63d68384bbb5c7924e5e218476ff18af5637d8671d2197d04b4033253107bc5da6d32d5cccfd356bbd9e
@@ -0,0 +1,8 @@
1
+ /coverage
2
+ /pkg
3
+ /doc
4
+
5
+ Gemfile.lock
6
+
7
+ .ruby-version
8
+ .ruby-gemset
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --require spec_helper
2
+ --format=documentation
3
+ --colour
@@ -0,0 +1,27 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ Note: this project forked `omniauth-identity` at v1.1.1. This project's *first* version is v2.0.
6
+
7
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
8
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
9
+
10
+ ## [2.0] - 2020-08-31
11
+
12
+ ### Added
13
+ - CHANGELOG to maintain a history of changes.
14
+ - Include mongoid-rspec gem.
15
+
16
+ ### Changed
17
+ - Updated README to include information about the reasoning and aims of the fork.
18
+ - Updated all references of the gem name to `omniauth-identity2`.
19
+ - Updated copyright information.
20
+ - Updated spec syntax from RSpec v2 -> v3.
21
+ - Updated mongoid_spec.rb to leverage mongoid-rspec features.
22
+ - Fix security warning about missing secret in session cookie.
23
+
24
+ ### Removed
25
+ - Gemfile.lock file
26
+ - Dependency version limits so that the most up-to-date gem dependencies are used.
27
+ - MongoMapper support; unable to satisfy dependencies of both MongoMapper and Mongoig now that MongoMapper is no longer actively maintained.
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source "http://rubygems.org"
2
+ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
3
+
4
+ gemspec
5
+
6
+ group :development, :test do
7
+ gem 'mongoid-rspec', github: 'mongoid/mongoid-rspec'
8
+ gem 'guard'
9
+ gem 'guard-rspec'
10
+ gem 'guard-bundler'
11
+ gem 'growl'
12
+ gem 'rb-fsevent'
13
+ end
@@ -0,0 +1,10 @@
1
+ guard 'rspec', :version => 2 do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
4
+ watch('spec/spec_helper.rb') { "spec" }
5
+ end
6
+
7
+ guard 'bundler' do
8
+ watch('Gemfile')
9
+ watch(/^.+\.gemspec/)
10
+ end
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2020- Andrew Roberts, and Jellybooks Ltd.
2
+ Copyright (c) 2010-2015 Michael Bleigh and Intridea, Inc.
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,240 @@
1
+ # OmniAuth Identity2 (fork of omniauth-identity)
2
+
3
+ The OmniAuth Identity2 gem provides a way for applications to utilize a
4
+ traditional login/password based authentication system without the need
5
+ to give up the simple authentication flow provided by OmniAuth. Identity
6
+ is designed on purpose to be as featureless as possible: it provides the
7
+ basic construct for user management and then gets out of the way.
8
+
9
+ ## Note about this fork
10
+
11
+ The official `omniauth-identity` gem has gone stale. With no disrespect
12
+ to the maintainers who have generously volunteered their time and energy,
13
+ they appear to have moved on and are not responding to issues and pull
14
+ requests, or offers to add additional maintainers to the main project.
15
+
16
+ Whilst the original `omniauth-identity` still *works* per se, primiarly
17
+ because it's relatively small and simple piece of code, there are
18
+ inevitably small issues that need attending to, especially security updates
19
+ to dependencies.
20
+
21
+ Therefore, the goal of this repository is to create a new home for a modern,
22
+ yet **compatible** version of the identity strategy, where issues can be raised
23
+ and addressed, and contributions welcome.
24
+
25
+ The new name of **omniauth-identity2** is to allow for the code to be distributed
26
+ via RubyGems, whilst being familiar enough so that developers will realise
27
+ that it's an up-to-date version of the `omniauth-identity` gem.
28
+
29
+
30
+ ### Compatibility with omniauth-identity
31
+
32
+ The goal is to maintain backward compatibility as closely as possible so that
33
+ developers need only change a single entry in their gemfile to
34
+ `omniauth-identity2` and existing code will work.
35
+
36
+ However, the Ruby ecosystem has evolved since 2010 when the upstream repo was
37
+ created and there instances where it may be necessary to drop support for
38
+ integrations that are no longer maintained. For example, MongoMapper integration
39
+ has been removed from this gem.
40
+
41
+ If and when new features are added they will be labelled as omniauth-identity2
42
+ specific.
43
+
44
+
45
+ ## Usage
46
+
47
+ This can be a bit hard to understand the first time. Luckily, Ryan Bates made
48
+ a [Railscast](http://railscasts.com/episodes/304-omniauth-identity) about it!
49
+
50
+ You use `omniauth-identity2` just like you would any other OmniAuth provider: as a
51
+ Rack middleware. The basic setup for a email/password authentication would
52
+ look something like this:
53
+
54
+ ```ruby
55
+ use OmniAuth::Builder do
56
+ provider :identity, :fields => [:email]
57
+ end
58
+ ```
59
+
60
+ Next, you need to create a model (called `Identity by default`) that will be
61
+ able to persist the information provided by the user. Luckily for you, there
62
+ are pre-built models for popular ORMs that make this dead simple.
63
+
64
+ **Note:** OmniAuth Identity is different from many other user authentication
65
+ systems in that it is *not* built to store authentication information in your primary
66
+ `User` model. Instead, the `Identity` model should be **associated** with your
67
+ `User` model giving you maximum flexibility to include other authentication
68
+ strategies such as Facebook, Twitter, etc.
69
+
70
+ ### ActiveRecord
71
+
72
+ Just subclass `OmniAuth::Identity::Models::ActiveRecord` and provide fields
73
+ in the database for all of the fields you are using.
74
+
75
+ ```ruby
76
+ class Identity < OmniAuth::Identity::Models::ActiveRecord
77
+ # Add whatever you like!
78
+ end
79
+ ```
80
+
81
+ ### Mongoid
82
+
83
+ Include the `OmniAuth::Identity::Models::Mongoid` mixin and specify
84
+ fields that you will need.
85
+
86
+ ```ruby
87
+ class Identity
88
+ include Mongoid::Document
89
+ include OmniAuth::Identity::Models::Mongoid
90
+
91
+ field :email, type: String
92
+ field :name, type: String
93
+ field :password_digest, type: String
94
+ end
95
+ ```
96
+
97
+ ### MongoMapper
98
+
99
+ Unfortunately MongoMapper is **not supported** in `omniauth-identity2` as a result of it
100
+ not being maintained for several years.
101
+
102
+ It wasn't possible to include Mongoid *and* MongoMapper due to incompatible gem version
103
+ requirements. Therefore precedence was given to Mongoid as it is significantly more
104
+ popular and actively maintained.
105
+
106
+ ### DataMapper
107
+
108
+ Include the `OmniAuth::Identity::Models::DataMapper` mixin and specify
109
+ fields that you will need.
110
+
111
+ ```ruby
112
+ class Identity
113
+ include DataMapper::Resource
114
+ include OmniAuth::Identity::Models::DataMapper
115
+
116
+ property :id, Serial
117
+ property :email, String
118
+ property :password_digest, Text
119
+
120
+ attr_accessor :password_confirmation
121
+
122
+ end
123
+ ```
124
+
125
+ ### CouchPotato
126
+
127
+ Include the `OmniAuth::Identity::Models::CouchPotatoModule` mixin and specify fields that you will need.
128
+
129
+ ```ruby
130
+ class Identity
131
+ include CouchPotato::Persistence
132
+ include OmniAuth::Identity::Models::CouchPotatoModule
133
+
134
+ property :email
135
+ property :password_digest
136
+
137
+ def self.where search_hash
138
+ CouchPotato.database.view Identity.by_email(:key => search_hash)
139
+ end
140
+
141
+ view :by_email, :key => :email
142
+ end
143
+ ```
144
+
145
+ Once you've got an Identity persistence model and the strategy up and
146
+ running, you can point users to `/auth/identity` and it will request
147
+ that they log in or give them the opportunity to sign up for an account.
148
+ Once they have authenticated with their identity, OmniAuth will call
149
+ through to `/auth/identity/callback` with the same kinds of information
150
+ it would had the user authenticated through an external provider.
151
+ Simple!
152
+
153
+ ## Custom Auth Model
154
+
155
+ To use a class other than the default, specify the <tt>:model</tt> option to a
156
+ different class.
157
+
158
+ ```ruby
159
+ use OmniAuth::Builder do
160
+ provider :identity, :fields => [:email], :model => MyCustomClass
161
+ end
162
+ ```
163
+
164
+ ## Customizing Registration Failure
165
+
166
+ To use your own custom registration form, create a form that POSTs to
167
+ '/auth/identity/register' with 'password', 'password_confirmation', and your
168
+ other fields.
169
+
170
+ ```erb
171
+ <%= form_tag '/auth/identity/register' do |f| %>
172
+ <h1>Create an Account</h1>
173
+ <%= text_field_tag :email %>
174
+ <%= password_field_tag :password %>
175
+ <%= password_field_tag :password_confirmation %>
176
+ <%= submit_tag %>
177
+ <% end %>
178
+ ```
179
+
180
+ Beware not to nest your form parameters within a namespace. This strategy
181
+ looks for the form parameters at the top level of the post params. If you are
182
+ using [simple\_form](https://github.com/plataformatec/simple_form), then you
183
+ can avoid the params nesting by specifying <tt>:input_html</tt>.
184
+
185
+ ```erb
186
+ <%= simple_form_for @identity, :url => '/auth/identity/register' do |f| %>
187
+ <h1>Create an Account</h1>
188
+ <%# specify :input_html to avoid params nesting %>
189
+ <%= f.input :email, :input_html => {:name => 'email'} %>
190
+ <%= f.input :password, :as => 'password', :input_html => {:name => 'password'} %>
191
+ <%= f.input :password_confirmation, :label => "Confirm Password", :as => 'password', :input_html => {:name => 'password_confirmation'} %>
192
+ <button type='submit'>Sign Up</button>
193
+ <% end %>
194
+ ```
195
+
196
+ Next you'll need to let OmniAuth know what action to call when a registration
197
+ fails. In your OmniAuth configuration, specify any valid rack endpoint in the
198
+ <tt>:on_failed_registration</tt> option.
199
+
200
+ ```ruby
201
+ use OmniAuth::Builder do
202
+ provider :identity,
203
+ :fields => [:email],
204
+ :on_failed_registration => UsersController.action(:new)
205
+ end
206
+ ```
207
+
208
+ For more information on rack endpoints, check out [this
209
+ introduction](http://library.edgecase.com/Rails/2011/01/04/rails-routing-and-rack-endpoints.html)
210
+ and
211
+ [ActionController::Metal](http://rubydoc.info/docs/rails/ActionController/Metal)
212
+
213
+ ## Customizing Locate Conditions
214
+
215
+ You can customize the way that matching records are found when authenticating.
216
+ For example, for a site with multiple domains, you may wish to scope the search
217
+ within a particular subdomain. To do so, add :locate_conditions to your config.
218
+ The default value is:
219
+
220
+ ```ruby
221
+ :locate_conditions => lambda { |req| { model.auth_key => req['auth_key']} }
222
+ ```
223
+
224
+ locate_conditions takes a Proc object, and must return a hash. The resulting hash is used
225
+ as a parameter in the locate method for your ORM. The proc is evaluated in the
226
+ callback context, and has access to the Identity model (using `model`) and receives the request
227
+ object as a parameter. Note that model.auth_key defaults to 'email', but is also configurable.
228
+
229
+ Note: Be careful when customizing locate_conditions. The best way to modify the conditions is
230
+ to copy the default value, and then add to the hash. Removing the default condition will almost
231
+ always break things!
232
+
233
+ ## License
234
+
235
+ MIT License. See LICENSE for details.
236
+
237
+ ## Copyright
238
+
239
+ Copyright (c) 2020- Andrew Roberts, and Jellybooks Ltd.
240
+ Copyright (c) 2010-2015 Michael Bleigh, and Intridea, Inc.
@@ -0,0 +1,9 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ desc "Run specs."
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task :default => :spec
9
+ task :test => :spec
@@ -0,0 +1,2 @@
1
+ require 'omniauth-identity/version'
2
+ require 'omniauth/identity'
@@ -0,0 +1,5 @@
1
+ module OmniAuth
2
+ module Identity
3
+ VERSION = '2.0'
4
+ end
5
+ end
@@ -0,0 +1,18 @@
1
+ require 'omniauth'
2
+
3
+ module OmniAuth
4
+ module Strategies
5
+ autoload :Identity, 'omniauth/strategies/identity'
6
+ end
7
+
8
+ module Identity
9
+ autoload :Model, 'omniauth/identity/model'
10
+ autoload :SecurePassword, 'omniauth/identity/secure_password'
11
+ module Models
12
+ autoload :ActiveRecord, 'omniauth/identity/models/active_record'
13
+ autoload :Mongoid, 'omniauth/identity/models/mongoid'
14
+ autoload :DataMapper, 'omniauth/identity/models/data_mapper'
15
+ autoload :CouchPotatoModule, 'omniauth/identity/models/couch_potato'
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,116 @@
1
+ module OmniAuth
2
+ module Identity
3
+ # This module provides an includable interface for implementing the
4
+ # necessary API for OmniAuth Identity to properly locate identities
5
+ # and provide all necessary information. All methods marked as
6
+ # abstract must be implemented in the including class for things to
7
+ # work properly.
8
+ module Model
9
+ def self.included(base)
10
+ base.extend ClassMethods
11
+ end
12
+
13
+ module ClassMethods
14
+ # Locate an identity given its unique login key.
15
+ #
16
+ # @abstract
17
+ # @param [String] key The unique login key.
18
+ # @return [Model] An instance of the identity model class.
19
+ def locate(key)
20
+ raise NotImplementedError
21
+ end
22
+
23
+ # Authenticate a user with the given key and password.
24
+ #
25
+ # @param [String] key The unique login key provided for a given identity.
26
+ # @param [String] password The presumed password for the identity.
27
+ # @return [Model] An instance of the identity model class.
28
+ def authenticate(conditions, password)
29
+ instance = locate(conditions)
30
+ return false unless instance
31
+ instance.authenticate(password)
32
+ end
33
+
34
+ # Used to set or retrieve the method that will be used to get
35
+ # and set the user-supplied authentication key.
36
+ # @return [String] The method name.
37
+ def auth_key(method = false)
38
+ @auth_key = method.to_s unless method == false
39
+ @auth_key = nil if @auth_key == ''
40
+
41
+ @auth_key || 'email'
42
+ end
43
+ end
44
+
45
+ # Returns self if the provided password is correct, false
46
+ # otherwise.
47
+ #
48
+ # @abstract
49
+ # @param [String] password The password to check.
50
+ # @return [self or false] Self if authenticated, false if not.
51
+ def authenticate(password)
52
+ raise NotImplementedError
53
+ end
54
+
55
+ SCHEMA_ATTRIBUTES = %w(name email nickname first_name last_name location description image phone)
56
+ # A hash of as much of the standard OmniAuth schema as is stored
57
+ # in this particular model. By default, this will call instance
58
+ # methods for each of the attributes it needs in turn, ignoring
59
+ # any for which `#respond_to?` is `false`.
60
+ #
61
+ # If `first_name`, `nickname`, and/or `last_name` is provided but
62
+ # `name` is not, it will be automatically calculated.
63
+ #
64
+ # @return [Hash] A string-keyed hash of user information.
65
+ def info
66
+ info = SCHEMA_ATTRIBUTES.inject({}) do |hash,attribute|
67
+ hash[attribute] = send(attribute) if respond_to?(attribute)
68
+ hash
69
+ end
70
+ info
71
+ end
72
+
73
+ # An identifying string that must be globally unique to the
74
+ # application. Defaults to stringifying the `id` method.
75
+ #
76
+ # @return [String] An identifier string unique to this identity.
77
+ def uid
78
+ if respond_to?(:id)
79
+ return nil if self.id.nil?
80
+ self.id.to_s
81
+ else
82
+ raise NotImplementedError
83
+ end
84
+ end
85
+
86
+ # Used to retrieve the user-supplied authentication key (e.g. a
87
+ # username or email). Determined using the class method of the same name,
88
+ # defaults to `:email`.
89
+ #
90
+ # @return [String] An identifying string that will be entered by
91
+ # users upon sign in.
92
+ def auth_key
93
+ if respond_to?(self.class.auth_key.to_sym)
94
+ send(self.class.auth_key)
95
+ else
96
+ raise NotImplementedError
97
+ end
98
+ end
99
+
100
+ # Used to set the user-supplied authentication key (e.g. a
101
+ # username or email. Determined using the `.auth_key` class
102
+ # method.
103
+ #
104
+ # @param [String] value The value to which the auth key should be
105
+ # set.
106
+ def auth_key=(value)
107
+ auth_key_setter = (self.class.auth_key + '=').to_sym
108
+ if respond_to?(auth_key_setter)
109
+ send(auth_key_setter, value)
110
+ else
111
+ raise NotImplementedError
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end