Améliorations et correctifs

This commit is contained in:
Pierre Coimbra
2020-03-28 15:02:42 +01:00
parent 8fad3725b6
commit ba3c64d182
106 changed files with 17902 additions and 53 deletions

View File

@@ -0,0 +1,7 @@
## -*- coding: utf-8 -*-
<%inherit file="navbar.tmpl"/>
<%block name="core">
<div class="alert alert-warning alert-dismissible" role="alert">
<strong>404 Page not found,</strong> URL not available
</div>
</%block>

View File

@@ -0,0 +1,31 @@
## -*- coding: utf-8 -*-
<%inherit file="navbar.tmpl"/>
<%block name="core">
<div class="row clearfix top-buffer bottom-buffer">
<div class="col-md-2 column">
</div>
<div class="col-md-12 column">
<div class="well well-sm">
<form method='POST' autocomplete="off" action='/adduser' role="form" class="form-signin" id="form">
<fieldset>
<legend>Informations de l'utilisateur:</legend>
${form | n}
</fieldset>
<fieldset>
<legend>Groupes de l'utilisateur:</legend>
${roles | n}
</fieldset>
<div class="form-group">
<div class="input-group">
<button class="btn btn-default green" type="submit">
<span class="glyphicon glyphicon-plus-sign"></span> Ajouter</button>
</div>
</div>
</form>
<script type="text/javascript" src="/static/js/ppolicy.js"></script>
</div>
</div>
<div class="col-md-2 column">
</div>
</div>
</%block>

View File

@@ -0,0 +1,76 @@
## -*- coding: utf-8 -*-
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>LDAP - Kr[HACK]en</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="directory manager">
<meta name="author" content="kakwa">
<!--link rel="stylesheet/less" href="/static/less/bootstrap.less" type="text/css" /-->
<!--link rel="stylesheet/less" href="/static/less/responsive.less" type="text/css" /-->
<!--script src="/static/js/less-1.3.3.min.js"></script-->
<!--append #!watch to the browser URL, then refresh the page. -->
<link href="/static/css/bootstrap.min.css" rel="stylesheet">
<link href="/static/css/custom.css" rel="stylesheet">
<link href="/static/css/style.css" rel="stylesheet">
<link href="/static/css/bootstrap-switch.css" rel="stylesheet">
<link href="/static/css/tablesorter-bootstrap.css" rel="stylesheet">
<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src="/static/js/html5shiv.js"></script>
<![endif]-->
<!-- Fav and touch icons -->
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="/static/img/apple-touch-icon-144-precomposed.png">
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="/static/img/apple-touch-icon-114-precomposed.png">
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="/static/img/apple-touch-icon-72-precomposed.png">
<link rel="apple-touch-icon-precomposed" href="/static/img/apple-touch-icon-57-precomposed.png">
<link rel="icon" type="image/png" href="/static/img/favicon.png">
<script type="text/javascript" src="/static/js/jquery.min.js"></script>
<script type="text/javascript" src="/static/js/bootstrap.min.js"></script>
<script type="text/javascript" src="/static/js/scripts.js"></script>
<script type="text/javascript" src="/static/js/validator.js"></script>
<script type="text/javascript" src="/static/js/bootstrap-notify.js"></script>
<script type="text/javascript" src="/static/js/jquery.tablesorter.min.js"></script>
<script type="text/javascript" src="/static/js/bootstrap-switch.js"></script>
<script type="text/javascript" src="/static/js/jquery.popconfirm.js"></script>
<script type="text/javascript" src="/static/js/removediacritic.js"></script>
<script type="text/javascript" src="/static/js/lc-filler.js"></script>
<script type="text/javascript" src="/static/js/sha1.js"></script>
% if custom_js:
% for js in custom_js:
<script type="text/javascript" src="/custom/${js}"></script>
% endfor
%endif
<script>
$(function(){
$("#RecordTable").tablesorter({ sortList: [[0,0]] });
});
</script>
</head>
<body>
% if notifications:
% for notif in notifications:
<script type="text/javascript">$.notify('${notif | n}')</script>
% endfor
% endif
<div class="container">
<%block name="navbar"/>
<%block name="core" />
</div>
<div id="footer">
<div class="container">
<p class="muted credit">Gestionnaire LDAP de <a href="https://krhacken.org" target="_blank">Kr[HACK]en</a> • © 2020 • Pierre Coimbra</p>
</div>
</div>
<script type="text/javascript" src="/static/js/alignforms.js"></script>
</body>
</html>

