saml2 2.2.11 → 2.2.12

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d29dce81582e9f864e9382373bff2d075041266b9a6c13931a2675b2a3b8665f
4
- data.tar.gz: a126314896499fd3a30fac541aa8a32ad3d1610c9f7b133b596502d543997a70
3
+ metadata.gz: 630f03aeb419e5d7ebae94ab4b809bf460be88903fdfdfe981d96dda990fbb5d
4
+ data.tar.gz: 2f17e8e081522cf5c7b2e8b5705bf600fd33fbc68e404203f865c442ffeea85c
5
5
  SHA512:
6
- metadata.gz: a6573df0b3f11f79e0878350a021c8bf3c28ebf2736469ea0a97202b22cf41a2823a6aa62a4f0bb18e0e79aecfac946d357e1e2d074dec130192510f997e5fe4
7
- data.tar.gz: 9b8011e5a896b084f5e30b552fd8337ea3bcfcce80bdbb99351cf9e6e319864af04f565bc1733c69ee286b53f8e928a4cf7267e7b23409110a5ccc70b2d5b1cc
6
+ metadata.gz: cad2fd1128ddfa7d8522ca592f8a72b717554ef0d8cddd55b160183e0656df306bebadd0f19e3b131267f8100f1a80ca0956c2c9a78a7eb0e9ad195eb4b72edc
7
+ data.tar.gz: d38744fc8b083257306a25b7d3f2e1538313f7791e2667debac3e915499153699ee8af484d6aed2769dc51baffa35e03694759af7e5b32407b77e973b7c66bef
@@ -174,9 +174,13 @@ module SAML2
174
174
  #
175
175
  # Repeated attributes become an array.
176
176
  #
177
- # @param name optional [:name, :friendly_name]
178
- # Which name field to use as keys to the hash
179
- def to_h(name = :friendly_name)
177
+ # @param name optional [:name, :friendly_name, :both]
178
+ # Which name field to use as keys to the hash. If :both
179
+ # is specified, attributes may be duplicated under both
180
+ # names.
181
+ def to_h(name = :both)
182
+ return to_h(:friendly_name).merge(to_h(:name)) if name == :both
183
+
180
184
  result = {}
181
185
  attributes.each do |attribute|
182
186
  key = attribute.send(name)
@@ -46,10 +46,10 @@ module SAML2
46
46
  def validate(verification_time: Time.now.utc, **options)
47
47
  options[:verification_time] ||= verification_time
48
48
  errors = []
49
- if not_before && verification_time < not_before - 5
49
+ if not_before && verification_time < not_before
50
50
  errors << "not_before #{not_before} is later than now (#{verification_time})"
51
51
  end
52
- if not_on_or_after && verification_time >= not_on_or_after + 5
52
+ if not_on_or_after && verification_time >= not_on_or_after
53
53
  errors << "not_on_or_after #{not_on_or_after} is earlier than now (#{verification_time})"
54
54
  end
55
55
 
@@ -109,7 +109,9 @@ module SAML2
109
109
  end
110
110
 
111
111
  # @param audience [String]
112
- def validate(audience: nil, **_)
112
+ def validate(audience: nil, ignore_audience_condition: false, **_)
113
+ return [] if ignore_audience_condition
114
+
113
115
  unless Array.wrap(self.audience).include?(audience)
114
116
  return ["audience #{audience} not in allowed list of #{Array.wrap(self.audience).join(', ')}"]
115
117
  end
data/lib/saml2/entity.rb CHANGED
@@ -168,9 +168,7 @@ module SAML2
168
168
  # @param identity_provider [Entity]
169
169
  def valid_response?(message,
170
170
  identity_provider,
171
- verification_time: Time.now.utc,
172
- allow_expired_certificate: false,
173
- verify_certificate: true)
171
+ **opts)
174
172
  unless message.is_a?(Response)
175
173
  message.errors << "not a Response object"
176
174
  return false
@@ -178,9 +176,7 @@ module SAML2
178
176
 
179
177
  message.validate(service_provider: self,
180
178
  identity_provider: identity_provider,
181
- verification_time: verification_time,
182
- allow_expired_certificate: allow_expired_certificate,
183
- verify_certificate: verify_certificate).empty?
179
+ **opts).empty?
184
180
  end
185
181
  end
186
182
  end
@@ -89,11 +89,19 @@ module SAML2
89
89
  # @param verification_time optional [DateTime]
90
90
  # Validate timestamps (signing certificate validity, issued at, etc.) as of
