Add iMuse support

Enable toolbar, sso, assoication and slo

Closes #5993
This commit is contained in:
Jérôme Schneider 2014-11-21 15:34:19 +01:00
parent 8be8f05d72
commit a964a2f11f
24 changed files with 377 additions and 499 deletions

26
cam/auth/imuse.py Normal file
View File

@ -0,0 +1,26 @@
import hashlib
import urllib
from urlparse import parse_qs
from mandaye.auth.saml2 import SAML2Auth
class IMuseAuth(SAML2Auth):
def associate_submit(self, env, values, request, response):
if request.msg:
if type(request.msg) == str:
post = parse_qs(request.msg, request)
else:
post = request.msg.read()
post = parse_qs(post, request)
pwd_field = self.form_values['password_field']
pwd = post[pwd_field][0]
post[pwd_field][0] = hashlib.md5(pwd).hexdigest()
post_values = {}
for key, value in post.iteritems():
post_values[key] = value[0]
request.msg = urllib.urlencode(post_values)
return super(IMuseAuth, self).associate_submit(env, values, request, response)

View File

@ -19,7 +19,8 @@ log_debug: false
sentry_dsn:
[mandaye]
toolbar: false
toolbar: true
offline_toolbar: true
; only sql at the moment
storage_backend: sql
auto_decompress: true
@ -30,8 +31,15 @@ encrypt_sp_password: false
; must be a 16, 24, or 32 bytes long
encrypt_secret:
[template-vars]
idp_url: https://connexion.montpellier-agglo.com
[mappers]
archimed: cam.mappers.archimed_saml
imuse: cam.mappers.imuse
[authentifications]
imuse: cam.auth.imuse.IMuseAuth
[session]
; file, dbm, memory or memcached

29
cam/filters/imuse.py Normal file
View File

@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
from urlparse import parse_qs
from mandaye.server import get_response
from mandaye.response import template_response, _302
def associate(env, values, request, response):
qs = parse_qs(env['QUERY_STRING'])
if qs.has_key('type'):
values['type'] = qs['type'][0]
else:
values['type'] = None
return template_response('imuse/associate.html', values)
def is_user_locally_logged_in(env, request, response):
session = env['beaker.session']
if session.has_key('locally_logged_in') and session['locally_logged_in']:
return True
return False
def is_locally_logged_in(env, values, request, response):
session = env['beaker.session']
if response.msg and response and 'Quitter' in response.msg:
session['locally_logged_in'] = True
else:
session['locally_logged_in'] = False
session.save()

View File

@ -18,6 +18,7 @@ urls = {
'login_url': '/mandaye/login',
'connection_url': '/mandaye/sso',
'associate_url': '/mandaye/associate',
'logout_url': '/mandaye/slo',
}
mapping = [

74
cam/mappers/imuse.py Normal file
View File

@ -0,0 +1,74 @@
from cam.filters import imuse
from mandaye.filters.default import MandayeFilter
form_values = {
'login_url': '/montpellier/extranet/login/usa_index_famille.php',
'post_url': '/montpellier/extranet/login/gen_identification.php',
'post_fields': ['login', 'mdp', 'site', 'groupe'],
'username_field': 'login',
'password_field': 'mdp',
}
urls = {
'login_url': '/mandaye/login',
'connection_url': '/mandaye/sso',
'associate_url': '/montpellier/extranet/login/mandaye_associate',
'disassociate_url': '/mandaye/disassociate',
}
replay_condition = lambda env, response: "OK" in response.msg
is_user_locally_logged_in = imuse.is_user_locally_logged_in
mapping = [
{
'path': r'/$',
'method': 'GET',
'redirect': '/montpellier/extranet'
},
{
'path': r'/mandaye/login$',
'method': 'GET',
'response': {
'auth': 'login',
'values': {
'associate_url': urls['associate_url'],
'next_url': '/montpellier/extranet/famille/usa_famille.php'
},
}
},
{
'path': r'/montpellier/extranet/login/gen_identification.php$',
'method': 'POST',
'on_request': [
{'filter': MandayeFilter.store_request_content_buffer}
],
'on_response': [{'auth': 'store_credentials_in_session'}]
},
{
'path': r'/montpellier/extranet/login/mandaye_associate$',
'method': 'GET',
'response': {
'filter': imuse.associate,
},
},
{
'path': r'/montpellier/extranet/login/mandaye_associate$',
'method': 'POST',
'response': {
'auth': 'associate_submit',
},
},
{
'path': r'/montpellier/extranet/login/gen_logout.php$',
'on_response': [{'auth': 'logout',}],
},
{
'path': r'/montpellier/extranet/.*.php$',
'method': 'GET',
'on_response': [{
'content-types': ['text/html'],
'filter': imuse.is_locally_logged_in,
}],
},
]

View File

@ -1,498 +0,0 @@
/* theme derived and inspired by TerraFirma
* <http://www.oswd.org/design/information/id/3557/>
*/
html, body {
margin: 0;
font-family: sans-serif;
font-size: 12px;
}
body#iframe {
background: white;
}
html {
background: #F9F9F7 url(../images/a1.gif) repeat-x;
color: #44b2cb;
}
a
{
color: #44b2cb;
text-decoration: underline;
}
a:hover
{
text-decoration: none;
}
div#wrap {
background: white;
width: 640px;
margin: 5em auto;
padding: 15px;
-moz-border-radius: 6px;
-webkit-border-radius:6px;
-moz-box-shadow: 0 0 4px rgba(0,0,0,0.75);
-webkit-box-shadow: 0 0 4px rgba(0,0,0,0.75);
position: relative;
}
#header
{
position: absolute;
background: url(../images/a8.png) repeat-x;
-moz-border-radius: 6px 0 0 6px;
-webkit-border-radius: 6px 0 0 6px;
width: 450px;
height: 92px;
color: #fff;
padding-left: 20px;
}
#header h1
{
font-size: 23px;
letter-spacing: -1px;
padding-top: 30px;
margin: 0;
}
#header span
{
margin: 0;
font-size: 13px;
font-weight: normal;
color: #FCE2CA;
}
#splash
{
position: absolute;
right: 20px;
background: url(../images/eo.png) no-repeat;
width: 153px;
height: 92px;
-moz-border-radius: 0 6px 6px 0;
-webkit-border-radius: 0 6px 6px 0;
}
div#content {
margin: 1em 1ex;
margin-top: 130px;
padding: 1ex;
}
div#content h2 {
margin-top: 0;
font-weight: normal;
color: #656551;
font-size: 18px;
letter-spacing: -1px;
line-height: 25px;
margin-bottom: 20px;
padding: 0 0 10px 15px;
position: relative;
top: 4px;
background: url(../images/a22.gif) bottom repeat-x;
}
#footer
{
font-size: 70%;
position: relative;
clear: both;
height: 66px;
text-align: center;
line-height: 66px;
background-image: url(../images/a8.png);
color: #fff;
}
#footer a
{
color: #8C8C73;
}
form#login-form p {
float: left;
width: 40%;
}
form#login-form input.submit {
float: right;
width: 18%;
margin-top: 30px;
}
div.login-actions {
clear: both;
padding-top: 1em;
}
div.login-actions p {
margin: 0;
}
form p {
margin: 0 0 1em 0;
}
form p label {
display: block;
}
form p input,
form p textarea {
margin-left: 10px;
}
ul.messages {
margin: 0;
padding: 0;
list-style: none;
}
ul.messages li.error {
color: #e80404;
}
ul.errorlist {
margin: 0;
padding: 0;
color: #e80404;
list-style: none;
}
input, textarea {
padding: 5px;
border: 1px solid #cccccc;
color:#666666;
background: white;
color: black;
}
textarea:focus, input[type="text"]:focus, input[type="password"]:focus {
border: 1px solid #4690d6;
color:#333333;
}
input[type=submit] {
color: #ffffff;
background:#4690d6;
border: 1px solid #2a567f;
font-weight: bold;
padding: 2px 8px 2px 8px;
margin: 0;
cursor: pointer;
}
input[type=submit]:hover {
border-color: #0e1d2b;
}
form#login-form ul.errorlist {
margin-bottom: 1em;
width: 80%;
font-weight: normal;
}
/* OpenID Stuff */
#openid_btns, #openid_btns br {
clear: both;
}
#openid_highlight a {
border: 1px solid #888;
}
#openid_input_area input[type=submit] {
padding-top: 0;
margin-top: 0;
margin-left: 1em;
}
.openid_large_btn {
width: 100px;
height: 60px;
border: 1px solid #DDD;
margin: 3px;
float: left;
}
.openid_small_btn {
width: 24px;
height: 24px;
border: 1px solid #DDD;
margin: 3px;
float: left;
}
a.openid_large_btn:focus {
outline: none;
}
a.openid_large_btn:focus {
-moz-outline-style: none;
}
.openid_selected {
border: 4px solid #DDD;
}
#openid_input_area {
clear: both;
padding-top: 2.5em;
}
li.indented {
margin-left: 50px;
}
ul.NoBullet {
list-style-type: none;
}
div#content h4 {
margin-bottom: 5px;
margin-top: 30px;
}
div#content p {
margin-top: 0;
}
div.errors {
margin: 0;
padding: 0;
color: #e80404;
list-style: none;
}
div#breadcrumb {
font-size: 80%;
margin-bottom: 1em;
}
div#user {
position: absolute;
top: 115px;
right: 12px;
}
a#logout {
font-size: 100%;
}
.ui-tabs .ui-tabs-hide {
display: none;
}
h4 {
padding-left: 0.5em;
}
h4 + div, div#profile {
padding-left: 1em;
}
div#menu {
position: relative;
background: #46461F url(../images/a17.gif) repeat-x;
height: 67px;
padding: 0px 20px 0px 5px;
margin: 136px 0px 0px 0px;
}
#menu ul
{
padding: 0;
margin: 0;
}
#menu ul li
{
display: inline;
line-height: 52px;
padding-left: 3px;
}
#menu ul li.first
{
border-left: 0px;
}
#menu ul li a
{
background-color: transparent;
background-repeat: repeat-x;
padding: 8px 12px 8px 12px;
font-size: 12px;
color: #fff;
font-weight: bold;
}
#menu ul li a:hover
{
background: #fff url(../images/a18.gif) repeat-x top;
color: #4A4A24;
text-decoration: none;
}
#eo
{
position: absolute;
top: 0px;
line-height: 52px;
color: #BDBDA2;
right: 30px;
font-weight: bold;
font-size: 12px;
letter-spacing: -1px;
}
#eo a {
color: inherit;
text-decoration: none;
}
ul#tab-nav {
list-style: none;
padding: 0;
width: 160px;
float: left;
}
ul#tab-nav li {
line-height: 300%;
position: relative;
right: -1px;
border: 1px solid transparent;
}
ul#tab-nav li.ui-tabs-selected {
border: 1px solid #ccc;
border-right: 1px solid white;
}
ul#tab-nav a {
display: block;
padding-left: 1ex;
outline: none;
-moz-user-focus:ignore;
}
ul#tab-nav a:hover {
}
ul#tab-nav a:active {
}
/* XXX: add a class to divs, so it works in IE */
div#tabs > div {
border: 1px solid #ccc;
float: left;
width: 420px;
padding: 10px;
min-height: 26em;
}
a.bigbutton {
display: block;
-moz-border-radius: 6px;
-webkit-border-radius:6px;
border: 1px solid black;
margin: 2em 0;
line-height: 300%;
text-align: center;
text-decoration: none;
font-weight: bold;
-webkit-box-shadow: 0 0 4px rgba(0,0,0,0.75);
-moz-box-shadow: 0 0 4px rgba(0,0,0,0.75);
}
a.bigbutton:hover {
background: #eee;
}
div#providers {
display: none;
}
#modalOverlay {
height:100%;
width:100%;
position:fixed;
left:0;
top:0;
z-index:3000;
background-color: rgba(0, 0, 0, 0.8);
cursor:wait;
}
div#popup {
display: none;
position:fixed;
width:500px;
left:50%;
margin-left:-250px;
z-index:3100;
top: 10%;
}
div#popup div {
position: relative;
margin: 0;
background: white;
border: 1px solid black;
border-color: #333 black black #333;
}
div#popup h2 {
text-align: center;
}
div#popup ul {
max-height: 70px;
overflow: auto;
margin: 0 1em 1em 1em;
padding: 0 1em 1em 1em;
}
div#popup h3 {
margin-bottom: 4px;
padding-left: 10px;
}
div#popup p {
margin: 5px;
}
div#popup a#close {
float: right;
padding: 1ex;
}
a.roleid_button {
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
background: #5C5C5C;
color: #44b2cb;
font-weight: bold;
padding-top: 5px;
padding-bottom: 5px;
padding-right: 10px;
padding-left: 10px;
margin: 0;
cursor: pointer;
text-decoration: none;
}
a.roleid_button:hover {
background: black;
}

