Skip to content
Snippets Groups Projects
Commit 807430ca authored by Andreas Åkre Solberg's avatar Andreas Åkre Solberg
Browse files

New simplesamlphp module: DiscoPower. It is a fancy tabbed discovery service...

New simplesamlphp module: DiscoPower. It is a fancy tabbed discovery service with filtering capabilities where SPs can have different sets of metadata listed...

git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@1046 44740490-163a-0410-bde0-09ae8108e29a
parent ae5118e0
No related branches found
No related tags found
No related merge requests found
Showing
with 1151 additions and 0 deletions
<?php
/*
* Configuration for the DiscoPower module.
*
* $Id: $
*/
$config = array (
// Which tab should be set as default. 0 is the first tab.
'defaulttab' => 0,
/*
* List a set of tags (Tabs) that should be listed in a specific order.
* All other available tabs will be listed after the ones specified below.
*/
'taborder' => array('norway'),
);
?>
<?php
$lang = array(
'norway' => array (
'no' => 'Norge',
'en' => 'Norway',
),
'kalmar' => array (
'no' => 'Kalmar',
'en' => 'Kalmar',
),
'haka' => array (
'no' => 'Finnland',
'en' => 'Finland',
),
'switch' => array (
'no' => 'Sveits',
'en' => 'Switzerland',
),
'edugain' => array (
'no' => 'Europa (eduGAIN)',
'en' => 'Europe (eduGAIN)',
),
'misc' => array (
'no' => 'Andre',
'en' => 'Miscellaneous',
),
);
?>
\ No newline at end of file
<?php
/**
* This class implements a generic IdP discovery service, for use in various IdP
* discovery service pages. This should reduce code duplication.
*
* This module extends the basic IdP disco handler, and add features like filtering
* and tabs.
*
* @author Andreas Åkre Solberg <andreas@uninett.no>, UNINETT AS.
* @package simpleSAMLphp
* @version $Id$
*/
class sspmod_discopower_PowerIdPDisco extends SimpleSAML_XHTML_IdPDisco {
private $discoconfig;
/**
* Initializes this discovery service.
*
* The constructor does the parsing of the request. If this is an invalid request, it will
* throw an exception.
*
* @param $discoType String which identifies the type of discovery service.
*/
public function __construct($discoType) {
parent::__construct($discoType);
$this->discoconfig = $this->config->copyFromBase('discopower', 'module_discopower.php');
}
/**
* Log a message.
*
* This is an helper function for logging messages. It will prefix the messages with our
* discovery service type.
*
* @param $message The message which should be logged.
*/
protected function log($message) {
SimpleSAML_Logger::info('PowerIdPDisco.' . $this->discoType['type'] . ': ' . $message);
}
/*
* This function will structure the idp list in a hierarchy based upon the tags.
*/
protected function idplistStructured($list) {
# echo '<pre>'; print_r($list); exit;
$slist = array();
$order = $this->discoconfig->getValue('taborder');
if (is_array($order)) {
foreach($order AS $oe) {
$slist[$oe] = array();
}
}
foreach($list AS $key => $val) {
$tags = array('misc');
if (array_key_exists('tags', $val)) {
$tags = $val['tags'];
}
foreach ($tags AS $tag) {
$slist[$tag][$key] = $val;
}
}
return $slist;
}
private function processFilter($filter, $entry, $default = TRUE) {
if (in_array($entry['entityid'], $filter['entities.include'] )) return TRUE;
if (in_array($entry['entityid'], $filter['entities.exclude'] )) return FALSE;
if (array_key_exists('tags', $entry)) {
foreach ($filter['tags.include'] AS $fe) {
if (in_array($fe, $entry['tags'])) return TRUE;
}
foreach ($filter['tags.exclude'] AS $fe) {
if (in_array($fe, $entry['tags'])) return FALSE;
}
}
return $default;
}
protected function filterList($list) {
try {
$spmd = $this->metadata->getMetaData($this->spEntityId, 'saml20-sp-remote');
} catch(Exception $e) {
return $list;
}
if (!isset($spmd)) return $list;
if (!array_key_exists('discopower.filter', $spmd)) return $list;
$filter = $spmd['discopower.filter'];
if (!array_key_exists('entities.include', $filter)) $filter['entities.include'] = array();
if (!array_key_exists('entities.exclude', $filter)) $filter['entities.exclude'] = array();
if (!array_key_exists('tags.include', $filter)) $filter['tags.include'] = array();
if (!array_key_exists('tags.exclude', $filter)) $filter['tags.exclude'] = array();
$defaultrule = TRUE;
if ( array_key_exists('entities.include', $filter) ||
array_key_exists('tags.include', $filter)) {
$defaultrule = FALSE;
}
$returnlist = array();
foreach ($list AS $key => $entry) {
if ($this->processFilter($filter, $entry, $defaultrule)) {
$returnlist[$key] = $entry;
}
}
return $returnlist;
}
/**
* Handles a request to this discovery service.
*
* The IdP disco parameters should be set before calling this function.
*/
public function handleRequest() {
$idp = $this->getTargetIdp();
if($idp !== NULL) {
if ($this->config->getValue('idpdisco.extDiscoveryStorage', NULL) != NULL) {
$extDiscoveryStorage = $this->config->getValue('idpdisco.extDiscoveryStorage');
$this->log('Choice made [' . $idp . '] (Forwarding to external discovery storage)');
SimpleSAML_Utilities::redirect($extDiscoveryStorage, array(
'entityID' => $this->spEntityId,
'IdPentityID' => $idp,
'returnIDParam' => $this->returnIdParam,
'isPassive' => 'true',
'return' => $this->returnURL
));
} else {
$this->log('Choice made [' . $idp . '] (Redirecting the user back. returnIDParam=' . $this->returnIdParam . ')');
SimpleSAML_Utilities::redirect($this->returnURL, array($this->returnIdParam => $idp));
}
return;
}
if ($this->isPassive) {
$this->log('Choice not made. (Redirecting the user back without answer)');
SimpleSAML_Utilities::redirect($this->returnURL);
return;
}
/* No choice made. Show discovery service page. */
$idpList = $this->idplistStructured($this->filterList($this->metadata->getList($this->discoType['metadata'])));
$preferredIdP = $this->getRecommendedIdP();
$t = new SimpleSAML_XHTML_Template($this->config, 'discopower:disco-tpl.php', 'disco');
$t->data['idplist'] = $idpList;
$t->data['preferredidp'] = $preferredIdP;
$t->data['return'] = $this->returnURL;
$t->data['returnIDParam'] = $this->returnIdParam;
$t->data['entityID'] = $this->spEntityId;
$t->data['urlpattern'] = htmlspecialchars(SimpleSAML_Utilities::selfURLNoQuery());
$t->data['rememberenabled'] = $this->config->getBoolean('idpdisco.enableremember', FALSE);
$t->data['rememberchecked'] = $this->config->getBoolean('idpdisco.rememberchecked', FALSE);
$t->data['defaulttab'] = $this->discoconfig->getValue('defaulttab', 0);
$t->show();
}
}
?>
\ No newline at end of file
<?php
if(!array_key_exists('header', $this->data)) {
$this->data['header'] = 'selectidp';
}
$this->data['header'] = $this->t($this->data['header']);
$this->data['head'] = '<script type="text/javascript" src="/' . $this->data['baseurlpath'] . 'resources/jquery.js"></script>';
$this->data['head'] .= '<script type="text/javascript" src="/' . $this->data['baseurlpath'] . 'resources/jquery-ui.js"></script>';
$this->data['head'] .= '<link rel="stylesheet" media="screen" type="text/css" href="/' . $this->data['baseurlpath'] . 'resources/uitheme/jquery-ui-themeroller.css" />';
$this->data['head'] .= '<script type="text/javascript">
$(document).ready(function() {
$("#discotabs > ul").tabs({ selected: ' . $this->data['defaulttab'] . ' });
/*
$("#foodledescr").resizable({
handles: "all"
});
*/
});
</script>';
$this->data['autofocus'] = 'preferredidp';
$this->includeAtTemplateBase('includes/header.php');
foreach ($this->data['idplist'] AS $slist) {
foreach ($slist AS $idpentry) {
if (isset($idpentry['name']))
$this->includeInlineTranslation('idpname_' . $idpentry['entityid'], $idpentry['name']);
if (isset($idpentry['description']))
$this->includeInlineTranslation('idpdesc_' . $idpentry['entityid'], $idpentry['description']);
}
}
?>
<h2><?php echo $this->data['header']; ?></h2>
<form method="get" action="<?php echo $this->data['urlpattern']; ?>">
<input type="hidden" name="entityID" value="<?php echo htmlspecialchars($this->data['entityID']); ?>" />
<input type="hidden" name="return" value="<?php echo htmlspecialchars($this->data['return']); ?>" />
<input type="hidden" name="returnIDParam" value="<?php echo htmlspecialchars($this->data['returnIDParam']); ?>" />
<p><?php
$checked = '';
if ($this->data['rememberchecked']) {
$checked = ' checked="checked"';
}
echo $this->t('selectidp_full');
if($this->data['rememberenabled']) {
echo('<br /><input type="checkbox"' . $checked . ' name="remember" value="1" /> ' . $this->t('remember'));
}
?></p>
<div id="discotabs">
<ul>
<?php
$tabs = array_keys( $this->data['idplist']);
foreach ($tabs AS $tab) {
echo '<li><a href="#' . $tab . '"><span>' . $this->t('{discopower:tabs:' . $tab . '}') . '</span></a></li> ';
}
?>
</ul>
<?php
foreach( $this->data['idplist'] AS $tab => $slist) {
echo '<div id="' . $tab . '">';
if (!empty($this->data['preferredidp']) && array_key_exists($this->data['preferredidp'], $slist)) {
$idpentry = $slist[$this->data['preferredidp']];
echo '<div class="preferredidp">';
echo ' <img src="/' . $this->data['baseurlpath'] .'resources/icons/star.png" style="float: right" />';
if(array_key_exists('icon', $idpentry) && $idpentry['icon'] !== NULL) {
$iconUrl = SimpleSAML_Utilities::resolveURL($idpentry['icon']);
echo '<img style="float: left; margin: 1em; padding: 3px; border: 1px solid #999" src="' . htmlspecialchars($iconUrl) . '" />';
}
echo '<h3 style="margin-top: 8px">' . htmlspecialchars($this->t('idpname_' . $idpentry['entityid'])) . '</h3>';
if (!empty($idpentry['description'])) {
echo ' <p>' . htmlspecialchars($this->t('idpdesc_' . $idpentry['entityid'])) . '<br />';
}
echo('<input id="preferredidp" type="submit" name="idp_' .
htmlspecialchars($idpentry['entityid']) . '" value="' .
$this->t('select') . '" /></p>');
echo '</div>';
}
foreach ($slist AS $idpentry) {
if ($idpentry['entityid'] != $this->data['preferredidp']) {
if(array_key_exists('icon', $idpentry) && $idpentry['icon'] !== NULL) {
$iconUrl = SimpleSAML_Utilities::resolveURL($idpentry['icon']);
echo '<img style="clear: both; float: left; margin: 1em; padding: 3px; border: 1px solid #999" src="' . htmlspecialchars($iconUrl) . '" />';
}
echo ' <h3 style="margin-top: 8px">' . htmlspecialchars($this->t('idpname_' . $idpentry['entityid'])) . '</h3>';
if (!empty($idpentry['description'])) {
echo ' <p>' . htmlspecialchars($this->t('idpdesc_' . $idpentry['entityid'])) . '<br />';
}
echo('<input id="preferredidp" type="submit" name="idp_' .
htmlspecialchars($idpentry['entityid']) . '" value="' .
$this->t('select') . '" /></p>');
}
}
echo '</div>';
}
?>
</div>
</form>
<?php $this->includeAtTemplateBase('includes/footer.php'); ?>
<?php
if(!array_key_exists('header', $this->data)) {
$this->data['header'] = 'selectidp';
}
$this->data['header'] = $this->t($this->data['header']);
$this->data['head'] = '<script type="text/javascript" src="' . $this->data['baseurlpath'] . 'resources/jquery.js"></script>';
$this->data['head'] .= '<script type="text/javascript" src="' . $this->data['baseurlpath'] . 'resources/jquery-ui.js"></script>';
$this->data['head'] .= '<script type="text/javascript">
$(document).ready(function() {
$("#discotabs > ul").tabs();
/*
$("#foodledescr").resizable({
handles: "all"
});
*/
});
</script>';
$this->data['autofocus'] = 'preferredidp';
$this->includeAtTemplateBase('includes/header.php');
foreach ($this->data['idplist'] AS $idpentry) {
if (isset($idpentry['name']))
$this->includeInlineTranslation('idpname_' . $idpentry['entityid'], $idpentry['name']);
if (isset($idpentry['description']))
$this->includeInlineTranslation('idpdesc_' . $idpentry['entityid'], $idpentry['description']);
}
?>
<h2><?php echo $this->data['header']; ?></h2>
<h2>h2</h2>
<h2>FOO</h2>
<form method="get" action="<?php echo $this->data['urlpattern']; ?>">
<input type="hidden" name="entityID" value="<?php echo htmlspecialchars($this->data['entityID']); ?>" />
<input type="hidden" name="return" value="<?php echo htmlspecialchars($this->data['return']); ?>" />
<input type="hidden" name="returnIDParam" value="<?php echo htmlspecialchars($this->data['returnIDParam']); ?>" />
<p><?php
echo $this->t('selectidp_full');
if($this->data['rememberenabled']) {
echo('<br /><input type="checkbox" name="remember" value="1" />' . $this->t('remember'));
}
?></p>
<div id="foodletabs">
<!--
<input type="button" onclick="$('#tabsEx1 > ul').tabs('add', '#appended-tab', 'New Tab');" value="Add new tab">
<input type="button" onclick="$('#tabsEx1 > ul').tabs('add', '#inserted-tab', 'New Tab', 1);" value="Insert tab">
<input type="button" onclick="$('#tabsEx1 > ul').tabs('disable', 1);" value="Disable tab 2">
<input type="button" onclick="$('#tabsEx1 > ul').tabs('enable', 1);" value="Enable tab 2">
<input type="button" onclick="$('#tabsEx1 > ul').tabs('select', 2);" value="Select tab 3">
-->
<ul style="height: 30px;">
<li><a href="#fdescr"><span>Foodle description</span></a></li>
<li><a href="#fcols"><span>Setup columns</span></a></li>
<li><a href="#preview"><span>Preview</span></a></li>
<li><a href="#advanced"><span>Advanced options</span></a></li>
</ul>
<div id="fdescr">
<?php
if (!empty($this->data['preferredidp']) && array_key_exists($this->data['preferredidp'], $this->data['idplist'])) {
$idpentry = $this->data['idplist'][$this->data['preferredidp']];
echo '<div class="preferredidp">';
echo ' <img src="/' . $this->data['baseurlpath'] .'resources/icons/star.png" style="float: right" />';
if(array_key_exists('icon', $idpentry) && $idpentry['icon'] !== NULL) {
$iconUrl = SimpleSAML_Utilities::resolveURL($idpentry['icon']);
echo '<img style="float: left; margin: 1em; padding: 3px; border: 1px solid #999" src="' . htmlspecialchars($iconUrl) . '" />';
}
echo '<h3 style="margin-top: 8px">' . htmlspecialchars($this->t('idpname_' . $idpentry['entityid'])) . '</h3>';
if (!empty($idpentry['description'])) {
echo ' <p>' . htmlspecialchars($this->t('idpdesc_' . $idpentry['entityid'])) . '<br />';
}
echo('<input id="preferredidp" type="submit" name="idp_' .
htmlspecialchars($idpentry['entityid']) . '" value="' .
$this->t('select') . '" /></p>');
echo '</div>';
}
foreach ($this->data['idplist'] AS $idpentry) {
if ($idpentry['entityid'] != $this->data['preferredidp']) {
if(array_key_exists('icon', $idpentry) && $idpentry['icon'] !== NULL) {
$iconUrl = SimpleSAML_Utilities::resolveURL($idpentry['icon']);
echo '<img style="clear: both; float: left; margin: 1em; padding: 3px; border: 1px solid #999" src="' . htmlspecialchars($iconUrl) . '" />';
}
echo ' <h3 style="margin-top: 8px">' . htmlspecialchars($this->t('idpname_' . $idpentry['entityid'])) . '</h3>';
if (!empty($idpentry['description'])) {
echo ' <p>' . htmlspecialchars($this->t('idpdesc_' . $idpentry['entityid'])) . '<br />';
}
echo('<input id="preferredidp" type="submit" name="idp_' .
htmlspecialchars($idpentry['entityid']) . '" value="' .
$this->t('select') . '" /></p>');
}
}
?>
</div>
<div>
</div>
</form>
<?php $this->includeAtTemplateBase('includes/footer.php'); ?>
<?php
require_once('../www/_include.php');
$session = SimpleSAML_Session::getInstance();
try {
$discoHandler = new sspmod_discopower_PowerIdPDisco('saml20');
} catch (Exception $exception) {
/* An error here should be caused by invalid query parameters. */
SimpleSAML_Utilities::fatalError($session->getTrackID(), 'DISCOPARAMS', $exception);
}
try {
$discoHandler->handleRequest();
} catch(Exception $exception) {
/* An error here should be caused by metadata. */
SimpleSAML_Utilities::fatalError($session->getTrackID(), 'METADATA', $exception);
}
?>
\ No newline at end of file
This diff is collapsed.
www/resources/uitheme/images/222222_11x11_icon_arrows_leftright.gif

58 B

www/resources/uitheme/images/222222_11x11_icon_arrows_updown.gif

56 B

www/resources/uitheme/images/222222_11x11_icon_close.gif

62 B

www/resources/uitheme/images/222222_11x11_icon_doc.gif

64 B

www/resources/uitheme/images/222222_11x11_icon_folder_closed.gif

61 B

www/resources/uitheme/images/222222_11x11_icon_folder_open.gif

61 B

www/resources/uitheme/images/222222_11x11_icon_minus.gif

56 B

www/resources/uitheme/images/222222_11x11_icon_plus.gif

61 B

www/resources/uitheme/images/222222_11x11_icon_resize_se.gif

61 B

www/resources/uitheme/images/222222_35x9_colorpicker_indicator.gif.gif

70 B

www/resources/uitheme/images/222222_7x7_arrow_down.gif

52 B

www/resources/uitheme/images/222222_7x7_arrow_left.gif

53 B

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