2015-04-15 23:10:01 +02:00
|
|
|
#!/usr/bin/env python
|
2014-06-02 23:10:19 +02:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# vim:set expandtab tabstop=4 shiftwidth=4:
|
|
|
|
#
|
|
|
|
# The MIT License (MIT)
|
2015-04-15 23:10:01 +02:00
|
|
|
# ldapCherry
|
2014-06-02 23:10:19 +02:00
|
|
|
# Copyright (c) 2014 Carpentier Pierre-Francois
|
|
|
|
|
2015-04-15 23:10:01 +02:00
|
|
|
#generic imports
|
|
|
|
import sys
|
|
|
|
import re
|
|
|
|
import traceback
|
2015-06-11 09:33:04 +02:00
|
|
|
import json
|
2015-04-15 23:10:01 +02:00
|
|
|
import logging
|
|
|
|
import logging.handlers
|
|
|
|
from operator import itemgetter
|
|
|
|
from socket import error as socket_error
|
|
|
|
|
2015-05-18 19:56:44 +02:00
|
|
|
from exceptions import *
|
2015-05-18 20:04:47 +02:00
|
|
|
from ldapcherry.roles import Roles
|
|
|
|
from ldapcherry.attributes import Attributes
|
2015-05-18 19:56:44 +02:00
|
|
|
|
2015-04-15 23:10:01 +02:00
|
|
|
#cherrypy http framework imports
|
|
|
|
import cherrypy
|
|
|
|
from cherrypy.lib.httputil import parse_query_string
|
|
|
|
|
|
|
|
#mako template engines imports
|
|
|
|
from mako.template import Template
|
|
|
|
from mako import lookup
|
|
|
|
|
|
|
|
SESSION_KEY = '_cp_username'
|
|
|
|
|
2015-05-18 19:56:44 +02:00
|
|
|
# Custom log function to overrige weird error.log function
|
|
|
|
# of cherrypy
|
2015-06-06 22:23:21 +02:00
|
|
|
def syslog_error(msg='', context='',
|
2015-05-18 19:56:44 +02:00
|
|
|
severity=logging.INFO, traceback=False):
|
|
|
|
if traceback:
|
|
|
|
msg += cherrypy._cperror.format_exc()
|
|
|
|
if context == '':
|
|
|
|
cherrypy.log.error_log.log(severity, msg)
|
|
|
|
else:
|
2015-06-06 22:23:21 +02:00
|
|
|
cherrypy.log.error_log.log(severity,
|
2015-05-18 19:56:44 +02:00
|
|
|
' '.join((context, msg)))
|
|
|
|
|
2015-05-18 15:06:39 +02:00
|
|
|
class LdapCherry(object):
|
2015-04-15 23:10:01 +02:00
|
|
|
|
2015-05-18 19:56:44 +02:00
|
|
|
def _handle_exception(self, e):
|
|
|
|
if hasattr(e, 'log'):
|
|
|
|
cherrypy.log.error(
|
|
|
|
msg = e.log,
|
|
|
|
severity = logging.ERROR
|
|
|
|
)
|
|
|
|
else:
|
|
|
|
cherrypy.log.error(
|
|
|
|
msg = "Unkwon exception <%(e)s>" % { 'e' : str(e) },
|
|
|
|
severity = logging.ERROR
|
|
|
|
)
|
|
|
|
# log the traceback as 'debug'
|
|
|
|
cherrypy.log.error(
|
|
|
|
msg = '',
|
|
|
|
severity = logging.DEBUG,
|
|
|
|
traceback= True
|
|
|
|
)
|
|
|
|
|
2015-04-15 23:10:01 +02:00
|
|
|
def _get_param(self, section, key, config, default=None):
|
|
|
|
""" Get configuration parameter "key" from config
|
|
|
|
@str section: the section of the config file
|
|
|
|
@str key: the key to get
|
|
|
|
@dict config: the configuration (dictionnary)
|
|
|
|
@str default: the default value if parameter "key" is not present
|
|
|
|
@rtype: str (value of config['key'] if present default otherwith
|
|
|
|
"""
|
|
|
|
if section in config and key in config[section]:
|
|
|
|
return config[section][key]
|
|
|
|
if not default is None:
|
|
|
|
return default
|
|
|
|
else:
|
|
|
|
raise MissingParameter(section, key)
|
|
|
|
|
2015-05-26 22:51:57 +02:00
|
|
|
|
|
|
|
def _get_groups(self, username):
|
|
|
|
ret = {}
|
|
|
|
for b in self.backends:
|
|
|
|
ret[b] = self.backends[b].get_groups(username)
|
|
|
|
return ret
|
|
|
|
|
|
|
|
def _get_roles(self, username):
|
|
|
|
groups = self._get_groups(username)
|
|
|
|
return self.roles.get_roles(groups)
|
|
|
|
|
|
|
|
def _is_admin(self, username):
|
|
|
|
roles = self._get_roles(username)
|
|
|
|
return self.roles.is_admin(roles['roles'])
|
|
|
|
|
2015-05-19 17:53:14 +02:00
|
|
|
def _check_backends(self):
|
|
|
|
backends = self.backends_params.keys()
|
|
|
|
for b in self.roles.get_backends():
|
|
|
|
if not b in backends:
|
|
|
|
raise MissingBackend(b)
|
|
|
|
for b in self.roles.get_backends():
|
|
|
|
if not b in backends:
|
|
|
|
raise MissingBackend(b)
|
|
|
|
|
2015-05-19 00:14:34 +02:00
|
|
|
def _init_backends(self, config):
|
2015-05-19 17:53:14 +02:00
|
|
|
self.backends_params = {}
|
2015-05-20 14:21:43 +02:00
|
|
|
self.backends = {}
|
2015-05-19 17:53:14 +02:00
|
|
|
for entry in config['backends']:
|
|
|
|
# split at the first dot
|
|
|
|
backend, sep, param = entry.partition('.')
|
|
|
|
value = config['backends'][entry]
|
|
|
|
if not backend in self.backends_params:
|
|
|
|
self.backends_params[backend] = {}
|
|
|
|
self.backends_params[backend][param] = value
|
2015-05-20 14:21:43 +02:00
|
|
|
for backend in self.backends_params:
|
|
|
|
params = self.backends_params[backend]
|
|
|
|
# Loading the backend module
|
|
|
|
try:
|
|
|
|
module = params['module']
|
|
|
|
except:
|
|
|
|
raise MissingParameter('backends', backend + '.module')
|
|
|
|
try:
|
|
|
|
bc = __import__(module, globals(), locals(), ['Backend'], -1)
|
|
|
|
except:
|
2015-06-06 22:23:21 +02:00
|
|
|
raise BackendModuleLoadingFail(module)
|
2015-05-20 14:21:43 +02:00
|
|
|
try:
|
2015-05-22 10:27:46 +02:00
|
|
|
attrslist = self.attributes.get_backend_attributes(backend)
|
2015-05-31 18:40:35 +02:00
|
|
|
key = self.attributes.get_backend_key(backend)
|
|
|
|
self.backends[backend] = bc.Backend(params, cherrypy.log, backend, attrslist, key)
|
2015-05-21 21:40:13 +02:00
|
|
|
except MissingParameter as e:
|
|
|
|
raise e
|
2015-05-20 14:21:43 +02:00
|
|
|
except:
|
|
|
|
raise BackendModuleInitFail(module)
|
2015-05-19 00:14:34 +02:00
|
|
|
|
2015-05-26 22:51:57 +02:00
|
|
|
def _init_auth(self, config):
|
|
|
|
self.auth_mode = self._get_param('auth', 'auth.mode', config)
|
|
|
|
if self.auth_mode in ['and', 'or', 'none']:
|
|
|
|
pass
|
|
|
|
elif self.auth_mode == 'custom':
|
|
|
|
# load custom auth module
|
|
|
|
auth_module = self._get_param('auth', 'auth.module', config)
|
|
|
|
auth = __import__(auth_module, globals(), locals(), ['Auth'], -1)
|
|
|
|
self.auth = auth.Auth(config['auth'], cherrypy.log)
|
|
|
|
else:
|
|
|
|
raise WrongParamValue('auth.mode', 'auth', ['and', 'or', 'none', 'custom'])
|
|
|
|
|
|
|
|
self.roles_file = self._get_param('roles', 'roles.file', config)
|
|
|
|
cherrypy.log.error(
|
|
|
|
msg = "loading roles file <%(file)s>" % { 'file': self.roles_file },
|
|
|
|
severity = logging.DEBUG
|
|
|
|
)
|
|
|
|
self.roles = Roles(self.roles_file)
|
|
|
|
|
|
|
|
|
2015-05-18 19:56:44 +02:00
|
|
|
def _set_access_log(self, config, level):
|
|
|
|
access_handler = self._get_param('global', 'log.access_handler', config, 'syslog')
|
|
|
|
|
|
|
|
# log format for syslog
|
|
|
|
syslog_formatter = logging.Formatter(
|
|
|
|
"ldapcherry[%(process)d]: %(message)s")
|
|
|
|
|
|
|
|
# replace access log handler by a syslog handler
|
|
|
|
if access_handler == 'syslog':
|
|
|
|
cherrypy.log.access_log.handlers = []
|
|
|
|
handler = logging.handlers.SysLogHandler(address = '/dev/log',
|
|
|
|
facility='user')
|
|
|
|
handler.setFormatter(syslog_formatter)
|
|
|
|
cherrypy.log.access_log.addHandler(handler)
|
|
|
|
|
|
|
|
# if file, we keep the default
|
|
|
|
elif access_handler == 'file':
|
|
|
|
pass
|
|
|
|
|
|
|
|
# replace access log handler by a null handler
|
|
|
|
elif access_handler == 'none':
|
|
|
|
cherrypy.log.access_log.handlers = []
|
|
|
|
handler = logging.NullHandler()
|
|
|
|
cherrypy.log.access_log.addHandler(handler)
|
|
|
|
|
|
|
|
# set log level
|
|
|
|
cherrypy.log.access_log.setLevel(level)
|
|
|
|
|
|
|
|
def _set_error_log(self, config, level):
|
|
|
|
error_handler = self._get_param('global', 'log.error_handler', config, 'syslog')
|
|
|
|
|
|
|
|
# log format for syslog
|
|
|
|
syslog_formatter = logging.Formatter(
|
|
|
|
"ldapcherry[%(process)d]: %(message)s")
|
|
|
|
|
|
|
|
# replacing the error handler by a syslog handler
|
|
|
|
if error_handler == 'syslog':
|
|
|
|
cherrypy.log.error_log.handlers = []
|
|
|
|
|
|
|
|
# redefining log.error method because cherrypy does weird
|
2015-06-06 22:23:21 +02:00
|
|
|
# things like adding the date inside the message
|
|
|
|
# or adding space even if context is empty
|
2015-05-18 19:56:44 +02:00
|
|
|
# (by the way, what's the use of "context"?)
|
|
|
|
cherrypy.log.error = syslog_error
|
|
|
|
|
|
|
|
handler = logging.handlers.SysLogHandler(address = '/dev/log',
|
|
|
|
facility='user')
|
|
|
|
handler.setFormatter(syslog_formatter)
|
|
|
|
cherrypy.log.error_log.addHandler(handler)
|
|
|
|
|
|
|
|
# if file, we keep the default
|
|
|
|
elif error_handler == 'file':
|
|
|
|
pass
|
|
|
|
|
|
|
|
# replacing the error handler by a null handler
|
|
|
|
elif error_handler == 'none':
|
|
|
|
cherrypy.log.error_log.handlers = []
|
|
|
|
handler = logging.NullHandler()
|
|
|
|
cherrypy.log.error_log.addHandler(handler)
|
|
|
|
|
|
|
|
# set log level
|
|
|
|
cherrypy.log.error_log.setLevel(level)
|
|
|
|
|
2015-05-19 00:03:28 +02:00
|
|
|
def _get_loglevel(self, level):
|
|
|
|
""" return logging level object
|
|
|
|
corresponding to a given level passed as
|
|
|
|
a string
|
|
|
|
"""
|
|
|
|
if level == 'debug':
|
|
|
|
return logging.DEBUG
|
|
|
|
elif level == 'notice':
|
|
|
|
return logging.INFO
|
|
|
|
elif level == 'info':
|
|
|
|
return logging.INFO
|
|
|
|
elif level == 'warning' or level == 'warn':
|
|
|
|
return logging.WARNING
|
|
|
|
elif level == 'error' or level == 'err':
|
|
|
|
return logging.ERROR
|
|
|
|
elif level == 'critical' or level == 'crit':
|
|
|
|
return logging.CRITICAL
|
|
|
|
elif level == 'alert':
|
|
|
|
return logging.CRITICAL
|
|
|
|
elif level == 'emergency' or level == 'emerg':
|
|
|
|
return logging.CRITICAL
|
|
|
|
else:
|
|
|
|
return logging.INFO
|
|
|
|
|
2015-05-26 22:51:57 +02:00
|
|
|
def _auth(self, user, password):
|
|
|
|
if self.auth_mode == 'none':
|
|
|
|
return {'connected': True, 'isadmin': True}
|
|
|
|
elif self.auth_mode == 'and':
|
|
|
|
ret1 = True
|
|
|
|
for b in self.backends:
|
|
|
|
ret1 = self.backends[b].auth(user, password) and ret1
|
|
|
|
elif self.auth_mode == 'or':
|
|
|
|
ret1 = False
|
|
|
|
for b in self.backends:
|
|
|
|
ret1 = self.backends[b].auth(user, password) or ret1
|
|
|
|
elif self.auth_mode == 'custom':
|
|
|
|
ret1 = self.auth.auth(user, password)
|
|
|
|
else:
|
|
|
|
raise Exception()
|
|
|
|
if not ret1:
|
|
|
|
return {'connected': False, 'isadmin': False}
|
|
|
|
else:
|
|
|
|
isadmin = self._is_admin(user)
|
|
|
|
return {'connected': True, 'isadmin': isadmin}
|
|
|
|
|
2015-04-15 23:10:01 +02:00
|
|
|
def reload(self, config = None):
|
|
|
|
""" load/reload the configuration
|
|
|
|
"""
|
|
|
|
try:
|
|
|
|
# log configuration handling
|
2015-06-06 22:23:21 +02:00
|
|
|
# get log level
|
2015-04-15 23:10:01 +02:00
|
|
|
# (if not in configuration file, log level is set to debug)
|
|
|
|
level = self._get_loglevel(self._get_param('global', 'log.level', config, 'debug'))
|
2015-05-18 19:56:44 +02:00
|
|
|
# configure access log
|
|
|
|
self._set_access_log(config, level)
|
|
|
|
# configure error log
|
|
|
|
self._set_error_log(config, level)
|
2015-04-15 23:10:01 +02:00
|
|
|
|
2015-05-18 19:56:44 +02:00
|
|
|
# definition of the template directory
|
|
|
|
self.template_dir = self._get_param('resources', 'templates.dir', config)
|
2015-05-20 12:44:33 +02:00
|
|
|
cherrypy.log.error(
|
2015-05-20 15:16:01 +02:00
|
|
|
msg = "loading templates from dir <%(dir)s>" % { 'dir': self.template_dir },
|
2015-05-20 12:44:33 +02:00
|
|
|
severity = logging.DEBUG
|
|
|
|
)
|
2015-04-15 23:10:01 +02:00
|
|
|
# preload templates
|
|
|
|
self.temp_lookup = lookup.TemplateLookup(
|
|
|
|
directories=self.template_dir, input_encoding='utf-8'
|
|
|
|
)
|
|
|
|
self.temp_index = self.temp_lookup.get_template('index.tmpl')
|
|
|
|
self.temp_error = self.temp_lookup.get_template('error.tmpl')
|
|
|
|
self.temp_login = self.temp_lookup.get_template('login.tmpl')
|
2015-05-31 17:44:36 +02:00
|
|
|
self.temp_searchadmin = self.temp_lookup.get_template('searchadmin.tmpl')
|
|
|
|
self.temp_searchuser = self.temp_lookup.get_template('searchuser.tmpl')
|
2015-05-31 22:40:20 +02:00
|
|
|
self.temp_adduser = self.temp_lookup.get_template('adduser.tmpl')
|
2015-06-10 19:59:35 +02:00
|
|
|
self.temp_roles = self.temp_lookup.get_template('roles.tmpl')
|
|
|
|
self.temp_groups = self.temp_lookup.get_template('groups.tmpl')
|
2015-05-31 22:40:20 +02:00
|
|
|
self.temp_form = self.temp_lookup.get_template('form.tmpl')
|
2015-05-31 23:42:24 +02:00
|
|
|
self.temp_selfmodify = self.temp_lookup.get_template('selfmodify.tmpl')
|
2015-05-20 12:44:33 +02:00
|
|
|
|
2015-05-26 22:51:57 +02:00
|
|
|
self._init_auth(config)
|
2015-05-18 20:04:47 +02:00
|
|
|
|
|
|
|
self.attributes_file = self._get_param('attributes', 'attributes.file', config)
|
2015-05-20 12:44:33 +02:00
|
|
|
cherrypy.log.error(
|
2015-05-20 15:16:01 +02:00
|
|
|
msg = "loading attributes file <%(file)s>" % { 'file': self.attributes_file },
|
2015-05-20 12:44:33 +02:00
|
|
|
severity = logging.DEBUG
|
|
|
|
)
|
2015-05-26 22:51:57 +02:00
|
|
|
|
2015-05-20 12:44:33 +02:00
|
|
|
self.attributes = Attributes(self.attributes_file)
|
|
|
|
|
|
|
|
cherrypy.log.error(
|
2015-05-20 15:16:01 +02:00
|
|
|
msg = "init directories backends",
|
2015-05-20 12:44:33 +02:00
|
|
|
severity = logging.DEBUG
|
|
|
|
)
|
2015-05-19 00:14:34 +02:00
|
|
|
self._init_backends(config)
|
2015-05-19 17:53:14 +02:00
|
|
|
self._check_backends()
|
2015-05-20 12:44:33 +02:00
|
|
|
cherrypy.log.error(
|
2015-05-20 15:16:01 +02:00
|
|
|
msg = "application started",
|
2015-05-20 12:44:33 +02:00
|
|
|
severity = logging.INFO
|
|
|
|
)
|
2015-05-18 20:04:47 +02:00
|
|
|
|
2015-05-18 19:56:44 +02:00
|
|
|
except Exception as e:
|
|
|
|
self._handle_exception(e)
|
2015-05-20 12:44:33 +02:00
|
|
|
cherrypy.log.error(
|
2015-05-20 15:16:01 +02:00
|
|
|
msg = "application failed to start",
|
2015-05-20 12:44:33 +02:00
|
|
|
severity = logging.ERROR
|
|
|
|
)
|
2015-04-15 23:10:01 +02:00
|
|
|
exit(1)
|
|
|
|
|
2015-05-31 17:44:36 +02:00
|
|
|
def _search(self, searchstring):
|
2015-05-31 19:38:31 +02:00
|
|
|
if searchstring is None:
|
|
|
|
return {}
|
2015-06-06 22:23:21 +02:00
|
|
|
ret = {}
|
2015-05-31 17:44:36 +02:00
|
|
|
for b in self.backends:
|
2015-05-31 19:38:31 +02:00
|
|
|
tmp = self.backends[b].search(searchstring)
|
|
|
|
for u in tmp:
|
|
|
|
if not u in ret:
|
|
|
|
ret[u] = {}
|
|
|
|
for attr in tmp[u]:
|
2015-06-15 23:03:47 +02:00
|
|
|
if attr in self.attributes.backend_attributes[b]:
|
|
|
|
attrid = self.attributes.backend_attributes[b][attr]
|
|
|
|
if not attr in ret[u]:
|
|
|
|
ret[u][attrid] = tmp[u][attr]
|
2015-05-31 19:38:31 +02:00
|
|
|
return ret
|
2015-04-15 23:10:01 +02:00
|
|
|
|
2015-06-10 21:26:59 +02:00
|
|
|
def _check_admin(self):
|
|
|
|
if self.auth_mode == 'none':
|
|
|
|
return True
|
|
|
|
return cherrypy.session['isadmin']
|
|
|
|
|
2015-05-28 00:57:15 +02:00
|
|
|
def _check_auth(self, must_admin):
|
2015-05-31 11:39:15 +02:00
|
|
|
if self.auth_mode == 'none':
|
|
|
|
return 'anonymous'
|
2015-05-30 21:33:44 +02:00
|
|
|
username = cherrypy.session.get(SESSION_KEY)
|
|
|
|
if not username:
|
|
|
|
raise cherrypy.HTTPRedirect("/signin")
|
|
|
|
|
2015-05-28 00:57:15 +02:00
|
|
|
if not 'connected' in cherrypy.session or not cherrypy.session['connected']:
|
|
|
|
raise cherrypy.HTTPRedirect("/signin")
|
|
|
|
if cherrypy.session['connected'] and \
|
|
|
|
not cherrypy.session['isadmin']:
|
|
|
|
if must_admin:
|
|
|
|
raise cherrypy.HTTPError("403 Forbidden", "You are not allowed to access this resource.")
|
|
|
|
else:
|
2015-05-30 21:33:44 +02:00
|
|
|
return username
|
2015-05-28 00:57:15 +02:00
|
|
|
if cherrypy.session['connected'] and \
|
|
|
|
cherrypy.session['isadmin']:
|
2015-05-30 21:33:44 +02:00
|
|
|
return username
|
2015-05-28 00:57:15 +02:00
|
|
|
else:
|
|
|
|
raise cherrypy.HTTPRedirect("/signin")
|
|
|
|
|
2015-04-15 23:10:01 +02:00
|
|
|
@cherrypy.expose
|
|
|
|
def signin(self):
|
|
|
|
"""simple signin page
|
|
|
|
"""
|
|
|
|
return self.temp_login.render()
|
|
|
|
|
|
|
|
@cherrypy.expose
|
|
|
|
def login(self, login, password):
|
|
|
|
"""login page
|
|
|
|
"""
|
2015-05-26 22:51:57 +02:00
|
|
|
auth = self._auth(login, password)
|
2015-05-28 00:57:15 +02:00
|
|
|
cherrypy.session['isadmin'] = auth['isadmin']
|
|
|
|
cherrypy.session['connected'] = auth['connected']
|
|
|
|
|
2015-05-26 22:51:57 +02:00
|
|
|
if auth['connected']:
|
2015-05-30 21:33:44 +02:00
|
|
|
if auth['isadmin']:
|
|
|
|
message = "login success for user '%(user)s' as administrator" % {
|
|
|
|
'user': login
|
|
|
|
}
|
|
|
|
else:
|
|
|
|
message = "login success for user '%(user)s' as normal user" % {
|
|
|
|
'user': login
|
|
|
|
}
|
2015-04-15 23:10:01 +02:00
|
|
|
cherrypy.log.error(
|
|
|
|
msg = message,
|
|
|
|
severity = logging.INFO
|
|
|
|
)
|
|
|
|
cherrypy.session[SESSION_KEY] = cherrypy.request.login = login
|
|
|
|
raise cherrypy.HTTPRedirect("/")
|
|
|
|
else:
|
|
|
|
message = "login failed for user '%(user)s'" % {
|
|
|
|
'user': login
|
|
|
|
}
|
|
|
|
cherrypy.log.error(
|
|
|
|
msg = message,
|
|
|
|
severity = logging.WARNING
|
|
|
|
)
|
|
|
|
raise cherrypy.HTTPRedirect("/signin")
|
|
|
|
|
2015-06-15 21:30:19 +02:00
|
|
|
def _adduser(self, params):
|
|
|
|
badd = {}
|
|
|
|
for attr in self.attributes.get_attributes():
|
|
|
|
if self.attributes.attributes[attr]['type'] == 'password':
|
|
|
|
pwd1 = attr + '1'
|
|
|
|
pwd2 = attr + '2'
|
|
|
|
if params[pwd1] != params[pwd2]:
|
|
|
|
raise Exception()
|
|
|
|
params[attr] = params[pwd1]
|
|
|
|
if attr in params:
|
|
|
|
backends = self.attributes.get_backends_attributes(attr)
|
|
|
|
for b in backends:
|
|
|
|
if not b in badd:
|
|
|
|
badd[b] = {}
|
|
|
|
badd[b][backends[b]] = params[attr]
|
|
|
|
for b in badd:
|
|
|
|
self.backends[b].add_user(badd[b])
|
|
|
|
|
2015-04-15 23:10:01 +02:00
|
|
|
@cherrypy.expose
|
|
|
|
def logout(self):
|
2015-06-06 22:23:21 +02:00
|
|
|
""" logout page
|
2015-04-15 23:10:01 +02:00
|
|
|
"""
|
2015-05-28 01:23:22 +02:00
|
|
|
sess = cherrypy.session
|
|
|
|
username = sess.get(SESSION_KEY, None)
|
|
|
|
sess[SESSION_KEY] = None
|
|
|
|
if username:
|
|
|
|
cherrypy.request.login = None
|
|
|
|
|
2015-04-15 23:10:01 +02:00
|
|
|
message = "user '%(user)s' logout" % {
|
2015-05-28 01:23:22 +02:00
|
|
|
'user': username
|
2015-04-15 23:10:01 +02:00
|
|
|
}
|
|
|
|
cherrypy.log.error(
|
|
|
|
msg = message,
|
|
|
|
severity = logging.INFO
|
|
|
|
)
|
|
|
|
raise cherrypy.HTTPRedirect("/signin")
|
|
|
|
|
|
|
|
@cherrypy.expose
|
2015-05-31 17:44:36 +02:00
|
|
|
def index(self):
|
2015-04-15 23:10:01 +02:00
|
|
|
"""main page rendering
|
|
|
|
"""
|
2015-05-28 00:57:15 +02:00
|
|
|
self._check_auth(must_admin=False)
|
2015-06-10 21:26:59 +02:00
|
|
|
is_admin = self._check_admin()
|
|
|
|
return self.temp_index.render(is_admin=is_admin)
|
2015-04-15 23:10:01 +02:00
|
|
|
|
|
|
|
@cherrypy.expose
|
2015-05-31 22:40:20 +02:00
|
|
|
def searchuser(self, searchstring=None):
|
2015-05-30 22:19:57 +02:00
|
|
|
""" search user page """
|
|
|
|
self._check_auth(must_admin=False)
|
2015-06-10 21:26:59 +02:00
|
|
|
is_admin = self._check_admin()
|
2015-05-31 22:40:20 +02:00
|
|
|
if not searchstring is None:
|
|
|
|
res = self._search(searchstring)
|
|
|
|
else:
|
|
|
|
res = None
|
2015-05-31 19:46:50 +02:00
|
|
|
attrs_list = self.attributes.get_search_attributes()
|
2015-06-10 21:26:59 +02:00
|
|
|
return self.temp_searchuser.render(searchresult = res, attrs_list = attrs_list, is_admin=is_admin)
|
2015-05-30 22:19:57 +02:00
|
|
|
|
|
|
|
@cherrypy.expose
|
2015-05-31 17:44:36 +02:00
|
|
|
def searchadmin(self, searchstring=None):
|
2015-04-15 23:10:01 +02:00
|
|
|
""" search user page """
|
2015-05-28 00:57:15 +02:00
|
|
|
self._check_auth(must_admin=True)
|
2015-06-10 21:26:59 +02:00
|
|
|
is_admin = self._check_admin()
|
2015-05-31 22:40:20 +02:00
|
|
|
if not searchstring is None:
|
|
|
|
res = self._search(searchstring)
|
|
|
|
else:
|
|
|
|
res = None
|
2015-05-31 19:38:31 +02:00
|
|
|
attrs_list = self.attributes.get_search_attributes()
|
2015-06-10 21:26:59 +02:00
|
|
|
return self.temp_searchadmin.render(searchresult = res, attrs_list = attrs_list, is_admin=is_admin)
|
2015-04-15 23:10:01 +02:00
|
|
|
|
|
|
|
@cherrypy.expose
|
2015-05-31 17:44:36 +02:00
|
|
|
def adduser(self, **params):
|
2015-04-15 23:10:01 +02:00
|
|
|
""" add user page """
|
2015-05-28 00:57:15 +02:00
|
|
|
self._check_auth(must_admin=True)
|
2015-06-10 21:26:59 +02:00
|
|
|
is_admin = self._check_admin()
|
2015-06-11 23:36:50 +02:00
|
|
|
|
2015-06-14 15:31:43 +02:00
|
|
|
if cherrypy.request.method.upper() == 'POST':
|
|
|
|
notification = "<script type=\"text/javascript\">$.notify('User Added')</script>"
|
2015-06-15 21:30:19 +02:00
|
|
|
self._adduser(params)
|
2015-06-14 15:31:43 +02:00
|
|
|
else:
|
|
|
|
notification = ''
|
|
|
|
|
2015-06-11 23:36:50 +02:00
|
|
|
graph={}
|
|
|
|
for r in self.roles.graph:
|
|
|
|
s = list(self.roles.graph[r]['sub_roles'])
|
|
|
|
p = list(self.roles.graph[r]['parent_roles'])
|
|
|
|
graph[r] = { 'sub_roles': s, 'parent_roles': p}
|
|
|
|
graph_js = json.dumps(graph, separators=(',',':'))
|
2015-06-12 00:25:17 +02:00
|
|
|
display_names = {}
|
|
|
|
for r in self.roles.flatten:
|
|
|
|
display_names[r] = self.roles.flatten[r]['display_name']
|
|
|
|
roles_js = json.dumps(display_names, separators=(',',':'))
|
2015-06-09 09:19:58 +02:00
|
|
|
form = self.temp_form.render(attributes=self.attributes.attributes, values=None)
|
2015-06-12 00:25:17 +02:00
|
|
|
roles = self.temp_roles.render(roles=self.roles.flatten, graph=self.roles.graph, graph_js=graph_js, roles_js=roles_js)
|
2015-06-14 15:31:43 +02:00
|
|
|
return self.temp_adduser.render(form=form, roles=roles, is_admin=is_admin, notification=notification)
|
2015-04-15 23:10:01 +02:00
|
|
|
|
|
|
|
@cherrypy.expose
|
2015-05-31 17:44:36 +02:00
|
|
|
def delete(self, **params):
|
2015-04-15 23:10:01 +02:00
|
|
|
""" remove user page """
|
2015-06-11 09:33:04 +02:00
|
|
|
self._check_auth(must_admin=True)
|
2015-06-10 21:26:59 +02:00
|
|
|
is_admin = self._check_admin()
|
2015-04-15 23:10:01 +02:00
|
|
|
pass
|
|
|
|
|
|
|
|
@cherrypy.expose
|
2015-05-31 17:44:36 +02:00
|
|
|
def modify(self, **params):
|
2015-04-15 23:10:01 +02:00
|
|
|
""" modify user page """
|
2015-06-11 09:33:04 +02:00
|
|
|
self._check_auth(must_admin=True)
|
2015-06-10 21:26:59 +02:00
|
|
|
is_admin = self._check_admin()
|
2015-04-15 23:10:01 +02:00
|
|
|
pass
|
|
|
|
|
|
|
|
@cherrypy.expose
|
2015-05-31 17:44:36 +02:00
|
|
|
def selfmodify(self, **params):
|
2015-04-15 23:10:01 +02:00
|
|
|
""" self modify user page """
|
2015-05-28 00:57:15 +02:00
|
|
|
self._check_auth(must_admin=False)
|
2015-06-10 21:26:59 +02:00
|
|
|
is_admin = self._check_admin()
|
2015-06-09 09:19:58 +02:00
|
|
|
form = self.temp_form.render(attributes=self.attributes.get_selfattributes(), values=None)
|
2015-06-10 21:26:59 +02:00
|
|
|
return self.temp_selfmodify.render(form=form, is_admin=is_admin)
|