View File

@ -0,0 +1,73 @@
#mandaye-toolbar {
font-family: 'Open Sans', 'Helvetica Neue', arial, sans-serif;
width: 100%;
position: fixed;
height: 36px;
top: 0px;
padding: 0;
background: black;
font-size: 14px;
z-index: 999;
}
.mandaye-toolbar-left {
float: left;
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
vertical-align: top;
padding-left: 12px;
padding-right: 12px;
}
.mandaye-toolbar-right {
float: right;
margin-right: 15px;
padding: 0;
border: 0;
}
.mandaye-toolbar-logo {
float: left;
padding: 4px 15px 0px 15px;
}
.mandaye-toolbar-link a:hover {
background: grey;
text-decoration: none;
}
.mandaye-toolbar-btn-right {
margin-left: 15px;
vertical-align: top;
z-index: 999;
}
.mandaye-toolbar-link ul {
vertical-align: top;
}
.mandaye-toolbar-link li {
list-style-type: none;
float: right;
}
.mandaye-toolbar-link a {
color: white;
text-decoration: none;
padding: 11px 16px 11px 16px;
}
.mandaye-toolbar-link {
display: inline-block;
height: 100%;
float: right;
margin: 10px 0 0 0;
}
.menuWidth {
top: 36px;
}
body { margin: 36px 0 0 0; }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 407 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 367 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 295 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 222 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 666 B

BIN
cam/static/images/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 781 B

View File

@ -0,0 +1,115 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="fr-FR" xml:lang="fr-FR" >
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="language" content="fr-FR" />
<link rel="icon" href="../favicon.ico"/>
<!-- JAVASCRIPT -->
<script type="text/javascript" src="../includes_extranet/javascript.php?files=../includes/functions.js,../includes_extranet/functions_web.js,../login/gen_index_generique.js,../includes/md5.js,../includes/functions_data.js" ></script>
<!-- Style CSS -->
<style type="text/css" title="currentStyle" media="all">
@import "../../DATA/extranet/CSS/defaut.css";
@import "../style/jquery.css";
</style>
<title>Extranet iMuse : Association accès usager</title>
</head>
<body onload="centrerContenuVertical();centrerBlocVertical('CONTENU_FIELDSET','INDEX_FLD_IDENTIFICATION');document.getElementById('INDEX_USER_PWD').focus();" onkeypress="" onresize="centrerContenuVertical();">
<input type="hidden" value="off" id="INTERFACE_MODE_ACCESSIBILITE"></input>
<input type="hidden" value="w" id="RACCOURCIS_DESACTIVER_TABLEAU"></input>
<input type="hidden" value="NAV_NON_SUPPORTE" id="INTERFACE_NAVIGATEUR"></input>
<!-- Menus (optionnel) -->
<!-- BEGIN MENU -->
<!-- END MENU -->
<!-- Contenu principal -->
<div id="CONTENU">
<fieldset id="INDEX_FLD_IDENTIFICATION" class="fld_identification">
<legend>Lier votre compte conservatoire</legend>
<div id="CONTENU_FIELDSET">
<div class="LogoCenter">
<img src="../img_extranet/logo_login.png" id="INDEX_LOGO_IMUSE" alt="Logo d'iMuse"/><br/>
</div>
<br/>
% if type == 'first':
<p>Veuillez saisir votre identifiant et votre mot de passe conservatoire afin de les lier avec votre compte citoyen Montpellier Agglomération.
La prochaine fois que vous vous connecterez sur iMuse via votre compte citoyen, vous serez directement authentifié sur iMuse.</p>
% endif
% if type == 'badlogin':
<p style="color: red;">
L'identifiant ou le mot de passe saisi est incorrect, vérifiez la syntaxe et réessayez.
</p>
% endif
% if type == 'failed':
<p style="color: red;">
Vos identifiants pour le conservatoire ne fonctionnent plus ! Merci de les ressaisir.
</p>
% endif
<form action="mandaye_associate?next_url=/montpellier/extranet/famille/usa_famille.php" method="POST">
<input type="hidden" name="groupe" value="famille">
<table id="INDEX_TBL_LOGIN">
<tr class="">
<td class="alignRight"><label id="INDEX_LABEL_SITE_NUMERO" for="INDEX_SITE_NUMERO">Site</label></td>
<td>
<select name="site" id="INDEX_SITE_NUMERO" class="login_site_numero" >
<option value="2">Conservatoire</option>
</select>
</td>
</tr>
<tr>
<td class="alignRight"><label id="INDEX_LABEL_USER" for="INDEX_USER_ID">Identifiant</label></td>
<td><input type="text" name="login" id="INDEX_USER_ID" class="login_user_id" value="" /></td>
</tr>
<tr>
<td class="alignRight"><label id="INDEX_LABEL_PWD" for="INDEX_USER_PWD">Mot de passe</label></td>
<td><input type="password" name="mdp" id="INDEX_USER_PWD" class="login_user_pwd" /></td>
</tr>
</table>
<br/>
<div class="alignCenter">
<label ></label>
</div>
<div class="alignCenter">
<input type="submit" name="login" id="INDEX_BT_LOGIN" value="S'asscoier" alt="S'associer à l'extranet" />
<br/><br/>
<a class="" href="#" id="INDEX_MDP_PERDU" onclick="open_popup_getpass();" alt="Accéder à la fenêtre de demande de mot de passe." onfocus="disable_onkeypress(true);" onblur="disable_onkeypress(false);">Mot de passe perdu</a>
</div>
</form>
<br/>
<a href="../accessibilite/gen_accessibilite.php" id="INDEX_ACCESSIBILITE" alt="Accéder à l'accessibilité" class="" onfocus="disable_onkeypress(true);" onblur="disable_onkeypress(false);">Accessiblité</a>
</div>
</fieldset>
<div class="alignCenter">
<p class="fontsize11">Navigateur recommandé : Mozilla Firefox 3.6 ou supérieur</p>
</div>
<script>
//on centre le contenu du fieldset verticalement code directement dans la page à cause d'IE (élément non centré une fois sur 2)
if(document.getElementById('INTERFACE_NAVIGATEUR').value=="IE" || document.getElementById('INTERFACE_NAVIGATEUR').value=="BAD_VERSION_NAV_IE")
{
centrerBlocVertical('CONTENU_FIELDSET','INDEX_FLD_IDENTIFICATION');
}
</script>
</div>
<!-- Footer -->
<div id="PIED_EXTRANET">
<span id="PIED_EXTRANET_GAUCHE">© Saiga Informatique</span>
<span id="PIED_EXTRANET_CENTRE">v1.5.3.0</span>
<span id="PIED_EXTRANET_DROIT">Extranet iMuse®</span>
</div>
</body>
</html>