View File

@@ -0,0 +1,16 @@
## -*- coding: utf-8 -*-
<%inherit file="navbar.tmpl"/>
<%block name="core">
<div class="row clearfix">
<div class="col-md-12 column">
<div class="alert alert-dismissable alert-${alert}">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
<h4>
${message}
</h4>
</div>
<a class="btn btn-default blue" href='/'><span class="glyphicon glyphicon-home"></span> Return</a>
</div>
</div>
</%block>

View File

@@ -0,0 +1,139 @@
## -*- coding: utf-8 -*-
<%
from markupsafe import Markup
len_attr = len(attributes)
switch = len_attr / 2
if not switch * 2 == len_attr:
switch = switch + 1
counter = 1
lc1 = []
lc2 = []
for a in sorted(attributes.keys(), key=lambda attr: attributes[attr]['weight']):
if counter <= switch:
lc1.append(a)
else:
lc2.append(a)
counter = counter + 1
%>
<%def name="form_col(l)">
% for a in l:
<% attr = attributes[a] %>
<div class="form-group">
<div class="input-group">
<%
if modify:
required = ''
else:
required = ' required '
if not values is None and a in values:
if type(values[a]) is list:
raw_value = values[a][0]
else:
raw_value = values[a]
if raw_value is None:
raw_value = ''
value = Markup(' value="{}"').format(raw_value)
value2 = Markup('<option>{}</option>').format(raw_value)
else:
raw_value = ''
value = ''
value2 = ''
if 'default' in attr and value == '':
value = Markup(' value="{}"').format(attr['default'])
%>
<span class="input-group-addon" id="basic-addon-${a}">${attr['display_name']}</span>
% if modify and a == keyattr:
<input type="hidden" id="attr.${a}" name="attr.${a}" class="form-control" autocomplete='off' aria-describedby="basic-addon-${a}" ${required} ${value | n} readonly onfocus="this.removeAttribute('readonly');">
<span class="form-control" aria-describedby="basic-addon-${a}">${raw_value}</span>
% elif attr['type'] == 'string':
<input type="text" id="attr.${a}" name="attr.${a}" class="form-control" autocomplete='off' placeholder="${attr['description']}" aria-describedby="basic-addon-${a}" ${required} ${value | n} readonly onfocus="this.removeAttribute('readonly');">
% elif attr['type'] == 'email':
<input type="email" id="attr.${a}" name="attr.${a}" class="form-control" autocomplete='off' placeholder="${attr['description']}" aria-describedby="basic-addon-${a}" ${required} ${value | n} data-error="email address is invalid" readonly onfocus="this.removeAttribute('readonly');">
% elif attr['type'] == 'int':
<input type="number" id="attr.${a}" name="attr.${a}" class="form-control" autocomplete='off' placeholder="${attr['description']}" aria-describedby="basic-addon-${a}" ${required} ${value | n} readonly onfocus="this.removeAttribute('readonly');">
% elif attr['type'] == 'fix':
<input type="hidden" id="attr.${a}" name="attr.${a}" class="form-control" autocomplete='off' aria-describedby="basic-addon-${a}" ${required} value="${attr['value']}" readonly onfocus="this.removeAttribute('readonly');">
<span class="form-control" placeholder="${attr['description']}" aria-describedby="basic-addon-${a}">${attr['value']}</span>
% elif attr['type'] == 'stringlist':
<select class="form-control" id="attr.${a}" name="attr.${a}">
${value2 | n}
%for val in attr['values']:
%if '<option>' + val + '</option>' != value2:
<option>${val}</option>
%endif
%endfor
</select>
% elif attr['type'] == 'password':
<input type="password" class="form-control" data-ppolicy="ppolicy" name="attr.${a}1" id="${a}1" autocomplete='off' placeholder="${attr['description']}" ${required} readonly onfocus="this.removeAttribute('readonly');">
<span class="input-group-addon" id="basic-addon-${a}2">Retaper le mot de passe</span>
<input type="password" class="form-control" data-match="#${a}1" data-match-error="Passwords don't match" name="attr.${a}2" id="#${a}2" autocomplete='off' placeholder="Confirm" ${required} readonly onfocus="this.removeAttribute('readonly');">
% elif attr['type'] == 'textfield':
<textarea id="attr.${a}" name="attr.${a}" class="form-control" placeholder="${attr['description']}">${raw_value}</textarea>
% endif
</div>
<div class="help-block with-errors"></div>
</div>
% endfor
</%def>
<div class="row">
<div class="col-md-6 column lcform-col-1" style="display:none;">
${form_col(lc1)}
</div>
<div class="col-md-6 column lcform-col-2" style="display:none;">
${form_col(lc2)}
</div>
</div>
% if autofill:
<%
attr_set = []
attr_events = {}
functions = {}
for attrid in attributes:
attr = attributes[attrid]
field = 'attr.' + attrid
if field not in attr_set:
attr_set.append(field)
if 'autofill' in attr:
function = attr['autofill']['function']
tuple = (field, function)
if not tuple in functions:
functions[tuple] = []
for arg in attr['autofill']['args']:
if arg[0] == '$':
field_arg = 'attr.' + arg[1:]
if field_arg not in attr_set:
attr_set.append(field_arg)
functions[tuple].append("fields['" + field_arg + "'].value")
if not field_arg in attr_events:
attr_events[field_arg] = []
attr_events[field_arg].append(tuple)
else:
value = arg
functions[tuple].append("'" + value + "'")
%>
<script>
var fields = new Object();
% for attr in attr_set:
fields['${attr}'] = document.getElementById('${attr}');
% endfor
% for attrid in attr_events:
if (fields['${attrid}'] != null) {
fields['${attrid}'].onchange = function () {
% for tuple in attr_events[attrid]:
if (typeof(${tuple[1]}) == "function") {
fields['${tuple[0]}'].value = ${tuple[1] | n}(${', '.join(functions[tuple]) | n});
}
% endfor
};
};
% endfor
</script>
% endif
<script>
$(document).ready(function() {
$('form:eq(1) *:input[type!=hidden]:first').focus();
});
</script>

