omniauth-onetime 1.0.3 → 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -3
- data/README.md +36 -10
- data/lib/omniauth/omniauth-onetime/version.rb +1 -1
- data/lib/omniauth/strategies/onetime.rb +22 -14
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 40834fd3d8b50476dadb4e1fb04acab0ff4a384e
|
4
|
+
data.tar.gz: 21f91f93bbb1c40cf8bdc38dea8450f236d71772
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a5d4809b47eee98df3b95322445d847bc3abb7b00901a710c8987e5414b6d66fc690dd4edc83c8bb1a8a0067f31faeab0666a7138d452b97c14d8d5cac1044df
|
7
|
+
data.tar.gz: d5f3e9eeadfa45f7b921f12017da747bccdaa2cf9f02826cf2046e2cddb04068e51228c419b1eca4e07bb717bdf8bc0649ef166adc4b1e086e4e942adbd1961d
|
data/.rubocop.yml
CHANGED
@@ -718,17 +718,17 @@ Style/LineEndConcatenation:
|
|
718
718
|
line end.
|
719
719
|
Enabled: false
|
720
720
|
|
721
|
-
Style/
|
721
|
+
Style/MethodCallWithoutArgsParentheses:
|
722
722
|
Description: 'Do not use parentheses for method calls with no arguments.'
|
723
723
|
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-args-no-parens'
|
724
|
-
Enabled:
|
724
|
+
Enabled: true
|
725
725
|
|
726
726
|
Style/MethodDefParentheses:
|
727
727
|
Description: >-
|
728
728
|
Checks if the method definitions have or don't have
|
729
729
|
parentheses.
|
730
730
|
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#method-parens'
|
731
|
-
Enabled:
|
731
|
+
Enabled: true
|
732
732
|
|
733
733
|
Style/MethodName:
|
734
734
|
Description: 'Use the configured style when naming methods.'
|
data/README.md
CHANGED
@@ -15,7 +15,7 @@ other password breaches every web development team needs to ask:
|
|
15
15
|
|
16
16
|
**Is it worth storing long term user generated passwords?**
|
17
17
|
|
18
|
-
I suggest that it very rarely is.
|
18
|
+
I suggest that it very rarely is, unless you are an email provider or a financial institution.
|
19
19
|
|
20
20
|
## Vision
|
21
21
|
|
@@ -59,7 +59,7 @@ end
|
|
59
59
|
`config/routes.rb` file something like this:
|
60
60
|
|
61
61
|
```ruby
|
62
|
-
|
62
|
+
post '/auth/:provider/callback', to: 'sessions#create'
|
63
63
|
```
|
64
64
|
|
65
65
|
`app/controllers/sessions_controller.rb` file something like this:
|
@@ -117,10 +117,15 @@ These settings can be passed as a hash in the initializer.
|
|
117
117
|
|
118
118
|
Reading List:
|
119
119
|
|
120
|
+
* 2012-07-25: [Is it time for password-less login?](http://notes.xoxco.com/post/27999787765/is-it-time-for-password-less-login)
|
121
|
+
* 2012-07-29: [More on password-less login](http://notes.xoxco.com/post/28288684632/more-on-password-less-login)
|
120
122
|
* 2014-04-12: [Passwords are Obsolete](https://medium.com/@ninjudd/passwords-are-obsolete-9ed56d483eb)
|
121
123
|
* 2014-10-15: [Passwordless authentication: Secure, simple, and fast to deploy](https://hacks.mozilla.org/2014/10/passwordless-authentication-secure-simple-and-fast-to-deploy/)
|
124
|
+
* 2015-06-29: [Signing in to Medium by email](https://blog.medium.com/signing-in-to-medium-by-email-aacc21134fcd)
|
122
125
|
* 2015-06-30: [Why passwords suck](https://medium.engineering/why-passwords-suck-d1d1f38c1bb4)
|
126
|
+
* 2016-05-12: [Password-less hassle-free authentication in Rails](https://masa331.github.io/2016/05/21/passwordless-authentication-in-rails.html)
|
123
127
|
* 2016-08-12: [Securing access to genetic and personal information without a password](https://biogeniq.ca/en/articles/securing-access-to-genetic-and-personal-information-without-a-password/)
|
128
|
+
* 2016-10-20: [Password-Less Authentication in Rails](https://www.sitepoint.com/password-less-authentication-in-rails/)
|
124
129
|
* [Passwordless](https://passwordless.net/)
|
125
130
|
|
126
131
|
The nomenclature has been settling on calling this approach "passwordless".
|
@@ -134,9 +139,10 @@ transmission of quickly expiring one-time passwords.
|
|
134
139
|
|
135
140
|
This approach may sound counter-intuitive, especially with a default password
|
136
141
|
length of 8 characters. However, the real key to the security is that the
|
137
|
-
passwords are sufficiently random and the window of opportunity
|
142
|
+
passwords are sufficiently random and the window of opportunity to crack them
|
143
|
+
is very short.
|
138
144
|
A traditional username / password system fails because the passwords are not
|
139
|
-
sufficiently random as truly random passwords are difficult to remember and
|
145
|
+
sufficiently random, as truly random passwords are difficult to remember, and
|
140
146
|
because the password lifetime is often very long. An issue which compounds
|
141
147
|
these traditional systems is password reuse which puts accounts at risk
|
142
148
|
whenever any system containing a user's password becomes compromised and
|
@@ -165,12 +171,13 @@ ends. See also: [xkcd: Password Reuse](https://xkcd.com/792/)
|
|
165
171
|
### Limitations:
|
166
172
|
|
167
173
|
* A compromised email account will compromise the user account. **However, this
|
168
|
-
is also true of any traditional password system that allows for
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
+
is also true of any traditional password system that allows for automated
|
175
|
+
password reset or recovery via email.**
|
176
|
+
The only way to circumvent this attack vector is to
|
177
|
+
handle password resets in a way that verifies a person's identity manually,
|
178
|
+
in person, and with identification. Since most websites are probably not
|
179
|
+
willing to take that step (though financial institutions should at the very
|
180
|
+
least consider it) then emailed one-time passwords are just as secure as
|
174
181
|
any website employing an automated email password reset system.
|
175
182
|
* Users must divulge an email account under their control to sign in. This does
|
176
183
|
not seem like a huge hurdle. If people are concerned with their privacy they
|
@@ -214,6 +221,25 @@ It's probably wise to keep this in mind:
|
|
214
221
|
|
215
222
|
[![xlcd: Security](http://imgs.xkcd.com/comics/security.png)](https://xkcd.com/538/)
|
216
223
|
|
224
|
+
### Comparisons to similar solutions
|
225
|
+
|
226
|
+
* [nopassword](https://github.com/alsmola/nopassword) -
|
227
|
+
I don't prefer this implementation: it's an engine, it's [very opinionated
|
228
|
+
about database structure](https://github.com/alsmola/nopassword/tree/master/db/migrate),
|
229
|
+
it always stores geographical location. I like OmniAuth because it allows
|
230
|
+
authentication mechanisms to be changed without requiring many, if any,
|
231
|
+
application changes. Storing geographic information may be something that
|
232
|
+
people want but I don't want to couple that with my solution.
|
233
|
+
* [omniauth-passwordless](https://github.com/ultima51x/omniauth-passwordless) -
|
234
|
+
This does not appear maintained or developed and is not comparable - it simply
|
235
|
+
asks for an email address and passes that straight through - much like the
|
236
|
+
[OmniAuth Developer strategy](https://github.com/omniauth/omniauth/blob/master/lib/omniauth/strategies/developer.rb).
|
237
|
+
To quote from that code, "It has zero security and should *never* be used in a
|
238
|
+
production setting."
|
239
|
+
* [omniauth-email](https://github.com/zshannon/omniauth-email) -
|
240
|
+
This does not appear maintained or developed. To quote the README, "this code
|
241
|
+
does not work, don't use it."
|
242
|
+
|
217
243
|
## Development
|
218
244
|
|
219
245
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -129,7 +129,7 @@ module OmniAuth
|
|
129
129
|
end
|
130
130
|
|
131
131
|
uid do
|
132
|
-
request
|
132
|
+
request['email']
|
133
133
|
end
|
134
134
|
|
135
135
|
info do
|
@@ -148,6 +148,9 @@ module OmniAuth
|
|
148
148
|
.deliver_now
|
149
149
|
end
|
150
150
|
|
151
|
+
# if a password does not exist for the email, generate one, save it
|
152
|
+
# to the cache, then email it to the email address provided
|
153
|
+
# ie generate, save, send
|
151
154
|
def prepare_password(email)
|
152
155
|
# to prevent DOS do not send another password until previous one has
|
153
156
|
# expired
|
@@ -161,7 +164,7 @@ module OmniAuth
|
|
161
164
|
def request_email
|
162
165
|
log :debug, 'STEP 1: Ask user for email'
|
163
166
|
|
164
|
-
form = OmniAuth::Form.new(title: 'User Info')
|
167
|
+
form = OmniAuth::Form.new(title: 'User Info', url: request_path)
|
165
168
|
form.text_field :email, :email
|
166
169
|
form.button 'Request Password'
|
167
170
|
form.to_response
|
@@ -171,23 +174,13 @@ module OmniAuth
|
|
171
174
|
log :debug, 'STEP 2: prepare password then ask user for password'
|
172
175
|
prepare_password(email)
|
173
176
|
|
174
|
-
form = OmniAuth::Form.new(title: 'User Info')
|
177
|
+
form = OmniAuth::Form.new(title: 'User Info', url: callback_path)
|
175
178
|
form.text_field :password, :password
|
176
179
|
form.html("<input type=\"hidden\" name=\"email\" value=\"#{email}\">")
|
177
180
|
form.button 'Sign In'
|
178
181
|
form.to_response
|
179
182
|
end
|
180
183
|
|
181
|
-
def request_verification(email, plaintext)
|
182
|
-
log :debug, 'STEP 3: verify password'
|
183
|
-
if verify_password(email, plaintext)
|
184
|
-
options[:password_cache].delete(email) # expire password
|
185
|
-
redirect callback_path
|
186
|
-
else
|
187
|
-
redirect request_path
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
184
|
def request_phase
|
192
185
|
email = request.params['email']
|
193
186
|
plaintext = request.params['password']
|
@@ -197,9 +190,24 @@ module OmniAuth
|
|
197
190
|
elsif plaintext.blank?
|
198
191
|
request_password(email)
|
199
192
|
else
|
200
|
-
|
193
|
+
fail!(:took_a_wrong_turn)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
def callback_phase
|
198
|
+
log :debug, 'STEP 3: verify password'
|
199
|
+
email = request.params['email']
|
200
|
+
plaintext = request.params['password']
|
201
|
+
|
202
|
+
if verify_password(email, plaintext)
|
203
|
+
# expire password
|
204
|
+
options[:password_cache].delete(email)
|
205
|
+
super
|
206
|
+
else
|
207
|
+
fail!(:invalid_credentials)
|
201
208
|
end
|
202
209
|
end
|
210
|
+
|
203
211
|
end
|
204
212
|
end
|
205
213
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: omniauth-onetime
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- thoughtafter
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-03-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|