91
91
  # this point in time.
92
+ # @param allow_expired_certificate optional [true, false]
93
+ # Allow signing certificate to be expired.
94
+ # @param verify_certificate optional [true, false]
95
+ # Don't validate the trust chain or validity dates of the signing
96
+ # certificate.
97
+ # @param ignore_audience_condition optional [true, false]
98
+ # Don't validate any Audience conditions.
92
99
  def validate(service_provider:,
93
100
  identity_provider:,
94
- verification_time: Time.now.utc,
101
+ verification_time: nil,
95
102
  allow_expired_certificate: false,
96
- verify_certificate: true)
103
+ verify_certificate: true,
104
+ ignore_audience_condition: false)
97
105
  raise ArgumentError, "service_provider should be an Entity object" unless service_provider.is_a?(Entity)
98
106
  raise ArgumentError, "service_provider should have at least one service_provider role" unless (sp = service_provider.service_providers.first)
99
107
 
@@ -101,6 +109,13 @@ module SAML2
101
109
  super()
102
110
  return errors unless errors.empty?
103
111
 
112
+ if verification_time.nil?
113
+ verification_time = Time.now.utc
114
+ # they issued it in the (near) future according to our clock;
115
+ # use their clock instead
116
+ verification_time = issue_instant if issue_instant > verification_time && issue_instant < verification_time + 5 * 60
117
+ end
118
+
104
119
  # not finding the issuer is not exceptional
105
120
  if identity_provider.nil?
106
121
  errors << "could not find issuer of response"
@@ -216,7 +231,8 @@ module SAML2
216
231
 
217
232
  if assertion.conditions &&
218
233
  !(condition_errors = assertion.conditions.validate(verification_time: verification_time,
219
- audience: service_provider.entity_id)).empty?
234
+ audience: service_provider.entity_id,
235
+ ignore_audience_condition: ignore_audience_condition)).empty?
220
236
  return errors.concat(condition_errors)
221
237
  end
222
238
 
data/lib/saml2/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SAML2
4
- VERSION = '2.2.11'
4
+ VERSION = '2.2.12'
5
5
  end
@@ -111,13 +111,16 @@ XML
111
111
  describe "#to_h" do
112
112
  it "works" do
113
113
  attr_statement = Response.parse(fixture("response_with_attribute_signed.xml")).assertions.first.attribute_statements.first
114
- expect(attr_statement.to_h).to eq('givenName' => 'cody')
114
+ expect(attr_statement.to_h(:friendly_name)).to eq('givenName' => 'cody')
115
115
  expect(attr_statement.to_h(:name)).to eq("urn:oid:2.5.4.42" => 'cody')
116
+ expect(attr_statement.to_h(:both)).to eq('givenName' => 'cody', "urn:oid:2.5.4.42" => 'cody')
116
117
  end
117
118
 
118
119
  it "infers friendly names if possible" do
119
120
  attr_statement = Response.parse(fixture("test3-response.xml")).assertions.first.attribute_statements.first
120
121
  expect(attr_statement.to_h).to eq({
122
+ 'urn:oid:1.3.6.1.4.1.5923.1.1.1.1' => 'member',
123
+ 'urn:oid:1.3.6.1.4.1.5923.1.1.1.6' => 'student@example.edu',
121
124
  'eduPersonAffiliation' => 'member',
122
125
  'eduPersonPrincipalName' => 'student@example.edu'})
123
126
  end
@@ -135,7 +138,7 @@ XML
135
138
  </saml2:AttributeStatement>
136
139
  XML
137
140
 
138
- expect(attr_statement.to_h).to eq({
141
+ expect(attr_statement.to_h(:friendly_name)).to eq({
139
142
  'eduPersonScopedAffiliation' => ['02', 'employee@school.edu', 'students@school.edu']
140
143
  })
141
144
  end
@@ -64,5 +64,9 @@ module SAML2
64
64
  it "should be valid with an array" do
65
65
  expect(Conditions::AudienceRestriction.new(['expected', 'actual']).valid?(audience: 'actual')).to eq true
66
66
  end
67
+
68
+ it "is valid when ignored" do
69
+ expect(Conditions::AudienceRestriction.new('expected').valid?(audience: 'actual', ignore_audience_condition: true)).to eq true
70
+ end
67
71
  end
68
72
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: saml2
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.11
4
+ version: 2.2.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cody Cutrer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-23 00:00:00.000000000 Z
11
+ date: 2018-06-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri