Skip to content
Snippets Groups Projects
Verified Commit 0042cc0b authored by Dominik Frantisek Bucik's avatar Dominik Frantisek Bucik
Browse files

feat: :guitar:LS AAI design

Refactored design to reflect migration into LS AAI

BREAKING CHANGE: dropped ELIXIR design, using LS design from now on.
parent 47fe980d
Branches
Tags
1 merge request!21feat: 🎸LS AAI design
Showing
with 1396 additions and 150 deletions
<?php
namespace SimpleSAML\Module\elixir;
class ConsentHelper
{
public function __construct()
{
}
const EU_EAA = [
'AT' => 'Austria',
'BE' => 'Belgium',
'BG' => 'Bulgaria',
'HR' => 'Croatia',
'CY' => 'Cyprus',
'CZ' => 'Czech Republic',
'DK' => 'Denmark',
'EE' => 'Estonia',
'FI' => 'Finland',
'FR' => 'France',
'DE' => 'Germany',
'EL' => 'Greece',
'HU' => 'Hungary',
'IE' => 'Ireland',
'IT' => 'Italy',
'LV' => 'Latvia',
'LT' => 'Lithuania',
'LU' => 'Luxembourg',
'MT' => 'Malta',
'NL' => 'Netherlands',
'PT' => 'Portugal',
'RO' => 'Romania',
'SK' => 'Slovakia',
'SI' => 'Slovenia',
'ES' => 'Spain',
'SE' => 'Sweden',
'NO' => 'Norway',
'IS' => 'Iceland',
'LI' => 'Liechtenstein',
'GB' => 'United Kingdom',
];
public static function getJurisdiction($dstMetadata): string
{
$countryCodes = json_decode(file_get_contents('http://country.io/names.json'), true);
$jurisdiction = empty($dstMetadata['jurisdiction']) ? '' : $dstMetadata['jurisdiction'];
if (empty($jurisdiction) || array_key_exists($jurisdiction, self::EU_EAA)) {
return '';
}
if ('INT' === $jurisdiction) {
return 'provided by an international organization.';
}
return 'in ' . $countryCodes[$jurisdiction];
}
public static function printUserAttributes(array $attributes, $getTranslator)
{
$newAttributes = [];
foreach ($attributes as $name => $value) {
if ($name === 'mail' || $name === 'displayname' || $name === 'givenName' || $name === 'sn') {
$newAttributes[$name] = $value;
}
}
ConsentHelper::printAttributes($newAttributes, $getTranslator);
}
public static function printTechnicalAttributes(array $attributes, $getTranslator)
{
$newAttributes = [];
foreach ($attributes as $name => $value) {
if ($name !== 'mail' && $name !== 'displayname' && $name !== 'givenName' && $name !== 'sn') {
$newAttributes[$name] = $value;
}
}
ConsentHelper::printAttributes($newAttributes, $getTranslator);
}
public static function printAttributes($attributes, $translator)
{
echo '<div class="card-body">' . PHP_EOL;
foreach ($attributes as $name => $value) {
$name = $translator->getAttributeTranslation($name);
echo ' <div class="attribute-row">' . PHP_EOL;
echo ' <div class="attribute">' . PHP_EOL;
echo ' <div class="attribute-name">' . PHP_EOL;
echo '<p>' . htmlspecialchars($name) . '</p>' . PHP_EOL;
echo ' </div>' . PHP_EOL;
echo ' </div>' . PHP_EOL;
echo ' <div class="attribute-values">' . PHP_EOL;
if (count($value) > 0) {
foreach ($value as $subValue) {
echo '<div class="attribute-choose">' . PHP_EOL;
echo ' <div class="attribute-value">' . PHP_EOL;
echo ' <code>' . htmlspecialchars($subValue) . '</code>';
echo ' </div>' . PHP_EOL;
echo '</div>' . PHP_EOL;
}
} else {
echo '<div class="attribute-choose">' . PHP_EOL;
echo ' <div class="attribute-value">' . PHP_EOL;
echo ' <code>-</code>';
echo ' </div>' . PHP_EOL;
echo '</div>' . PHP_EOL;
}
echo ' </div>' . PHP_EOL;
echo ' </div>' . PHP_EOL;
}
echo '</div>' . PHP_EOL;
}
public static function printJurisdictionWarning(string $parsedJurisdiction, $spPrivacyPolicy)
{
if (!empty($parsedJurisdiction)) {
echo '<div class="alert alert-danger" role="alert">' . PHP_EOL;
echo ' <h6>This service is ' . $parsedJurisdiction . '</h6>' . PHP_EOL;
echo ' <p>In order to access the requested services, the Life Science Login needs to transfer your personal data to a country outside EU/EEA. We cannot guarantee that this country offers an adequately high level of personal data protection as EU/EEA countries.</p>' . PHP_EOL;
if (false !== $spPrivacyPolicy) {
echo 'Please, read the <a target="_blank" href="' .$spPrivacyPolicy . '">Privacy Policy</a> of the service provider to learn more about its commitments to protect your data.' . PHP_EOL;
}
echo ' <div class="form-check">' . PHP_EOL;
echo ' <input class="form-check-input" type="checkbox" name="transfer" id="transfer" data-np-checked="1">' . PHP_EOL;
echo ' <label class="form-check-label" for="transfer">To continue, consent to the transfer of your personal data.</label>' . PHP_EOL;
echo ' </div>' . PHP_EOL;
echo '</div>' . PHP_EOL;
}
}
public static function printPrivacyPolicyWarning($spPrivacyPolicy)
{
if (false === $spPrivacyPolicy) {
echo '<div class="alert alert-warning" role="alert">' . PHP_EOL;
echo ' <h6>This service is missing a Privacy Policy document.</h6>' . PHP_EOL;
echo '</div>' . PHP_EOL;
}
}
public static function printAcceptedTosWarning($dstMetadata)
{
if (empty($dstMetadata['accepted_tos'])) {
echo '<div class="alert alert-warning" role="alert">' . PHP_EOL;
echo ' <h6>This service has not declared compliance with the <a target="_blank" href="https://lifescience-ri.eu/aai/terms-of-use">Terms of Use for service providers</a> that govern the service\'s use of Life Science Login.</h6>' . PHP_EOL;
echo '</div>' . PHP_EOL;
}
}
public static function getDestinationName($templateData, $t)
{
if (isset($templateData['dstMetadata']['UIInfo']['DisplayName'])) {
$dstName = $templateData['dstMetadata']['UIInfo']['DisplayName'];
} elseif (array_key_exists('name', $templateData['dstMetadata'])) {
$dstName = $templateData['dstMetadata']['name'];
} elseif (array_key_exists('OrganizationDisplayName', $templateData['dstMetadata'])) {
$dstName = $templateData['dstMetadata']['OrganizationDisplayName'];
} else {
$dstName = $templateData['dstMetadata']['entityid'];
}
if (is_array($dstName)) {
$dstName = $t->t($dstName);
}
return htmlspecialchars($dstName);
}
}
\ No newline at end of file
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\elixir;
use SimpleSAML\Auth\State;
use SimpleSAML\Configuration;
use SimpleSAML\Logger;
use SimpleSAML\Module\discopower\PowerIdPDisco;
use SimpleSAML\Module\perun\Auth\Process\MultifactorAcrs;
use SimpleSAML\Module\perun\model\WarningConfiguration;
use SimpleSAML\Utils\HTTP;
/**
* This class implements a IdP discovery service.
*
* 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
* directly with metadata. In case of manual idps comment them out or in case of automated metadata fetching configure
* blacklist in config-metarefresh.php
*/
class Disco extends PowerIdPDisco
{
public const CONFIG_FILE_NAME = 'module_perun.php';
public const URN_CESNET_PROXYIDP_IDPENTITYID = 'urn:cesnet:proxyidp:idpentityid:';
public const LS_IDP = 'https://proxy.aai.lifescience-ri.eu/proxy';
// ROOT CONFIGURATION ENTRY
public const WAYF = 'wayf_config';
public const INTERFACE = 'interface';
public const RPC = 'rpc';
public const REMOVE_AUTHN_CONTEXT_CLASS_PREFIXES = 'remove_authn_context_class_ref_prefixes';
public const ADD_AUTHN_CONTEXT_CLASSES_FOR_MFA = 'add_authn_context_classes_for_mfa';
public const RETURN = 'return';
public const AUTHN_CONTEXT_CLASS_REF = 'AuthnContextClassRef';
public const WARNING_ATTRIBUTES = 'warningAttributes';
public const AUTH_ID = 'AuthID';
public const CONTINUE_URL = 'continueUrl';
// STATE KEYS
public const SAML_REQUESTED_AUTHN_CONTEXT = 'saml:RequestedAuthnContext';
public const STATE_AUTHN_CONTEXT_CLASS_REF = 'AuthnContextClassRef';
public const SAML_SP_SSO = 'saml:sp:sso';
public const NAME = 'name';
// VARIABLES
private array $originalAuthnContextClassRef = [];
private $wayfConfiguration;
private Configuration $perunModuleConfiguration;
private $proxyIdpEntityId;
private $state;
public function __construct(array $metadataSets, $instance)
{
//LOAD CONFIG FOR MODULE PERUN, WHICH CONTAINS WAYF CONFIGURATION
try {
$this->perunModuleConfiguration = Configuration::getConfig(self::CONFIG_FILE_NAME);
$this->wayfConfiguration = $this->perunModuleConfiguration->getConfigItem(self::WAYF);
} catch (\Exception $ex) {
Logger::error("perun:disco-tpl: missing or invalid '" . self::CONFIG_FILE_NAME . "' config file");
throw $ex;
}
if (!array_key_exists(self::RETURN, $_GET)) {
throw new \Exception('Missing parameter: ' . self::RETURN);
}
$returnURL = HTTP::checkURLAllowed($_GET[self::RETURN]);
parse_str(parse_url($returnURL)['query'], $query);
if (isset($query[self::AUTH_ID])) {
$id = explode(':', $query[self::AUTH_ID])[0];
$state = State::loadState($id, self::SAML_SP_SSO, true);
if (null !== $state) {
if (isset($state[self::SAML_REQUESTED_AUTHN_CONTEXT][self::AUTHN_CONTEXT_CLASS_REF])) {
$this->originalAuthnContextClassRef = $state[self::SAML_REQUESTED_AUTHN_CONTEXT][self::AUTHN_CONTEXT_CLASS_REF];
$this->removeAuthContextClassRefWithPrefixes($state);
$this->prepareAcrsForMfa($state);
if (isset($state['IdPMetadata']['entityid'])) {
$this->proxyIdpEntityId = $state['IdPMetadata']['entityid'];
}
State::saveState($state, self::SAML_SP_SSO);
}
$e = explode('=', $returnURL)[0];
$newReturnURL = $e . '=' . urlencode($id);
$_GET[self::RETURN] = $newReturnURL;
}
$this->state = $state;
}
parent::__construct($metadataSets, $instance);
}
/**
* Handles a request to this discovery service. It is entry point of Discovery service.
*
* The IdP disco parameters should be set before calling this function.
*/
public function handleRequest()
{
$this->start();
// IF IS SET AUTHN CONTEXT CLASS REF, REDIRECT USER TO THE IDP
if (!empty($this->originalAuthnContextClassRef)) {
// Check authnContextClassRef and select IdP directly if the correct value is set
foreach ($this->originalAuthnContextClassRef as $value) {
// VERIFY THE PREFIX IS CORRECT AND WE CAN PERFORM THE REDIRECT
$acrStartSubstr = substr($value, 0, strlen(self::URN_CESNET_PROXYIDP_IDPENTITYID));
if (self::URN_CESNET_PROXYIDP_IDPENTITYID === $acrStartSubstr) {
$idpEntityId = substr($value, strlen(self::URN_CESNET_PROXYIDP_IDPENTITYID), strlen($value));
if ($idpEntityId === $this->proxyIdpEntityId) {
continue;
}
Logger::info('Redirecting to ' . $idpEntityId);
$continueUrl = self::buildContinueUrl(
$this->spEntityId,
$this->returnURL,
$this->returnIdParam,
$idpEntityId
);
HTTP::redirectTrustedURL($continueUrl);
exit;
}
}
}
$continueUrl = self::buildContinueUrl(
$this->spEntityId,
$this->returnURL,
$this->returnIdParam,
!empty($this->state['aarc_hinted_idp']) ? $this->state['aarc_hinted_idp'] : self::LS_IDP
);
$warningInstance = WarningConfiguration::getInstance();
$warningAttributes = $warningInstance->getWarningAttributes();
$t = new DiscoTemplate($this->config);
$t->data[self::WARNING_ATTRIBUTES] = $warningAttributes;
$t->data[self::CONTINUE_URL] = $continueUrl;
$t->show();
}
/**
* @param $entityID
* @param $return
* @param $returnIDParam
* @param $idpEntityId
*
* @return string url where user should be redirected when he choose idp
*/
public static function buildContinueUrl(
string $entityID,
string $return,
string $returnIDParam,
string $idpEntityId
): string {
return '?' .
'entityID=' . urlencode($entityID) . '&' .
'return=' . urlencode($return) . '&' .
'returnIDParam=' . urlencode($returnIDParam) . '&' .
'idpentityid=' . urlencode($idpEntityId);
}
/**
* This method remove all AuthnContextClassRef which start with prefix from configuration.
*
* @param mixed $state
*/
public function removeAuthContextClassRefWithPrefixes(&$state)
{
$prefixes = $this->wayfConfiguration->getArray(self::REMOVE_AUTHN_CONTEXT_CLASS_PREFIXES, []);
if (empty($prefixes)) {
return;
}
unset($state[self::SAML_REQUESTED_AUTHN_CONTEXT][self::STATE_AUTHN_CONTEXT_CLASS_REF]);
$filteredAcrs = [];
foreach ($this->originalAuthnContextClassRef as $acr) {
$acr = trim($acr);
$retain = true;
foreach ($prefixes as $prefix) {
if (substr($acr, 0, strlen($prefix)) === $prefix) {
$retain = false;
break;
}
}
if ($retain) {
$filteredAcrs[] = $acr;
}
}
if (!empty($filteredAcrs)) {
$state[self::SAML_REQUESTED_AUTHN_CONTEXT][self::STATE_AUTHN_CONTEXT_CLASS_REF] = $filteredAcrs;
}
}
private function prepareAcrsForMfa(array &$state)
{
$contextsToAdd = $this->wayfConfiguration->getArray(self::ADD_AUTHN_CONTEXT_CLASSES_FOR_MFA, []);
MultifactorAcrs::addAndStoreAcrs($state, $contextsToAdd);
}
}
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\elixir;
use SimpleSAML\Configuration;
use SimpleSAML\XHTML\Template;
/**
* This class extends basic SimpleSAML template class. It provides some utils functions used in templates specific for
* Discovery services so template do not have to access directly $this->data field.
*
* Here should NOT be defined any view specific methods.
*/
class DiscoTemplate extends Template
{
public const NAME = 'name';
/**
* sspmod_perun_DiscoTemplate constructor.
*
* @param Configuration $configuration of SimpleSAMLphp
*/
public function __construct(Configuration $configuration)
{
parent::__construct($configuration, 'elixir:disco-tpl.php', 'disco');
// Translate title in header
$this->data['header'] = $this->t(isset($this->data['header']) ? $this->data['header'] : 'selectidp');
}
}
<?php declare(strict_types=1);
use SimpleSAML\Module\elixir\ConsentHelper;
assert(is_array($this->data['dstMetadata']));
assert(is_string($this->data['yesTarget']));
assert(is_array($this->data['yesData']));
assert(is_array($this->data['attributes']));
assert(false === $this->data['sppp'] || is_string($this->data['sppp']));
$dstName = ConsentHelper::getDestinationName($this->data, $this);
$parsedJurisdiction = ConsentHelper::getJurisdiction($this->data['dstMetadata']);
$this->includeAtTemplateBase('includes/header.php');
?>
<div class="aas-message">
<p>
The service <strong><?php echo $dstName; ?></strong> requires access to your personal data.
<?php
if (false !== $this->data['sppp']) {
echo 'Please, read the <a target="_blank" href="' . $this->data['sppp'] . '">Privacy Policy</a> of the service to learn more about its commitments to protect your data.';
}
?>
</p>
</div>
<?php
ConsentHelper::printPrivacyPolicyWarning($this->data['sppp']);
ConsentHelper::printAcceptedTosWarning($this->data['dstMetadata']);
?>
<form name="confirmationForm" id="yesform" class="form-group"
action="<?php echo htmlspecialchars($this->data['yesTarget']); ?>" method="post">
<div id="accordion">
<div class="section">
<div class="card-header" id="headingOne">
<h5 class="mb-0">
<button class="btn btn-link" type="button" data-toggle="collapse" data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
User Information
</button>
</h5>
</div>
</div>
<div class="section">
<div id="collapseOne" class="collapse show" aria-labelledby="headingThree" data-parent="#accordion">
<?php ConsentHelper::printUserAttributes($this->data['attributes'], $this->getTranslator()); ?>
</div>
<div class="card-header" id="headingThree">
<h5 class="mb-0">
<button class="btn btn-link" type="button" data-toggle="collapse" data-target="#collapseThree" aria-expanded="true" aria-controls="collapseOne">
Technical Information
</button>
</h5>
</div>
<div id="collapseThree" class="collapse show" aria-labelledby="headingThree" data-parent="#accordion">
<?php ConsentHelper::printTechnicalAttributes($this->data['attributes'], $this->getTranslator()); ?>
</div>
</div>
</div>
<?php
declare(strict_types=1);
ConsentHelper::printJurisdictionWarning($parsedJurisdiction, $this->data['sppp']);
use SimpleSAML\Module;
foreach ($this->data['yesData'] as $name => $value) {
echo '<input type="hidden" name="' . htmlspecialchars($name) . '" value="' . htmlspecialchars(
$value
) . '" />';
}
include Module::getModuleDir('perun') . '/themes/perun/consent/consentform.php';
?>
<div class="footer-buttons">
<div class="remember">
<label>Remember:</label>
<div id="select-amount">
<label for="month"></label>
<select name="saveconsent" id="month" class="btn btn-sm btn-secondary amount">
<option value="0">Just this time</option>
<option value="1">Forever</option>
</select>
</div>
</div>
<div class="consent-button">
<a id="abort" class="btn btn-danger" href="https://lifescience-ri.eu/index.php?id=409">Abort</a>
<input type="submit" class="btn btn-primary" name="yes"
<?php echo empty($parsedJurisdiction) ? '' : 'disabled=""'; ?> value="Consent" id="submit">
</div>
</div>
</form>
<?php
$this->includeAtTemplateBase('includes/footer.php');
......@@ -10,31 +10,22 @@ if (!empty($this->data['htmlinject']['htmlContentPost'])) {
?>
</div><!-- #content -->
</div><!-- #wrap -->
<div id="footer">
<div style="margin: 0px auto; max-width: 1000px;">
<div style="float: left;">
<img src="<?php echo Module::getModuleUrl('elixir/res/img/logo_64.png'); ?>">
</div> <!-- ENDCARD_BODY -->
</div> <!-- ENDCARD -->
</div> <!-- ENDCOL -->
</div> <!-- ENDROW -->
<footer>
<div class="footer offset-1 col-10 offset-sm-1 col-sm-10 offset-md-2 col-md-8 offset-lg-3 col-lg-6 offset-xl-3 col-xl-6">
<div class="footer-contact">
<a class="contact-link" href="mailto:support@aai.lifescience-ri.eu">Contact us</a>
</div>
<div style="float: left;">
<p>ELIXIR, Wellcome Trust Genome Campus, Hinxton, Cambridgeshire, CB10 1SD, UK
&nbsp; &nbsp; +44 (0)1223 492-670 &nbsp;
<a href="mailto:info@elixir-europe.org">info@elixir-europe.org</a>
</p>
<p>Copyright © ELIXIR <?php echo date('Y'); ?> |
<a href="https://www.elixir-europe.org/legal/privacy">Privacy</a> |
<a href="https://www.elixir-europe.org/legal/cookies">Cookies</a> |
<a href="https://www.elixir-europe.org/legal/terms-of-use">Terms of use</a>
</p>
<div class="footer-policy">
<a class="footer-policy-link" href="https://lifescience-ri.eu/ls-login/ls-aai-aup.html">Privacy Policy</a>
</div>
</div>
</div><!-- #footer -->
</footer>
<script type="text/javascript" src="<?php echo Module::getModuleURL('elixir/res/js/jquery-3.5.1.min.js'); ?>"></script>
<script type="text/javascript" src="<?php echo Module::getModuleURL('elixir/res/js/bootstrap.min.js'); ?>"></script>
<script type="text/javascript" src="<?php echo Module::getModuleURL('elixir/res/js/cmservice.js'); ?>"></script>
</body>
</html>
......@@ -38,123 +38,29 @@ if (array_key_exists('pageid', $this->data)) {
*/
header('X-Frame-Options: SAMEORIGIN');
?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0"/>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link href="<?php echo Module::getModuleUrl('elixir/res/css/bootstrap.min.css'); ?>" rel="stylesheet" type="text/css"/>
<link href="<?php echo Module::getModuleUrl('elixir/res/css/eduteams.css'); ?>" rel="stylesheet" type="text/css"/>
<link href="<?php echo Module::getModuleUrl('elixir/res/css/cmservice.css'); ?>" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="/<?php echo $this->data['baseurlpath']; ?>resources/script.js"></script>
<title><?php
if (array_key_exists('header', $this->data)) {
echo $this->data['header'];
} else {
echo 'SimpleSAMLphp';
}
?></title>
<link rel="stylesheet" type="text/css" href="/<?php echo $this->data['baseurlpath']; ?>resources/default.css"/>
<link rel="icon" type="image/icon"
href="<?php echo Module::getModuleUrl('elixir/res/img/icons/favicon.ico'); ?>"/>
<?php
if (!empty($jquery)) {
$version = '1.8';
if (array_key_exists('version', $jquery)) {
$version = $jquery['version'];
}
if ('1.8' === $version) {
if (isset($jquery['core']) && $jquery['core']) {
echo '<script type="text/javascript" src="/' . $this->data['baseurlpath'] .
'resources/jquery-1.8.js"></script>' . "\n";
}
if (isset($jquery['ui']) && $jquery['ui']) {
echo '<script type="text/javascript" src="/' . $this->data['baseurlpath'] .
'resources/jquery-ui-1.8.js"></script>' . "\n";
}
if (isset($jquery['css']) && $jquery['css']) {
echo '<link rel="stylesheet" media="screen" type="text/css" href="/' . $this->data['baseurlpath'] .
'resources/uitheme1.8/jquery-ui.css" />' . "\n";
}
}
}
if (isset($this->data['clipboard.js'])) {
echo '<script type="text/javascript" src="/' . $this->data['baseurlpath'] .
'resources/clipboard.min.js"></script>' . "\n";
}
if (!empty($this->data['htmlinject']['htmlContentHead'])) {
foreach ($this->data['htmlinject']['htmlContentHead'] as $c) {
echo $c;
}
}
if ($this->isLanguageRTL()) {
?>
<link rel="stylesheet" type="text/css"
href="/<?php echo $this->data['baseurlpath']; ?>resources/default-rtl.css"/>
<?php
}
?>
<link rel="stylesheet" type="text/css"
href="<?php echo Module::getModuleUrl('elixir/res/bootstrap/css/bootstrap.min.css'); ?>"/>
<link rel="stylesheet" type="text/css"
href="<?php echo Module::getModuleUrl('elixir/res/css/elixir.css'); ?>"/>
<meta name="robots" content="noindex, nofollow"/>
<?php
if (array_key_exists('head', $this->data)) {
echo '<!-- head -->' . $this->data['head'] . '<!-- /head -->';
}
?>
<title><?php echo (array_key_exists('header', $this->data)) ? $this->data['header'] : 'SimpleSAMLphp'; ?></title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel="stylesheet">
</head>
<?php
$onLoad = '';
if (array_key_exists('autofocus', $this->data)) {
$onLoad .= 'SimpleSAML_focus(\'' . $this->data['autofocus'] . '\');';
}
if (isset($this->data['onLoad'])) {
$onLoad .= $this->data['onLoad'];
}
if ('' !== $onLoad) {
$onLoad = ' onload="' . $onLoad . '"';
}
?>
<body<?php echo $onLoad; ?>>
<div id="wrap">
<div id="header">
<img src="<?php echo Module::getModuleUrl('elixir/res/img/logo_256.png'); ?>" alt="Elixir logo">
<h1>
<?php
echo isset($this->data['header']) ? $this->data['header'] : 'Elixir proxy IdP';
?>
</h1>
</div>
<div id="content">
<?php
if (!empty($this->data['htmlinject']['htmlContentPre'])) {
foreach ($this->data['htmlinject']['htmlContentPre'] as $c) {
echo $c;
}
}
<body>
<div class="row">
<div class="offset-1 col-10 offset-sm-1 col-sm-10 offset-md-2 col-md-8 offset-lg-3 col-lg-6 offset-xl-3 col-xl-6">
<div class="card">
<img class="card-img-top" src="<?php echo Module::getModuleURL('elixir/res/img/lsaai_logo.png'); ?>" alt="Life Science Login logo">
<div class="card-body">
<?php
if (isset($this->data['header'])) {
echo '<h1>' . PHP_EOL;
echo $this->data['header'];
echo '</h1>' . PHP_EOL;
}
<?php
declare(strict_types=1);
use SimpleSAML\Module\elixir\Disco;
use SimpleSAML\Module\perun\model\WarningConfiguration;
use SimpleSAML\Utils\HTTP;
$warningAccepted = false;
if (isset($_POST['accepted'])) {
$warningAccepted = true;
}
$idpEntityId = null;
$authContextClassRef = null;
$warningAttributes = $this->data[Disco::WARNING_ATTRIBUTES];
$continueUrl = $this->data[Disco::CONTINUE_URL];
$preventUserContinue = WarningConfiguration::WARNING_TYPE_ERROR === $warningAttributes->getType();
if (!$warningAttributes->isEnabled() || ($warningAccepted && !$preventUserContinue)) {
HTTP::redirectTrustedURL($continueUrl);
}
if ($warningAttributes->isEnabled()) {
$this->data['header'] = $this->t('{perun:disco:warning}');
}
$this->data['jquery'] = [
'core' => true,
'ui' => true,
'css' => true,
];
$this->includeAtTemplateBase('includes/header.php');
if ($warningAttributes->isEnabled()) {
$this->includeInlineTranslation('{perun:disco:warning_title}', $warningAttributes->getTitle());
$this->includeInlineTranslation('{perun:disco:warning_text}', $warningAttributes->getText());
if (WarningConfiguration::WARNING_TYPE_INFO === $warningAttributes->getType()) {
echo '<div class="alert alert-info">';
} elseif (WarningConfiguration::WARNING_TYPE_WARNING === $warningAttributes->getType()) {
echo '<div class="alert alert-warning">';
} elseif (WarningConfiguration::WARNING_TYPE_ERROR === $warningAttributes->getType()) {
echo '<div class="alert alert-danger">';
}
echo '<h4><strong>' . $this->t('{perun:disco:warning_title}') . '</strong> </h4>';
echo $this->t('{perun:disco:warning_text}');
echo '</div>';
if (!$preventUserContinue) {
echo '<form method="POST">';
echo '<input class="btn btn-lg btn-primary btn-block" type="submit" name="accepted" value="Continue" />';
echo '</form>';
}
} else {
$warningAccepted = true;
}
$this->includeAtTemplateBase('includes/footer.php');
<?php
declare(strict_types=1);
use SimpleSAML\Module;
include Module::getModuleDir('perun') . '/themes/perun/perun/disco-tpl.php';
<?php
declare(strict_types=1);
use SimpleSAML\Error\Error;
use SimpleSAML\Module\elixir\Disco;
try {
$discoHandler = new Disco(['saml20-idp-remote'], 'poweridpdisco');
} catch (\Exception $exception) {
// An error here should be caused by invalid query parameters
throw new Error('DISCOPARAMS', $exception);
}
try {
$discoHandler->handleRequest();
} catch (\Exception $exception) {
// An error here should be caused by metadata
throw new Error('METADATA', $exception);
}
This diff is collapsed.
This diff is collapsed.
/* universal - with new colors vars*/
:root {
--color-blue: #003f5e;
--color-orange: #f0893b;
--color-white: #ffffff;
--color-red: #dc3545;
--color-red-light: #fef7f1;
/* add for cm service*/
--color-blue-light: #e0e3ef;
--color-grey: #ddd;
--color-grey-light: #eee;
--color-grey-lighter: #f2f2f2;
/* add for cm service*/
}
html {
background: var(--color-white);
}
body {
background: var(--color-white);
font-family: "Roboto", sans-serif; /*added*/
}
a:not([class~="btn"]):link,
a:not([class~="btn"]):hover,
a:not([class~="btn"]):focus,
a:not([class~="btn"]):visited {
color: var(--color-orange);
outline: none;
}
a:focus {
text-decoration:underline;
}
.card {
box-shadow: 0rem 1rem 3rem 0.5rem rgba(0, 0, 0, 0.15);
margin-bottom: 5rem;
max-width: 970px;
margin-left: auto;
margin-right: auto;
}
footer {
background-color: var(--color-blue);
color: var(--color-white);
font-size: 0.9rem;
font-family: "Roboto", sans-serif;
padding: 0.5rem;
}
.footer {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: baseline;
flex-wrap: wrap;
}
.footer-policy {
display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: baseline;
flex-wrap: wrap;
}
.footer-policy img {
width: auto;
height: 2rem;
margin-left: 0.5rem;
margin-right: 0.5rem;
}
.footer-policy-img {
display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: baseline;
}
.footer-policy-img p {
white-space: nowrap;
}
.footer-policy-link {
margin-left: 0.5rem;
}
.contact-link {
font-weight: bold;
}
/*universal*/
/*cm service main content*/
.attribute-row {
display: flex;
flex-direction: row;
}
.attribute-row code {
color: var(--color-blue);
}
.attribute-name p {
font-size: 0.9rem;
font-weight: bold;
word-break: break-all;
}
.attribute {
display: flex;
flex-direction: column;
flex: 0 0 12rem;
margin-right: 1rem;
}
.attribute-choose {
margin-bottom: 8px;
}
.attribute-values {
display: flex;
flex-direction: column;
flex: 0 1 auto;
overflow-x: auto;
/* break down string at any place */
/*word-break: break-all;*/
/* preserve string in one scrollable line */
white-space: nowrap;
}
.aas-message,
form > #accordion,
form > .footer-buttons,
form > .alert {
margin-bottom: 2rem;
margin-top: 2rem;
}
form #accordion p {
margin-bottom: 0px;
}
form .footer-buttons {
display: flex;
flex-direction: row;
align-items: baseline;
}
form .remember,
form .consent-button {
display: flex;
flex-direction: row;
align-items: baseline;
}
form .consent-button {
margin-left: auto;
}
form .consent-button #abort {
margin-right: 10px;
}
form #submit {
background-color: var(--color-blue);
border: 0;
}
form #submit:not([disabled]):hover {
background-color: var(--color-orange);
border: 0;
}
form .alert label,
form .remember label {
font-size: 0.9rem;
}
form .remember label {
color: var(--color-blue);
margin-right: 10px;
}
form .remember select.amount,
form .remember select.amount:focus,
form .remember select.amount:active {
color: var(--color-blue);
background-color: var(--color-blue-light);
border: 0;
box-shadow: none;
}
/*cm service main content*/
.footer-contact {
margin-top: 1rem;
margin-bottom: 1rem;
}
@media (max-width: 1150px) {
.footer {
padding-top: 0.5rem;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
}
.footer-contact {
text-align: center;
margin-bottom: 0.8rem;
}
}
@media (min-width: 992px) and (max-width: 1150px) {
.attribute-row {
flex-direction: column;
flex: 0 0 auto;
}
.attribute {
display: flex;
flex-direction: column;
flex: 0 0 auto;
margin-right: 0;
}
.attribute-values {
margin-top: 0.5rem;
}
}
@media (max-width: 767px) {
.attribute-row {
flex-direction: column;
flex: 0 0 auto;
}
.attribute {
display: flex;
flex-direction: column;
flex: 0 0 auto;
margin-right: 0;
}
}
@media (max-width: 576px) {
.footer-contact {
text-align: center;
margin-bottom: 0.8rem;
}
/*add for cm service*/
form .footer-buttons {
flex-direction: column;
}
/* # XXX */
.consent-button {
margin-left: 0;
}
.consent-input {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
} /*add for cm service*/
}
.wrap {
width: 100%;
height: 188px;
position: absolute;
overflow: hidden;
color: white;
text-transform: uppercase;
font-weight: bold;
}
.ribbon {
width: 200px;
height: 40px;
line-height: 40px;
position: absolute;
top: 30px;
right: -50px;
z-index: 2;
overflow: hidden;
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
box-shadow: 0 0 0 3px #eb3814, 0px 21px 5px -18px rgba(0,0,0,0.6);
background: #eb3814;
text-align: center;
}
@media (max-width: 350px) {
.footer-policy {
display: flex;
flex-direction: column;
justify-content: flex-end;
align-items: center;
}
.line {
display: none;
}
/*add for cm service*/
form .footer-buttons .remember {
flex-direction: column;
} /*add for cm service*/
}
html {
height: 100%;
background-image: linear-gradient(#ffffff, #d3d3d3);
background-repeat: no-repeat;
background-attachment: fixed;
font-family: "Roboto", sans-serif;
color: #3b3b3b;
}
h1,
h2,
h3,
h4,
h5 {
font-family: "Roboto", sans-serif;
color: #3b3b3b;
}
h3 {
font-size: 1rem;
}
body {
display: flex;
flex-direction: column;
min-width: 100%;
height: 100%;
/*background-image: url("./imgs/ra_pattern_04.png");*/
background-color: rgba(0, 0, 0, 0);
margin: 0;
padding: 0;
}
h2 img {
margin-left: 10px;
width: 67px;
}
a.identityprovider {
display: inline-block;
vertical-align: middle;
width: 100%;
}
a.identityprovider li svg {
display: inline-block;
vertical-align: middle;
}
a.identityprovider li span {
display: inline-block;
vertical-align: middle;
text-align: left;
padding-top: 8px;
}
a#registration-btn {
color: #fff;
background-color: #20368c;
white-space: normal;
cursor: pointer;
display: block;
}
.default-label {
color: #3b3b3b;
display: inline;
padding: 0.2em 0.6em 0.3em;
font-weight: 500;
line-height: 1;
text-align: center;
white-space: nowrap;
vertical-align: baseline;
border-radius: 0.25em;
border: 2px #3b3b3b solid;
}
.row {
margin-left: 0px;
margin-right: 0px;
}
.no-left {
margin-left: 0px;
padding-left: 0px;
}
.padding-left {
padding-left: 15px;
}
.light {
font-weight: 300;
}
.container {
position: relative;
}
.card-container {
height: 100% !important;
max-width: 800px;
}
.card-container.card {
padding: 40px 40px;
text-align: left;
}
.card {
background-color: #ffffff;
padding: 20px 25px 30px;
margin: 0 auto 25px;
margin-top: 50px;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
border-radius: 2px;
-moz-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
-webkit-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
}
.form-control:focus {
border-color: rgb(20, 125, 250);
outline: 0;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075),
0 0 8px rgb(20, 125, 250);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgb(20, 125, 250);
}
/*-------------------------------------------------*/
.input-group {
margin: 3px 0 5px 0;
}
h2.accessHeader {
font-size: 1.4rem;
margin-top: 4px;
}
p {
font-size: 0.9rem;
font-family: "Roboto", sans-serif;
}
.lookupRA21 {
margin: 50px 0 50px 0;
}
.detailtextRA21 {
color: rgba(0, 0, 0, 0.65);
font-size: 0.9rem;
}
.subtitleRA21 {
font-size: 1.25rem;
font-weight: 300;
color: rgba(0, 0, 0, 0.65);
}
.notopborder {
border-top-style: none;
}
.counter {
color: rgba(0, 0, 0, 0.65);
font-weight: 2rem;
background-color: #e7effb;
text-align: center;
padding-right: 13px;
padding-left: 13px;
padding-top: 5px;
padding-bottom: 5px;
margin-right: 5px;
}
.howItWorksSectionHeading {
color: rgba(0, 0, 0, 0.65);
}
.card-title {
color: rgba(0, 0, 0, 0.65);
}
.howItWorksImg {
height: 100px;
width: 100px;
}
.spacer {
margin: 0;
padding: 0;
height: 50px;
}
.lightGrey {
color: #999999;
}
.d-flex {
display: flex;
}
.card-block {
-webkit-box-flex: 1;
-webkit-flex: 1 1 auto;
-ms-flex: 1 1 auto;
flex: 1 1 auto;
padding: 1.25rem;
}
.card {
position: relative;
border: none;
box-shadow: 0 1.5rem 3rem rgba(0, 0, 0, 0.15);
}
.card-deck .card {
padding: 0;
margin: 0;
flex-wrap: wrap;
flex: initial;
}
.card-img-top {
width: 75%;
max-width: 440px;
margin: 20px auto;
}
.card-block {
position: relative;
padding: 1.4rem;
}
.card-text {
margin-bottom: 0;
font-size: 0.9rem;
font-weight: 300;
line-height: 1.5em;
}
.card-title {
font-size: 1.35rem;
font-weight: 300;
line-height: 1.2em;
}
.card-title span {
color: #147dfa;
}
.card-links {
list-style: none;
margin: 0;
padding: 0;
}
.card-links hr {
border-bottom: 0;
border-top: 1px solid #ddd;
margin: 0;
}
.card-links a {
text-decoration: none;
color: #147dfa;
cursor: pointer;
width: 100%;
}
.card-links a li {
margin: 0;
padding: 14px 6px;
border-left: 3px solid #fff;
transition: background-color 0.2s ease, border-left 0.2s ease, color 0.2s ease;
cursor: pointer;
}
.card-links a:hover li {
border-left: 3px solid #033d83;
background: #ffffff;
color: #44474a;
}
.card-links a li > i {
float: right;
color: #147dfa;
margin-top: 2px;
margin-left: 4px;
}
.card-links a li.known-inst {
margin: 0;
margin-bottom: 5px;
border-radius: 3px;
padding: 14px 6px;
border-left: none;
color: #147dfa;
transition: background-color 0.2s ease, border-left 0.2s ease, color 0.2s ease;
cursor: pointer;
background-color: #f3f3f3;
}
.card-links a:hover li.known-inst {
border-left: none;
background: #284788;
color: #ffffff;
cursor: pointer;
}
.card-header {
padding: 0.75rem 0rem;
margin-bottom: 0;
border-bottom: 1px solid rgba(0, 0, 0, 0.125);
}
.card-header .btn-link,
.card-header .btn-link:hover {
box-shadow: none;
text-decoration: none;
color: var(--color-blue);
}
.logo {
width: 40px;
height: 40px;
margin-right: 7px;
padding: 0;
border-width: 2px;
}
.link-favorites {
border-bottom-left-radius: 4px;
}
.site {
display: flex;
flex-direction: column;
}
main {
flex: 1 0 auto;
}
footer {
flex-shrink: 0;
margin-top: auto;
}
/*--*/
.institution {
position: relative;
display: inline-block;
}
a.active div.external {
display: inline-block;
}
div.external {
padding-top: 5px;
padding-right: 7px;
position: absolute;
right: 0;
top: 0;
display: none;
}
div.cancel {
padding-top: 5px;
padding-right: 7px;
position: absolute;
right: 0;
top: 0;
}
.label {
max-width: 80%;
}
.label-url {
float: right;
margin-right: 25px;
max-width: 18%;
color: #ababab;
}
.searchaux {
max-width: 75%;
font-size: small;
}
.searchmatch {
max-width: 75%;
font-size: x-small;
}
.alert ul {
padding-left: 1rem;
}
.fa-spinner {
font-size: 36px;
color: #007bff;
display: block;
margin-left: auto;
margin-right: auto;
}
h3.searching {
text-align: center;
}
div#titlefind {
margin-top: 30px;
text-align: center;
}
div#eduteams_logo {
text-align: center;
margin-top: 20px;
}
div#eduteams_logo > img {
width: 50%;
}
.buttoncopy {
padding-top: 0px;
}
input#oidc-client-input {
color: var(--color-blue);
background: transparent;
}
input#oidc-secret-input {
color: var(--color-blue);
background: transparent;
}
div#btnGroupAddon2 {
color: var(--color-blue);
background: transparent;
width: 85px;
}
div#oidc-text {
margin-bottom: 2rem;
}
/*--*/
www/res/img/logo_1024.png

45.4 KiB

www/res/img/logo_128.png

4.89 KiB

www/res/img/logo_256.png

9.7 KiB

www/res/img/logo_32.png

1.2 KiB

www/res/img/logo_512.png

20.3 KiB

www/res/img/logo_64.png

2.37 KiB

www/res/img/lsaai_logo.png

14 KiB

0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment