Commit 5d43ab1a authored by LE GAC Renaud's avatar LE GAC Renaud
Browse files

Add the logic for user loggin.

parent 72dfd06c
""" Controllers """
def index():
"""Main Controller to run the application launching the plugin dbui.
if db.auth_user[auth.user_id]:
id_group = db.auth_membership(user_id=auth.user_id).group_id
session.role = db.auth_group(id=id_group).role
return 'No users !!!!'
return LOAD('plugin_dbui', 'index', vars=request.vars)
......@@ -15,6 +24,22 @@ def schema():
return IMG(_src=URL("static", "docs/database.png"), _height="99%")
def user():
use @auth.requires_login()
@auth.requires_membership('group name')
@auth.requires_permission('read','table name',record_id)
to decorate functions that need access control
return dict(form=auth())
def versions():
""" expose http://.../default/versions and show software versions.
......@@ -3,39 +3,57 @@
'%s between %s and %s': '%s du %s au %s',
'%s in %s': '%s en %s',
'%Y-%m-%d': '%Y-%m-%d',
'%Y-%m-%d %H:%M:%S': '%Y-%m-%d %H:%M:%S',
'Add a new history line %i': 'Add a new history line %i',
'Add a new person successfully': 'Une nouvelle personne a été ajouté',
'Add person': 'Ajouter une personne',
'Add trainee': 'Ajouter un stagiaire',
'administrators, team leader,...': 'administrators, team leader,...',
'Age': 'Age',
'Agencies': 'Agences',
'agencies': 'agences',
'Agency': 'Agence',
'Are you sure you want to delete this object?': 'Are you sure you want to delete this object?',
'auth_cas': 'auth_cas',
'auth_event': 'auth_event',
'auth_group': 'auth_group',
'auth_membership': 'auth_membership',
'auth_permission': 'auth_permission',
'auth_user': 'auth_user',
'Birth Date': 'Né le',
'budgets': 'budgets',
'Cannot be empty': 'Cannot be empty',
'careers': 'carrières',
'CAS': 'CAS',
'categories': 'catégories',
'Category': 'Catégorie',
'Catégorie': 'Catégorie',
'CDD': 'CDD',
'Cdd': 'Cdd',
'Cdd Flag': 'Cdd Flag',
'Check to delete': 'Check to delete',
'Client IP': 'Client IP',
'Code': 'Code',
'Collections': 'Collections',
'contains': 'contiens',
'Contract': 'Contrat',
'Controller': 'Controller',
'Copyright': 'Copyright',
'Cost': 'Coût',
'Count people': 'Nombre de personne',
'Coverage': 'Coverage',
'Coût': 'Coût',
'Created By': 'Created By',
'Created On': 'Created On',
'database schema': 'schéma de la base de données',
'Defined a year or a time period !!!': 'Defined a year or a time period !!!',
'Definition': 'Définition',
'Demanded': 'Demandé',
'Description': 'Description',
'Domain': 'Domaine',
'Domaine': 'Domaine',
'Duration': 'Durée',
'E-mail': 'E-mail',
'End': 'Fin',
'end': 'fin',
'End Date': 'Date de fin',
......@@ -57,7 +75,9 @@
'Filter projects': 'Filtrer les projets',
'Filter responsibilities': 'Filter les responsabilities',
'Filter teams': 'Filtrer les équipes',
'First name': 'First name',
'First Name': 'Prénom',
'Forgot username?': 'Forgot username?',
'Format': 'Format',
'Forms': 'Formulaire',
'FTE': 'FTE',
......@@ -67,6 +87,9 @@
'General': 'Général',
'Grade': 'Grade',
'greater or equal to': 'plus grand ou égual à',
'Group': 'Group',
'Group ID': 'Group ID',
'Group uniquely assigned to user %(id)s': 'Group uniquely assigned to user %(id)s',
'hardware': 'matériel',
'Hardware': 'Matériel',
'Hardware Cost': 'Hardware Cost',
......@@ -76,11 +99,15 @@
'Hdr Date': 'Hdr Date',
'Hdr defense date': "Date de soutenace de l'hdr",
'Help': 'Aide',
'History': 'Historique',
'history': 'historique',
'History': 'Historique',
'Id': 'Id',
'Initials': 'Initiales',
'Invalid email': 'Invalid email',
'Invalid login': 'Invalid login',
'Is Active': 'Is Active',
'is equal to': 'égal à',
'Last name': 'Last name',
'Last Name': 'Nom de famille',
'less or equal to': 'inférieur ou égal à',
'Level': 'Niveau',
......@@ -93,16 +120,27 @@
'List of responsibilities': 'Liste des responsabilités',
'List of trainee': 'Liste des stagiaires',
'Lists': 'Lists',
'Logged in': 'Logged in',
'Login': 'Login',
'Logout': 'Logout',
'Lost Password': 'Lost Password',
'Lost password?': 'Lost password?',
'Max Records': 'Max Records',
'Model': 'Modèle',
'Modified By': 'Modified By',
'Modified On': 'Modified On',
'Modèle': 'Modèle',
'Name': 'Nom',
'Niveau': 'Niveau',
'Note': 'Note',
'Notified': 'Notifié',
'Object or table name': 'Object or table name',
'Organization': 'Organisation',
'organization_levels': "niveau de l'organisation",
'organizations': 'organisations',
'Origin': 'Origin',
'Password': 'Password',
"Password fields don't match": "Password fields don't match",
'people': 'personnel',
'People': 'Personnel',
'people_categories': 'catégories de personnel',
......@@ -116,15 +154,25 @@
'PhD': 'PhD',
'Phd Date': 'Phd Date',
'Phd defense date': 'Date de la soutenance de la thèse',
'please input your password again': 'please input your password again',
'plugin not install': 'plugin not install',
'Profile': 'Profile',
'Project': 'Projet',
'project leader,...': 'project leader,...',
'projects': 'projets',
'Quality': 'Qualité',
'Qualité': 'Qualité',
'Ratio': 'Ratio',
'Record ID': 'Record ID',
'Register': 'Register',
'Registration identifier': 'Registration identifier',
'Registration key': 'Registration key',
'Registration successful': 'Registration successful',
'Reports': 'Rapports',
'Reset Password key': 'Reset Password key',
'responsibilities': 'responsabilités',
'Responsibility': 'Responsabilité',
'Role': 'Role',
'Select': 'Selectionnez',
'Select a teams and/or a project !!!': 'Select a teams and/or a project !!!',
'select...': 'selectionner...',
......@@ -138,6 +186,7 @@
'Team': 'Équipe',
'teams': 'équipes',
'Time': 'Temps',
'Timestamp': 'Timestamp',
'Title': 'Titre',
'Titre': 'Titre',
'Tools': 'Outils',
......@@ -150,9 +199,15 @@
'University': 'Université',
'Université': 'Université',
'unknown': 'unknown',
'User': 'User',
'User %(id)s Logged-in': 'User %(id)s Logged-in',
'User %(id)s Registered': 'User %(id)s Registered',
'User ID': 'User ID',
'Usual': 'Habituel',
'value already in database or empty': 'value already in database or empty',
'Verify Password': 'Verify Password',
'versions': 'versions',
'Welcome': 'Welcome',
'Wizards': 'Assistants',
'Year': 'Année',
'Year End': 'Year End',
......@@ -4,4 +4,60 @@
setup the connection to the databases
db = DAL('sqlite://storage.sqlite', migrate_enabled=False)
from import Auth
DB_MYSQL = 'mysql://'
ID_ADMIN, ADMIN, DEF_ADMIN = 1, 'admin', 'administrators, team leader,...'
ID_USER, USER, DEF_USER = 2, 'user', 'project leader,...'
# connect to the database
# try:
# db = DAL(DB_MYSQL, migrate=MIGRATE, pool_size=10)
# except:
# raise HTTP(500, T("Can't access the MySQL database !!!"))
db = DAL('sqlite://storage.sqlite', migrate_enabled=MIGRATE)
# User logging
# Approval is required for newly registered users
auth = Auth(db, hmac_key=Auth.get_or_create_key())
auth.settings.create_user_groups = False
auth.settings.registration_requires_approval = True
auth.settings.registration_requires_verification = False
auth.settings.remember_me_form = False
auth.settings.reset_password_requires_verification = True
# after registration go to the login page
auth.settings.register_next = URL('user', args='login')
# create user and admin groups
if not db(
db.auth_group.insert(id=ID_ADMIN, role=ADMIN, description=T(DEF_ADMIN))
db.auth_group.insert(id=ID_USER, role=USER, description=T(DEF_USER))
# Newly registered users go in the user group
auth.settings.everybody_group_id = ID_USER
# The first user is auto approved and get all privilege (admin)
if not db(
auth.settings.everybody_group_id = ID_ADMIN
auth.settings.registration_requires_approval = False
# tune authentication fields for the extJS interface
db.auth_user.registration_key.readable = True
db.auth_user.registration_key.writable = True
db.auth_membership.user_id.label = 'User'
db.auth_membership.group_id.label = 'Group'
db.auth_membership.user_id.requires = \
IS_IN_DB(db, 'auth_user.last_name')
......@@ -2,12 +2,37 @@
""" widgets viewport
# list of useful tables
# To be used to build the list of hidden tables
# which depend on the role and the node
AUTH_TABLES = ['auth_cas',
# CAS node
hidden_tables = list(db.tables)
for el in ('auth_user', 'auth_group', 'auth_membership'):
casNode = dbui.Node(T('CAS'))
configurator = lambda tablename: dbui.to_gridPanel(db[tablename])
casNode.add_children(db.tables, func=configurator, hidden=hidden_tables)
# grid node
hidden_tables = list(AUTH_TABLES)
gridNode = dbui.Node(T('Tables'))
configurator = lambda tablename: dbui.to_gridPanel(db[tablename])
gridNode.add_children(db.tables, func=configurator)
gridNode.add_children(db.tables, func=configurator, hidden=hidden_tables)
# report node
......@@ -70,4 +95,4 @@ wizardNode.add_child(T('Add trainee'), traineeLeaf)
# The viewport with its navigation tree
viewportModifier = dbui.ViewportModifier()
viewportModifier.add_node(helpNode, wizardNode, gridNode, reportNode)
viewportModifier.add_node(helpNode, casNode, wizardNode, gridNode, reportNode)
This diff is collapsed.
This diff is collapsed.
.calendar{z-index:99;position:relative;display:none;background:#fff;border:2px solid #000;font-size:11px;color:#000;cursor:default;font-family:Arial,Helvetica,sans-serif;
border-radius: 10px;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
}.calendar table{margin:0px;font-size:11px;color:#000;cursor:default;font-family:tahoma,verdana,sans-serif;}.calendar .button{text-align:center;padding:1px;color:#fff;background:#000;}.calendar .nav{background:#000;color:#fff}.calendar thead .title{font-weight:bold;padding:1px;background:#000;color:#fff;text-align:center;}.calendar thead .name{padding:2px;text-align:center;background:#bbb;}.calendar thead .weekend{color:#f00;}.calendar thead .hilite {background-color:#666;}.calendar thead .active{padding:2px 0 0 2px;background-color:#c4c0b8;}.calendar tbody .day{width:2em;text-align:right;padding:2px 4px 2px 2px;}.calendar tbody .day.othermonth{color:#aaa;}.calendar tbody .day.othermonth.oweekend{color:#faa;}.calendar table .wn{padding:2px 3px 2px 2px;background:#bbb;}.calendar tbody .rowhilite td{background:#ddd;}.calendar tbody td.hilite{background:#bbb;}.calendar tbody{background:#bbb;}.calendar tbody td.selected{font-weight:bold;background:#ddd;}.calendar tbody td.weekend{color:#f00;}.calendar tbody{font-weight:bold;color:#00f;}.calendar tbody .disabled{color:#999;}.calendar tbody .emptycell{visibility:hidden;}.calendar tbody .emptyrow{display:none;}.calendar tfoot .ttip{background:#bbb;padding:1px;background:#000;color:#fff;text-align:center;}.calendar tfoot .hilite{background:#ddd;}.calendar tfoot .active{}.calendar .combo{position:absolute;display:none;width:4em;top:0;left:0;cursor:default;background:#e4e0d8;padding:1px;z-index:100;}.calendar .combo .label,.calendar .combo .label-IEfix{text-align:center;padding:1px;}.calendar .combo .label-IEfix{width:4em;}.calendar .combo .active{background:#c4c0b8;}.calendar .combo .hilite{background:#048;color:#fea;}.calendar td.time{padding:1px 0;text-align:center;background-color:#bbb;}.calendar td.time .hour,.calendar td.time .minute,.calendar td.time .ampm{padding:0 3px 0 4px;font-weight:bold;}.calendar td.time .ampm{text-align:center;}.calendar td.time .colon{padding:0 2px 0 3px;font-weight:bold;}.calendar td.time span.hilite{}.calendar td.time{border-color:#f00;background-color:#000;color:#0f0;}.hour,.minute{font-size:2em;}
#CP_hourcont{z-index:99;padding:0;position:absolute;border:1px dashed #666;background-color:#eee;display:none;}#CP_minutecont{z-index:99;background-color:#ddd;padding:1px;position:absolute;width:45px;display:none;}.floatleft{float:left;}.CP_hour{z-index:99;padding:1px;font-family:Arial,Helvetica,sans-serif;font-size:9px;white-space:nowrap;cursor:pointer;width:35px;}.CP_minute{z-index:99;padding:1px;font-family:Arial,Helvetica,sans-serif;font-size:9px;white-space:nowrap;cursor:pointer;width:auto;}.CP_over{background-color:#fff;z-index:99}
This diff is collapsed.
.sf-menu, .sf-menu * {
margin: 0;
padding: 0;
list-style: none;
.sf-menu {
line-height: 1.0;
.sf-menu ul {
position: absolute;
top: -999em;
width: 10em; /* left offset of submenus need to match (see below) */
.sf-menu ul li {
width: 100%;
.sf-menu li:hover {
visibility: inherit; /* fixes IE7 'sticky bug' */
.sf-menu li {
float: left;
position: relative;
.sf-menu a {
padding: 5px;
display: block;
position: relative;
.sf-menu li:hover ul,
.sf-menu li.sfHover ul {
left: 0;
top: 26px; /* match top ul list item height */
z-index: 99;
ul.sf-menu li:hover li ul,
ul.sf-menu li.sfHover li ul {
top: -999em;
ul.sf-menu li li:hover ul,
ul.sf-menu li li.sfHover ul {
left: 10em; /* match ul width */
top: 0;
ul.sf-menu li li:hover li ul,
ul.sf-menu li li.sfHover li ul {
top: -999em;
ul.sf-menu li li li:hover ul,
ul.sf-menu li li li.sfHover ul {
left: 10em; /* match ul width */
top: 0;
/*** DEMO SKIN ***/
.sf-menu {
float: left;
/*margin-bottom: 1em;*/
.sf-menu a {
padding-left: 1em;
padding-right: 1em;
.sf-menu a, .sf-menu a:visited { /* visited pseudo selector so IE6 applies text colour*/
// color: #959595;
background-color: transparent;
font-weight: bold;
.sf-menu li {
background-color: transparent;
.sf-menu li li {
background: #232323;
text-align: left;
.sf-menu li li a {
padding-top: 0.25em;
padding-bottom: 0.25em;
color: #959595;
.sf-menu li li li {
background: #232323;
text-align: left;
.sf-menu li li li a {
padding-top: 0.25em;
padding-bottom: 0.25em;
color: #959595;
.sf-menu li:hover, .sf-menu a:focus, .sf-menu a:active, .sf-menu li.sfHover, .sf-menu a:hover {
color: #FFFFFF;
background-color: #303030;
outline: 0;
/*** arrows **/
.sf-menu a.sf-with-ul {
padding-right: 2.25em;
min-width: 1px; /* trigger IE7 hasLayout so spans position accurately */
.sf-sub-indicator {
position: absolute;
display: block;
right: .75em;
top: 1.05em; /* IE6 only */
width: 10px;
height: 10px;
text-indent: -999em;
overflow: hidden;
background: url('../images/arrows-ffffff.png') no-repeat -10px -100px; /* 8-bit indexed alpha png. IE6 gets solid image only */
a > .sf-sub-indicator { /* give all except IE6 the correct values */
top: .8em;
background-position: 0 -100px; /* use translucent arrow for modern browsers*/
/* apply hovers to modern browsers */
a:focus > .sf-sub-indicator,
a:hover > .sf-sub-indicator,
a:active > .sf-sub-indicator,
li:hover > a > .sf-sub-indicator,
li.sfHover > a > .sf-sub-indicator {
background-position: -10px -100px; /* arrow hovers for modern browsers*/
/* point right for anchors in subs */
.sf-menu ul .sf-sub-indicator { background-position: -10px 0; }
.sf-menu ul a > .sf-sub-indicator { background-position: 0 0; }
/* apply hovers to modern browsers */
.sf-menu ul a:focus > .sf-sub-indicator,
.sf-menu ul a:hover > .sf-sub-indicator,
.sf-menu ul a:active > .sf-sub-indicator,
.sf-menu ul li:hover > a > .sf-sub-indicator,
.sf-menu ul li.sfHover > a > .sf-sub-indicator {
background-position: -10px 0; /* arrow hovers for modern browsers*/
/*** shadows for all but IE6 ***/
.sf-shadow ul {
background: url('../images/shadow.png') no-repeat bottom right;
padding: 0 8px 9px 0;
-moz-border-radius-bottomleft: 17px;
-moz-border-radius-topright: 17px;
-webkit-border-top-right-radius: 17px;
-webkit-border-bottom-left-radius: 17px;
.sf-shadow ul.sf-shadow-off {
background: transparent;
/** these MUST stay **/
body { margin: 0; padding:0; border: 0; }
a { text-decoration:none}
a:hover {text-decoration: underline}
a.button {text-decoration: none}
h1,h2,h3,h4,h5,h6 {margin: 0.5em 0 0.25em 0; display: block; font-family: Helvetica}
h1 { font-size: 4.00em;}
h2 { font-size: 3.00em;}
h3 { font-size: 2.00em;}
h4 { font-size: 1.50em;}
h5 { font-size: 1.25em;}
h6 { font-size: 1.12em;}
right { float:right; text-align: right; }
left { float:left; text-align: left; }
center { width:100; text-align: center; vertical-align:middle;}
label { white-space: nowrap; }
th, label { font-weight: bold; }
th, td { text-align: left; vertical-align: top; padding: 2px 5px 2px 5px;}
form table tr td label { text-align: left; }
p, table, ol, ul { padding: 0.5em 0 0.5em 0 }
p {text-align: justify }
ol, ul { padding-left: 30px }
li { margin-bottom: 0.5em; }
span, input, select, textarea, button, label, a { display: inline }
img { border: 0; }
blockquote, blockquote p, p blockquote { font-style: italic; margin: 0.5em 30px 0.5em 30px; font-size: 0.9em}
i, em { font-style: italic; }
strong { font-weight: bold; }
small { font-size: 0.8em; }
textarea { width: 600px; }
code { font-family: Courier;}
input[type=text], input[type=password], select { width: 300px; }
ul { list-style-type: none; margin: 0px; padding: 0px; }
/** end **/
/* Sticky footer begin */
html, body {
height: 100%;
.wrapper {
min-height: 100%;
height: auto !important;
height: 100%;
margin: 0 auto -8em; /* set last value to footer height plus footer vertical padding */
.main {
padding: 20px 0 50px 0;
.footer, .push {
height: 6em;
padding: 1em 0;
clear: both;
.footer-content {position: relative; bottom: -4em; width: 100%;}
.auth_navbar {
white-space: nowrap;
/* Sticky footer end */
body {
background-color: #FFFFFF;
.footer {
background-color: #ECECEC;
.header {
// background: <fill here for header image>;
fieldset { padding: 16px; border-top: 1px #DEDEDE solid;}
fieldset legend {text-transform:uppercase; font-weight: bold; padding: 4px 16px 4px 16px; background: #f1f1f1;}
/* fix ie problem with menu */
.ie-lte7 .topbar .container {z-index: 2; }
td.w2p_fw {padding-bottom: 1em;}
td.w2p_fl, td.w2p_fw, td.w2p_fc { vertical-align:top; }
td.w2p_fl { text-align:right; }
td.w2p_fl, td.w2p_fw {padding-right: 7px;}
td.w2p_fl, td.w2p_fc { padding-top: 4px; }
/* tr#submit_record__row {border-top: 1px solid #E5E5E5;} */
#submit_record__row td {padding-top: .5em;}
/* Fix */
#auth_user_remember__row label {display: inline;}
#web2py_user_form td { vertical-align:top; }
a, a:visited, a:hover { color:#0069D6}
/*********** web2py specific ***********/
div.flash {
font-weight: bold;
display: none;
position: fixed;
padding: 10px;
top: 48px;
right: 50px;
min-width: 280px;
opacity: 0.85;
margin: 0px 0px 10px 10px;
color: #fff;
vertical-align: middle;
cursor: pointer;
background: #000;
border: 2px solid #fff;
border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
z-index: 2;
div.error {
background-color: red;