Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • perun/perun-proxyidp/v1/simplesamlphp-module-perun
1 result
Show changes
Commits on Source (5)
## [9.0.7](https://gitlab.ics.muni.cz/perun-proxy-aai/simplesamlphp/simplesamlphp-module-perun/compare/v9.0.6...v9.0.7) (2022-12-15)
### Performance Improvements
* use getFacilitiesByAttributeWithAttributes ([5f0f625](https://gitlab.ics.muni.cz/perun-proxy-aai/simplesamlphp/simplesamlphp-module-perun/commit/5f0f625b33843f6749481c21755ec11d775e9cb8))
## [9.0.6](https://gitlab.ics.muni.cz/perun-proxy-aai/simplesamlphp/simplesamlphp-module-perun/compare/v9.0.5...v9.0.6) (2022-12-12) ## [9.0.6](https://gitlab.ics.muni.cz/perun-proxy-aai/simplesamlphp/simplesamlphp-module-perun/compare/v9.0.5...v9.0.6) (2022-12-12)
......
...@@ -297,6 +297,9 @@ $config = [ ...@@ -297,6 +297,9 @@ $config = [
], ],
], ],
/*
* Local database, currently used for challenges.
*/
'database' => [ 'database' => [
'store' => [ 'store' => [
'database.dsn' => 'dsn', 'database.dsn' => 'dsn',
...@@ -314,15 +317,5 @@ $config = [ ...@@ -314,15 +317,5 @@ $config = [
// PDO::MYSQL_ATTR_SSL_CAPATH => '/etc/ssl', // Path for the ssl ca dir // PDO::MYSQL_ATTR_SSL_CAPATH => '/etc/ssl', // Path for the ssl ca dir
// ], // ],
], ],
/*
* Fill the table name for whiteList
*/
'whiteListTableName' => 'whiteList',
/*
* Fill the table name for greyList
*/
'greyListTableName' => 'greyList',
], ],
]; ];
<?php
/**
* This is example configuration for connection to database with whitelist/greylist Copy this file to default config
* directory and edit the properties.
*/
declare(strict_types=1);
$config = [
/*
* Fill the serverName
*/
'serverName' => 'localhost',
/*
* If you want to use the default port, please comment this option
*/
'port' => 3306,
/*
* Fill the user name
*/
'userName' => 'proxy',
/*
* Fill the password
*/
'password' => 'passwd',
/*
* Fill the database name
*/
'databaseName' => 'Proxy',
/*
* Fill the table name for whiteList
*/
'whiteListTableName' => 'whiteList',
/*
* Fill the table name for greyList
*/
'greyListTableName' => 'greyList',
/*
* Fill true, if your SQL Server used encrypted connections. False if not
*/
'encryption' => true / false,
/*
* The path name to the certificate authority file.
*
* If your SQL Server used encrypted connections, you must fill this option.
*/
'ssl_ca' => '/example/ca.pem',
/*
* The path name to the certificate file.
*
* If your SQL Server used encrypted connections, you must fill this option.
*/
'ssl_cert_path' => '/example/cert.pem',
/*
* The path name to the key file.
*
* If your SQL Server used encrypted connections, you must fill this option.
*/
'ssl_key_path' => '/example/key.pem',
/*
* The pathname to a directory that contains trusted SSL CA certificates in PEM format.
*
* If your SQL Server used encrypted connections, you must fill this option.
*/
'ssl_ca_path' => '/etc/ssl',
];
...@@ -824,6 +824,26 @@ class AdapterRpc extends Adapter ...@@ -824,6 +824,26 @@ class AdapterRpc extends Adapter
return $this->connector->post('facilitiesManager', 'createFacility', $facility); return $this->connector->post('facilitiesManager', 'createFacility', $facility);
} }
public function getFacilitiesByAttributeWithAttributes($attributeName, $attributeValue, $attrNames)
{
$facilitiesWithAttributes = $this->connector->post(
'facilitiesManager',
'getFacilitiesByAttributeWithAttributes',
['attributeName' => $attributeName, 'attributeValue' => $attributeValue, 'attrNames' => $attrNames]
);
$attrNamesMap = AttributeUtils::getRpcAttrNames($attrNames);
foreach ($facilitiesWithAttributes as $facilityWithAttributes) {
$facilityWithAttributes['attributes'] = $this->getAttributes(
$facilityWithAttributes['attributes'],
$attrNamesMap
);
}
return $facilitiesWithAttributes;
}
private function getAttributes($perunAttrs, $attrNamesMap) private function getAttributes($perunAttrs, $attrNamesMap)
{ {
$attributes = []; $attributes = [];
......
...@@ -19,7 +19,7 @@ use SimpleSAML\Utils\HTTP; ...@@ -19,7 +19,7 @@ use SimpleSAML\Utils\HTTP;
* *
* This module extends the DiscoPower IdP disco handler, so it needs to be avaliable and enabled and configured. * This module extends the DiscoPower IdP disco handler, so it needs to be avaliable and enabled and configured.
* *
* It adds functionality of whitelisting and greylisting IdPs. for security reasons for blacklisting please manipulate * It adds functionality of greylisting IdPs per SP. for security reasons for blacklisting please manipulate
* directly with metadata. In case of manual idps comment them out or in case of automated metadata fetching configure * directly with metadata. In case of manual idps comment them out or in case of automated metadata fetching configure
* blacklist in config-metarefresh.php * blacklist in config-metarefresh.php
*/ */
...@@ -49,8 +49,6 @@ class Disco extends PowerIdPDisco ...@@ -49,8 +49,6 @@ class Disco extends PowerIdPDisco
public const REMOVE_AUTHN_CONTEXT_CLASS_PREFIXES = 'remove_authn_context_class_ref_prefixes'; public const REMOVE_AUTHN_CONTEXT_CLASS_PREFIXES = 'remove_authn_context_class_ref_prefixes';
public const DISABLE_WHITELISTING = 'disable_whitelisting';
public const DISPLAY_SP = 'display_sp_name'; public const DISPLAY_SP = 'display_sp_name';
public const SKIP_PREVIOUS_SELECTION = 'skip_previous_selection_services'; public const SKIP_PREVIOUS_SELECTION = 'skip_previous_selection_services';
...@@ -109,12 +107,6 @@ class Disco extends PowerIdPDisco ...@@ -109,12 +107,6 @@ class Disco extends PowerIdPDisco
public const METADATA_ADD_INSTITUTION_APP = 'disco.addInstitutionApp'; public const METADATA_ADD_INSTITUTION_APP = 'disco.addInstitutionApp';
public const IDP_ENTITY_ATTRIBUTES = 'EntityAttributes';
public const IDP_COCO = 'CoCo';
public const IDP_RAS = 'RaS';
public const SP_GREYLIST = 'greylist'; public const SP_GREYLIST = 'greylist';
public const IDP_ENTITY_ID = 'entityid'; public const IDP_ENTITY_ID = 'entityid';
...@@ -322,8 +314,10 @@ class Disco extends PowerIdPDisco ...@@ -322,8 +314,10 @@ class Disco extends PowerIdPDisco
} }
/** /**
* Filter out IdP which: 1. are not in SAML2 Scoping attribute list (SAML2 feature) 2. are not whitelisted (if * Filter out IdP which:
* whitelisting is allowed) 3. are greylisted. * 1. are not in SAML2 Scoping attribute list (SAML2 feature)
* 2. do not support research and scholarship
* 3. do not support code of conduct.
* *
* @param array $list a map of entities to filter * @param array $list a map of entities to filter
* *
...@@ -331,19 +325,9 @@ class Disco extends PowerIdPDisco ...@@ -331,19 +325,9 @@ class Disco extends PowerIdPDisco
*/ */
public static function doFilter( public static function doFilter(
array $list, array $list,
bool $disableWhitelisting = false,
array $scopedIdPList = [] array $scopedIdPList = []
): array { ): array {
$service = IdpListsService::getInstance(); return self::scoping($list, $scopedIdPList);
$whitelist = $service->getWhitelistEntityIds();
$greylist = $service->getGreylistEntityIds();
$list = self::scoping($list, $scopedIdPList);
if (!$disableWhitelisting) {
$list = self::whitelisting($list, $whitelist);
}
return self::greylisting($list, $greylist);
} }
/** /**
...@@ -553,7 +537,6 @@ class Disco extends PowerIdPDisco ...@@ -553,7 +537,6 @@ class Disco extends PowerIdPDisco
public static function showInlineSearch( public static function showInlineSearch(
DiscoTemplate $t, DiscoTemplate $t,
Configuration $blockConfig, Configuration $blockConfig,
bool $disableWhitelisting,
Configuration $addInstitution = null Configuration $addInstitution = null
): string { ): string {
$result = ''; $result = '';
...@@ -603,11 +586,7 @@ class Disco extends PowerIdPDisco ...@@ -603,11 +586,7 @@ class Disco extends PowerIdPDisco
$result .= ' </div>' . PHP_EOL; $result .= ' </div>' . PHP_EOL;
// NO ENTRIES BLOCK // NO ENTRIES BLOCK
$result .= ' <div id="no-entries" class="no-idp-found alert alert-info entries-warning-block">' . PHP_EOL; $result .= ' <div id="no-entries" class="no-idp-found alert alert-info entries-warning-block">' . PHP_EOL;
if ($disableWhitelisting && $addInstitutionEmail !== null) { if ($isAddInstitutionApp && $addInstitutionEmail !== null) {
$result .= ' ' . $t->t('{perun:disco:cannot_find_institution_disabled_whitelisting}') .
' <a href="mailto:' . $addInstitutionEmail . '?subject=Request%20for%20adding%20new%20IdP">' .
$addInstitutionEmail . '</a>' . PHP_EOL;
} elseif ($isAddInstitutionApp && $addInstitutionEmail !== null) {
$result .= ' ' . $t->t('{perun:disco:add_institution_no_entries_contact_us}') . $result .= ' ' . $t->t('{perun:disco:add_institution_no_entries_contact_us}') .
' <a href="mailto:' . $addInstitutionEmail . '?subject=Request%20for%20adding%20new%20IdP">' . ' <a href="mailto:' . $addInstitutionEmail . '?subject=Request%20for%20adding%20new%20IdP">' .
$addInstitutionEmail . '</a>' . PHP_EOL; $addInstitutionEmail . '</a>' . PHP_EOL;
...@@ -653,39 +632,13 @@ class Disco extends PowerIdPDisco ...@@ -653,39 +632,13 @@ class Disco extends PowerIdPDisco
*/ */
protected function filterList($list): array protected function filterList($list): array
{ {
$disableWhitelisting = $this->wayfConfiguration->getBoolean(self::DISABLE_WHITELISTING, false);
if ( if (
!isset($this->originalsp[self::METADATA_DO_NOT_FILTER_IDPS]) !isset($this->originalsp[self::METADATA_DO_NOT_FILTER_IDPS])
|| !$this->originalsp[self::METADATA_DO_NOT_FILTER_IDPS] || !$this->originalsp[self::METADATA_DO_NOT_FILTER_IDPS]
) { ) {
$list = parent::filterList($list); $list = parent::filterList($list);
$list = self::doFilter($list, $disableWhitelisting, $this->scopedIDPList); $list = self::doFilter($list, $this->scopedIDPList);
$list = $this->greylistingPerSP($list, $this->originalsp); $list = $this->hideFromDiscovery($list, $this->originalsp);
}
if (empty($list)) {
throw new Exception('All IdPs has been filtered out. And no one left.');
}
return $list;
}
/**
* Filter a list of entities for addInstitution app according to if entityID is whitelisted or not.
*
* @param array $list a map of entities to filter
*
* @return array the list in $list after filtering entities
*/
protected function filterAddInstitutionList(array $list): array
{
$service = IdpListsService::getInstance();
$whitelist = $service->getWhitelistEntityIds();
foreach ($list as $entityId => $idp) {
if (in_array($entityId, $whitelist, true)) {
unset($list[$entityId]);
}
} }
if (empty($list)) { if (empty($list)) {
...@@ -715,72 +668,7 @@ class Disco extends PowerIdPDisco ...@@ -715,72 +668,7 @@ class Disco extends PowerIdPDisco
return $list; return $list;
} }
/** protected function hideFromDiscovery($list, $sp): array
* Filter out IdP which: 1. are not whitelisted 2. are not supported research and scholarship 3. are not supported
* code of conduct.
*
* @param array $list a map of entities to filter
* @param array $whitelist The list of whitelisted IdPs
*
* @return array the list in $list after filtering entities
*/
protected static function whitelisting(array $list, array $whitelist): array
{
foreach ($list as $entityId => $idp) {
$unset = true;
if (in_array($entityId, $whitelist, true)) {
$unset = false;
}
if (isset($idp[self::IDP_ENTITY_ATTRIBUTES]['http://macedir.org/entity-category-support'])) {
$entityCategorySupport
= $idp[self::IDP_ENTITY_ATTRIBUTES]['http://macedir.org/entity-category-support'];
if (
in_array('http://refeds.org/category/research-and-scholarship', $entityCategorySupport, true)
) {
$unset = false;
}
if (
in_array('http://www.geant.net/uri/dataprotection-code-of-conduct/v1', $entityCategorySupport, true)
) {
$unset = false;
}
}
if (isset($idp[self::IDP_COCO]) and $idp[self::IDP_COCO] === true) {
$unset = false;
}
if (isset($idp[self::IDP_RAS]) and $idp[self::IDP_RAS] === true) {
$unset = false;
}
if ($unset === true) {
unset($list[$entityId]);
}
}
return $list;
}
/**
* Filter out IdP which are greylisted.
*
* @param array $list a map of entities to filter
* @param array $greylist The list of greylisted IdPs
*
* @return array the list in $list after filtering entities
*/
protected static function greylisting(array $list, array $greylist): array
{
foreach ($list as $entityId => $idp) {
if (in_array($entityId, $greylist, true)) {
unset($list[$entityId]);
}
}
return $list;
}
protected function greylistingPerSP($list, $sp): array
{ {
foreach ($list as $entityId => $idp) { foreach ($list as $entityId => $idp) {
if ( if (
......
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\perun;
use SimpleSAML\Configuration;
use SimpleSAML\Error\Exception;
/**
* This interface provides abstraction of manipulation with lists of IdPs saved and managed by Proxy IdP. e.g. Whitelist
* or greylist. It should abstract from a form how the data is stored.
*
* IdP here is represented by an associative array with keys: entityid, timestamp and optionally reason. when the IdP
* was added or lately modified.
*
* Note that implementation should be thread/concurrency safe.
*/
abstract class IdpListsService
{
public const CONFIG_FILE_NAME = 'module_perun.php';
public const PROPNAME_IDP_LIST_SERVICE_TYPE = 'idpListServiceType';
public const CSV = 'csv';
public const DB = 'db';
/**
* Function returns the instance of sspmod_perun_IdPListsService by configuration Default is CSV.
*
* @return IdpListsServiceCsv|IdpListsServiceDB
*/
public static function getInstance()
{
$configuration = Configuration::getConfig(self::CONFIG_FILE_NAME);
$idpListServiceType = $configuration->getString(self::PROPNAME_IDP_LIST_SERVICE_TYPE, self::CSV);
if ($idpListServiceType === self::CSV) {
return new IdpListsServiceCsv();
}
if ($idpListServiceType === self::DB) {
return new IdpListsServiceDB();
}
throw new Exception('Unknown idpListService type. Hint: try ' . self::CSV . ' or ' . self::DB);
}
/**
* Function returns all whitelisted IdPs as array.
*
* @return array of all whitelisted IdPs, every IdP is represents as array
*/
abstract public function getWhitelist();
/**
* Function returns all greylisted IdPs as array.
*
* @return array of all greylisted IdPs, every IdP is represents as array
*/
abstract public function getGreylist();
/**
* Function returns all whitelisted entityIds as array.
*
* @return array of all whitelisted entityIds
*/
abstract public function getWhitelistEntityIds();
/**
* Function returns all greylisted entityIds as array.
*
* @return array of all greylisted entityIds
*/
abstract public function getGreylistEntityIds();
/**
* @param string $entityID
*
* @return bool true if whitelist contains given entityID, false otherwise
*/
abstract public function isWhitelisted($entityID);
/**
* @param string $entityID
*
* @return bool true if greylist contains given entityID, false otherwise
*/
abstract public function isGreylisted($entityID);
/**
* Function check if this entity is already whitelisted. If not, it will be added into whitelist and if this
* entityId is greylisted, it will be removed from greylist.
*
* @param string $entityID
* @param string|null $reason
*/
abstract public function whitelistIdp($entityID, $reason = null);
}
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\perun;
use SimpleSAML\Error\Exception;
use SimpleSAML\Utils\Config;
/**
* Implementation of IdpListsService using in simple csv files. first column is timestamp, second entityid and third
* reason.
*/
class IdpListsServiceCsv extends IdpListsService
{
private $whitelistFile;
private $greylistFile;
public function __construct()
{
$dir = Config::getConfigDir();
$this->whitelistFile = $dir . DIRECTORY_SEPARATOR . 'idplists' . DIRECTORY_SEPARATOR . 'whitelist.csv';
$this->greylistFile = $dir . DIRECTORY_SEPARATOR . 'idplists' . DIRECTORY_SEPARATOR . 'greylist.csv';
}
public function isWhitelisted($entityID)
{
return in_array($this->getWhitelistEntityIds(), $entityID, true);
}
public function isGreylisted($entityID)
{
return in_array($this->getGreylistEntityIds(), $entityID, true);
}
public function whitelistIdp($entityID, $reason = null)
{
$wf = fopen($this->whitelistFile, 'a');
if (flock($wf, LOCK_EX)) {
$gf = fopen($this->greylistFile, 'c+');
if (flock($gf, LOCK_EX)) {
$idp = [date('Y-m-d H:i:s'), $entityID, $reason];
fputcsv($wf, $idp);
$greylist = [];
while (($idp = $this->arrayToIdp(fgetcsv($gf))) !== false) {
if ($idp['entityid'] !== $entityID) {
$greylist[] = $idp;
}
}
ftruncate($gf, 0);
rewind($gf);
foreach ($greylist as $idp) {
fputcsv($gf, array_values($idp));
}
fflush($wf);
fflush($gf);
// TODO: Possible deadlock? Is this correct order of unlocking?
flock($gf, LOCK_UN);
flock($wf, LOCK_UN);
} else {
throw new Exception(
'IdpListsServiceCsv - unable to get file lock. Hint: '
. 'Try to create folder config/idplists and add write rights.'
);
}
} else {
throw new Exception(
'IdpListsServiceCsv - unable to get file lock. Hint: '
. 'Try to create folder config/idplists and add write rights.'
);
}
fclose($wf);
fclose($gf);
}
public function getWhitelist()
{
return $this->listToArray('whitelist', true);
}
public function getGreylist()
{
return $this->listToArray('greyList', true);
}
public function getWhitelistEntityIds()
{
return $this->listToArray('whitelist', false);
}
public function getGreylistEntityIds()
{
return $this->listToArray('greyList', false);
}
/**
* @param string $listName "whitelist" or "greylist"
* @param bool $all
*
* @return array of IdPS if $all is true or arrayOf entityIds
*/
public function listToArray($listName, $all)
{
if ($listName === 'whitelist') {
$list = $this->whitelistFile;
} else {
$list = $this->greylistFile;
}
$resultList = [];
if (!file_exists($list)) {
return $resultList;
}
$f = fopen($list, 'r');
if (flock($f, LOCK_SH)) {
while (($idp = $this->arrayToIdp(fgetcsv($f))) !== false) {
if ($all) {
if (!in_array($idp, $resultList, true)) {
array_push($resultList, $idp);
}
} elseif (!in_array($idp['entityid'], $resultList, true)) {
array_push($resultList, $idp['entityid']);
}
}
fflush($f);
flock($f, LOCK_UN);
} else {
throw new Exception(
'IdpListsServiceCsv - unable to get file lock. Hint: '
. 'Try to create folder config/idplists and add write rights.'
);
}
fclose($f);
return $resultList;
}
private function arrayToIdp($csv)
{
if (!is_array($csv)) {
return false;
}
$idp = [];
$idp['timestamp'] = $csv[0];
$idp['entityid'] = $csv[1];
$idp['reason'] = $csv[2];
return $idp;
}
}
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\perun;
use SimpleSAML\Module\perun\databaseCommand\IdpListsServiceDbCmd;
/**
* Implementation of IdpListsService using DB.
*/
class IdpListsServiceDB extends IdpListsService
{
private $idpListServiceDbCmd;
public function __construct()
{
$this->idpListServiceDbCmd = new IdpListsServiceDbCmd();
}
public function getWhitelist()
{
return $this->idpListServiceDbCmd->getAllIdps($this->idpListServiceDbCmd::WHITELIST);
}
public function getGreylist()
{
return $this->idpListServiceDbCmd->getAllIdps($this->idpListServiceDbCmd::GREYLIST);
}
public function getWhitelistEntityIds()
{
return $this->idpListServiceDbCmd->getAllEntityIds($this->idpListServiceDbCmd::WHITELIST);
}
public function getGreylistEntityIds()
{
return $this->idpListServiceDbCmd->getAllEntityIds($this->idpListServiceDbCmd::GREYLIST);
}
public function isWhitelisted($entityID)
{
return in_array($entityID, $this->getWhitelistEntityIds(), true);
}
public function isGreylisted($entityID)
{
return in_array($entityID, $this->getGreylistEntityIds(), true);
}
public function whitelistIdp($entityID, $reason = null)
{
if (!$this->isWhitelisted($entityID)) {
$this->idpListServiceDbCmd->insertToList($this->idpListServiceDbCmd::WHITELIST, $entityID, $reason);
if ($this->isGreylisted($entityID)) {
$this->idpListServiceDbCmd->deleteFromList($this->idpListServiceDbCmd::GREYLIST, $entityID);
}
}
}
}
...@@ -172,42 +172,36 @@ class MetadataFromPerun ...@@ -172,42 +172,36 @@ class MetadataFromPerun
return $allAttrNames; return $allAttrNames;
} }
/**
* Get all facilities with proxyIdentifiers.
*/
private function getFacilities()
{
$perunProxyIdentifierAttr = $this->conf->getString(self::PERUN_PROXY_IDENTIFIER_ATTR_NAME);
$perunProxyIdentifierRpcAttrName = AttributeUtils::getRpcAttrName($perunProxyIdentifierAttr);
$proxyIdentifier = $this->conf->getString(self::PROXY_IDENTIFIER);
$attributeDefinition = [
$perunProxyIdentifierRpcAttrName => $proxyIdentifier,
];
return $this->rpcAdapter->searchFacilitiesByAttributeValue($attributeDefinition);
}
/*+ /*+
* Get facilities with attributes. * Get facilities with attributes.
*/ */
private function getFacilitiesWithAttributes() private function getFacilitiesWithAttributes()
{ {
$perunProxyIdentifierAttr = $this->conf->getString(self::PERUN_PROXY_IDENTIFIER_ATTR_NAME);
$perunProxyIdentifierRpcAttrName = AttributeUtils::getRpcAttrName($perunProxyIdentifierAttr);
$allAttrNames = $this->getAllAttributeNames(); $allAttrNames = $this->getAllAttributeNames();
$facilitiesWithAttributes = [];
foreach ($this->getFacilities() as $facility) { $facilitiesWithAttributes = $this->rpcAdapter->getFacilitiesByAttributeWithAttributes(
$attributes = $this->rpcAdapter->getFacilityAttributes($facility, $allAttrNames); $perunProxyIdentifierRpcAttrName,
$this->conf->getString(self::PROXY_IDENTIFIER),
$allAttrNames
);
$facilitiesWithAttributesRes = [];
foreach ($facilitiesWithAttributes as $facilityWithAttributes) {
$attributes = $facilityWithAttributes['attributes'];
$facilityAttributes = []; $facilityAttributes = [];
foreach ($attributes as $attribute) { foreach ($attributes as $attribute) {
$facilityAttributes[$attribute['name']] = $attribute; $facilityAttributes[$attribute['name']] = $attribute;
} }
if (!empty($facilityAttributes[$this->perunProxyEntityIDAttr]['value'])) { if (!empty($facilityAttributes[$this->perunProxyEntityIDAttr]['value'])) {
$facilitiesWithAttributes[$facility->getId()] = [ $facilitiesWithAttributesRes[$facilityWithAttributes['facility']['id']] = [
'facility' => $facility, 'facility' => $facilityWithAttributes['facility'],
self::FACILITY_ATTRIBUTES => $facilityAttributes, self::FACILITY_ATTRIBUTES => $facilityAttributes,
]; ];
} }
} }
return $facilitiesWithAttributes; return $facilitiesWithAttributesRes;
} }
} }
...@@ -14,18 +14,10 @@ class DatabaseConfig ...@@ -14,18 +14,10 @@ class DatabaseConfig
private const STORE = 'store'; private const STORE = 'store';
private const WHITELIST_TABLE_NAME = 'whiteListTableName';
private const GREYLIST_TABLE_NAME = 'greyListTableName';
private $config; private $config;
private $store; private $store;
private $whitelistTableName;
private $greyListTableName;
private static $instance; private static $instance;
private function __construct() private function __construct()
...@@ -34,9 +26,6 @@ class DatabaseConfig ...@@ -34,9 +26,6 @@ class DatabaseConfig
$this->config = $configuration->getConfigItem(self::DATABASE); $this->config = $configuration->getConfigItem(self::DATABASE);
$this->store = $this->config->getConfigItem(self::STORE, null); $this->store = $this->config->getConfigItem(self::STORE, null);
$this->whitelistTableName = $this->config->getString(self::WHITELIST_TABLE_NAME, null);
$this->greyListTableName = $this->config->getString(self::GREYLIST_TABLE_NAME, null);
} }
public static function getInstance() public static function getInstance()
...@@ -52,14 +41,4 @@ class DatabaseConfig ...@@ -52,14 +41,4 @@ class DatabaseConfig
{ {
return $this->store; return $this->store;
} }
public function getWhitelistTableName()
{
return $this->whitelistTableName;
}
public function getGreyListTableName()
{
return $this->greyListTableName;
}
} }
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\perun\databaseCommand;
use PDO;
use SimpleSAML\Logger;
class IdpListsServiceDbCmd extends DatabaseCommand
{
public const WHITELIST = 'whiteList';
public const GREYLIST = 'greyList';
public const ENTITY_ID_COLUMN = 'entityId';
public const REASON_COLUMN = 'reason';
public const LOG_PREFIX = 'perun:IdpListsServiceDbCmd: ';
public function __construct()
{
parent::__construct();
}
/**
* Function returns array of all IdPs in whitelist/greylist.
*
* @param string $tableName 'whitelist' or 'greylist'
*
* @return array of all IdPs, every IdP is represents as array
*/
public function getAllIdps($tableName)
{
$whiteListTableName = $this->config->getWhitelistTableName();
$greyListTableName = $this->config->getGreyListTableName();
$table = null;
if ($tableName === self::WHITELIST) {
$table = $whiteListTableName;
} elseif ($tableName === self::GREYLIST) {
$table = $greyListTableName;
}
$query = 'SELECT * FROM ' . $table;
$params = [];
return $this->read($query, $params)
->fetchAll(PDO::FETCH_ASSOC)
;
}
/**
* Function returns array of all entityId in whitelist/greylist.
*
* @param string $tableName 'whitelist' or 'greylist'
*
* @return array of entityIds
*/
public function getAllEntityIds($tableName)
{
$whiteListTableName = $this->config->getWhitelistTableName();
$greyListTableName = $this->config->getGreyListTableName();
$table = null;
if ($tableName === self::WHITELIST) {
$table = $whiteListTableName;
} elseif ($tableName === self::GREYLIST) {
$table = $greyListTableName;
}
$query = 'SELECT ' . self::ENTITY_ID_COLUMN . ' FROM ' . $table;
$params = [];
return $this->read($query, $params)
->fetchAll(PDO::FETCH_COLUMN)
;
}
/**
* Function inserts the line into table with $tableName.
*
* @param string $tableName 'whitelist' or 'greylist'
* @param string $entityId
* @param string $reason
*/
public function insertToList($tableName, $entityId, $reason)
{
$whiteListTableName = $this->config->getWhitelistTableName();
$greyListTableName = $this->config->getGreyListTableName();
$table = null;
if ($tableName === self::WHITELIST) {
$table = $whiteListTableName;
} elseif ($tableName === self::GREYLIST) {
$table = $greyListTableName;
}
$query = 'INSERT INTO ' . $table .
' (' . self::ENTITY_ID_COLUMN . ', ' . self::REASON_COLUMN . ') VALUES' .
' (:' . self::ENTITY_ID_COLUMN . ', :' . self::REASON_COLUMN . ')';
$params = [
self::ENTITY_ID_COLUMN => $entityId,
self::REASON_COLUMN => $reason,
];
if (!$this->write($query, $params)) {
Logger::error(self::LOG_PREFIX . 'Error while inserting into the database.');
}
}
/**
* Function deletes the line from table with $tableName and $entityID.
*
* @param string $tableName 'whitelist' or 'greylist'
* @param string $entityId
*/
public function deleteFromList($tableName, $entityId)
{
$whiteListTableName = $this->config->getWhitelistTableName();
$greyListTableName = $this->config->getGreyListTableName();
$table = null;
if ($tableName === self::WHITELIST) {
$table = $whiteListTableName;
} elseif ($tableName === self::GREYLIST) {
$table = $greyListTableName;
}
$query = 'DELETE FROM ' . $table . ' WHERE ' . self::ENTITY_ID_COLUMN . ' = :' . self::ENTITY_ID_COLUMN;
$params = [
self::ENTITY_ID_COLUMN => $entityId,
];
if (!$this->write($query, $params)) {
Logger::error(self::LOG_PREFIX . 'Error while deleting from the database.');
}
}
}
...@@ -86,7 +86,6 @@ if ($this->isAddInstitutionApp()) { ...@@ -86,7 +86,6 @@ if ($this->isAddInstitutionApp()) {
echo Disco::showInlineSearch( echo Disco::showInlineSearch(
$this, $this,
$blockConfig, $blockConfig,
$wayfConfig->getBoolean(Disco::DISABLE_WHITELISTING, false),
$addInstitutionConfig $addInstitutionConfig
) . PHP_EOL; ) . PHP_EOL;
} }
...@@ -129,7 +128,6 @@ if ($this->isAddInstitutionApp()) { ...@@ -129,7 +128,6 @@ if ($this->isAddInstitutionApp()) {
echo Disco::showInlineSearch( echo Disco::showInlineSearch(
$this, $this,
$blockConfig, $blockConfig,
$wayfConfig->getBoolean(Disco::DISABLE_WHITELISTING, false),
$addInstitutionConfig $addInstitutionConfig
) . PHP_EOL; ) . PHP_EOL;
} elseif (strtolower($type) === Disco::IDP_BLOCK_TYPE_TAGGED) { } elseif (strtolower($type) === Disco::IDP_BLOCK_TYPE_TAGGED) {
......
...@@ -74,12 +74,7 @@ $perunShowOnServiceListAttr ...@@ -74,12 +74,7 @@ $perunShowOnServiceListAttr
= $conf->getString(PERUN_SHOW_ON_SERVICE_LIST_ATTR_NAME, null); = $conf->getString(PERUN_SHOW_ON_SERVICE_LIST_ATTR_NAME, null);
$showProtocol = $conf->getBoolean(PERUN_SHOW_PROTOCOL, true); $showProtocol = $conf->getBoolean(PERUN_SHOW_PROTOCOL, true);
$rpcAdapter = new AdapterRpc(); $rpcAdapter = new AdapterRpc();
$attributeDefinition = [];
$attributeDefinition[$perunProxyIdentifierAttr] = $proxyIdentifier;
$facilities
= $rpcAdapter->searchFacilitiesByAttributeValue($attributeDefinition);
$attrNames = []; $attrNames = [];
...@@ -105,16 +100,21 @@ $samlServices = []; ...@@ -105,16 +100,21 @@ $samlServices = [];
$oidcServices = []; $oidcServices = [];
$samlTestServicesCount = 0; $samlTestServicesCount = 0;
$oidcTestServicesCount = 0; $oidcTestServicesCount = 0;
foreach ($facilities as $facility) {
$attributes = $rpcAdapter->getFacilityAttributes($facility, $attrNames);
$facilitiesWithAttributes = $rpcAdapter->getFacilitiesByAttributeWithAttributes(
$perunProxyIdentifierAttr,
$proxyIdentifier,
$attrNames
);
foreach ($facilitiesWithAttributes as $facilityWithAttributes) {
$facilityAttributes = []; $facilityAttributes = [];
foreach ($attributes as $attribute) { foreach ($facilityWithAttributes['attributes'] as $attribute) {
$facilityAttributes[$attribute['name']] = $attribute; $facilityAttributes[$attribute['name']] = $attribute;
} }
if (!empty($facilityAttributes[$perunSaml2EntityIdAttr]['value'])) { if (!empty($facilityAttributes[$perunSaml2EntityIdAttr]['value'])) {
$samlServices[$facility->getId()] = [ $samlServices[$facilityWithAttributes['facility']['id']] = [
'facility' => $facility, 'facility' => $facilityWithAttributes['facility'],
'name' => $facilityAttributes[$perunServiceNameAttr], 'name' => $facilityAttributes[$perunServiceNameAttr],
'loginURL' => $facilityAttributes[$perunLoginURLAttr], 'loginURL' => $facilityAttributes[$perunLoginURLAttr],
'showOnServiceList' => $facilityAttributes[$perunShowOnServiceListAttr], 'showOnServiceList' => $facilityAttributes[$perunShowOnServiceListAttr],
...@@ -126,8 +126,8 @@ foreach ($facilities as $facility) { ...@@ -126,8 +126,8 @@ foreach ($facilities as $facility) {
} }
if ($showOIDCServices && !empty($facilityAttributes[$perunOidcClientIdAttr]['value'])) { if ($showOIDCServices && !empty($facilityAttributes[$perunOidcClientIdAttr]['value'])) {
$oidcServices[$facility->getId()] = [ $oidcServices[$facilityWithAttributes['facility']['id']] = [
'facility' => $facility, 'facility' => $facilityWithAttributes['facility'],
'name' => $facilityAttributes[$perunServiceNameAttr], 'name' => $facilityAttributes[$perunServiceNameAttr],
'loginURL' => $facilityAttributes[$perunLoginURLAttr], 'loginURL' => $facilityAttributes[$perunLoginURLAttr],
'showOnServiceList' => $facilityAttributes[$perunShowOnServiceListAttr], 'showOnServiceList' => $facilityAttributes[$perunShowOnServiceListAttr],
......
<?php
declare(strict_types=1);
use SimpleSAML\Error\Exception;
use SimpleSAML\Metadata\MetaDataStorageHandler;
use SimpleSAML\Module\perun\IdpListsService;
/*
* endpoint which whitelist given idp defined by entityID param. Optionally consumes and saves reason param.
*
* example call:
* https://login.example.org/proxy/module.php/perun/protected/whitelistIdp.php?entityId=hey&reason=Attribute%20check%20by%20user
*/
if (!isset($_REQUEST['entityId'])) {
sendError('parametr \'entityId\' is missing', 400);
}
$entityid = $_REQUEST['entityId'];
$reason = (isset($_REQUEST['reason']) ? $_REQUEST['reason'] : null);
$metadataHandler = MetaDataStorageHandler::getMetadataHandler();
$idpsMatadata = $metadataHandler->getList('saml20-idp-remote');
if (!array_key_exists($entityid, $idpsMatadata)) {
http_response_code(400);
header('Content-Type: application/json');
echo json_encode([
'result' => 'ERROR',
'msg' => 'unknown IdP with entityId \'' . $entityid . '\'. Metadata not found.',
]);
exit;
}
try {
//FIXME: Not thread safe!!!
$service = IdpListsService::getInstance();
if ($service->isWhitelisted($entityid)) {
if (!$service->isGreylisted($entityid)) {
header('Content-Type: application/json');
echo json_encode([
'result' => 'ALREADY_THERE',
'msg' => "IdP '{$entityid}' is already whitelisted.",
]);
exit;
}
}
$service->whitelistIdp($entityid, $reason);
header('Content-Type: application/json');
echo json_encode([
'result' => 'ADDED',
'msg' => "IdP '{$entityid}' was added to whitelist.",
]);
} catch (Exception $e) {
sendError($e->getMessage());
}
<?php
/**
* List all whitelisted IdPs.
*
* Returns list of service in format: IdP Name^IdP EnityID\n
*
* Author: Michal Prochazka <michalp@ics.muni.cz> Author: Ondrej Velisek <ondrejvelisek@gmail.com> Author: Pavel
* Vyskocil <vyskocilpavel@muni.cz>
*
* TODO: Use standardized format (JSON)
*/
declare(strict_types=1);
use SimpleSAML\Metadata\MetaDataStorageHandler;
use SimpleSAML\Module\perun\IdpListsService;
use SimpleSAML\Module\perun\Whitelisting;
$metadataHandler = MetaDataStorageHandler::getMetadataHandler();
$idpsMetadata = $metadataHandler->getList('saml20-idp-remote');
$service = IdpListsService::getInstance();
header('Content-Type: text/plain');
$delimiter = '^';
$idps = $service->getWhitelist();
foreach ($idps as $idp) {
$entityID = $idp['entityid'];
echo Whitelisting::getEntityName($idpsMetadata[$entityID]);
echo $delimiter;
echo $entityID;
echo "\n";
}