Commit 1d24b2a4 authored by haemmer's avatar haemmer

Implemented changes for #1849

parent 043036ce
......@@ -19,22 +19,26 @@ Description
The SWITCHwayf is an implementation of the Shibboleth WAYF and SAML2 Discovery
Service protocol for use withing a Shibboleth architecture.
The features of the SWITCHwayf are:
Some of the Features:
- Preselecting an entry in drop down list by:
- Supports Discovery Service and the Shibboleth authentication request protocol
- Supports processing SAML2 metadata files
- Search-as-you type or selection from a list of organisations
- Various customizations options for header, footer, language strings etc.
- I18N support, currently language packs for en, de, it, fr and some other
languages are included
- HTML code generation for embedding the WAYF directly into a web page
- Support for remembering IdP selection accross different services (when
Embedded WAYF is used)
- Preselecting entry in drop down list by
- SAML common domain cookie that contains selected Identity Providers
- resource path info hint (e.g.
/WAYF/unige.ch?entityID=https://... pre-selects 'University of Geneva',
depends of course on the ID scheme a federation uses
/WAYF/unige.ch?shire=https://... selects University of Geneva, depends
of course on the ID scheme a federation uses)
- Kerberos preselection
- IP range preselection
- IP reverse DNS lookup preselection
- Supports embedding the WAYF directly into a web page by means of Javascript
- Supports SAML2 metadata
- Supports Discovery Service and the Shibboleth authentication request protocol
- Various customizations options for header, footer, language strings etc.
- Support for remembering IdP selection permanently
- I18N support, currently locales for en, de, it, fr, pt and ja are included
- Transparent redirection mode, e.g. /WAYF/unige.ch/redirect?shire=https://...
-------------------------------------------------------------------------------
......@@ -68,22 +72,28 @@ Customize page footer
* HTML Error: custom-error.php
Customize error messages
* CSS Styles: css/custom-styles.css
Customize CSS styles that are printed inline in header. The custom styles are
loaded in addition to the default styles. Therefore, they can be used to
overwrite the default CSS styles.
* CSS Main Style: css/custom-styles.css
Customize CSS styles that are loaded in addition to the default-styles.css.
Therefore, they can be used to overwrite the default CSS styles.
* CSS Improved Drop Down Style: css/custom-ImprovedDropDown.css
Customize CSS styles to alter the appearance of the improved drop-down list,
both for the stand-alone WAYF as well as the Embedded WAYF. The styles are
loaded in addition to the default-ImprovedDropDown.css.
* Languages: custom-languages.php
Can be used to change default or add new language strings. The custom
languages strings in addition to the default styles. Therefore, they can be
used to overwrite the default CSS styles.
If the above files don't exist yet, the default templates and settings
will be used. To create a custom template, copy the default files with:
If a custom file doesn't exist yet, the default templates and settings
are used. To create a custom template, copy the default files with:
`cp default-{$template}.php custom-{$template}.php`
where {$template} stands for the file you want to customize.
where {$template} stands for the file you want to customize. Unless otherwise
mentioned the custom files replace the default files completely. Please read the
above information for each custom file.
-------------------------------------------------------------------------------
......
......@@ -516,6 +516,22 @@ if (
printError($message);
exit;
} elseif(isRequestType('styles.css')){
header('Content-Type: text/css');
printCSS('styles.css');
exit;
} elseif(isRequestType('ImprovedDropDown.css')){
header('Content-Type: text/css');
printCSS('ImprovedDropDown.css');
exit;
} elseif(isRequestType('snippet.html')){
// Check if this feature is activated at all
......
/* Improved Drop Down CSS */
/* textbox part of the dropdown list */
.idd_textbox {
border: 1px #848484 solid;
vertical-align: middle;
}
.idd_textbox:hover {
border-color: black;
box-shadow: 1px 1px 8px #999999;
-webkit-box-shadow: 1px 1px 8px #999999;
-moz-box-shadow: 1px 1px 8px #999999;
}
/* dropdown arrow control */
.idd_icon
{
border-top: 1px #999999 solid;
border-right: 1px #999999 solid;
border-bottom: 1px #999999 solid;
border-left: 0;
}
.idd_icon:hover
{
border-color: black;
box-shadow: 1px 1px 8px #999999;
-webkit-box-shadow: 1px 1px 8px #999999;
-moz-box-shadow: 1px 1px 8px #999999;
}
/* Dropdown list */
div.idd_list {
border: thin solid #848484;
background-color: #FFFFFF;
padding-left: 5px;
padding-top: 0px;
padding-bottom: 0px;
z-index: 900;
text-align:left;
box-shadow: 1px 1px 4px #999999;
-webkit-box-shadow: 1px 1px 4px #999999;
-moz-box-shadow: 1px 1px 4px #999999;
}
/* Option Group headers */
.idd_listItemGroupHeader
{
color: #555;
font-family:Verdana, sans-serif;
font-size: 12px;
padding-bottom: 2px;
font-weight: bold;
text-align: left;
}
/* Dropdown list items except group headers */
.idd_listItem
{
font-family: Verdana, sans-serif;
font-size: 12px;
height: 16px;
margin: 0;
margin-bottom: 4px;
text-align: left;
}
/* Dropdown list items nested under group headers */
.idd_listItem_Nested {
margin-left: 15px;
display: block;
}
/* mouseover on all list items except group headers */
.idd_listItem_Hover
{
color: black;
background-color: #B5D5FF;
}
/* List items that are disabled */
.idd_listItem_Disabled {
color: #C0C0C0;
cursor: default;
}
.idd_listItemText {
margin-bottom: 2px;
margin-left: 20px;
}
.idd_listItemLogo {
margin-right: 4px;
vertical-align:top;
}
.user_idp_iddwrap {
margin: 10px;
}
\ No newline at end of file
......@@ -184,101 +184,3 @@ input {
html, body, form, fieldset, p, div, h1, h2, h3, h4, h5, h6 {
-webkit-text-size-adjust:none;
}
/* Improved Drop Down CSS */
/* textbox part of the dropdown list */
.idd_textbox {
border: 1px #848484 solid;
vertical-align: middle;
}
.idd_textbox:hover {
border-color: black;
box-shadow: 1px 1px 8px #999999;
-webkit-box-shadow: 1px 1px 8px #999999;
-moz-box-shadow: 1px 1px 8px #999999;
}
/* dropdown arrow control */
.idd_icon
{
border-top: 1px #999999 solid;
border-right: 1px #999999 solid;
border-bottom: 1px #999999 solid;
border-left: 0;
}
.idd_icon:hover
{
border-color: black;
box-shadow: 1px 1px 8px #999999;
-webkit-box-shadow: 1px 1px 8px #999999;
-moz-box-shadow: 1px 1px 8px #999999;
}
/* Dropdown list */
div.idd_list {
border: thin solid #848484;
background-color: #FFFFFF;
padding-left: 5px;
padding-top: 0px;
padding-bottom: 0px;
z-index: 900;
text-align:left;
box-shadow: 1px 1px 4px #999999;
-webkit-box-shadow: 1px 1px 4px #999999;
-moz-box-shadow: 1px 1px 4px #999999;
}
/* Option Group headers */
.idd_listItemGroupHeader
{
color: #555;
font-family:Verdana, sans-serif;
font-size: 12px;
padding-bottom: 2px;
font-weight: bold;
text-align: left;
}
/* Dropdown list items except group headers */
.idd_listItem
{
font-family: Verdana, sans-serif;
font-size: 12px;
height: 16px;
margin: 0;
margin-bottom: 4px;
text-align: left;
}
/* Dropdown list items nested under group headers */
.idd_listItem_Nested {
margin-left: 15px;
display: block;
}
/* mouseover on all list items except group headers */
.idd_listItem_Hover
{
color: black;
background-color: #B5D5FF;
}
/* List items that are disabled */
.idd_listItem_Disabled {
color: #C0C0C0;
cursor: default;
}
.idd_listItemText {
margin-bottom: 2px;
margin-left: 20px;
}
.idd_listItemLogo {
margin-right: 4px;
vertical-align:top;
}
......@@ -130,6 +130,13 @@ var wayf_return_url = "https://my-app.switch.ch/aai/index.php?page=show_welcome"
// [Optional, default: commented out]
// var wayf_use_discovery_service = false;
// If enabled, the Embedded WAYF uses the improved drop down list feature
// will transform the list of organisations into a search-field while keeping
// its original list character.
// [Optional, default: false]
// var wayf_use_improved_drop_down_list = false
// Force the user's Home Organisation selection to be remembered for the
// current browser session. If wayf_show_remember_checkbox is true
// the checkbox will be shown but will be read only.
......@@ -202,8 +209,19 @@ var wayf_return_url = "https://my-app.switch.ch/aai/index.php?page=show_welcome"
// }
// EntityIDs, Names and SSO URLs of Identity Providers from other federations
// that should be added to the drop-down list
// The IdPs will be displayed in the sequence they are defined
// that should be added to the drop-down list.
// name: Name of the Identity Provider to display
// entityID: SAML entityID/providerID of this Identity Provider
// SAML1SSOurl: Endpoint for the SAML1 SSO handler
// logoURL: URL or inline image data of that IdP. Image must be a 16x16 pixel image
// and it should be loaded from an HTTPS URL. Otherwise IE and other
// browsers complain
// data: Non-visible data that may be used to find this Identity Provider when the
// improve drop-down feature is enabled. This string for example can include
// the domain names, abbreviations, localities or alternative names of the
// organisation. Basically, anything the user could use to search his institution.
//
// The IdPs will be displayed in the order they are defined
// [Optional, commented out by default]
// var wayf_additional_idps = [ ];
......@@ -212,11 +230,15 @@ var wayf_return_url = "https://my-app.switch.ch/aai/index.php?page=show_welcome"
//
// {name:"International University X",
// entityID:"urn:mace:example.org:example.university.org",
// SAML1SSOurl:"https://int.univ.org/shibboleth-idp/SSO"},
// SAML1SSOurl:"https://int.univ.org/shibboleth-idp/SSO",
// logoURL:"https://int.univ.org/favicon.ico",
// data:"univ.org université intérnationale X"},
//
// {name:"Some Other University",
// entityID:"https://other.univ.edu/idp/shibboleth",
// SAML1SSOurl:"https://other.univ.edu/shibboleth-idp/SSO"},
// SAML1SSOurl:"https://other.univ.edu/shibboleth-idp/SSO",
// logoURL:"https://other.univ.edu/favicon.ico",
// data:"other.univ.org autre université intérnationale X"},
// ];
......
......@@ -7,6 +7,8 @@
<meta name="keywords" content="Home Organisation, Discovery Service, WAYF, Shibboleth, Login, AAI">
<meta name="description" content="Choose your home organisation to authenticate">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
<link rel="stylesheet" href="<?php echo $_SERVER['SCRIPT_NAME'] ?>/styles.css" type="text/css">
<link rel="stylesheet" href="<?php echo $_SERVER['SCRIPT_NAME'] ?>/ImprovedDropDown.css" type="text/css">
<script type="text/javascript" src="<?php echo $javascriptURL ?>/jquery.js"></script>
<script type="text/javascript" src="<?php echo $javascriptURL ?>/improvedDropDown.js"></script>
<script type="text/javascript">
......@@ -97,11 +99,6 @@
-->
</script>
<style type="text/css">
<!--
<?php printCSS() ?>
-->
</style>
</head>
<body>
......
......@@ -6,8 +6,8 @@
<div id="userInputArea">
<p class="promptMessage"><?php echo getLocalString('permanent_cookie_notice'); ?></p>
<div style="text-align: center">
<select name="permanent_user_idp" id="userIdPSelection" disabled="disabled">
<option value="-"><?php echo $permanentUserIdPName ?></option>
<select name="permanent_user_idp" id="userIdPSelection">
<option value="<?php echo $permanentUserIdP ?>" logo="<?php echo $permanentUserIdPLogo ?>"><?php echo $permanentUserIdPName ?></option>
</select>
<input type="submit" accesskey="c" name="clear_user_idp" value="<?php echo getLocalString('delete_permanent_cookie_button') ?>">
<?php if (isValidShibRequest()) : ?>
......
......@@ -6,7 +6,7 @@
<div id="userInputArea">
<p class="promptMessage"><?php echo getLocalString('permanently_remember_selection') ?></p>
<div style="text-align: center">
<select name="user_idp" id="userIdPSelection">
<select name="user_idp" id="userIdPSelection">
<option value="-" <?php echo $defaultSelected ?>><?php echo getLocalString('select_idp') ?> ...</option>
<?php printDropDownList($IDProviders, $selectedIDP) ?>
</select>
......
......@@ -481,17 +481,17 @@ function getIdPPathInfoHint(){
/******************************************************************************/
// Parses the Kerbores realm out of the string and returns it
function composeOptionTitle($IdPValues){
$title = '';
function composeOptionData($IdPValues){
$data = '';
foreach($IdPValues as $key => $value){
if (is_array($value) && isset($value['Name'])){
$title .= ' '.$value['Name'];
$data .= ' '.$value['Name'];
} elseif (is_array($value) && isset($value['Keywords'])) {
$title .= ' '.$value['Keywords'];
$data .= ' '.$value['Keywords'];
}
}
return $title;
return $data;
}
/******************************************************************************/
......
......@@ -125,7 +125,6 @@ function getWrapperElement(sourceElement) {
newWrapperElement.attr('id', newID + idd_wrap_suffix)
.css('border-style','none')
.css('white-space', 'nowrap')
.css('margin', '0')
.css('padding', '0')
.click(function () {return false;});
......@@ -138,15 +137,24 @@ function addLogoToTextElement(newTextElement, url){
return;
}
if (url){
newTextElement.css('text-indent' , '20px');
newTextElement.css('background-color' , '#fff');
newTextElement.css('background-repeat' , 'no-repeat');
newTextElement.css('background-position' , '1px 1px');
newTextElement.css('background-image' , 'url(' + url + ')');
} else {
if (!url){
newTextElement.css('text-indent' , '0');
newTextElement.css('background' , '#fff');
return;
}
newTextElement.css('text-indent' , '20px');
// IE Fix
newTextElement.css('line-height' , '18px');
// Add logo as background
newTextElement.css('background-color' , '#fff');
newTextElement.css('background-repeat' , 'no-repeat');
newTextElement.css('background-position' , '1px 1px');
if (url.match(/^url\(/)){
newTextElement.css('background-image' , url);
} else {
newTextElement.css('background-image' , 'url(' + url + ')');
}
}
......@@ -157,13 +165,13 @@ function getTextElement(sourceElement, imgElement) {
var newTextElement = $('<input type="text" />');
// For some reason we have to substract 2px from the height when using <!DOCTYPE HTML>
var quirksModeOffset = 2;
var controlWidth = Math.max(sourceElement.innerWidth() - imgElement.outerWidth(),40);
var controlWidth = Math.max(sourceElement.outerWidth() - imgElement.outerWidth(),40);
newTextElement.attr('id', newID + idd_text_suffix)
.addClass('idd_textbox')
.attr('value', sourceElement.find('option:selected').text())
.css('height', (imgElement.innerHeight() - quirksModeOffset) + 'px')
.css('height', Math.max((imgElement.innerHeight() - quirksModeOffset), 18) + 'px')
.css('font-family', sourceElement.css('font-family'))
.css('font-size', sourceElement.css('font-size'))
.css('border-width', '1px')
......@@ -241,6 +249,7 @@ function getTextElement(sourceElement, imgElement) {
if (obj.target.value != ''){
obj.target.savedValue = obj.target.value;
obj.target.value = '';
obj.target.savedLogo = $(obj.target).css('background-image');
addLogoToTextElement($(obj.target), null);
}
......@@ -251,6 +260,7 @@ function getTextElement(sourceElement, imgElement) {
newTextElement.focusout(function (obj) {
if (obj.target.value == '' && obj.target.savedValue != ''){
obj.target.value = obj.target.savedValue;
addLogoToTextElement($(obj.target), obj.target.savedLogo);
}
});
......@@ -261,12 +271,14 @@ function getImageElement(sourceElement,iconPath) {
var newID = sourceElement.attr('id');
var newImgElement = $('<img />');
var quirksModeOffset = jQuery.support.boxModel ? 0 : 2;
var imageSize = sourceElement.outerHeight() + quirksModeOffset;
newImgElement.attr('id', newID + idd_icon_suffix)
.attr('src',iconPath)
.addClass('idd_icon')
.css('cursor', 'pointer')
.css('height', (sourceElement.outerHeight() - quirksModeOffset) + 'px')
.css('height', imageSize + 'px')
.css('width', imageSize + 'px')
.css('vertical-align','middle')
.css('overflow','hidden')
.css('display','inline-block')
......@@ -316,6 +328,7 @@ function getListElement(sourceElement) {
.css('overflow-y','auto')
.css('overflow-x', 'hidden')
.css('padding-right','20px')
.css('background-color','white')
.addClass('idd_list')
.mouseenter(function () { suspendTextBoxExitHandler = true; })
.mouseleave(function () { suspendTextBoxExitHandler = false; });
......@@ -392,7 +405,7 @@ function populateListItem(newListControl, optionItem) {
if (displayLogos){
if (optionItem.attr('logo')){
logo = '<img src="' + optionItem.attr('logo') + '" width="16" height="16" class="idd_listItemLogo" />';
} else if (optionItem.attr('title')){
} else if (optionItem.attr('data')){
// Add an invisible 1px gif inline
logo = '<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" width="16" height="16" class="idd_listItemLogo" />';
}
......@@ -411,10 +424,17 @@ function populateListItem(newListControl, optionItem) {
newListItem.attr('savedValue', optionItem.val())
.attr('title', title)
.attr('savedTitle', optionItem.attr('title'))
.css('white-space','nowrap')
.css('cursor','pointer');
// Move data element to list element
if (optionItem.attr('data')){
newListItem.attr('data', optionItem.attr('data'))
optionItem.removeAttr('data');
} else {
newListItem.attr('data', optionItem.text())
}
// Move logo from source element to list
if (optionItem.attr('logo')){
newListItem.attr('logo', optionItem.attr('logo'));
......@@ -699,7 +719,7 @@ function doesListItemMach(listItem, compareText) {
}
// Compares a listItem (jQuery object representing item in dropdown list) to compareText
return (!listItem.hasClass('idd_listItem_Disabled')) && (stringContainsCaseInsensitive(listItem.text(), compareText) || stringContainsCaseInsensitive(listItem.attr('savedTitle'), compareText))
return (!listItem.hasClass('idd_listItem_Disabled')) && (stringContainsCaseInsensitive(listItem.text(), compareText) || stringContainsCaseInsensitive(listItem.attr('data'), compareText))
}
function getIsDirty(textControl) {
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment