rack-openid2 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,7 @@
1
+ module Rack
2
+ class OpenID
3
+ module Version
4
+ VERSION = "2.0.0"
5
+ end
6
+ end
7
+ end
@@ -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