Skip to content
This repository was archived by the owner on Sep 19, 2022. It is now read-only.

Commit 1c84441

Browse files
BaranekDDominik Frantisek Bucik
authored andcommitted
feat: Added possibility to add a service name on WAYF
1 parent 0cd38c7 commit 1c84441

File tree

7 files changed

+132
-1
lines changed

7 files changed

+132
-1
lines changed

config-templates/module_perun.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,9 @@
261261
'entityIds' => [],
262262
],
263263
],
264+
'display_sp_name' => false,
265+
// interface needed just in case of display_sp_name => true
266+
'interface' => 'rpc',
264267
],
265268

266269
'warning_test_sp_config' => [

dictionaries/disco.definition.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
{
22
"header": {
33
"en": "Choose how to log in",
4-
"cs": "Vyberte čím se chcete přihlásit"
4+
"cs": "Vyberte, čím se chcete přihlásit"
5+
},
6+
"header_display_service": {
7+
"en": "to the service",
8+
"cs": "ke službě"
59
},
610
"institutional_account": {
711
"en": "your institutional account",

lib/Adapter.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,12 @@ abstract public function getFacilityAttribute($facility, $attrName);
131131
*/
132132
abstract public function getFacilityByEntityId($spEntityId);
133133

134+
/**
135+
* @param string $clientId
136+
* @return Facility facility
137+
*/
138+
abstract public function getFacilityByClientId($clientId);
139+
134140
/**
135141
* @param string $spEntityId entity id of the sp
136142
* @param int $userId

lib/AdapterLdap.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,29 @@ public function getFacilityByEntityId($spEntityId)
307307
return $facility;
308308
}
309309

310+
public function getFacilityByClientId($clientId)
311+
{
312+
$ldapResult = $this->connector->searchForEntity(
313+
$this->ldapBase,
314+
'(&(objectClass=perunFacility)(OIDCClientID=' . $clientId . '))',
315+
[self::PERUN_FACILITY_ID, self::CN, self::DESCRIPTION]
316+
);
317+
318+
if (empty($ldapResult)) {
319+
Logger::warning('perun:AdapterLdap: No facility with clientId \'' . $clientId . '\' found.');
320+
return null;
321+
}
322+
323+
$facility = new Facility(
324+
$ldapResult[self::PERUN_FACILITY_ID][0],
325+
$ldapResult[self::CN][0],
326+
$ldapResult[self::DESCRIPTION][0],
327+
$clientId
328+
);
329+
330+
return $facility;
331+
}
332+
310333
public function getEntitylessAttribute($attrName)
311334
{
312335
return $this->fallbackAdapter->getEntitylessAttribute($attrName);

lib/AdapterRpc.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,26 @@ public function getFacilityByEntityId($spEntityId)
390390
return new Facility($perunAttr[0]['id'], $perunAttr[0]['name'], $perunAttr[0]['description'], $spEntityId);
391391
}
392392

393+
public function getFacilityByClientId($clientId)
394+
{
395+
$perunAttr = $this->connector->get('facilitiesManager', 'getFacilitiesByAttribute', [
396+
'attributeName' => 'urn:perun:facility:attribute-def:def:OIDCClientID',
397+
'attributeValue' => $clientId,
398+
]);
399+
400+
if (empty($perunAttr)) {
401+
Logger::warning('perun:AdapterRpc: No facility with clientId \'' . $clientId . '\' found.');
402+
return null;
403+
}
404+
405+
if (count($perunAttr) > 1) {
406+
Logger::warning('perun:AdapterRpc: There is more than one facility with clientId \'' . $clientId . '.');
407+
return null;
408+
}
409+
410+
return new Facility($perunAttr[0]['id'], $perunAttr[0]['name'], $perunAttr[0]['description'], $clientId);
411+
}
412+
393413
/**
394414
* Returns member by User and Vo
395415
*

lib/Disco.php

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use SimpleSAML\Auth\State;
88
use SimpleSAML\Configuration;
99
use SimpleSAML\Error\Exception;
10+
use SimpleSAML\Locale\Translate;
1011
use SimpleSAML\Logger;
1112
use SimpleSAML\Module;
1213
use SimpleSAML\Module\discopower\PowerIdPDisco;
@@ -42,6 +43,8 @@ class Disco extends PowerIdPDisco
4243

4344
public const DISABLE_WHITELISTING = 'disable_whitelisting';
4445

46+
public const DISPLAY_SP_NAME = 'display_sp_name';
47+
4548
# CONFIGURATION ENTRIES IDP BLOCKS
4649
public const IDP_BLOCKS = 'idp_blocks_config';
4750

@@ -121,6 +124,18 @@ class Disco extends PowerIdPDisco
121124

122125
public const SAML_SP_SSO = 'saml:sp:sso';
123126

127+
public const NAME = 'name';
128+
129+
# DISPLAY SERVICE NAME KEYS
130+
131+
public const CLIENT_ID_PREFIX = 'urn:cesnet:proxyidp:Client_id:';
132+
133+
public const INTERFACE = 'interface';
134+
135+
public const RPC = 'rpc';
136+
137+
public const SERVICE_NAME_ATTR = 'urn:perun:facility:attribute-def:def:serviceName';
138+
124139
private $originalsp;
125140

126141
private array $originalAuthnContextClassRef = [];
@@ -129,6 +144,12 @@ class Disco extends PowerIdPDisco
129144

130145
private $perunModuleConfiguration;
131146

147+
private $displaySpName;
148+
149+
private $spName;
150+
151+
private $adapter;
152+
132153
private $proxyIdpEntityId;
133154

134155
public function __construct(array $metadataSets, $instance)
@@ -156,12 +177,19 @@ public function __construct(array $metadataSets, $instance)
156177
if ($state !== null) {
157178
if (isset($state[self::SAML_REQUESTED_AUTHN_CONTEXT][self::AUTHN_CONTEXT_CLASS_REF])) {
158179
$this->originalAuthnContextClassRef = $state[self::SAML_REQUESTED_AUTHN_CONTEXT][self::AUTHN_CONTEXT_CLASS_REF];
180+
159181
$this->removeAuthContextClassRefWithPrefixes($state);
160182
if (isset($state['IdPMetadata']['entityid'])) {
161183
$this->proxyIdpEntityId = $state['IdPMetadata']['entityid'];
162184
}
163185
State::saveState($state, self::SAML_SP_SSO);
164186
}
187+
188+
$this->displaySpName = $this->wayfConfiguration->getBoolean(self::DISPLAY_SP_NAME, false);
189+
if ($this->displaySpName) {
190+
$this->fillSpName($state);
191+
}
192+
165193
$e = explode('=', $returnURL)[0];
166194
$newReturnURL = $e . '=' . urlencode($id);
167195
$_GET[self::RETURN] = $newReturnURL;
@@ -248,6 +276,8 @@ public function handleRequest()
248276
$t->data[self::AUTHN_CONTEXT_CLASS_REF] = $this->originalAuthnContextClassRef;
249277
$t->data[self::WARNING_ATTRIBUTES] = $warningAttributes;
250278
$t->data[self::WAYF] = $this->wayfConfiguration;
279+
$t->data[self::NAME] = $this->spName;
280+
$t->data[self::DISPLAY_SP_NAME] = $this->displaySpName;
251281
$t->show();
252282
}
253283

@@ -844,4 +874,43 @@ private static function constructSearchData($idpMetadata): string
844874

845875
return strtolower(str_replace('"', '', iconv('UTF-8', 'US-ASCII//TRANSLIT', $res)));
846876
}
877+
878+
private static function substrInArray($needle, array $haystack)
879+
{
880+
foreach ($haystack as $item) {
881+
if (strpos($item, $needle) !== false) {
882+
return $item;
883+
}
884+
}
885+
886+
return null;
887+
}
888+
889+
private function fillSpName($state)
890+
{
891+
$translate = new Translate(Configuration::getInstance());
892+
893+
$clientIdWithPrefix = self::substrInArray(self::CLIENT_ID_PREFIX, $this->originalAuthnContextClassRef);
894+
895+
if ($clientIdWithPrefix !== null) {
896+
$parts = explode(':', $clientIdWithPrefix);
897+
$clientId = end($parts);
898+
899+
$this->adapter = Adapter::getInstance($this->wayfConfiguration->getString(self::INTERFACE, self::RPC));
900+
901+
$facility = $this->adapter->getFacilityByClientId($clientId);
902+
903+
if ($facility !== null) {
904+
$spNameMap = $this->adapter->getFacilityAttribute($facility, self::SERVICE_NAME_ATTR);
905+
}
906+
907+
if (! empty($spNameMap)) {
908+
$this->spName = $translate->getPreferredTranslation($spNameMap);
909+
}
910+
} else {
911+
if (! empty($state[self::STATE_SP_METADATA][self::NAME])) {
912+
$this->spName = $translate->getPreferredTranslation($state[self::STATE_SP_METADATA][self::NAME]);
913+
}
914+
}
915+
}
847916
}

themes/perun/perun/disco-tpl.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
Module::getModuleUrl('perun/res/css/disco.css') . '" />';
3030

3131
$wayfConfig = $this->data[Disco::WAYF];
32+
$displaySpName = $this->data[Disco::DISPLAY_SP_NAME];
33+
$spName = $this->data[Disco::NAME];
3234

3335
$translateModule = $wayfConfig->getString(Disco::TRANSLATE_MODULE, 'disco');
3436
$addInstitutionConfig = $wayfConfig->getConfigItem(Disco::ADD_INSTITUTION, null);
@@ -55,6 +57,10 @@
5557
$this->data['header'] = $this->t('{perun:disco:add_institution}');
5658
} else {
5759
$this->data['header'] = $this->t('{perun:disco:header}');
60+
61+
if ($displaySpName && ! empty($spName)) {
62+
$this->data['header'] .= ' ' . $this->t('{perun:disco:header_display_service}') . ' ' . $spName;
63+
}
5864
}
5965

6066
$this->includeAtTemplateBase('includes/header.php');

0 commit comments

Comments
 (0)