View File

@@ -0,0 +1,39 @@
## -*- coding: utf-8 -*-
<%inherit file="navbar.tmpl"/>
<%block name="core">
<div class="row clearfix top-buffer bottom-buffer">
<div class="col-md-2 column">
</div>
<div class="col-md-12 column">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Vos attributs</h3>
</div>
<div class="panel-body">
<table id="RecordTable" class="table table-hover table-condensed">
% if not searchresult is None:
<tbody>
%for attr in sorted(attrs_list.keys(), key=lambda attr: attrs_list[attr]['weight']):
<tr>
% if attr in searchresult:
<%
value = searchresult[attr]
if type(value) is list:
value = ', '.join(value)
%>
<td><b>${attrs_list[attr]['display_name']}</b>:</td>
<td>${value}</td>
% endif
</tr>
% endfor
</tbody>
%endif
</table>
</div>
</div>
</div>
<div class="col-md-2 column">
</div>
</div>
</%block>

View File

@@ -0,0 +1,37 @@
## -*- coding: utf-8 -*-
<%inherit file="base.tmpl"/>
<%block name="core">
<div class="row clearfix" style="margin-top:30px">
<div class="col-md-4 column"></div>
<div class="col-md-4 column well">
<form method='POST' role="form" class="form-signin"
% if url:
action='login?url=${url | u}'
% else:
action='login'
% endif
>
<div class="form-group">
<h2 class="form-signin-heading">Connectez-Vous</h2>
<div class="input-group">
<span class="input-group-addon glyphicon glyphicon-user"></span>
<input type="text" class="form-control" name="login" placeholder="Nom d'utilisateur" required autofocus>
</div>
</div>
<div class="form-group">
<div class="input-group">
<span class="input-group-addon glyphicon glyphicon-lock"></span>
<input type="password" class="form-control" name="password" placeholder="Mot de passe" required>
</div>
</div>
<div class="form-group">
<div class="input-group">
<button class="btn btn-default blue" type="submit"><span class="glyphicon glyphicon-off"></span> Connexion</button>
</div>
</div>
</form>
</div>
<div class="col-md-4 column"></div>
</div>
</%block>

View File

@@ -0,0 +1,72 @@
## -*- coding: utf-8 -*-
<%inherit file="navbar.tmpl"/>
<%block name="core">
<div class="row clearfix top-buffer bottom-buffer">
<div class="col-md-2 column">
</div>
<div class="col-md-12 column">
<div class="well well-sm">
<form method='POST' action='/modify' role="form" class="form-signin" id="form">
<fieldset>
<legend>Informations de l'utilisateur:</legend>
${form | n}
</fieldset>
<fieldset>
<legend>Groupes de l'utilisateur:</legend>
${roles | n}
</fieldset>
% if len(standalone_groups) != 0:
<fieldset>
<legend>Enlever des groupes spéciaux::</legend>
<table id="RecordTable" class="table table-hover table-condensed tablesorter">
<thead>
<tr>
<th class="sorter-false">
Backend
</th>
<th class="sorter-false">
Groupe
</th>
<th class="sorter-false">
Activer/Désactiver
</th>
</tr>
</thead>
<tbody>
% for backend in standalone_groups:
% for group in standalone_groups[backend]:
<tr>
<td>
${backends_display_names[backend]}
</td>
<td>
${group}
</td>
<td>
<input data-on-color="success" data-off-color="danger" data-on-text="Activer"
data-off-text="Désactiver" data-handle-width="75" type="checkbox"
name="group.${backend}.${group}" data-size="mini" id="group.${backend}.${group}" checked>
<script>$("[name='group.${backend}.${group}']").bootstrapSwitch();</script>
</td>
</tr>
% endfor
% endfor
</tbody>
</table>
</fieldset>
% endif
<div class="form-group">
<div class="input-group">
<button class="btn btn-default blue" type="submit">
<span class="glyphicon glyphicon-cog"></span> Modifier</button>
</div>
</div>
</form>
<script type="text/javascript" src="/static/js/ppolicy.js"></script>
</div>
</div>
<div class="col-md-2 column">
</div>
</div>
</%block>

View File

@@ -0,0 +1,36 @@
## -*- coding: utf-8 -*-
#<%inherit file="base.tmpl"/>
<%block name="navbar">
<div class="row clearfix">
<div class="col-md-12 column">
<nav class="navbar navbar-inverse" role="navigation">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"> <span class="sr-only">Toggle navigation</span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button>
<a class="navbar-brand" href="/"><img src="/static/img/icon.png" alt="Gestionnaire LDAP" height="22" width="22"></a>
<a class="navbar-brand" href="/selfmodify">Changer de mot de passe</a>
% if is_admin:
<a class="navbar-brand" href="/adduser">Ajouter un utilisateur</a>
<a class="navbar-brand" href="/searchadmin">Supprimer/Editer un utilisateur</a>
% endif
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<a class="navbar-brand navbar-right" href='/logout'><span class="glyphicon glyphicon-off"></span> Déconnexion</a>
<!-- njj
% if is_admin:
<form method='GET' action='/searchadmin' class="navbar-form navbar-right" role="search" data-toggle="validator">
% endif
<div class="form-group">
% if is_admin:
<input type="text" class="form-control" name="searchstring" placeholder="Recherche">
% endif
</div>
% if is_admin:
<button type="submit" class="btn btn-default">Chercher</button>
% endif
</form>-->
</div>
</nav>
</div>
</div>
</%block>

View File

@@ -0,0 +1,92 @@
## -*- coding: utf-8 -*-
<script type="text/javascript">
var graph = ${graph_js | n};
var roles = ${roles_js | n};
function enableParentRoles(roleid){
var parentRoles = graph[roleid]['parent_roles'];
var DnRole = roles[roleid];
var len = parentRoles.length;
for (var i = 0; i < len; i++) {
var role = parentRoles[i];
var DnParentRole = roles[role];
var checked = document.getElementById('role.'+ role).checked;
$('input[name="role.' + role +'"]').bootstrapSwitch('state', true, true);
if ( ! checked){
$.notify("Enable Role '" + DnParentRole + "' (Parent Role of '" + DnRole +"')",
{
type: 'info',
delay: 6500,
}
);
}
}
}
function disableSubRoles(roleid){
var parentRoles = graph[roleid]['sub_roles'];
var DnRole = roles[roleid];
var len = parentRoles.length;
for (var i = 0; i < len; i++) {
var role = parentRoles[i];
var DnParentRole = roles[role];
var checked = document.getElementById('role.'+role).checked;
$('input[name="role.' + role +'"]').bootstrapSwitch('state', false, true);
if (checked){
$.notify("Disable Role '" + DnParentRole + "' (Sub Role of '" + DnRole +"')",
{
type: 'warning',
delay: 6500,
}
);
}
}
}
</script>
<table id="RecordTable" class="table table-hover table-condensed tablesorter">
<thead>
<tr>
<th>
Rôle
</th>
<th class="sorter-false">
Description
</th>
<th class="sorter-false">
Activer/Désactiver
</th>
</tr>
</thead>
<tbody>
%for role in roles:
<%
if not current_roles is None and role in current_roles:
checked = ' checked '
else:
checked = ''
%>
<tr>
<td>
${roles[role]['display_name']}
</td>
<td>
${roles[role]['description']}
</td>
<td>
<input data-on-color="success" data-off-color="danger" data-on-text="Activé"
data-off-text="Désactivé" data-handle-width="75" type="checkbox"
name="role.${role}" data-size="mini" id="role.${role}" ${checked}>
<script>$("[name='role.${role}']").bootstrapSwitch();
$('input[name="role.${role}"]').on('switchChange.bootstrapSwitch', function(event, state) {
if (state) {
enableParentRoles('${role}');
}
else {
disableSubRoles('${role}');
}
});
</script>
</td>
</tr>
% endfor
</tbody>
</table>

View File

@@ -0,0 +1,75 @@
## -*- coding: utf-8 -*-
<%inherit file="navbar.tmpl"/>
<%block name="core">
<div class="row clearfix">
<div class="col-md-12 column">
<form method='get' action='/searchadmin' role="form" class="form-inline" data-toggle="validator">
<div class="form-group">
<label for="searchstring">Recherche d'un utilisateur:</label>
<input type="text" class="form-control" id="searchstring" name="searchstring" placeholder="Rechercher un utilisateur">
</div>
<div class="form-group">
<label for="submit"></label>
<button type="submit" id="submit" class="form-control btn btn-default green">
<span class="glyphicon glyphicon-search"></span> Chercher</button>
</div>
</form>
</div>
</div>
% if not searchresult is None:
<div class="row clearfix top-buffer bottom-buffer">
<div class="col-md-12 column">
<div class="well well-sm">
<table id="RecordTable" class="table table-hover table-condensed tablesorter">
<thead>
<tr>
%for attr in sorted(attrs_list.keys(), key=lambda attr: attrs_list[attr]['weight']):
<th>
${attrs_list[attr]['display_name']}
</th>
% endfor
<th class="sorter-false">
Modify
</th>
<th class="sorter-false">
Delete
</th>
</tr>
</thead>
<tbody>
%for user in searchresult:
<tr>
%for attr in sorted(attrs_list.keys(), key=lambda attr: attrs_list[attr]['weight']):
<td>
% if attr in searchresult[user]:
<%
value = searchresult[user][attr]
if type(value) is list:
value = ', '.join(value)
%>
${value}
% endif
</td>
% endfor
<td>
<a href="/modify?user=${user | n,u}" class="btn btn-xs blue pad" ><span class="glyphicon glyphicon-cog"></span> Modifier</a>
</td>
<td>
<a href="/delete?user=${user | n,u}" data-toggle='confirmation-delete' class="btn btn-xs red pad"><span class="glyphicon glyphicon-remove-sign"></span> Supprimer</a>
</td>
</tr>
% endfor
</tbody>
</table>
</div>
</div>
</div>
%endif
<script>
// Full featured example
$("[data-toggle='confirmation-delete']").popConfirm({
content: "Supprimer cet utilisateur ?",
placement: "right" // (top, right, bottom, left)
});
</script>
</%block>

View File

@@ -0,0 +1,56 @@
## -*- coding: utf-8 -*-
<%inherit file="navbar.tmpl"/>
<%block name="core">
<div class="row clearfix">
<div class="col-md-12 column">
<form method='get' action='/searchuser' role="form" class="form-inline" data-toggle="validator">
<div class="form-group">
<label for="searchstring">Search user</label>
<input type="text" id="searchstring" data-minlength="3" data-error="Too short" class="form-control" name="searchstring" placeholder="Search User" required>
</div>
<div class="form-group">
<label for="submit">Submit</label>
<button type="submit" id="submit" class="form-control btn btn-default green">
<span class="glyphicon glyphicon-search"></span> Search</button>
</div>
</form>
</div>
</div>
% if not searchresult is None:
<div class="row clearfix top-buffer bottom-buffer">
<div class="col-md-12 column">
<div class="well well-sm">
<table id="RecordTable" class="table table-hover table-condensed tablesorter">
<thead>
<tr>
%for attr in sorted(attrs_list.keys(), key=lambda attr: attrs_list[attr]['weight']):
<th>
${attrs_list[attr]['display_name']}
</th>
% endfor
</tr>
</thead>
<tbody>
%for user in searchresult:
<tr>
%for attr in sorted(attrs_list.keys(), key=lambda attr: attrs_list[attr]['weight']):
<td>
% if attr in searchresult[user]:
<%
value = searchresult[user][attr]
if type(value) is list:
value = ', '.join(value)
%>
${value}
% endif
</td>
% endfor
</tr>
% endfor
</tbody>
</table>
</div>
</div>
</div>
%endif
</%block>

View File

@@ -0,0 +1,26 @@
## -*- coding: utf-8 -*-
<%inherit file="navbar.tmpl"/>
<%block name="core">
<div class="row clearfix top-buffer bottom-buffer">
<div class="col-md-2 column">
</div>
<div class="col-md-12 column">
<div class="well well-sm">
<form method='POST' action='/selfmodify' autocomplete="off" role="form" class="form-signin" id="form">
<legend>Modify your attributes:</legend>
${form | n}
</fieldset>
<div class="form-group">
<div class="input-group">
<button type="submit" class="btn btn-default blue">
<span class="glyphicon glyphicon-cog"></span> Modify</button>
</div>
</div>
</form>
<script type="text/javascript" src="/static/js/ppolicy.js"></script>
</div>
</div>
<div class="col-md-2 column">
</div>
</div>
</%block>

View File

@@ -0,0 +1,16 @@
## -*- coding: utf-8 -*-
<%inherit file="base.tmpl"/>
<%block name="core">
<div class="row clearfix" style="margin-top:30px">
<div class="col-md-4 column"></div>
<div class="col-md-4 column well">
<div class="alert alert-dismissable alert-danger">
<h4>
Service Unavailable
</h4>
</div>
<a class="btn btn-default blue" href='/signin'><span class="glyphicon glyphicon-home"></span> Return</a>
</div>
<div class="col-md-4 column"></div>
</div>
</%block>