Skip to content

Commit 1830a47

Browse files
committed
Change the ValidateAllowedConnection input filter so that collab_enabled-services skip the IdP-SP check. I.e., if coin:collab_enabled is set, skip the check if the correct IdP is connected, and always allow the flow to continue.
1 parent 194b2b5 commit 1830a47

File tree

16 files changed

+355
-32
lines changed

16 files changed

+355
-32
lines changed

library/EngineBlock/Corto/Filter/Command/EnforcePolicy.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public function execute()
6363

6464
try {
6565
$pdp = $this->getPdpClient();
66-
$policyDecision = $pdp->requestDecisionFor($pdpRequest);
66+
$policyDecision = $pdp->requestInterruptDecisionFor($pdpRequest);
6767
} catch (\OpenConext\EngineBlock\Http\Exception\HttpException $e) {
6868
throw new EngineBlock_Exception_PdpCheckFailed(
6969
'Policy Enforcement Point: Could not perform PDP check: ' . $e->getMessage()

library/EngineBlock/Corto/Filter/Command/SRAMTestFilter.php

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ public function getResponseAttributes()
2929

3030
public function execute(): void
3131
{
32-
3332
$application = EngineBlock_ApplicationSingleton::getInstance();
3433

3534
$sramEndpoint = $application->getDiContainer()->getSRAMEndpoint();
@@ -46,8 +45,15 @@ public function execute(): void
4645
$user_id = $attributes['urn:mace:dir:attribute-def:uid'][0];
4746
$continue_url = $this->_server->getUrl('SRAMInterruptService', '') . "?ID=$id";
4847
$service_id = $this->_serviceProvider->entityId;
48+
// @TODO at the very start of this function, check if the SP has `coin:collab_enabled`, skip otherwise?
4949
$issuer_id = $this->_identityProvider->entityId;
5050

51+
/***
52+
* @TODO Move all curl related things to new HttpClient. See PDPClient as an example.
53+
* @TODO Make sure it has tests
54+
* @TODO add tests for this Input Filter
55+
*/
56+
5157
$headers = array(
5258
"Authorization: $sramApiToken"
5359
);
@@ -74,16 +80,16 @@ public function execute(): void
7480
$data = curl_exec($ch);
7581
curl_close($ch);
7682

77-
$body = json_decode($data);
83+
$body = json_decode($data, false);
7884
// error_log("SRAMTestFilter " . var_export($body, true));
7985

86+
// @TODO Add integration test: Assert the redirect url on the saml response is SRAM
87+
8088
$msg = $body->msg;
81-
if ('interrupt' == $msg) {
89+
if ($msg === 'interrupt') {
8290
$this->_response->setSRAMInterruptNonce($body->nonce);
83-
} else {
84-
if ($body->attributes) {
85-
$this->_responseAttributes = array_merge_recursive($this->_responseAttributes, (array) $body->attributes);
86-
}
91+
} elseif ($body->attributes) {
92+
$this->_responseAttributes = array_merge_recursive($this->_responseAttributes, (array) $body->attributes);
8793
}
8894

8995
}

library/EngineBlock/Corto/Filter/Command/ValidateAllowedConnection.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
* limitations under the License.
1717
*/
1818

19+
use OpenConext\EngineBlock\Metadata\Entity\ServiceProvider;
20+
1921
/**
2022
* Validate if the IDP sending this response is allowed to connect to the SP that made the request.
2123
**/
@@ -24,6 +26,11 @@ class EngineBlock_Corto_Filter_Command_ValidateAllowedConnection extends EngineB
2426
public function execute()
2527
{
2628
$sp = $this->_serviceProvider;
29+
30+
if ($this->sbsFlowActive($sp)) {
31+
return;
32+
}
33+
2734
// When dealing with an SP that acts as a trusted proxy, we should perform the validatoin on the proxying SP
2835
// and not the proxy itself.
2936
if ($sp->getCoins()->isTrustedProxy()) {
@@ -41,4 +48,9 @@ public function execute()
4148
);
4249
}
4350
}
51+
52+
private function sbsFlowActive(ServiceProvider $sp)
53+
{
54+
return $sp->getCoins()->collabEnabled();
55+
}
4456
}

library/EngineBlock/Corto/Filter/Input.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ public function getCommands()
100100

101101
// SRAM Test filter
102102
// When feature_enable_sram_interrupt enabled
103+
// @TODO Should this check be here, or in the filter itself like \EngineBlock_Corto_Filter_Command_SsoNotificationCookieFilter
104+
// @TODO if it stays here, add test to make sure it's in the command[] or not
103105
if ($featureConfiguration->isEnabled('eb.feature_enable_sram_interrupt')) {
104106
$commands[] = new EngineBlock_Corto_Filter_Command_SRAMTestFilter();
105107
}

library/EngineBlock/Corto/Module/Service/AssertionConsumer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ public function serve($serviceName, Request $httpRequest)
171171
$this->_server->filterInputAssertionAttributes($receivedResponse, $receivedRequest);
172172

173173
// Send SRAM Interrupt call
174-
if ("" != $receivedResponse->getSRAMInterruptNonce()) {
174+
if ($receivedResponse->getSRAMInterruptNonce() !== "") {
175175
$log->info('Handle SRAM Interrupt callout');
176176

177177
// Add the SRAM step

library/EngineBlock/Saml2/ResponseAnnotationDecorator.php

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -311,24 +311,11 @@ public function setIsTransparentErrorResponse(bool $isTransparentErrorResponse):
311311
$this->isTransparentErrorResponse = $isTransparentErrorResponse;
312312
}
313313

314-
/**
315-
* @param bool
316-
*/
317-
public function setSRAMInterrupt(bool $SRAMInterrupt)
318-
{
319-
$this->SRAMInterrupt = $SRAMInterrupt;
320-
}
321-
322-
/**
323-
* @param string
324-
*/
325-
public function setSRAMInterruptNonce(string $SRAMInterruptNonce)
314+
public function setSRAMInterruptNonce(string $SRAMInterruptNonce): void
326315
{
327316
$this->SRAMInterruptNonce = $SRAMInterruptNonce;
328317
}
329-
/**
330-
* @return string
331-
*/
318+
332319
public function getSRAMInterruptNonce(): string
333320
{
334321
return $this->SRAMInterruptNonce;

src/OpenConext/EngineBlockBundle/Pdp/PdpClient.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public function __construct(
4343
$this->policyDecisionPointPath = $policyDecisionPointPath;
4444
}
4545

46-
public function requestDecisionFor(Request $request) : PolicyDecision
46+
public function requestInterruptDecisionFor(Request $request) : PolicyDecision
4747
{
4848
$jsonData = $this->httpClient->post(
4949
json_encode($request),

src/OpenConext/EngineBlockBundle/Pdp/PdpClientInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,5 @@
2222

2323
interface PdpClientInterface
2424
{
25-
public function requestDecisionFor(Request $request) : PolicyDecision;
25+
public function requestInterruptDecisionFor(Request $request) : PolicyDecision;
2626
}

src/OpenConext/EngineBlockBundle/Resources/config/services.yml

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,11 +207,32 @@ services:
207207
arguments:
208208
- base_uri: "%pdp.host%"
209209
auth: ["%pdp.username%", "%pdp.password%", "Basic"]
210-
# Verify CAs for certificates for prod, but not for other environments
211-
# as we are working with self signed signatures
210+
# Verify CAs for certificates for prod, but not for other environments
211+
# as we are working with self signed signatures
212212
verify: "@=service('kernel').getEnvironment() === 'prod'"
213213
timeout: "%http_client.timeout%"
214214

215+
engineblock.sbs.sbs_client:
216+
class: OpenConext\EngineBlockBundle\Sbs\SbsClient
217+
arguments:
218+
- "@engineblock.sbs.http_client"
219+
- "%sram.interrupt_location%"
220+
- "%sram.entitlements_location%"
221+
222+
engineblock.sbs.http_client:
223+
class: OpenConext\EngineBlock\Http\HttpClient
224+
arguments:
225+
- "@engineblock.sbs.guzzle_http_client"
226+
227+
engineblock.sbs.guzzle_http_client:
228+
class: GuzzleHttp\Client
229+
arguments:
230+
- base_uri: "%sram.authz_location%"
231+
options:
232+
headers:
233+
Authentication: "%sram.api_token%"
234+
timeout: "%http_client.timeout%"
235+
215236
engineblock.authentication.authentication_loop_guard:
216237
class: OpenConext\EngineBlockBundle\Authentication\AuthenticationLoopGuard
217238
arguments:
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?php
2+
3+
/**
4+
* Copyright 2025 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+
namespace OpenConext\EngineBlockBundle\Sbs;
20+
21+
use OpenConext\EngineBlock\Http\HttpClient;
22+
use OpenConext\EngineBlockBundle\Pdp\Dto\Request;
23+
use OpenConext\EngineBlockBundle\Pdp\Dto\Response;
24+
use OpenConext\EngineBlockBundle\Pdp\PdpClientInterface;
25+
use OpenConext\EngineBlockBundle\Pdp\PolicyDecision;
26+
27+
final class SbsClient implements PdpClientInterface
28+
{
29+
/**
30+
* @var HttpClient
31+
*/
32+
private $httpClient;
33+
/**
34+
* @var string
35+
*/
36+
private $interruptLocation;
37+
/**
38+
* @var string
39+
*/
40+
private $entitlementsLocation;
41+
42+
43+
public function __construct(
44+
HttpClient $httpClient,
45+
string $interruptLocation,
46+
string $entitlementsLocation
47+
) {
48+
$this->httpClient = $httpClient;
49+
$this->interruptLocation = $interruptLocation;
50+
$this->entitlementsLocation = $entitlementsLocation;
51+
}
52+
53+
public function requestInterruptDecisionFor(Request $request) : PolicyDecision
54+
{
55+
$jsonData = $this->httpClient->post(
56+
json_encode($request),
57+
$this->interruptLocation,
58+
[],
59+
[
60+
'Content-Type' => 'application/json',
61+
'Accept' => 'application/json',
62+
]
63+
);
64+
$response = Response::fromData($jsonData);
65+
66+
return PolicyDecision::fromResponse($response);
67+
}
68+
public function requestEntitlementsFor(Request $request) : PolicyDecision
69+
{
70+
$jsonData = $this->httpClient->post(
71+
json_encode($request),
72+
$this->entitlementsLocation,
73+
[],
74+
[
75+
'Content-Type' => 'application/json',
76+
'Accept' => 'application/json',
77+
]
78+
);
79+
$response = Response::fromData($jsonData);
80+
81+
return PolicyDecision::fromResponse($response);
82+
}
83+
}

0 commit comments

Comments
 (0)