lyrebird 1.0.0 → 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 +4 -4
- data/README.md +50 -9
- data/lib/lyrebird/assertion.rb +6 -4
- data/lib/lyrebird/certificate.rb +20 -7
- data/lib/lyrebird/encryption.rb +2 -2
- data/lib/lyrebird/response.rb +14 -7
- data/lib/lyrebird/signature.rb +9 -9
- data/lib/lyrebird/version.rb +1 -1
- data/lib/lyrebird.rb +0 -2
- metadata +6 -18
- data/.github/workflows/ci.yml +0 -25
- data/.github/workflows/publish.yml +0 -20
- data/Rakefile +0 -11
- data/lyrebird.gemspec +0 -33
- data/sig/lyrebird.rbs +0 -4
- data/test/lyrebird/assertion_test.rb +0 -348
- data/test/lyrebird/certificate_test.rb +0 -120
- data/test/lyrebird/defaults_test.rb +0 -58
- data/test/lyrebird/encryption_test.rb +0 -139
- data/test/lyrebird/id_test.rb +0 -18
- data/test/lyrebird/integration_test.rb +0 -243
- data/test/lyrebird/namespaces_test.rb +0 -63
- data/test/lyrebird/response_test.rb +0 -250
- data/test/lyrebird/signature_test.rb +0 -171
- data/test/test_helper.rb +0 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6b9457c5f260c26c5adf43de4262d67077e1f5729b4506ff0efa92ec61519346
|
|
4
|
+
data.tar.gz: 16a5dbf97973cd9c3673c26212fa0be146955ef9ddaf877768d40120416d6e54
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fc83af3b91fb52553dc96733c2a8ea0e89c561fe124bddc1b769cb39f681e03c1e18ff78ec2c83ffe886114b369e4a1630e637e56a1cf2dcee2137a5fe88680b
|
|
7
|
+
data.tar.gz: 138bd3e26e223c69dc10e435b21c12e0e1fcf3322e64df65d1775695d8920e6a274caf0d1323c5722244d73a47a09296d4d2a1d2037f2761084f470fcff6202c
|
data/README.md
CHANGED
|
@@ -7,6 +7,7 @@ A Ruby gem for mimicking SAML Identity Provider (IdP) responses in test
|
|
|
7
7
|
environments.
|
|
8
8
|
|
|
9
9
|
## Installation
|
|
10
|
+
Requires Ruby 3.2 or newer.
|
|
10
11
|
```ruby
|
|
11
12
|
gem "lyrebird", group: :test
|
|
12
13
|
```
|
|
@@ -24,6 +25,7 @@ class SAMLTest < ActionDispatch::IntegrationTest
|
|
|
24
25
|
r.recipient = saml_consume_url
|
|
25
26
|
r.audience = root_url
|
|
26
27
|
r.name_id = user.email
|
|
28
|
+
r.sign_with = Lyrebird::Certificate.default
|
|
27
29
|
|
|
28
30
|
r.attributes do |a|
|
|
29
31
|
a.email = user.email
|
|
@@ -88,8 +90,12 @@ end
|
|
|
88
90
|
### Getting the encoded response
|
|
89
91
|
```ruby
|
|
90
92
|
response.mimic # Base64-encoded SAML response (for POST binding)
|
|
91
|
-
response.
|
|
93
|
+
response.to_xml # the same response as plain XML (for reading)
|
|
94
|
+
response.document # the response as a Nokogiri document (for searching)
|
|
92
95
|
```
|
|
96
|
+
Use `response.to_xml`, not `document.to_xml`. Going through `document`
|
|
97
|
+
adds spaces and line breaks, which breaks the signature, and the SP
|
|
98
|
+
rejects the response.
|
|
93
99
|
|
|
94
100
|
### Signing
|
|
95
101
|
Sign both the assertion and response with an IdP certificate:
|
|
@@ -112,6 +118,35 @@ response = Lyrebird::Response.build do |r|
|
|
|
112
118
|
r.encrypt_with = sp_cert
|
|
113
119
|
end
|
|
114
120
|
```
|
|
121
|
+
The assertion is signed first and then encrypted, and the response is
|
|
122
|
+
signed over the ciphertext.
|
|
123
|
+
|
|
124
|
+
### Testing rejection paths
|
|
125
|
+
Build deliberately invalid responses the SP should reject:
|
|
126
|
+
```ruby
|
|
127
|
+
# Expired (NotOnOrAfter in the past)
|
|
128
|
+
response = Lyrebird::Response.build do |r|
|
|
129
|
+
r.sign_with = idp_cert
|
|
130
|
+
r.valid_for = -10
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Not yet valid (NotBefore in the future)
|
|
134
|
+
response = Lyrebird::Response.build do |r|
|
|
135
|
+
r.sign_with = idp_cert
|
|
136
|
+
r.not_before = Time.now.utc + 600
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Wrong audience
|
|
140
|
+
response = Lyrebird::Response.build do |r|
|
|
141
|
+
r.sign_with = idp_cert
|
|
142
|
+
r.audience = "https://wrong.example.com"
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Untrusted signature (a certificate the SP does not know)
|
|
146
|
+
response = Lyrebird::Response.build do |r|
|
|
147
|
+
r.sign_with = Lyrebird::Certificate.build
|
|
148
|
+
end
|
|
149
|
+
```
|
|
115
150
|
|
|
116
151
|
### NameID Formats
|
|
117
152
|
```ruby
|
|
@@ -134,13 +169,19 @@ Lyrebird.configure do |d|
|
|
|
134
169
|
d.attributes = { role: "user" }
|
|
135
170
|
end
|
|
136
171
|
```
|
|
137
|
-
Defaults are frozen after configuration for thread safety
|
|
172
|
+
Defaults are frozen after configuration for thread safety, so
|
|
173
|
+
`configure` can only be called once.
|
|
138
174
|
|
|
139
175
|
## Certificate
|
|
140
176
|
Generates and manages X.509 certificates for signing SAML responses.
|
|
141
177
|
|
|
142
178
|
### Building a certificate
|
|
179
|
+
Key generation is slow, so `Lyrebird::Certificate.default` generates one
|
|
180
|
+
certificate and reuses it.
|
|
143
181
|
```ruby
|
|
182
|
+
# Generated once and reused
|
|
183
|
+
cert = Lyrebird::Certificate.default
|
|
184
|
+
|
|
144
185
|
# With defaults
|
|
145
186
|
cert = Lyrebird::Certificate.build
|
|
146
187
|
|
|
@@ -164,11 +205,11 @@ cert = Lyrebird::Certificate.load(
|
|
|
164
205
|
|
|
165
206
|
### Using a certificate
|
|
166
207
|
```ruby
|
|
167
|
-
cert.key
|
|
168
|
-
cert.x509
|
|
169
|
-
cert.key_pem
|
|
170
|
-
cert.x509_pem
|
|
171
|
-
cert.
|
|
172
|
-
cert.
|
|
173
|
-
cert.fingerprint #
|
|
208
|
+
cert.key # OpenSSL::PKey::RSA private key
|
|
209
|
+
cert.x509 # OpenSSL::X509::Certificate object
|
|
210
|
+
cert.key_pem # PEM-encoded private key
|
|
211
|
+
cert.x509_pem # PEM-encoded certificate
|
|
212
|
+
cert.base64 # Base64-encoded certificate (for SAML metadata)
|
|
213
|
+
cert.fingerprint # SHA256 fingerprint, colon-separated
|
|
214
|
+
cert.fingerprint(:sha1) # SHA1 fingerprint
|
|
174
215
|
```
|
data/lib/lyrebird/assertion.rb
CHANGED
|
@@ -20,15 +20,15 @@ module Lyrebird
|
|
|
20
20
|
@name_id_format = name_id_format
|
|
21
21
|
@recipient = recipient
|
|
22
22
|
@in_response_to = in_response_to
|
|
23
|
-
@not_before = not_before || @issue_instant
|
|
24
|
-
@not_on_or_after = @issue_instant + valid_for
|
|
23
|
+
@not_before = (not_before || @issue_instant).to_time.getutc
|
|
24
|
+
@not_on_or_after = [@issue_instant, @not_before].max + valid_for
|
|
25
25
|
@audience = audience
|
|
26
26
|
@authn_context = authn_context
|
|
27
27
|
@attributes = attributes
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
def document
|
|
31
|
-
Nokogiri::XML::Document.new.tap do |doc|
|
|
31
|
+
@document ||= Nokogiri::XML::Document.new.tap do |doc|
|
|
32
32
|
doc.root = root(doc)
|
|
33
33
|
end
|
|
34
34
|
end
|
|
@@ -121,12 +121,14 @@ module Lyrebird
|
|
|
121
121
|
as.namespace = ns
|
|
122
122
|
|
|
123
123
|
@attributes.each do |name, values|
|
|
124
|
+
list = values.is_a?(Enumerable) ? values.to_a : [values].compact
|
|
125
|
+
|
|
124
126
|
as.add_child(doc.create_element("Attribute")).tap do |a|
|
|
125
127
|
a.namespace = ns
|
|
126
128
|
a["Name"] = name
|
|
127
129
|
a["NameFormat"] = ATTR_NAME_FORMAT
|
|
128
130
|
|
|
129
|
-
|
|
131
|
+
list.each do |value|
|
|
130
132
|
a.add_child(doc.create_element("AttributeValue")).tap do |av|
|
|
131
133
|
av.namespace = ns
|
|
132
134
|
av.content = value
|
data/lib/lyrebird/certificate.rb
CHANGED
|
@@ -2,8 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
module Lyrebird
|
|
4
4
|
class Certificate
|
|
5
|
+
LOCK = Mutex.new
|
|
6
|
+
|
|
7
|
+
EXTENSIONS = {
|
|
8
|
+
"basicConstraints" => "CA:FALSE",
|
|
9
|
+
"keyUsage" => "digitalSignature,keyEncipherment"
|
|
10
|
+
}.freeze
|
|
11
|
+
|
|
5
12
|
attr_reader :key, :x509
|
|
6
13
|
|
|
14
|
+
def self.default
|
|
15
|
+
LOCK.synchronize { @default ||= build }
|
|
16
|
+
end
|
|
17
|
+
|
|
7
18
|
def self.build(**kwargs)
|
|
8
19
|
config = OpenStruct.new(kwargs)
|
|
9
20
|
yield config if block_given?
|
|
@@ -18,7 +29,7 @@ module Lyrebird
|
|
|
18
29
|
|
|
19
30
|
def initialize(
|
|
20
31
|
bits: 2048,
|
|
21
|
-
cn:
|
|
32
|
+
cn: "lyrebird",
|
|
22
33
|
o: nil,
|
|
23
34
|
valid_for: 365,
|
|
24
35
|
valid_until: nil,
|
|
@@ -41,18 +52,15 @@ module Lyrebird
|
|
|
41
52
|
@x509.to_pem
|
|
42
53
|
end
|
|
43
54
|
|
|
44
|
-
def fingerprint
|
|
45
|
-
OpenSSL::Digest
|
|
55
|
+
def fingerprint(algorithm = :sha256)
|
|
56
|
+
digest = OpenSSL::Digest.new(algorithm.to_s)
|
|
57
|
+
digest.hexdigest(@x509.to_der).upcase.scan(/../).join(":")
|
|
46
58
|
end
|
|
47
59
|
|
|
48
60
|
def base64
|
|
49
61
|
Base64.strict_encode64(@x509.to_der)
|
|
50
62
|
end
|
|
51
63
|
|
|
52
|
-
def sign(data)
|
|
53
|
-
@key.sign("SHA256", data)
|
|
54
|
-
end
|
|
55
|
-
|
|
56
64
|
private
|
|
57
65
|
|
|
58
66
|
def build_x509
|
|
@@ -66,6 +74,11 @@ module Lyrebird
|
|
|
66
74
|
c.issuer = c.subject
|
|
67
75
|
c.not_before = now
|
|
68
76
|
c.not_after = @valid_until || now + (@valid_for * 86_400)
|
|
77
|
+
|
|
78
|
+
EXTENSIONS.each do |oid, value|
|
|
79
|
+
c.add_extension(OpenSSL::X509::Extension.new(oid, value, true))
|
|
80
|
+
end
|
|
81
|
+
|
|
69
82
|
c.sign(@key, OpenSSL::Digest::SHA256.new)
|
|
70
83
|
end
|
|
71
84
|
end
|
data/lib/lyrebird/encryption.rb
CHANGED
|
@@ -49,7 +49,6 @@ module Lyrebird
|
|
|
49
49
|
|
|
50
50
|
def build_encrypted_key
|
|
51
51
|
@doc.create_element("EncryptedKey").tap do |ek|
|
|
52
|
-
ek.add_namespace_definition("xenc", XMLENC_NS)
|
|
53
52
|
ek.namespace = @xenc
|
|
54
53
|
|
|
55
54
|
ek.add_child(@doc.create_element("EncryptionMethod")).tap do |em|
|
|
@@ -81,7 +80,8 @@ module Lyrebird
|
|
|
81
80
|
cipher.encrypt
|
|
82
81
|
cipher.key = @aes_key
|
|
83
82
|
iv = cipher.random_iv
|
|
84
|
-
|
|
83
|
+
plaintext = @element.to_xml(save_with: 0)
|
|
84
|
+
ciphertext = cipher.update(plaintext) + cipher.final
|
|
85
85
|
|
|
86
86
|
@doc.create_element("CipherData").tap do |cd|
|
|
87
87
|
cd.namespace = @xenc
|
data/lib/lyrebird/response.rb
CHANGED
|
@@ -6,7 +6,11 @@ module Lyrebird
|
|
|
6
6
|
config = OpenStruct.new(kwargs)
|
|
7
7
|
|
|
8
8
|
config.define_singleton_method(:attributes) do |&block|
|
|
9
|
-
self
|
|
9
|
+
current = self[:attributes] || {}
|
|
10
|
+
return current unless block
|
|
11
|
+
|
|
12
|
+
fresh = OpenStruct.new.tap(&block).to_h
|
|
13
|
+
self[:attributes] = current.transform_keys(&:to_sym).merge(fresh)
|
|
10
14
|
end
|
|
11
15
|
|
|
12
16
|
yield config if block_given?
|
|
@@ -35,11 +39,15 @@ module Lyrebird
|
|
|
35
39
|
end
|
|
36
40
|
|
|
37
41
|
def mimic
|
|
38
|
-
Base64.strict_encode64(
|
|
42
|
+
Base64.strict_encode64(to_xml)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def to_xml
|
|
46
|
+
document.to_xml(save_with: 0)
|
|
39
47
|
end
|
|
40
48
|
|
|
41
49
|
def document
|
|
42
|
-
Nokogiri::XML::Document.new.tap do |doc|
|
|
50
|
+
@document ||= Nokogiri::XML::Document.new.tap do |doc|
|
|
43
51
|
doc.root = build_response(doc)
|
|
44
52
|
sign_assertion(doc) if @sign_with && !@encrypt_with
|
|
45
53
|
sign_response(doc) if @sign_with
|
|
@@ -66,13 +74,12 @@ module Lyrebird
|
|
|
66
74
|
end
|
|
67
75
|
|
|
68
76
|
r.add_child(build_status(doc))
|
|
69
|
-
r.add_child(build_assertion_element
|
|
77
|
+
r.add_child(build_assertion_element)
|
|
70
78
|
end
|
|
71
79
|
end
|
|
72
80
|
|
|
73
|
-
def build_assertion_element
|
|
74
|
-
|
|
75
|
-
element = assertion_doc.root
|
|
81
|
+
def build_assertion_element
|
|
82
|
+
element = @assertion.document.root
|
|
76
83
|
|
|
77
84
|
if @encrypt_with
|
|
78
85
|
Signature.new(element, @sign_with).sign! if @sign_with
|
data/lib/lyrebird/signature.rb
CHANGED
|
@@ -11,8 +11,11 @@ module Lyrebird
|
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def sign!
|
|
14
|
-
|
|
14
|
+
ns = { "saml" => SAML_ASSERTION_NS, "ds" => XMLDSIG_NS }
|
|
15
|
+
@element.at_xpath("ds:Signature", ns)&.remove
|
|
16
|
+
issuer = @element.at_xpath("saml:Issuer", ns)
|
|
15
17
|
issuer.add_next_sibling(build_signature)
|
|
18
|
+
populate_signature_value
|
|
16
19
|
self
|
|
17
20
|
end
|
|
18
21
|
|
|
@@ -32,7 +35,6 @@ module Lyrebird
|
|
|
32
35
|
def build_signed_info
|
|
33
36
|
@doc.create_element("SignedInfo").tap do |si|
|
|
34
37
|
@signed_info = si
|
|
35
|
-
si.add_namespace_definition("ds", XMLDSIG_NS)
|
|
36
38
|
si.namespace = @ds
|
|
37
39
|
|
|
38
40
|
si.add_child(@doc.create_element("CanonicalizationMethod")).tap do |cm|
|
|
@@ -52,16 +54,14 @@ module Lyrebird
|
|
|
52
54
|
def build_signature_value
|
|
53
55
|
@doc.create_element("SignatureValue").tap do |sv|
|
|
54
56
|
sv.namespace = @ds
|
|
55
|
-
|
|
56
|
-
sig = @certificate.sign(canonical)
|
|
57
|
-
sv.content = Base64.strict_encode64(sig)
|
|
57
|
+
@signature_value = sv
|
|
58
58
|
end
|
|
59
59
|
end
|
|
60
60
|
|
|
61
|
-
def
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
def populate_signature_value
|
|
62
|
+
canonical = @signed_info.canonicalize(C14N_EXCLUSIVE)
|
|
63
|
+
sig = @certificate.key.sign("SHA256", canonical)
|
|
64
|
+
@signature_value.content = Base64.strict_encode64(sig)
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
def build_key_info
|
data/lib/lyrebird/version.rb
CHANGED
data/lib/lyrebird.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lyrebird
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Josh
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-08-26 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: base64
|
|
@@ -114,11 +114,8 @@ executables: []
|
|
|
114
114
|
extensions: []
|
|
115
115
|
extra_rdoc_files: []
|
|
116
116
|
files:
|
|
117
|
-
- ".github/workflows/ci.yml"
|
|
118
|
-
- ".github/workflows/publish.yml"
|
|
119
117
|
- LICENSE.md
|
|
120
118
|
- README.md
|
|
121
|
-
- Rakefile
|
|
122
119
|
- lib/lyrebird.rb
|
|
123
120
|
- lib/lyrebird/assertion.rb
|
|
124
121
|
- lib/lyrebird/certificate.rb
|
|
@@ -129,22 +126,13 @@ files:
|
|
|
129
126
|
- lib/lyrebird/response.rb
|
|
130
127
|
- lib/lyrebird/signature.rb
|
|
131
128
|
- lib/lyrebird/version.rb
|
|
132
|
-
- lyrebird.gemspec
|
|
133
|
-
- sig/lyrebird.rbs
|
|
134
|
-
- test/lyrebird/assertion_test.rb
|
|
135
|
-
- test/lyrebird/certificate_test.rb
|
|
136
|
-
- test/lyrebird/defaults_test.rb
|
|
137
|
-
- test/lyrebird/encryption_test.rb
|
|
138
|
-
- test/lyrebird/id_test.rb
|
|
139
|
-
- test/lyrebird/integration_test.rb
|
|
140
|
-
- test/lyrebird/namespaces_test.rb
|
|
141
|
-
- test/lyrebird/response_test.rb
|
|
142
|
-
- test/lyrebird/signature_test.rb
|
|
143
|
-
- test/test_helper.rb
|
|
144
129
|
homepage: https://github.com/simplesaml/lyrebird
|
|
145
130
|
licenses:
|
|
146
131
|
- MIT
|
|
147
|
-
metadata:
|
|
132
|
+
metadata:
|
|
133
|
+
source_code_uri: https://github.com/simplesaml/lyrebird
|
|
134
|
+
changelog_uri: https://github.com/simplesaml/lyrebird/releases
|
|
135
|
+
bug_tracker_uri: https://github.com/simplesaml/lyrebird/issues
|
|
148
136
|
post_install_message:
|
|
149
137
|
rdoc_options: []
|
|
150
138
|
require_paths:
|
data/.github/workflows/ci.yml
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
name: CI
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches: [main]
|
|
6
|
-
pull_request:
|
|
7
|
-
branches: [main]
|
|
8
|
-
|
|
9
|
-
jobs:
|
|
10
|
-
test:
|
|
11
|
-
runs-on: ubuntu-latest
|
|
12
|
-
strategy:
|
|
13
|
-
fail-fast: false
|
|
14
|
-
matrix:
|
|
15
|
-
ruby-version: ["3.2", "3.3", "3.4", "4.0"]
|
|
16
|
-
|
|
17
|
-
steps:
|
|
18
|
-
- uses: actions/checkout@v4
|
|
19
|
-
- name: Set up Ruby ${{ matrix.ruby-version }}
|
|
20
|
-
uses: ruby/setup-ruby@v1
|
|
21
|
-
with:
|
|
22
|
-
ruby-version: ${{ matrix.ruby-version }}
|
|
23
|
-
bundler-cache: true
|
|
24
|
-
- name: Run tests
|
|
25
|
-
run: bundle exec rake test
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
name: Publish
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
release:
|
|
5
|
-
types: [published]
|
|
6
|
-
|
|
7
|
-
jobs:
|
|
8
|
-
publish:
|
|
9
|
-
runs-on: ubuntu-latest
|
|
10
|
-
steps:
|
|
11
|
-
- uses: actions/checkout@v4
|
|
12
|
-
- uses: ruby/setup-ruby@v1
|
|
13
|
-
with:
|
|
14
|
-
ruby-version: "3.2"
|
|
15
|
-
- name: Build gem
|
|
16
|
-
run: gem build lyrebird.gemspec
|
|
17
|
-
- name: Publish to RubyGems
|
|
18
|
-
run: gem push lyrebird-*.gem
|
|
19
|
-
env:
|
|
20
|
-
GEM_HOST_API_KEY: ${{ secrets.RUBYGEMS_API_KEY }}
|
data/Rakefile
DELETED
data/lyrebird.gemspec
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative "lib/lyrebird/version"
|
|
4
|
-
|
|
5
|
-
Gem::Specification.new do |spec|
|
|
6
|
-
spec.name = "lyrebird"
|
|
7
|
-
spec.version = Lyrebird::VERSION
|
|
8
|
-
spec.authors = ["Josh"]
|
|
9
|
-
|
|
10
|
-
spec.summary = "Mimics SAML Identity Provider (IdP) responses for testing"
|
|
11
|
-
spec.homepage = "https://github.com/simplesaml/lyrebird"
|
|
12
|
-
spec.license = "MIT"
|
|
13
|
-
spec.required_ruby_version = ">= 3.2.0"
|
|
14
|
-
|
|
15
|
-
spec.files = `git ls-files -z`.split("\x0")
|
|
16
|
-
spec.files.delete("Gemfile")
|
|
17
|
-
spec.files.delete(".gitignore")
|
|
18
|
-
spec.files.reject! { |f| f.start_with?("bin/") }
|
|
19
|
-
|
|
20
|
-
spec.require_paths = ["lib"]
|
|
21
|
-
|
|
22
|
-
spec.add_dependency "base64"
|
|
23
|
-
spec.add_dependency "nokogiri"
|
|
24
|
-
spec.add_dependency "ostruct"
|
|
25
|
-
|
|
26
|
-
# ruby-saml's gemspec has a conditional dependency on logger for Ruby >= 3.4,
|
|
27
|
-
# but it was evaluated at gem build time (on Ruby < 3.4), so the published gem
|
|
28
|
-
# doesn't include it.
|
|
29
|
-
spec.add_development_dependency "logger"
|
|
30
|
-
spec.add_development_dependency "minitest"
|
|
31
|
-
spec.add_development_dependency "rake"
|
|
32
|
-
spec.add_development_dependency "ruby-saml"
|
|
33
|
-
end
|
data/sig/lyrebird.rbs
DELETED