forget-passwords 0.2.13 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +5 -3
- data/lib/forget-passwords/template.rb +64 -13
- data/lib/forget-passwords/version.rb +1 -1
- data/lib/forget-passwords.rb +10 -7
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dacb56a002005cc14bb46809690604cccd905eee5c5fc8c5efb78557629611e6
|
4
|
+
data.tar.gz: 704b521acb64f33a934c8768e8bc1496a86ae55d27a0598f4172a7ddc6c8d0e0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1e79d40cbf1151f1a6fb056e17e90f022f65cf575e9eac4a2d1931b4c9c32723924a7e27f83ec893acbafa46710c6da68de3e2791005066ba74eea2a880f0f39
|
7
|
+
data.tar.gz: c306b865ed182f590338d26a7a41a165c38626519dbfc627b77fac4f8a271f7a9d83274a10ec8ae7629a9992407fe92524a4b2a9eb5e4c74ebf1b3b5907e67de
|
data/README.md
CHANGED
@@ -578,9 +578,11 @@ favourite flavour of templating engine.
|
|
578
578
|
|
579
579
|
### Reconcile with OAuth
|
580
580
|
|
581
|
-
|
582
|
-
|
583
|
-
|
581
|
+
Let's face it: this thing is 98% of what [OAuth](https://oauth.net/)
|
582
|
+
does: it trades one token for another over a more-or-less secure side
|
583
|
+
channel. It could be made a heck of a lot simpler by just…wrapping
|
584
|
+
OAuth.
|
585
|
+
|
584
586
|
Indeed, bearer tokens would make for an _excellent_ cleavage plane for
|
585
587
|
_segmented_ authentication: Method X to bearer token, then bearer
|
586
588
|
token to `REMOTE_USER`. This means we could have multiple
|
@@ -4,6 +4,7 @@ require 'xml-mixup'
|
|
4
4
|
require 'http-negotiate'
|
5
5
|
require 'forget-passwords/types'
|
6
6
|
require 'uri'
|
7
|
+
require 'time'
|
7
8
|
|
8
9
|
module ForgetPasswords
|
9
10
|
|
@@ -18,6 +19,8 @@ module ForgetPasswords
|
|
18
19
|
DEFAULT_PATH = (
|
19
20
|
Pathname(__FILE__).parent + '../../content').expand_path.freeze
|
20
21
|
|
22
|
+
# this is a default document root subpath
|
23
|
+
DEFAULT_DOCROOT = '.forgetpw'.freeze
|
21
24
|
|
22
25
|
# Normalize the input to symbol `:like_this`.
|
23
26
|
#
|
@@ -57,21 +60,67 @@ module ForgetPasswords
|
|
57
60
|
@path = Pathname(path).expand_path
|
58
61
|
@base = base
|
59
62
|
@transform = transform
|
60
|
-
@mapping = mapping
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
63
|
+
@mapping = mapping
|
64
|
+
@templates = {
|
65
|
+
@path => mapping.map do |k, v|
|
66
|
+
name = normalize k
|
67
|
+
template = v.is_a?(ForgetPasswords::Template) ? v :
|
68
|
+
ForgetPasswords::Template.new(self, k, @path + v)
|
69
|
+
[name, template]
|
70
|
+
end.to_h
|
71
|
+
}
|
66
72
|
end
|
67
73
|
|
68
|
-
|
69
|
-
|
74
|
+
# Fetch the appropriate template, optionally relative to a given root.
|
75
|
+
#
|
76
|
+
# @param key [Symbol, #to_sym] the template key.
|
77
|
+
# @param root [nil, String] an optional document root.
|
78
|
+
#
|
79
|
+
# @return [nil, ForgetPasswords::Template] a template
|
80
|
+
#
|
81
|
+
def [] key, root = nil
|
82
|
+
key = normalize key
|
83
|
+
# bail early if we don't know the key
|
84
|
+
return unless @mapping[key]
|
85
|
+
|
86
|
+
# obtain optional root
|
87
|
+
root = if root
|
88
|
+
r = root.respond_to?(:env) ? root.env['DOCUMENT_ROOT'] : root
|
89
|
+
r = (Pathname(r) + DEFAULT_DOCROOT).expand_path
|
90
|
+
r.readable? ? r : nil
|
91
|
+
end
|
92
|
+
|
93
|
+
if root
|
94
|
+
# get the full file path
|
95
|
+
fp = root + @mapping[key]
|
96
|
+
if fp.readable?
|
97
|
+
mt = fp.mtime
|
98
|
+
rootmap = @templates[root] ||= {}
|
99
|
+
template = rootmap[key]
|
100
|
+
|
101
|
+
# congratulations, you found it
|
102
|
+
return template if template and mt <= template.modified
|
103
|
+
|
104
|
+
# XXX this could explode obvs
|
105
|
+
begin
|
106
|
+
template = ForgetPasswords::Template.new(self, key, fp, mt)
|
107
|
+
rootmap[key] = template
|
108
|
+
return template
|
109
|
+
rescue
|
110
|
+
# XXX duhh what do we do here
|
111
|
+
nil
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# otherwise just return the default
|
117
|
+
@templates[@path][key]
|
70
118
|
end
|
71
119
|
|
72
120
|
def []= key, path
|
73
121
|
name = normalize key
|
74
|
-
|
122
|
+
# XXX do something less dumb here
|
123
|
+
@templates[@path][name] = path.is_a?(ForgetPasswords::Template) ? path :
|
75
124
|
ForgetPasswords::Template.new(self, key, @path + path)
|
76
125
|
end
|
77
126
|
|
@@ -132,12 +181,13 @@ module ForgetPasswords
|
|
132
181
|
|
133
182
|
public
|
134
183
|
|
135
|
-
attr_reader :name, :doc, :mapper
|
184
|
+
attr_reader :name, :doc, :mapper, :modified
|
136
185
|
|
137
|
-
def initialize mapper, name, content
|
186
|
+
def initialize mapper, name, content, modified = Time.now
|
138
187
|
# boring members
|
139
|
-
@mapper
|
140
|
-
@name
|
188
|
+
@mapper = mapper
|
189
|
+
@name = name
|
190
|
+
@modified = modified
|
141
191
|
|
142
192
|
# resolve content
|
143
193
|
@doc = case content
|
@@ -253,6 +303,7 @@ module ForgetPasswords
|
|
253
303
|
# @return [Rack::Response] the response object, updated in place
|
254
304
|
#
|
255
305
|
def populate resp, headers = {}, vars = {}, base: nil
|
306
|
+
|
256
307
|
if (body, type = serialize(
|
257
308
|
process(vars: vars, base: base), headers, full: true))
|
258
309
|
#resp.length = body.bytesize # not sure if necessary
|
data/lib/forget-passwords.rb
CHANGED
@@ -311,7 +311,7 @@ module ForgetPasswords
|
|
311
311
|
}
|
312
312
|
|
313
313
|
# grab the template since we'll use it
|
314
|
-
template = @templates[:email]
|
314
|
+
template = @templates[:email, req]
|
315
315
|
|
316
316
|
# process the templates
|
317
317
|
doc = template.process vars: vars
|
@@ -336,7 +336,7 @@ module ForgetPasswords
|
|
336
336
|
uri = req_uri req
|
337
337
|
resp = Rack::Response.new
|
338
338
|
resp.status = status
|
339
|
-
@templates[key].populate resp, req, vars, base: uri
|
339
|
+
@templates[key, req].populate resp, req, vars, base: uri
|
340
340
|
resp.set_header "Variable-#{@vars[:type]}", resp.content_type
|
341
341
|
raise ForgetPasswords::ErrorResponse, resp
|
342
342
|
end
|
@@ -347,7 +347,7 @@ module ForgetPasswords
|
|
347
347
|
uri = req_uri req
|
348
348
|
resp = Rack::Response.new
|
349
349
|
resp.status = 401
|
350
|
-
@templates[:default_401].populate resp, req, {
|
350
|
+
@templates[:default_401, req].populate resp, req, {
|
351
351
|
FORWARD: req_uri(req).to_s, LOGIN: @targets[:login] }, base: uri
|
352
352
|
resp.set_header "Variable-#{@vars[:type]}", resp.content_type
|
353
353
|
resp
|
@@ -386,7 +386,7 @@ module ForgetPasswords
|
|
386
386
|
target != uri # (note this should always be true)
|
387
387
|
resp.set_cookie @keys[:cookie], {
|
388
388
|
value: token, secure: req.ssl?, httponly: true,
|
389
|
-
domain: uri.host, path: ?/, same_site: :strict
|
389
|
+
domain: uri.host, path: ?/, same_site: :lax, # strict is too strict
|
390
390
|
expires: time_delta(@state.expiry[:cookie]),
|
391
391
|
}
|
392
392
|
|
@@ -444,7 +444,7 @@ module ForgetPasswords
|
|
444
444
|
# update the cookie expiration
|
445
445
|
resp.set_cookie @keys[:cookie], {
|
446
446
|
value: token, secure: req.ssl?, httponly: true,
|
447
|
-
domain: uri.host, path: ?/, same_site: :strict
|
447
|
+
domain: uri.host, path: ?/, same_site: :lax, # strict is too strict
|
448
448
|
expires: time_delta(@state.expiry[:cookie], now),
|
449
449
|
}
|
450
450
|
|
@@ -495,7 +495,7 @@ module ForgetPasswords
|
|
495
495
|
|
496
496
|
# return 200 now because this is now a content handler
|
497
497
|
resp.status = 200
|
498
|
-
@templates[:email_sent].populate resp, req, {
|
498
|
+
@templates[:email_sent, req].populate resp, req, {
|
499
499
|
FORWARD: forward.to_s, FROM: @email[:from].to_s, EMAIL: address.to_s },
|
500
500
|
base: uri
|
501
501
|
end
|
@@ -534,6 +534,7 @@ module ForgetPasswords
|
|
534
534
|
def handle_auth req
|
535
535
|
auth = req.get_header('Authorization') || req.env['HTTP_AUTHORIZATION']
|
536
536
|
if auth and !auth.strip.empty?
|
537
|
+
# warn "has authorization header #{auth}"
|
537
538
|
mech, *auth = auth.strip.split
|
538
539
|
token = case mech.downcase
|
539
540
|
when 'basic'
|
@@ -549,13 +550,15 @@ module ForgetPasswords
|
|
549
550
|
default_401 req
|
550
551
|
end
|
551
552
|
elsif knock = req.GET[@keys[:query]]
|
552
|
-
# check for a knock
|
553
|
+
# check for a knock; this overrides an existing cookie
|
554
|
+
# warn "has knock token #{knock}"
|
553
555
|
handle_knock req, knock
|
554
556
|
# elsif req.post?
|
555
557
|
# # next check for a login/logout attempt
|
556
558
|
# handle_post req
|
557
559
|
elsif token = req.cookies[@keys[:cookie]]
|
558
560
|
# next check for a cookie
|
561
|
+
# warn "has cookie #{token}"
|
559
562
|
handle_cookie req, token
|
560
563
|
else
|
561
564
|
default_401 req
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: forget-passwords
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dorian Taylor
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-03-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -290,7 +290,7 @@ homepage: https://github.com/doriantaylor/rb-forget-passwords
|
|
290
290
|
licenses:
|
291
291
|
- Apache-2.0
|
292
292
|
metadata: {}
|
293
|
-
post_install_message:
|
293
|
+
post_install_message:
|
294
294
|
rdoc_options: []
|
295
295
|
require_paths:
|
296
296
|
- lib
|
@@ -305,8 +305,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
305
305
|
- !ruby/object:Gem::Version
|
306
306
|
version: '0'
|
307
307
|
requirements: []
|
308
|
-
rubygems_version: 3.
|
309
|
-
signing_key:
|
308
|
+
rubygems_version: 3.1.2
|
309
|
+
signing_key:
|
310
310
|
specification_version: 4
|
311
311
|
summary: Web authentication module for the extremely lazy
|
312
312
|
test_files: []
|