rack-openid2 2.0.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.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data/LICENSE.txt +21 -0
- data/README.md +137 -0
- data/lib/rack/openid/simple_auth.rb +80 -0
- data/lib/rack/openid/version.rb +7 -0
- data/lib/rack/openid.rb +319 -0
- data.tar.gz.sig +0 -0
- metadata +310 -0
- metadata.gz.sig +0 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6e20d1ffad12ca51d18f244bad5932c7eb45e1e3dc2f26d07f6ac3446d6d1fad
|
4
|
+
data.tar.gz: 26ec20ac08847c203293a9d545ac8c7673ff219a8432e4537bac25e763cbea21
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 53cba4e65ce7d4ffc3a6bf7da94088417df3789464cbe65a28e22432bba7d0fedac7d2156aaee4764672ec5ec0086c2df45ab2fc6e07c187f40407f31a5bf066
|
7
|
+
data.tar.gz: a37b8bf96acda455f479dc0f5d9fbd8aadff4fdee2982b63c9c136c09110a10e8df2afac8179adf1b2c4964f12d8e00983eabaa8c8cef67d35d2172edb89450a
|
checksums.yaml.gz.sig
ADDED
Binary file
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Copyright (c) 2010 Joshua Peek
|
2
|
+
Copyright (c) 2024 Peter Boling
|
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.
|
data/README.md
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
# Rack::OpenID
|
2
|
+
|
3
|
+
<div id="badges">
|
4
|
+
|
5
|
+
[![CI Supported Build][๐s-wfi]][๐s-wf]
|
6
|
+
[![CI Unsupported Build][๐us-wfi]][๐us-wf]
|
7
|
+
[![CI Style Build][๐st-wfi]][๐st-wf]
|
8
|
+
[![CI Coverage Build][๐cov-wfi]][๐cov-wf]
|
9
|
+
[![CI Heads Build][๐hd-wfi]][๐hd-wf]
|
10
|
+
|
11
|
+
[๐s-wf]: https://github.com/VitalConnectInc/rack-openid2/actions/workflows/supported.yml
|
12
|
+
[๐s-wfi]: https://github.com/VitalConnectInc/rack-openid2/actions/workflows/supported.yml/badge.svg
|
13
|
+
[๐us-wf]: https://github.com/VitalConnectInc/rack-openid2/actions/workflows/unsupported.yml
|
14
|
+
[๐us-wfi]: https://github.com/VitalConnectInc/rack-openid2/actions/workflows/unsupported.yml/badge.svg
|
15
|
+
[๐st-wf]: https://github.com/VitalConnectInc/rack-openid2/actions/workflows/style.yml
|
16
|
+
[๐st-wfi]: https://github.com/VitalConnectInc/rack-openid2/actions/workflows/style.yml/badge.svg
|
17
|
+
[๐cov-wf]: https://github.com/VitalConnectInc/rack-openid2/actions/workflows/coverage.yml
|
18
|
+
[๐cov-wfi]: https://github.com/VitalConnectInc/rack-openid2/actions/workflows/coverage.yml/badge.svg
|
19
|
+
[๐hd-wf]: https://github.com/VitalConnectInc/rack-openid2/actions/workflows/heads.yml
|
20
|
+
[๐hd-wfi]: https://github.com/VitalConnectInc/rack-openid2/actions/workflows/heads.yml/badge.svg
|
21
|
+
|
22
|
+
</div>
|
23
|
+
|
24
|
+
Provides a more HTTPish API around the ruby-openid library.
|
25
|
+
|
26
|
+
## Usage
|
27
|
+
|
28
|
+
You trigger an OpenID request similar to HTTP authentication. From your app, return a "401 Unauthorized" and a "WWW-Authenticate" header with the identifier you would like to validate.
|
29
|
+
|
30
|
+
On competition, the OpenID response is automatically verified and assigned to `env["rack.openid.response"]`.
|
31
|
+
|
32
|
+
### Rack Example
|
33
|
+
|
34
|
+
```Ruby
|
35
|
+
MyApp = lambda do |env|
|
36
|
+
if resp = env["rack.openid.response"]
|
37
|
+
case resp.status
|
38
|
+
when :success
|
39
|
+
...
|
40
|
+
when :failure
|
41
|
+
...
|
42
|
+
else
|
43
|
+
[401, {"WWW-Authenticate" => 'OpenID identifier="http://example.com/"'}, []]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
use Rack::OpenID
|
49
|
+
run MyApp
|
50
|
+
```
|
51
|
+
|
52
|
+
### Sinatra Example
|
53
|
+
|
54
|
+
```Ruby
|
55
|
+
# Session needs to be before Rack::OpenID
|
56
|
+
use Rack::Session::Cookie
|
57
|
+
|
58
|
+
require 'rack/openid'
|
59
|
+
use Rack::OpenID
|
60
|
+
|
61
|
+
get '/login' do
|
62
|
+
erb :login
|
63
|
+
end
|
64
|
+
|
65
|
+
post '/login' do
|
66
|
+
if resp = request.env["rack.openid.response"]
|
67
|
+
if resp.status == :success
|
68
|
+
"Welcome: #{resp.display_identifier}"
|
69
|
+
else
|
70
|
+
"Error: #{resp.status}"
|
71
|
+
end
|
72
|
+
else
|
73
|
+
headers 'WWW-Authenticate' => Rack::OpenID.build_header(
|
74
|
+
:identifier => params["openid_identifier"]
|
75
|
+
)
|
76
|
+
throw :halt, [401, 'got openid?']
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
enable :inline_templates
|
81
|
+
|
82
|
+
__END__
|
83
|
+
|
84
|
+
@@ login
|
85
|
+
<form action="/login" method="post">
|
86
|
+
<p>
|
87
|
+
<label for="openid_identifier">OpenID:</label>
|
88
|
+
<input id="openid_identifier" name="openid_identifier" type="text" />
|
89
|
+
</p>
|
90
|
+
|
91
|
+
<p>
|
92
|
+
<input name="commit" type="submit" value="Sign in" />
|
93
|
+
</p>
|
94
|
+
</form>
|
95
|
+
```
|
96
|
+
|
97
|
+
## TODO
|
98
|
+
|
99
|
+
- 1 failing test (skipped)
|
100
|
+
- rewrite tests with minitest/spec
|
101
|
+
|
102
|
+
## ๐ Contributors
|
103
|
+
|
104
|
+
Current maintainer(s):
|
105
|
+
|
106
|
+
- [Peter Boling](https://github.com/pboling)
|
107
|
+
|
108
|
+
Special thanks to:
|
109
|
+
- [Joshua Peek](https://github.com/josh) author of original `rack-openid`
|
110
|
+
- [Michael Grosser](http://grosser.it) maintainer of original `rack-openid`
|
111
|
+
|
112
|
+
and contributors to original `rack-openid`:
|
113
|
+
- [Kenny Buckler](https://github.com/kbuckler)
|
114
|
+
- [Mike Dillon](https://github.com/md5)
|
115
|
+
- [Richard Wilson](https://github.com/Senjai)
|
116
|
+
|
117
|
+
[![Contributors][๐contributors-img]][๐contributors]
|
118
|
+
|
119
|
+
Made with [contributors-img][๐contrib-rocks].
|
120
|
+
|
121
|
+
[๐contrib-rocks]: https://contrib.rocks
|
122
|
+
[๐contributors]: https://github.com/VitalConnectInc/rack-openid2/graphs/contributors
|
123
|
+
[๐contributors-img]: https://contrib.rocks/image?repo=VitalConnectInc/rack-openid2
|
124
|
+
|
125
|
+
## ๐ License
|
126
|
+
|
127
|
+
The gem is available as open source under the terms of
|
128
|
+
the [MIT License][๐license] [![License: MIT][๐license-img]][๐license-ref].
|
129
|
+
|
130
|
+
See [LICENSE.txt][๐license] for the official [Copyright Notice][๐copyright-notice-explainer].
|
131
|
+
|
132
|
+
[comment]: <> ( ๐ LEGAL LINKS )
|
133
|
+
|
134
|
+
[๐copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
|
135
|
+
[๐license]: LICENSE.txt
|
136
|
+
[๐license-ref]: https://opensource.org/licenses/MIT
|
137
|
+
[๐license-img]: https://img.shields.io/badge/License-MIT-green.svg
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require "rack/openid"
|
2
|
+
require "rack/request"
|
3
|
+
|
4
|
+
module Rack
|
5
|
+
class OpenID
|
6
|
+
# A simple OpenID middleware that restricts access to
|
7
|
+
# a single identifier.
|
8
|
+
#
|
9
|
+
# use Rack::OpenID::SimpleAuth, "http://example.org"
|
10
|
+
#
|
11
|
+
# SimpleAuth will automatically insert the required Rack::OpenID
|
12
|
+
# middleware, so use Rack::OpenID is unnecessary.
|
13
|
+
class SimpleAuth
|
14
|
+
class << self
|
15
|
+
def new(*args)
|
16
|
+
Rack::OpenID.new(super)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
attr_reader :app, :identifier
|
21
|
+
|
22
|
+
def initialize(app, identifier)
|
23
|
+
@app = app
|
24
|
+
@identifier = identifier
|
25
|
+
end
|
26
|
+
|
27
|
+
def call(env)
|
28
|
+
if session_authenticated?(env)
|
29
|
+
app.call(env)
|
30
|
+
elsif successful_response?(env)
|
31
|
+
authenticate_session(env)
|
32
|
+
redirect_to(requested_url(env))
|
33
|
+
else
|
34
|
+
authentication_request
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def session(env)
|
41
|
+
env["rack.session"] || raise_session_error
|
42
|
+
end
|
43
|
+
|
44
|
+
def raise_session_error
|
45
|
+
raise "Rack::OpenID::SimpleAuth requires a session"
|
46
|
+
end
|
47
|
+
|
48
|
+
def session_authenticated?(env)
|
49
|
+
session(env)["authenticated"] == true
|
50
|
+
end
|
51
|
+
|
52
|
+
def authenticate_session(env)
|
53
|
+
session(env)["authenticated"] = true
|
54
|
+
end
|
55
|
+
|
56
|
+
def successful_response?(env)
|
57
|
+
if (resp = env[OpenID::RESPONSE])
|
58
|
+
resp.status == :success && resp.display_identifier == identifier
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def requested_url(env)
|
63
|
+
req = Rack::Request.new(env)
|
64
|
+
req.url
|
65
|
+
end
|
66
|
+
|
67
|
+
def redirect_to(url)
|
68
|
+
[303, {"Content-Type" => "text/html", "Location" => url}, []]
|
69
|
+
end
|
70
|
+
|
71
|
+
def authentication_request
|
72
|
+
[401, {OpenID::AUTHENTICATE_HEADER => www_authenticate_header}, []]
|
73
|
+
end
|
74
|
+
|
75
|
+
def www_authenticate_header
|
76
|
+
OpenID.build_header(identifier: identifier)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
data/lib/rack/openid.rb
ADDED
@@ -0,0 +1,319 @@
|
|
1
|
+
# External Libraries
|
2
|
+
require "version_gem"
|
3
|
+
require "rack/request"
|
4
|
+
require "rack/utils"
|
5
|
+
# Require ruby-openid2 and some of its extensions
|
6
|
+
require "openid"
|
7
|
+
require "openid/consumer"
|
8
|
+
require "openid/extensions/sreg"
|
9
|
+
require "openid/extensions/ax"
|
10
|
+
require "openid/extensions/oauth"
|
11
|
+
require "openid/extensions/pape"
|
12
|
+
|
13
|
+
# This gem
|
14
|
+
require_relative "openid/version"
|
15
|
+
|
16
|
+
module Rack
|
17
|
+
# A Rack middleware that provides a more HTTPish API around the
|
18
|
+
# ruby-openid library.
|
19
|
+
#
|
20
|
+
# You trigger an OpenID request similar to HTTP authentication.
|
21
|
+
# From your app, return a "401 Unauthorized" and a "WWW-Authenticate"
|
22
|
+
# header with the identifier you would like to validate.
|
23
|
+
#
|
24
|
+
# On competition, the OpenID response is automatically verified and
|
25
|
+
# assigned to env["rack.openid.response"].
|
26
|
+
class OpenID
|
27
|
+
class << self
|
28
|
+
# Helper method for building the "WWW-Authenticate" header value.
|
29
|
+
#
|
30
|
+
# Rack::OpenID.build_header(:identifier => "http://josh.openid.com/")
|
31
|
+
# #=> OpenID identifier="http://josh.openid.com/"
|
32
|
+
def build_header(params = {})
|
33
|
+
"OpenID " + params.map { |key, value|
|
34
|
+
if value.is_a?(Array)
|
35
|
+
"#{key}=\"#{value.join(",")}\""
|
36
|
+
else
|
37
|
+
"#{key}=\"#{value}\""
|
38
|
+
end
|
39
|
+
}.join(", ")
|
40
|
+
end
|
41
|
+
|
42
|
+
# Helper method for parsing "WWW-Authenticate" header values into
|
43
|
+
# a hash.
|
44
|
+
#
|
45
|
+
# Rack::OpenID.parse_header("OpenID identifier='http://josh.openid.com/'")
|
46
|
+
# #=> {:identifier => "http://josh.openid.com/"}
|
47
|
+
def parse_header(str)
|
48
|
+
params = {}
|
49
|
+
if AUTHENTICATE_REGEXP.match?(str)
|
50
|
+
str = str.gsub(/#{AUTHENTICATE_REGEXP}\s+/o, "")
|
51
|
+
str.split(", ").each { |pair|
|
52
|
+
key, *value = pair.split("=")
|
53
|
+
value = value.join("=")
|
54
|
+
value.gsub!(/^\"/, "").gsub!(/\"$/, "")
|
55
|
+
value = value.split(",")
|
56
|
+
params[key] = (value.length > 1) ? value : value.first
|
57
|
+
}
|
58
|
+
end
|
59
|
+
params
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class TimeoutResponse
|
64
|
+
include ::OpenID::Consumer::Response
|
65
|
+
STATUS = :failure
|
66
|
+
end
|
67
|
+
|
68
|
+
class MissingResponse
|
69
|
+
include ::OpenID::Consumer::Response
|
70
|
+
STATUS = :missing
|
71
|
+
end
|
72
|
+
|
73
|
+
HTTP_METHODS = %w(GET HEAD PUT POST DELETE OPTIONS)
|
74
|
+
|
75
|
+
RESPONSE = "rack.openid.response"
|
76
|
+
AUTHENTICATE_HEADER = "WWW-Authenticate"
|
77
|
+
AUTHENTICATE_REGEXP = /^OpenID/
|
78
|
+
|
79
|
+
URL_FIELD_SELECTOR = lambda { |field| field.to_s =~ %r{^https?://} }
|
80
|
+
|
81
|
+
# Initialize middleware with application and optional OpenID::Store.
|
82
|
+
# If no store is given, OpenID::Store::Memory is used.
|
83
|
+
#
|
84
|
+
# use Rack::OpenID
|
85
|
+
#
|
86
|
+
# or
|
87
|
+
#
|
88
|
+
# use Rack::OpenID, OpenID::Store::Memcache.new
|
89
|
+
def initialize(app, store = nil)
|
90
|
+
@app = app
|
91
|
+
@store = store || default_store
|
92
|
+
end
|
93
|
+
|
94
|
+
# Standard Rack +call+ dispatch that accepts an +env+ and
|
95
|
+
# returns a [status, header, body] response.
|
96
|
+
def call(env)
|
97
|
+
req = Rack::Request.new(env)
|
98
|
+
|
99
|
+
sanitize_params!(req.params)
|
100
|
+
|
101
|
+
if req.params["openid.mode"]
|
102
|
+
complete_authentication(env)
|
103
|
+
end
|
104
|
+
|
105
|
+
status, headers, body = @app.call(env)
|
106
|
+
|
107
|
+
qs = headers[AUTHENTICATE_HEADER]
|
108
|
+
if status.to_i == 401 && qs && qs.match(AUTHENTICATE_REGEXP)
|
109
|
+
begin_authentication(env, qs)
|
110
|
+
else
|
111
|
+
[status, headers, body]
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
private
|
116
|
+
|
117
|
+
def sanitize_params!(params)
|
118
|
+
["openid.sig", "openid.response_nonce"].each do |param|
|
119
|
+
(params[param] || "").tr!(" ", "+")
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def begin_authentication(env, qs)
|
124
|
+
req = Rack::Request.new(env)
|
125
|
+
params = self.class.parse_header(qs)
|
126
|
+
session = env["rack.session"]
|
127
|
+
|
128
|
+
unless session
|
129
|
+
raise "Rack::OpenID requires a session"
|
130
|
+
end
|
131
|
+
|
132
|
+
consumer = ::OpenID::Consumer.new(session, @store)
|
133
|
+
identifier = params["identifier"] || params["identity"]
|
134
|
+
|
135
|
+
begin
|
136
|
+
oidreq = consumer.begin(identifier)
|
137
|
+
add_simple_registration_fields(oidreq, params)
|
138
|
+
add_attribute_exchange_fields(oidreq, params)
|
139
|
+
add_oauth_fields(oidreq, params)
|
140
|
+
add_pape_fields(oidreq, params)
|
141
|
+
|
142
|
+
url = open_id_redirect_url(req, oidreq, params)
|
143
|
+
redirect_to(url)
|
144
|
+
rescue ::OpenID::OpenIDError, ::Timeout::Error
|
145
|
+
env[RESPONSE] = MissingResponse.new
|
146
|
+
@app.call(env)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def complete_authentication(env)
|
151
|
+
req = Rack::Request.new(env)
|
152
|
+
session = env["rack.session"]
|
153
|
+
|
154
|
+
unless session
|
155
|
+
raise "Rack::OpenID requires a session"
|
156
|
+
end
|
157
|
+
|
158
|
+
oidresp = timeout_protection_from_identity_server {
|
159
|
+
consumer = ::OpenID::Consumer.new(session, @store)
|
160
|
+
consumer.complete(flatten_params(req.params), req.url)
|
161
|
+
}
|
162
|
+
|
163
|
+
env[RESPONSE] = oidresp
|
164
|
+
|
165
|
+
method = req.GET["_method"]
|
166
|
+
override_request_method(env, method)
|
167
|
+
|
168
|
+
sanitize_query_string(env)
|
169
|
+
end
|
170
|
+
|
171
|
+
def flatten_params(params)
|
172
|
+
Rack::Utils.parse_query(Rack::Utils.build_nested_query(params))
|
173
|
+
end
|
174
|
+
|
175
|
+
def override_request_method(env, method)
|
176
|
+
return unless method
|
177
|
+
method = method.upcase
|
178
|
+
if HTTP_METHODS.include?(method)
|
179
|
+
env["REQUEST_METHOD"] = method
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def sanitize_query_string(env)
|
184
|
+
query_hash = env["rack.request.query_hash"]
|
185
|
+
query_hash.delete("_method")
|
186
|
+
query_hash.delete_if do |key, value|
|
187
|
+
key =~ /^openid\./
|
188
|
+
end
|
189
|
+
|
190
|
+
env["QUERY_STRING"] = env["rack.request.query_string"] =
|
191
|
+
Rack::Utils.build_query(env["rack.request.query_hash"])
|
192
|
+
|
193
|
+
qs = env["QUERY_STRING"]
|
194
|
+
request_uri = (env["PATH_INFO"] || "").dup
|
195
|
+
request_uri << "?" + qs unless qs == ""
|
196
|
+
env["REQUEST_URI"] = request_uri
|
197
|
+
end
|
198
|
+
|
199
|
+
def scheme_with_host_and_port(req, host = nil)
|
200
|
+
url = req.scheme + "://"
|
201
|
+
url << (host || req.host)
|
202
|
+
|
203
|
+
scheme, port = req.scheme, req.port
|
204
|
+
if scheme == "https" && port != 443 ||
|
205
|
+
scheme == "http" && port != 80
|
206
|
+
url << ":#{port}"
|
207
|
+
end
|
208
|
+
|
209
|
+
url
|
210
|
+
end
|
211
|
+
|
212
|
+
def realm(req, domain = nil)
|
213
|
+
if domain
|
214
|
+
scheme_with_host_and_port(req, domain)
|
215
|
+
else
|
216
|
+
scheme_with_host_and_port(req)
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
def request_url(req)
|
221
|
+
url = scheme_with_host_and_port(req)
|
222
|
+
url << req.script_name
|
223
|
+
url << req.path_info
|
224
|
+
url << "?#{req.query_string}" if req.query_string.to_s.length > 0
|
225
|
+
url
|
226
|
+
end
|
227
|
+
|
228
|
+
def redirect_to(url)
|
229
|
+
[303, {"Content-Type" => "text/html", "Location" => url}, []]
|
230
|
+
end
|
231
|
+
|
232
|
+
def open_id_redirect_url(req, oidreq, options)
|
233
|
+
trust_root = options["trust_root"]
|
234
|
+
return_to = options["return_to"]
|
235
|
+
method = options["method"]
|
236
|
+
immediate = options["immediate"] == "true"
|
237
|
+
|
238
|
+
realm = realm(req, options["realm_domain"])
|
239
|
+
request_url = request_url(req)
|
240
|
+
|
241
|
+
if return_to
|
242
|
+
method ||= "get"
|
243
|
+
else
|
244
|
+
return_to = request_url
|
245
|
+
method ||= req.request_method
|
246
|
+
end
|
247
|
+
|
248
|
+
method = method.to_s.downcase
|
249
|
+
oidreq.return_to_args["_method"] = method unless method == "get"
|
250
|
+
oidreq.redirect_url(trust_root || realm, return_to || request_url, immediate)
|
251
|
+
end
|
252
|
+
|
253
|
+
def add_simple_registration_fields(oidreq, fields)
|
254
|
+
sregreq = ::OpenID::SReg::Request.new
|
255
|
+
|
256
|
+
required = Array(fields["required"]).reject(&URL_FIELD_SELECTOR)
|
257
|
+
sregreq.request_fields(required, true) if required.any?
|
258
|
+
|
259
|
+
optional = Array(fields["optional"]).reject(&URL_FIELD_SELECTOR)
|
260
|
+
sregreq.request_fields(optional, false) if optional.any?
|
261
|
+
|
262
|
+
policy_url = fields["policy_url"]
|
263
|
+
sregreq.policy_url = policy_url if policy_url
|
264
|
+
|
265
|
+
oidreq.add_extension(sregreq)
|
266
|
+
end
|
267
|
+
|
268
|
+
def add_attribute_exchange_fields(oidreq, fields)
|
269
|
+
axreq = ::OpenID::AX::FetchRequest.new
|
270
|
+
|
271
|
+
required = Array(fields["required"]).select(&URL_FIELD_SELECTOR)
|
272
|
+
optional = Array(fields["optional"]).select(&URL_FIELD_SELECTOR)
|
273
|
+
|
274
|
+
if required.any? || optional.any?
|
275
|
+
required.each do |field|
|
276
|
+
axreq.add(::OpenID::AX::AttrInfo.new(field, nil, true))
|
277
|
+
end
|
278
|
+
|
279
|
+
optional.each do |field|
|
280
|
+
axreq.add(::OpenID::AX::AttrInfo.new(field, nil, false))
|
281
|
+
end
|
282
|
+
|
283
|
+
oidreq.add_extension(axreq)
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
def add_oauth_fields(oidreq, fields)
|
288
|
+
if (consumer = fields["oauth[consumer]"]) && (scope = fields["oauth[scope]"])
|
289
|
+
oauthreq = ::OpenID::OAuth::Request.new(consumer, Array(scope).join(" "))
|
290
|
+
oidreq.add_extension(oauthreq)
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
def add_pape_fields(oidreq, fields)
|
295
|
+
preferred_auth_policies = fields["pape[preferred_auth_policies]"]
|
296
|
+
max_auth_age = fields["pape[max_auth_age]"]
|
297
|
+
if preferred_auth_policies || max_auth_age
|
298
|
+
preferred_auth_policies = preferred_auth_policies.split if preferred_auth_policies.is_a?(String)
|
299
|
+
pape_request = ::OpenID::PAPE::Request.new(preferred_auth_policies || [], max_auth_age)
|
300
|
+
oidreq.add_extension(pape_request)
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
def default_store
|
305
|
+
require "openid/store/memory"
|
306
|
+
::OpenID::Store::Memory.new
|
307
|
+
end
|
308
|
+
|
309
|
+
def timeout_protection_from_identity_server
|
310
|
+
yield
|
311
|
+
rescue ::Timeout::Error
|
312
|
+
TimeoutResponse.new
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
Rack::OpenID::Version.class_eval do
|
318
|
+
extend VersionGem::Basic
|
319
|
+
end
|
data.tar.gz.sig
ADDED
Binary file
|
metadata
ADDED
@@ -0,0 +1,310 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rack-openid2
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Peter Boling
|
8
|
+
- Michael Grosser
|
9
|
+
- Joshua Peek
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain:
|
13
|
+
- |
|
14
|
+
-----BEGIN CERTIFICATE-----
|
15
|
+
MIIEgDCCAuigAwIBAgIBATANBgkqhkiG9w0BAQsFADBDMRUwEwYDVQQDDAxwZXRl
|
16
|
+
ci5ib2xpbmcxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkW
|
17
|
+
A2NvbTAeFw0yMzA5MjAxNzMwMjhaFw0yNDA5MTkxNzMwMjhaMEMxFTATBgNVBAMM
|
18
|
+
DHBldGVyLmJvbGluZzEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPy
|
19
|
+
LGQBGRYDY29tMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA+a9UvHo3
|
20
|
+
84k96WgU5Kk5HB+cLZs/modjorsTfqY67MJF5nNvAoqcKTUBW4uG+Zpfnm3jaDO5
|
21
|
+
GxhJEIZWfndYzycHT2KMVQ1uTP82ba8ZaKrPlPIafkbui3mdds47qsmqHiblKERg
|
22
|
+
U532lkwfqHDlJwE7OBZQ59EwWWLynlT/yAUHpOBbqIuHKUxdpmBI+sIjrZcD1e05
|
23
|
+
WmjkO6fwIdC5oM757aoPxIgXD587VOViH11Vkm2doskj4T8yONtwVHlcrrhJ9Bzd
|
24
|
+
/zdp6vEn7GZQrABvpOlqwWxQ72ZnFhJe/RJZf6CXOPOh69Ai0QKYl2a1sYuCJKS3
|
25
|
+
nsBnxXJINEEznjR7rZjNUmYD+CZqfjzgPqedRxTlASe7iA4w7xZOqMDzcuhNwcUQ
|
26
|
+
tMEH6BTktxKP3jXZPXRfHCf6s+HRVb6vezAonTBVyydf5Xp5VwWkd6cwm+2BzHl5
|
27
|
+
7kc/3lLxKMcsyEUprAsk8LdHohwZdC267l+RS++AP6Cz6x+nB3oGob19AgMBAAGj
|
28
|
+
fzB9MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBQCSSas60GqqMjt
|
29
|
+
xR7LoY1gucEvtzAhBgNVHREEGjAYgRZwZXRlci5ib2xpbmdAZ21haWwuY29tMCEG
|
30
|
+
A1UdEgQaMBiBFnBldGVyLmJvbGluZ0BnbWFpbC5jb20wDQYJKoZIhvcNAQELBQAD
|
31
|
+
ggGBAMl9ifcw5p+PdvB7dCPoNKoVdp/2LbC9ztETHuYL2gUMJB6UoS3o9c/piSuR
|
32
|
+
V3ZMQaijmNu6ms1bWAtJ66LjmYrVflJtf9yp31Kierr9LpisMSUx2qbMOHGa8d2Z
|
33
|
+
vCUWPF8E9Cg0mP3GAyZ6qql8jDh/anUKeksPXqJvNxNPDu2DVYsa/IWdl96whzS4
|
34
|
+
Bl7SwB1E7agps40UcshCSKaVDOU0M+XN6SrnJMElnBic+KSAkBkVFbzS0BE4ODZM
|
35
|
+
BgE6nYzQ05qhuvbE+oGdACTlemNtDDWCh0uw+7x0q2PocGIDU5zsPn/WNTkCXPmB
|
36
|
+
CHGvqDNWq4M7ncTKAaS2XExgyb7uPdq9fKiOW8nmH+zCiGzJXzBWwZlKf7L4Ht9E
|
37
|
+
a3f0e5C+zvee9Z5Ng9ciyfav9/fcXgYt5MjoBv27THr5XfBhgOCIHSYW2tqJmWKi
|
38
|
+
KuxrfYrN+9HvMdm+nZ6TypmKftHY3Gj+/uu+g8Icm/zrvTWAEE0mcJOkfrIoNPJb
|
39
|
+
pF8dMA==
|
40
|
+
-----END CERTIFICATE-----
|
41
|
+
date: 2024-09-05 00:00:00.000000000 Z
|
42
|
+
dependencies:
|
43
|
+
- !ruby/object:Gem::Dependency
|
44
|
+
name: rack
|
45
|
+
requirement: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '2.2'
|
50
|
+
type: :runtime
|
51
|
+
prerelease: false
|
52
|
+
version_requirements: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '2.2'
|
57
|
+
- !ruby/object:Gem::Dependency
|
58
|
+
name: ruby-openid2
|
59
|
+
requirement: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '3.0'
|
64
|
+
type: :runtime
|
65
|
+
prerelease: false
|
66
|
+
version_requirements: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '3.0'
|
71
|
+
- !ruby/object:Gem::Dependency
|
72
|
+
name: version_gem
|
73
|
+
requirement: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - "~>"
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '1.1'
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: 1.1.4
|
81
|
+
type: :runtime
|
82
|
+
prerelease: false
|
83
|
+
version_requirements: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - "~>"
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '1.1'
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: 1.1.4
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: minitest
|
93
|
+
requirement: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '5'
|
98
|
+
type: :development
|
99
|
+
prerelease: false
|
100
|
+
version_requirements: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '5'
|
105
|
+
- !ruby/object:Gem::Dependency
|
106
|
+
name: minitest-rg
|
107
|
+
requirement: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '5'
|
112
|
+
type: :development
|
113
|
+
prerelease: false
|
114
|
+
version_requirements: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '5'
|
119
|
+
- !ruby/object:Gem::Dependency
|
120
|
+
name: rack-session
|
121
|
+
requirement: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '2'
|
126
|
+
type: :development
|
127
|
+
prerelease: false
|
128
|
+
version_requirements: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '2'
|
133
|
+
- !ruby/object:Gem::Dependency
|
134
|
+
name: rake
|
135
|
+
requirement: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - ">="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: '13'
|
140
|
+
type: :development
|
141
|
+
prerelease: false
|
142
|
+
version_requirements: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '13'
|
147
|
+
- !ruby/object:Gem::Dependency
|
148
|
+
name: kettle-soup-cover
|
149
|
+
requirement: !ruby/object:Gem::Requirement
|
150
|
+
requirements:
|
151
|
+
- - "~>"
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '1.0'
|
154
|
+
- - ">="
|
155
|
+
- !ruby/object:Gem::Version
|
156
|
+
version: 1.0.2
|
157
|
+
type: :development
|
158
|
+
prerelease: false
|
159
|
+
version_requirements: !ruby/object:Gem::Requirement
|
160
|
+
requirements:
|
161
|
+
- - "~>"
|
162
|
+
- !ruby/object:Gem::Version
|
163
|
+
version: '1.0'
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: 1.0.2
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: rubocop-lts
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - "~>"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '18.2'
|
174
|
+
- - ">="
|
175
|
+
- !ruby/object:Gem::Version
|
176
|
+
version: 18.2.1
|
177
|
+
type: :development
|
178
|
+
prerelease: false
|
179
|
+
version_requirements: !ruby/object:Gem::Requirement
|
180
|
+
requirements:
|
181
|
+
- - "~>"
|
182
|
+
- !ruby/object:Gem::Version
|
183
|
+
version: '18.2'
|
184
|
+
- - ">="
|
185
|
+
- !ruby/object:Gem::Version
|
186
|
+
version: 18.2.1
|
187
|
+
- !ruby/object:Gem::Dependency
|
188
|
+
name: rubocop-minitest
|
189
|
+
requirement: !ruby/object:Gem::Requirement
|
190
|
+
requirements:
|
191
|
+
- - "~>"
|
192
|
+
- !ruby/object:Gem::Version
|
193
|
+
version: '0.36'
|
194
|
+
type: :development
|
195
|
+
prerelease: false
|
196
|
+
version_requirements: !ruby/object:Gem::Requirement
|
197
|
+
requirements:
|
198
|
+
- - "~>"
|
199
|
+
- !ruby/object:Gem::Version
|
200
|
+
version: '0.36'
|
201
|
+
- !ruby/object:Gem::Dependency
|
202
|
+
name: rubocop-packaging
|
203
|
+
requirement: !ruby/object:Gem::Requirement
|
204
|
+
requirements:
|
205
|
+
- - "~>"
|
206
|
+
- !ruby/object:Gem::Version
|
207
|
+
version: '0.5'
|
208
|
+
- - ">="
|
209
|
+
- !ruby/object:Gem::Version
|
210
|
+
version: 0.5.2
|
211
|
+
type: :development
|
212
|
+
prerelease: false
|
213
|
+
version_requirements: !ruby/object:Gem::Requirement
|
214
|
+
requirements:
|
215
|
+
- - "~>"
|
216
|
+
- !ruby/object:Gem::Version
|
217
|
+
version: '0.5'
|
218
|
+
- - ">="
|
219
|
+
- !ruby/object:Gem::Version
|
220
|
+
version: 0.5.2
|
221
|
+
- !ruby/object:Gem::Dependency
|
222
|
+
name: standard
|
223
|
+
requirement: !ruby/object:Gem::Requirement
|
224
|
+
requirements:
|
225
|
+
- - ">="
|
226
|
+
- !ruby/object:Gem::Version
|
227
|
+
version: 1.35.1
|
228
|
+
type: :development
|
229
|
+
prerelease: false
|
230
|
+
version_requirements: !ruby/object:Gem::Requirement
|
231
|
+
requirements:
|
232
|
+
- - ">="
|
233
|
+
- !ruby/object:Gem::Version
|
234
|
+
version: 1.35.1
|
235
|
+
- !ruby/object:Gem::Dependency
|
236
|
+
name: yard
|
237
|
+
requirement: !ruby/object:Gem::Requirement
|
238
|
+
requirements:
|
239
|
+
- - "~>"
|
240
|
+
- !ruby/object:Gem::Version
|
241
|
+
version: '0.9'
|
242
|
+
- - ">="
|
243
|
+
- !ruby/object:Gem::Version
|
244
|
+
version: 0.9.34
|
245
|
+
type: :development
|
246
|
+
prerelease: false
|
247
|
+
version_requirements: !ruby/object:Gem::Requirement
|
248
|
+
requirements:
|
249
|
+
- - "~>"
|
250
|
+
- !ruby/object:Gem::Version
|
251
|
+
version: '0.9'
|
252
|
+
- - ">="
|
253
|
+
- !ruby/object:Gem::Version
|
254
|
+
version: 0.9.34
|
255
|
+
- !ruby/object:Gem::Dependency
|
256
|
+
name: yard-junk
|
257
|
+
requirement: !ruby/object:Gem::Requirement
|
258
|
+
requirements:
|
259
|
+
- - "~>"
|
260
|
+
- !ruby/object:Gem::Version
|
261
|
+
version: '0.0'
|
262
|
+
type: :development
|
263
|
+
prerelease: false
|
264
|
+
version_requirements: !ruby/object:Gem::Requirement
|
265
|
+
requirements:
|
266
|
+
- - "~>"
|
267
|
+
- !ruby/object:Gem::Version
|
268
|
+
version: '0.0'
|
269
|
+
description:
|
270
|
+
email: peter.boling@gmail.com
|
271
|
+
executables: []
|
272
|
+
extensions: []
|
273
|
+
extra_rdoc_files: []
|
274
|
+
files:
|
275
|
+
- LICENSE.txt
|
276
|
+
- README.md
|
277
|
+
- lib/rack/openid.rb
|
278
|
+
- lib/rack/openid/simple_auth.rb
|
279
|
+
- lib/rack/openid/version.rb
|
280
|
+
homepage: https://github.com/VitalConnectInc/rack-openid2
|
281
|
+
licenses:
|
282
|
+
- MIT
|
283
|
+
metadata:
|
284
|
+
homepage_uri: https://github.com/VitalConnectInc/rack-openid2
|
285
|
+
source_code_uri: https://github.com/VitalConnectInc/rack-openid2/tree/v2.0.0
|
286
|
+
changelog_uri: https://github.com/VitalConnectInc/rack-openid2/blob/v2.0.0/CHANGELOG.md
|
287
|
+
bug_tracker_uri: https://github.com/VitalConnectInc/rack-openid2/issues
|
288
|
+
documentation_uri: https://www.rubydoc.info/gems/rack-openid2/2.0.0
|
289
|
+
wiki_uri: https://github.com/VitalConnectInc/rack-openid2/wiki
|
290
|
+
rubygems_mfa_required: 'true'
|
291
|
+
post_install_message:
|
292
|
+
rdoc_options: []
|
293
|
+
require_paths:
|
294
|
+
- lib
|
295
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
296
|
+
requirements:
|
297
|
+
- - ">="
|
298
|
+
- !ruby/object:Gem::Version
|
299
|
+
version: 2.7.0
|
300
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
301
|
+
requirements:
|
302
|
+
- - ">="
|
303
|
+
- !ruby/object:Gem::Version
|
304
|
+
version: '0'
|
305
|
+
requirements: []
|
306
|
+
rubygems_version: 3.4.22
|
307
|
+
signing_key:
|
308
|
+
specification_version: 4
|
309
|
+
summary: Provides a more HTTPish API around the ruby-openid library
|
310
|
+
test_files: []
|
metadata.gz.sig
ADDED
Binary file
|