lyrebird 0.0.0 → 1.0.0.alpha2
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 +4 -4
- data/.github/workflows/ci.yml +25 -0
- data/.github/workflows/publish.yml +20 -0
- data/README.md +148 -17
- data/Rakefile +8 -1
- data/lib/lyrebird/assertion.rb +104 -0
- data/lib/lyrebird/certificate.rb +71 -0
- data/lib/lyrebird/defaults.rb +41 -0
- data/lib/lyrebird/encryption.rb +75 -0
- data/lib/lyrebird/id.rb +9 -0
- data/lib/lyrebird/namespaces.rb +17 -0
- data/lib/lyrebird/response.rb +79 -0
- data/lib/lyrebird/signature.rb +75 -0
- data/lib/lyrebird/version.rb +1 -1
- data/lib/lyrebird.rb +15 -1
- data/lyrebird.gemspec +26 -0
- data/test/lyrebird/assertion_test.rb +329 -0
- data/test/lyrebird/certificate_test.rb +87 -0
- data/test/lyrebird/defaults_test.rb +11 -0
- data/test/lyrebird/encryption_test.rb +126 -0
- data/test/lyrebird/id_test.rb +11 -0
- data/test/lyrebird/response_test.rb +240 -0
- data/test/lyrebird/signature_test.rb +137 -0
- data/test/test_helper.rb +4 -0
- metadata +103 -8
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "test_helper"
|
|
4
|
+
|
|
5
|
+
module Lyrebird
|
|
6
|
+
class ResponseTest < Minitest::Test
|
|
7
|
+
def setup
|
|
8
|
+
@response = Response.new
|
|
9
|
+
@root = @response.document.root
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def test_build_with_defaults
|
|
13
|
+
response = Response.build
|
|
14
|
+
root = response.document.root
|
|
15
|
+
assert_equal DEFAULTS.issuer, root.elements["saml:Issuer"].text
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def test_build_with_kwargs
|
|
19
|
+
issuer = "https://test.example.com"
|
|
20
|
+
refute_equal issuer, DEFAULTS.issuer
|
|
21
|
+
response = Response.build(issuer: issuer)
|
|
22
|
+
root = response.document.root
|
|
23
|
+
assert_equal issuer, root.elements["saml:Issuer"].text
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def test_build_with_block
|
|
27
|
+
issuer = "https://test.example.com"
|
|
28
|
+
refute_equal issuer, DEFAULTS.issuer
|
|
29
|
+
response = Response.build { |r| r.issuer = issuer }
|
|
30
|
+
root = response.document.root
|
|
31
|
+
assert_equal issuer, root.elements["saml:Issuer"].text
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def test_build_with_kwargs_and_block
|
|
35
|
+
issuer = "https://test.example.com"
|
|
36
|
+
email = "test@example.com"
|
|
37
|
+
|
|
38
|
+
refute_equal issuer, DEFAULTS.issuer
|
|
39
|
+
refute_equal email, DEFAULTS.name_id
|
|
40
|
+
|
|
41
|
+
response = Response.build(issuer: issuer) do |r|
|
|
42
|
+
r.name_id = email
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
root = response.document.root
|
|
46
|
+
assert_equal issuer, root.elements["saml:Issuer"].text
|
|
47
|
+
name_id = root.elements["saml:Assertion/saml:Subject/saml:NameID"]
|
|
48
|
+
assert_equal email, name_id.text
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def test_build_with_attributes_block
|
|
52
|
+
email = "test@example.com"
|
|
53
|
+
role = "admin"
|
|
54
|
+
|
|
55
|
+
response = Response.build do |r|
|
|
56
|
+
r.attributes do |a|
|
|
57
|
+
a.email = email
|
|
58
|
+
a.role = role
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
root = response.document.root
|
|
63
|
+
statement = root.elements["saml:Assertion/saml:AttributeStatement"]
|
|
64
|
+
email_element = statement.elements["saml:Attribute[@Name='email']"]
|
|
65
|
+
role_element = statement.elements["saml:Attribute[@Name='role']"]
|
|
66
|
+
|
|
67
|
+
assert_equal email, email_element.elements["saml:AttributeValue"].text
|
|
68
|
+
assert_equal role, role_element.elements["saml:AttributeValue"].text
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def test_build_with_attributes_hash
|
|
72
|
+
email = "user@example.com"
|
|
73
|
+
|
|
74
|
+
response = Response.build do |r|
|
|
75
|
+
r.attributes = { email: email }
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
root = response.document.root
|
|
79
|
+
statement = root.elements["saml:Assertion/saml:AttributeStatement"]
|
|
80
|
+
email_element = statement.elements["saml:Attribute[@Name='email']"]
|
|
81
|
+
assert_equal email, email_element.elements["saml:AttributeValue"].text
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def test_mimic_returns_base64
|
|
85
|
+
encoded = @response.mimic
|
|
86
|
+
decoded = Base64.strict_decode64(encoded)
|
|
87
|
+
assert decoded.include?("<samlp:Response")
|
|
88
|
+
assert decoded.include?("<saml:Assertion")
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def test_root_name
|
|
92
|
+
assert_equal "Response", @root.name
|
|
93
|
+
assert_equal "samlp", @root.prefix
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def test_root_namespace
|
|
97
|
+
assert_equal SAML_PROTOCOL_NS, @root.namespace
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def test_saml_namespace_declared
|
|
101
|
+
assert_equal SAML_ASSERTION_NS, @root.namespace("saml")
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def test_root_id
|
|
105
|
+
assert @root.attributes["ID"].start_with?("_")
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def test_root_version
|
|
109
|
+
assert_equal "2.0", @root.attributes["Version"]
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def test_root_issue_instant
|
|
113
|
+
instant = Time.iso8601(@root.attributes["IssueInstant"])
|
|
114
|
+
assert_in_delta Time.now.to_i, instant.to_i, 1
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def test_destination_default
|
|
118
|
+
assert_equal DEFAULTS.recipient, @root.attributes["Destination"]
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def test_destination_override
|
|
122
|
+
destination = "https://test.example.com/acs"
|
|
123
|
+
refute_equal destination, DEFAULTS.recipient
|
|
124
|
+
root = Response.new(destination: destination).document.root
|
|
125
|
+
assert_equal destination, root.attributes["Destination"]
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def test_in_response_to_default
|
|
129
|
+
assert_equal DEFAULTS.in_response_to, @root.attributes["InResponseTo"]
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def test_in_response_to_override
|
|
133
|
+
in_response_to = "_test_request"
|
|
134
|
+
refute_equal in_response_to, DEFAULTS.in_response_to
|
|
135
|
+
root = Response.new(in_response_to: in_response_to).document.root
|
|
136
|
+
assert_equal in_response_to, root.attributes["InResponseTo"]
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def test_destination_omitted_when_nil
|
|
140
|
+
root = Response.new(destination: nil).document.root
|
|
141
|
+
assert_nil root.attributes["Destination"]
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def test_in_response_to_omitted_when_nil
|
|
145
|
+
root = Response.new(in_response_to: nil).document.root
|
|
146
|
+
assert_nil root.attributes["InResponseTo"]
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def test_issuer
|
|
150
|
+
issuer = @root.elements["saml:Issuer"]
|
|
151
|
+
assert_equal "Issuer", issuer.name
|
|
152
|
+
assert_equal "saml", issuer.prefix
|
|
153
|
+
assert_equal DEFAULTS.issuer, issuer.text
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def test_issuer_override
|
|
157
|
+
url = "https://test.idp.example.com"
|
|
158
|
+
refute_equal url, DEFAULTS.issuer
|
|
159
|
+
root = Response.new(issuer: url).document.root
|
|
160
|
+
issuer = root.elements["saml:Issuer"]
|
|
161
|
+
assert_equal url, issuer.text
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def test_status
|
|
165
|
+
status = @root.elements["samlp:Status"]
|
|
166
|
+
assert_equal "Status", status.name
|
|
167
|
+
assert_equal "samlp", status.prefix
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def test_status_code
|
|
171
|
+
status_code = @root.elements["samlp:Status/samlp:StatusCode"]
|
|
172
|
+
assert_equal "StatusCode", status_code.name
|
|
173
|
+
assert_equal "samlp", status_code.prefix
|
|
174
|
+
assert_equal STATUS_SUCCESS, status_code.attributes["Value"]
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def test_assertion_embedded
|
|
178
|
+
assertion = @root.elements["saml:Assertion"]
|
|
179
|
+
assert_equal "Assertion", assertion.name
|
|
180
|
+
assert_equal "saml", assertion.prefix
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def test_assertion_has_id
|
|
184
|
+
assertion = @root.elements["saml:Assertion"]
|
|
185
|
+
assert assertion.attributes["ID"].start_with?("_")
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def test_assertion_inherits_issuer
|
|
189
|
+
url = "https://test.idp.example.com"
|
|
190
|
+
refute_equal url, DEFAULTS.issuer
|
|
191
|
+
root = Response.new(issuer: url).document.root
|
|
192
|
+
assertion = root.elements["saml:Assertion"]
|
|
193
|
+
issuer = assertion.elements["saml:Issuer"]
|
|
194
|
+
assert_equal url, issuer.text
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def test_assertion_options_flow_through
|
|
198
|
+
email = "test@example.com"
|
|
199
|
+
refute_equal email, DEFAULTS.name_id
|
|
200
|
+
root = Response.new(name_id: email).document.root
|
|
201
|
+
assertion = root.elements["saml:Assertion"]
|
|
202
|
+
name_id = assertion.elements["saml:Subject/saml:NameID"]
|
|
203
|
+
assert_equal email, name_id.text
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def test_unsigned_by_default
|
|
207
|
+
assert_nil @root.elements["ds:Signature"]
|
|
208
|
+
assert_nil @root.elements["saml:Assertion/ds:Signature"]
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def test_sign_with_signs_response_and_assertion
|
|
212
|
+
root = Response.new(sign_with: Certificate.generate).document.root
|
|
213
|
+
refute_nil root.elements["ds:Signature"]
|
|
214
|
+
refute_nil root.elements["saml:Assertion/ds:Signature"]
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def test_not_encrypted_by_default
|
|
218
|
+
assert_nil @root.elements["saml:EncryptedAssertion"]
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def test_encrypt_with_creates_encrypted_assertion
|
|
222
|
+
root = Response.new(encrypt_with: Certificate.generate).document.root
|
|
223
|
+
ea = root.elements["saml:EncryptedAssertion"]
|
|
224
|
+
assert_equal "EncryptedAssertion", ea.name
|
|
225
|
+
assert_equal "saml", ea.prefix
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
def test_encrypt_with_removes_plain_assertion
|
|
229
|
+
root = Response.new(encrypt_with: Certificate.generate).document.root
|
|
230
|
+
assert_nil root.elements["saml:Assertion"]
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
def test_encrypt_with_contains_encrypted_data
|
|
234
|
+
root = Response.new(encrypt_with: Certificate.generate).document.root
|
|
235
|
+
ed = root.elements["saml:EncryptedAssertion/xenc:EncryptedData"]
|
|
236
|
+
assert_equal "EncryptedData", ed.name
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
end
|
|
240
|
+
end
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "test_helper"
|
|
4
|
+
|
|
5
|
+
module Lyrebird
|
|
6
|
+
class SignatureTest < Minitest::Test
|
|
7
|
+
def setup
|
|
8
|
+
@certificate = Certificate.generate
|
|
9
|
+
@assertion = Assertion.new.document
|
|
10
|
+
@element = @assertion.root
|
|
11
|
+
Signature.new(@element, @certificate).sign!
|
|
12
|
+
@signature = @element.elements["ds:Signature"]
|
|
13
|
+
@signed_info = @signature.elements["ds:SignedInfo"]
|
|
14
|
+
@reference = @signed_info.elements["ds:Reference"]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def test_sign_inserts_after_issuer
|
|
18
|
+
children = @element.elements.to_a
|
|
19
|
+
issuer_index = children.index { |e| e.name == "Issuer" }
|
|
20
|
+
signature_index = children.index { |e| e.name == "Signature" }
|
|
21
|
+
assert_equal issuer_index + 1, signature_index
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def test_signature_element
|
|
25
|
+
assert_equal "Signature", @signature.name
|
|
26
|
+
assert_equal "ds", @signature.prefix
|
|
27
|
+
assert_equal XMLDSIG_NS, @signature.namespace
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def test_signature_element_children
|
|
31
|
+
children = @signature.elements.to_a
|
|
32
|
+
assert_equal 3, children.size
|
|
33
|
+
assert_equal "SignedInfo", children[0].name
|
|
34
|
+
assert_equal "SignatureValue", children[1].name
|
|
35
|
+
assert_equal "KeyInfo", children[2].name
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def test_signed_info_element
|
|
39
|
+
assert_equal "SignedInfo", @signed_info.name
|
|
40
|
+
assert_equal "ds", @signed_info.prefix
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def test_canonicalization_method
|
|
44
|
+
cm = @signed_info.elements["ds:CanonicalizationMethod"]
|
|
45
|
+
assert_equal "CanonicalizationMethod", cm.name
|
|
46
|
+
assert_equal EXC_C14N, cm.attributes["Algorithm"]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def test_signature_method
|
|
50
|
+
sm = @signed_info.elements["ds:SignatureMethod"]
|
|
51
|
+
assert_equal "SignatureMethod", sm.name
|
|
52
|
+
assert_equal RSA_SHA256, sm.attributes["Algorithm"]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def test_reference_element
|
|
56
|
+
assert_equal "Reference", @reference.name
|
|
57
|
+
assert_equal "ds", @reference.prefix
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def test_reference_uri
|
|
61
|
+
element_id = @element.attributes["ID"]
|
|
62
|
+
assert_equal "##{element_id}", @reference.attributes["URI"]
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def test_transforms_element
|
|
66
|
+
transforms = @reference.elements["ds:Transforms"]
|
|
67
|
+
assert_equal "Transforms", transforms.name
|
|
68
|
+
assert_equal "ds", transforms.prefix
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def test_enveloped_signature_transform
|
|
72
|
+
transforms = @reference.elements["ds:Transforms"]
|
|
73
|
+
transform = transforms.elements.to_a("ds:Transform")[0]
|
|
74
|
+
assert_equal ENVELOPED_SIG, transform.attributes["Algorithm"]
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def test_c14n_transform
|
|
78
|
+
transforms = @reference.elements["ds:Transforms"]
|
|
79
|
+
transform = transforms.elements.to_a("ds:Transform")[1]
|
|
80
|
+
assert_equal EXC_C14N, transform.attributes["Algorithm"]
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def test_digest_method_element
|
|
84
|
+
digest_method = @reference.elements["ds:DigestMethod"]
|
|
85
|
+
assert_equal "DigestMethod", digest_method.name
|
|
86
|
+
assert_equal "ds", digest_method.prefix
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def test_digest_method_algorithm
|
|
90
|
+
digest_method = @reference.elements["ds:DigestMethod"]
|
|
91
|
+
assert_equal SHA256_DIGEST, digest_method.attributes["Algorithm"]
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def test_digest_value_element
|
|
95
|
+
digest_value = @reference.elements["ds:DigestValue"]
|
|
96
|
+
assert_equal "DigestValue", digest_value.name
|
|
97
|
+
assert_equal "ds", digest_value.prefix
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def test_digest_value_is_base64
|
|
101
|
+
digest_value = @reference.elements["ds:DigestValue"]
|
|
102
|
+
decoded = Base64.strict_decode64(digest_value.text)
|
|
103
|
+
assert_equal 32, decoded.bytesize
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def test_signature_value_element
|
|
107
|
+
sv = @signature.elements["ds:SignatureValue"]
|
|
108
|
+
assert_equal "SignatureValue", sv.name
|
|
109
|
+
assert_equal "ds", sv.prefix
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def test_signature_value_is_base64
|
|
113
|
+
sv = @signature.elements["ds:SignatureValue"]
|
|
114
|
+
decoded = Base64.strict_decode64(sv.text)
|
|
115
|
+
assert_equal 256, decoded.bytesize
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def test_key_info_element
|
|
119
|
+
ki = @signature.elements["ds:KeyInfo"]
|
|
120
|
+
assert_equal "KeyInfo", ki.name
|
|
121
|
+
assert_equal "ds", ki.prefix
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def test_x509_data_element
|
|
125
|
+
x509_data = @signature.elements["ds:KeyInfo/ds:X509Data"]
|
|
126
|
+
assert_equal "X509Data", x509_data.name
|
|
127
|
+
assert_equal "ds", x509_data.prefix
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def test_x509_certificate_element
|
|
131
|
+
cert = @signature.elements["ds:KeyInfo/ds:X509Data/ds:X509Certificate"]
|
|
132
|
+
assert_equal "X509Certificate", cert.name
|
|
133
|
+
assert_equal "ds", cert.prefix
|
|
134
|
+
assert_equal @certificate.base64, cert.text
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
CHANGED
|
@@ -1,25 +1,119 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lyrebird
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 1.0.0.alpha2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Josh
|
|
8
|
-
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
9
10
|
cert_chain: []
|
|
10
|
-
date:
|
|
11
|
-
dependencies:
|
|
11
|
+
date: 2026-01-27 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: base64
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: ostruct
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rexml
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ">="
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
48
|
+
type: :runtime
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ">="
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: minitest
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ">="
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '0'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: rake
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - ">="
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '0'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - ">="
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '0'
|
|
83
|
+
description:
|
|
84
|
+
email:
|
|
12
85
|
executables: []
|
|
13
86
|
extensions: []
|
|
14
87
|
extra_rdoc_files: []
|
|
15
88
|
files:
|
|
89
|
+
- ".github/workflows/ci.yml"
|
|
90
|
+
- ".github/workflows/publish.yml"
|
|
16
91
|
- README.md
|
|
17
92
|
- Rakefile
|
|
18
93
|
- lib/lyrebird.rb
|
|
94
|
+
- lib/lyrebird/assertion.rb
|
|
95
|
+
- lib/lyrebird/certificate.rb
|
|
96
|
+
- lib/lyrebird/defaults.rb
|
|
97
|
+
- lib/lyrebird/encryption.rb
|
|
98
|
+
- lib/lyrebird/id.rb
|
|
99
|
+
- lib/lyrebird/namespaces.rb
|
|
100
|
+
- lib/lyrebird/response.rb
|
|
101
|
+
- lib/lyrebird/signature.rb
|
|
19
102
|
- lib/lyrebird/version.rb
|
|
103
|
+
- lyrebird.gemspec
|
|
20
104
|
- sig/lyrebird.rbs
|
|
105
|
+
- test/lyrebird/assertion_test.rb
|
|
106
|
+
- test/lyrebird/certificate_test.rb
|
|
107
|
+
- test/lyrebird/defaults_test.rb
|
|
108
|
+
- test/lyrebird/encryption_test.rb
|
|
109
|
+
- test/lyrebird/id_test.rb
|
|
110
|
+
- test/lyrebird/response_test.rb
|
|
111
|
+
- test/lyrebird/signature_test.rb
|
|
112
|
+
- test/test_helper.rb
|
|
113
|
+
homepage:
|
|
21
114
|
licenses: []
|
|
22
115
|
metadata: {}
|
|
116
|
+
post_install_message:
|
|
23
117
|
rdoc_options: []
|
|
24
118
|
require_paths:
|
|
25
119
|
- lib
|
|
@@ -30,11 +124,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
30
124
|
version: 3.2.0
|
|
31
125
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
32
126
|
requirements:
|
|
33
|
-
- - "
|
|
127
|
+
- - ">"
|
|
34
128
|
- !ruby/object:Gem::Version
|
|
35
|
-
version:
|
|
129
|
+
version: 1.3.1
|
|
36
130
|
requirements: []
|
|
37
|
-
rubygems_version: 4.
|
|
131
|
+
rubygems_version: 3.4.19
|
|
132
|
+
signing_key:
|
|
38
133
|
specification_version: 4
|
|
39
|
-
summary: Mimics
|
|
134
|
+
summary: Mimics SAML Identity Provider (IdP) responses for testing
|
|
40
135
|
test_files: []
|