View File

@ -0,0 +1,38 @@
<div id="mandaye-toolbar">
<div class="mandaye-toolbar-left">
<div class="mandaye-toolbar-logo">
<a href="http://www.montpellier3m.fr/">
<img src="${static_url}/images/logo.png" alt="Montpellier Méditerranée Métropole" title="Montpellier Méditerranée Métropole" />
</a>
</div>
</div>
<div class="mandaye-toolbar-right">
<ul class="mandaye-toolbar-link">
% if is_login:
<li>
<a href="/mandaye/logout?next_url=/montpellier/extranet/login/usa_index_famille.php" title="Cliquer ici pour vous déconnecter de ${site_name} et du portail citoyen">Me déconnecter</a>
</li>
% if account:
<li>
<a href="javascript:mandaye_disassociate_logout('${urls['disassociate_url']}', '${account['sp_login']}', ${account['id']}, '/mandaye/logout?next_url=/montpellier/extranet/login/usa_index_famille.php')" title="Cliquer ici pour supprimer l'association entre ce compte et votre compte citoyen.">Me désassocier</a>
</li>
% endif
% elif is_user_locally_logged_in:
% if not is_user_associated:
<li>
<a href="${urls['connection_url']}" title="Cliquer ici pour lier votre compte citoyen avec ${site_name}">Lier mon compte</a>
</li>
% endif
% else:
<li>
<a href="/mandaye/sso" title="Cliquer ici pour vous connecter sur ${site_name} en utilisant votre compte citoyen 3M">Me connecter avec mon compte citoyen</a>
</li>
% endif
% if is_login or is_user_associated:
<li>
<a href="${idp_url}/accounts" title="Cliquer ici pour vous rendre sur votre compte citoyen">Mon compte citoyen</a>
</li>
% endif
</ul>
</div>
</div>

12
conf.d/imuse Normal file
View File

@ -0,0 +1,12 @@
{
"site_name": "imuse",
"server_name": ["imuse.local:8000"],
"location": "/",
"target": "https://www.imuse-demo.fr",
"mapper": "imuse",
"auth_type": "imuse",
"sp_logout_url": "/montpellier/extranet/login/gen_logout.php",
"saml2_idp_metadata": "http://authentic.local/idp/saml2/metadata",
"saml2_signature_public_key": "certs/saml.crt",
"saml2_signature_private_key": "certs/saml.key"
}