Skip to content

Commit 6dd7aec

Browse files
committed
Add unit tests for subject-id filter
1 parent 80da3db commit 6dd7aec

File tree

2 files changed

+284
-2
lines changed

2 files changed

+284
-2
lines changed

tests/library/EngineBlock/Test/Corto/Filter/Command/VerifyShibMdScopingAllowsEduPersonPrincipalNameTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ public function testNoEduPersonPrincipalNameLeadsToNoVerification()
8282
{
8383
$scope = new ShibMdScope();
8484
$scope->regexp = false;
85-
$scope->allowed = self::EPPN_VALUE;
85+
$scope->allowed = self::EPPN_SUFFIX;
8686

8787
$identityProvider = new IdentityProvider('OpenConext');
8888
$identityProvider->shibMdScopes = array($scope);
@@ -110,7 +110,7 @@ public function testEduPersonPrincipalNameWithoutAtSignIsLoggedAsWarning()
110110
{
111111
$scope = new ShibMdScope();
112112
$scope->regexp = false;
113-
$scope->allowed = self::EPPN_VALUE;
113+
$scope->allowed = self::EPPN_SUFFIX;
114114

115115
$identityProvider = new IdentityProvider('OpenConext');
116116
$identityProvider->shibMdScopes = array($scope);
Lines changed: 282 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,282 @@
1+
<?php
2+
3+
/**
4+
* Copyright 2010 SURFnet B.V.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration;
20+
use Monolog\Handler\TestHandler;
21+
use Monolog\Logger;
22+
use OpenConext\EngineBlock\Metadata\Entity\IdentityProvider;
23+
use OpenConext\EngineBlock\Metadata\ShibMdScope;
24+
use PHPUnit\Framework\TestCase;
25+
use SAML2\Constants;
26+
use SAML2\Assertion;
27+
use SAML2\Response;
28+
29+
class EngineBlock_Test_Corto_Filter_Command_VerifyShibMdScopingAllowsSubjectIdTest extends TestCase
30+
{
31+
use MockeryPHPUnitIntegration;
32+
33+
const SUB_NAME = Constants::ATTR_SUBJECT_ID;
34+
const SUB_SUFFIX = 'openconext.org';
35+
const SUB_VALUE = 'invalid@' . self::SUB_SUFFIX;
36+
37+
/**
38+
* @var TestHandler
39+
*/
40+
private $handler;
41+
42+
/**
43+
* @var Logger
44+
*/
45+
private $logger;
46+
47+
/**
48+
* @var EngineBlock_Saml2_ResponseAnnotationDecorator
49+
*/
50+
private $response;
51+
52+
public function setUp()
53+
{
54+
$this->handler = new TestHandler();
55+
$this->logger = new Logger('Test', [$this->handler]);
56+
57+
$assertion = new Assertion();
58+
$assertion->setAttributes([self::SUB_NAME => [self::SUB_VALUE]]);
59+
60+
$response = new Response();
61+
$response->setAssertions([$assertion]);
62+
63+
$this->response = new EngineBlock_Saml2_ResponseAnnotationDecorator($response);
64+
}
65+
66+
public function testNoConfiguredScopesLeadsToNoVerification()
67+
{
68+
$verifier = new EngineBlock_Corto_Filter_Command_VerifyShibMdScopingAllowsSubjectId($this->logger, false);
69+
$verifier->setResponse($this->response);
70+
$verifier->setIdentityProvider(new IdentityProvider('OpenConext'));
71+
72+
$verifier->execute();
73+
74+
$noScopeMessageLogged = $this->handler->hasNotice(
75+
'No shibmd:scope found in the IdP metadata, not verifying subject-id'
76+
);
77+
78+
$this->assertTrue($noScopeMessageLogged, 'Logging that no shibmd:scope is configured is required');
79+
}
80+
81+
public function testNoSubjectIdLeadsToNoVerification()
82+
{
83+
$scope = new ShibMdScope();
84+
$scope->regexp = false;
85+
$scope->allowed = self::SUB_SUFFIX;
86+
87+
$identityProvider = new IdentityProvider('OpenConext');
88+
$identityProvider->shibMdScopes = [$scope];
89+
90+
// wipe the assertion attributes
91+
$this->response->getAssertion()->setAttributes([]);
92+
93+
$verifier = new EngineBlock_Corto_Filter_Command_VerifyShibMdScopingAllowsSubjectId($this->logger, false);
94+
$verifier->setResponse($this->response);
95+
$verifier->setIdentityProvider($identityProvider);
96+
97+
$verifier->execute();
98+
99+
$noSubjectIdMessageLogged = $this->handler->hasNotice(
100+
'No subject-id found in response, not verifying'
101+
);
102+
103+
$this->assertTrue(
104+
$noSubjectIdMessageLogged,
105+
'Logging that no subject-id is found is required'
106+
);
107+
}
108+
109+
public function testSubjectIdWithoutAtSignIsRejected()
110+
{
111+
$scope = new ShibMdScope();
112+
$scope->regexp = false;
113+
$scope->allowed = self::SUB_SUFFIX;
114+
115+
$identityProvider = new IdentityProvider('OpenConext');
116+
$identityProvider->shibMdScopes = [$scope];
117+
118+
// wipe the assertion attributes
119+
$this->response->getAssertion()->setAttributes([self::SUB_NAME => ['NoAtSign']]);
120+
121+
$verifier = new EngineBlock_Corto_Filter_Command_VerifyShibMdScopingAllowsSubjectId($this->logger, false);
122+
$verifier->setResponse($this->response);
123+
$verifier->setIdentityProvider($identityProvider);
124+
125+
$this->expectException(EngineBlock_Corto_Exception_InvalidAttributeValue::class);
126+
$this->expectExceptionMessage('Invalid subject-id, missing @');
127+
128+
$verifier->execute();
129+
}
130+
131+
public function testSubjectIdWithMultipleValuesRejected()
132+
{
133+
$scope = new ShibMdScope();
134+
$scope->regexp = false;
135+
$scope->allowed = self::SUB_SUFFIX;
136+
137+
$identityProvider = new IdentityProvider('OpenConext');
138+
$identityProvider->shibMdScopes = [$scope];
139+
140+
$attributes = [self::SUB_NAME => ['something@' . self::SUB_SUFFIX, 'other@' . self::SUB_SUFFIX]];
141+
$this->response->getAssertion()->setAttributes($attributes);
142+
143+
$verifier = new EngineBlock_Corto_Filter_Command_VerifyShibMdScopingAllowsSubjectId($this->logger, false);
144+
$verifier->setResponse($this->response);
145+
$verifier->setIdentityProvider($identityProvider);
146+
147+
$this->expectException(EngineBlock_Corto_Exception_InvalidAttributeValue::class);
148+
$this->expectExceptionMessage('Only exactly one subject-id allowed');
149+
150+
$verifier->execute();
151+
}
152+
153+
public function testSubjectIdNotInScopeIsLoggedAsWarning()
154+
{
155+
$scope = new ShibMdScope();
156+
$scope->regexp = false;
157+
$scope->allowed = 'You shall not pass';
158+
159+
$identityProvider = new IdentityProvider('OpenConext');
160+
$identityProvider->shibMdScopes = [$scope];
161+
162+
$verifier = new EngineBlock_Corto_Filter_Command_VerifyShibMdScopingAllowsSubjectId($this->logger, false);
163+
$verifier->setResponse($this->response);
164+
$verifier->setIdentityProvider($identityProvider);
165+
166+
$verifier->execute();
167+
168+
$invalidScopeIsLogged = $this->handler->hasWarningThatContains(
169+
'subject-id attribute value "' . self::SUB_SUFFIX . '" is not allowed by configured ShibMdScopes for IdP '
170+
);
171+
172+
$this->assertTrue($invalidScopeIsLogged);
173+
}
174+
175+
public function testSubjectIdThatMatchesLogsNoWarning()
176+
{
177+
$scope = new ShibMdScope();
178+
$scope->regexp = false;
179+
$scope->allowed = 'openconext.org;
180+
181+
$identityProvider = new IdentityProvider('OpenConext');
182+
$identityProvider->shibMdScopes = [$scope];
183+
184+
$verifier = new EngineBlock_Corto_Filter_Command_VerifyShibMdScopingAllowsSubjectId($this->logger, false);
185+
$verifier->setResponse($this->response);
186+
$verifier->setIdentityProvider($identityProvider);
187+
188+
$verifier->execute();
189+
190+
$invalidScopeIsLogged = $this->handler->hasWarningThatContains(
191+
'subject-id attribute value "' . self::SUB_SUFFIX . '" is not allowed by configured ShibMdScopes for IdP '
192+
);
193+
194+
$this->assertFalse($invalidScopeIsLogged);
195+
}
196+
197+
public function testSubjectIdThatMatchesCaseInsensitivelyLogsNoWarning()
198+
{
199+
$scope = new ShibMdScope();
200+
$scope->regexp = false;
201+
$scope->allowed = 'openconext.ORG';
202+
203+
$identityProvider = new IdentityProvider('OpenConext');
204+
$identityProvider->shibMdScopes = [$scope];
205+
206+
$verifier = new EngineBlock_Corto_Filter_Command_VerifyShibMdScopingAllowsSubjectId($this->logger, false);
207+
$verifier->setResponse($this->response);
208+
$verifier->setIdentityProvider($identityProvider);
209+
210+
$verifier->execute();
211+
212+
$invalidScopeIsLogged = $this->handler->hasWarningThatContains(
213+
'subject-id attribute value "' . self::SUB_SUFFIX . '" is not allowed by configured ShibMdScopes for IdP '
214+
);
215+
216+
$this->assertFalse($invalidScopeIsLogged);
217+
}
218+
219+
public function testSubjectIdThatMatchesRegexpLogsNoWarning()
220+
{
221+
$scope = new ShibMdScope();
222+
$scope->regexp = true;
223+
$scope->allowed = '.*conext\.org';
224+
225+
$identityProvider = new IdentityProvider('OpenConext');
226+
$identityProvider->shibMdScopes = [$scope];
227+
228+
$verifier = new EngineBlock_Corto_Filter_Command_VerifyShibMdScopingAllowsSubjectId($this->logger, false);
229+
$verifier->setResponse($this->response);
230+
$verifier->setIdentityProvider($identityProvider);
231+
232+
$verifier->execute();
233+
234+
$invalidScopeIsLogged = $this->handler->hasWarningThatContains(
235+
'subject-id attribute value "' . self::SUB_SUFFIX . '" is not allowed by configured ShibMdScopes for IdP '
236+
);
237+
238+
$this->assertFalse($invalidScopeIsLogged);
239+
}
240+
241+
public function testSubjectIdNotInRegexpScopeIsLoggedAsWarning()
242+
{
243+
$scope = new ShibMdScope();
244+
$scope->regexp = true;
245+
$scope->allowed = '.*\.noconext\.org';
246+
247+
$identityProvider = new IdentityProvider('OpenConext');
248+
$identityProvider->shibMdScopes = [$scope];
249+
250+
$verifier = new EngineBlock_Corto_Filter_Command_VerifyShibMdScopingAllowsSubjectId($this->logger, false);
251+
$verifier->setResponse($this->response);
252+
$verifier->setIdentityProvider($identityProvider);
253+
254+
$verifier->execute();
255+
256+
$invalidScopeIsLogged = $this->handler->hasWarningThatContains(
257+
'subject-id attribute value "' . self::SUB_SUFFIX . '" is not allowed by configured ShibMdScopes for IdP '
258+
);
259+
260+
$this->assertTrue($invalidScopeIsLogged);
261+
}
262+
263+
public function testSubjectIdNotInRegexpScopeThrowsException()
264+
{
265+
$this->expectException(EngineBlock_Corto_Exception_InvalidAttributeValue::class);
266+
$this->expectExceptionMessage('subject-id attribute value "openconext.org" is not allowed by configured ShibMdScopes for IdP "OpenConext"');
267+
268+
$scope = new ShibMdScope();
269+
$scope->regexp = true;
270+
$scope->allowed = '.*\.noconext\.org';
271+
272+
$identityProvider = new IdentityProvider('OpenConext');
273+
$identityProvider->shibMdScopes = [$scope];
274+
275+
$verifier = new EngineBlock_Corto_Filter_Command_VerifyShibMdScopingAllowsSubjectId($this->logger, true);
276+
$verifier->setResponse($this->response);
277+
$verifier->setIdentityProvider($identityProvider);
278+
279+
$verifier->execute();
280+
}
281+
282+
}

0 commit comments

Comments
 (0)