wcs/wcs/users.py

187 lines
6.4 KiB
Python

# w.c.s. - web application for online forms
# Copyright (C) 2005-2010 Entr'ouvert
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
import hashlib
import hmac
from qommon.storage import StorableObject
from qommon import get_cfg
import wcs.qommon.storage as st
from qommon.substitution import Substitutions
class User(StorableObject):
_names = 'users'
name = None
email = None
roles = None
is_admin = False
anonymous = False
form_data = None # dumping ground for custom fields
name_identifiers = None
lasso_dump = None
last_seen = None
def __init__(self, name = None):
StorableObject.__init__(self)
self.name = name
self.name_identifiers = []
self.roles = []
def get_hash(self):
if not self.id:
raise AttributeError('No hash for anonymous user')
identification_cfg = get_cfg('identification', {})
if not identification_cfg.get('use_user_hash'):
raise AttributeError('User hash is not enabled')
secret_key = identification_cfg.get('user_hash_secret_key')
if not secret_key:
raise AttributeError('No user hash secret key defined')
return hmac.new(secret_key, str(self.id), hashlib.sha256).hexdigest()
hash = property(get_hash)
def migrate(self):
changed = False
if self.roles and 'site-admin' in self.roles:
self.is_admin = True
self.roles = [x for x in self.roles if x != 'site-admin']
changed = True
if self.roles:
for role in self.roles:
if type(role) is int:
self.roles = [str(x) for x in self.roles]
changed = True
break
if changed:
self.store()
def get_formdef(cls):
from admin.settings import UserFieldsFormDef
return UserFieldsFormDef()
get_formdef = classmethod(get_formdef)
def get_display_name(self):
if self.name:
return self.name
if self.email:
return self.email
return _('Unknown User')
display_name = property(get_display_name)
def set_attributes_from_formdata(self, formdata):
users_cfg = get_cfg('users', {})
if formdata.get('email'):
self.email = formdata.get('email')
field_email = users_cfg.get('field_email')
if field_email:
self.email = formdata.get(field_email)
field_name_values = users_cfg.get('field_name')
if type(field_name_values) is str: # it was a string in previous versions
field_name_values = [field_name_values]
if field_name_values:
self.name = ' '.join([formdata.get(x) for x in field_name_values if formdata.get(x)])
def can_go_in_admin(self):
return self.is_admin
def can_go_in_backoffice(self):
if self.is_admin:
return True
if self.anonymous:
return False
from roles import Role
for role_id in self.roles or []:
try:
role = Role.get(role_id)
if role.allows_backoffice_access:
return True
except KeyError: # role has been deleted
pass
return False
def get_available_roles(cls):
from roles import get_user_roles
return get_user_roles()
get_available_roles = classmethod(get_available_roles)
def add_roles(self, roles):
if not self.roles:
self.roles = []
self.roles.extend(roles)
def get_users_with_role(cls, role_id):
# this will be slow with the pickle backend as there is no index
# suitable for Intersects()
return cls.select([st.Intersects('roles', [str(role_id)])])
get_users_with_role = classmethod(get_users_with_role)
def get_users_with_name_identifier(cls, name_identifier):
return cls.select([st.Intersects('name_identifiers', [name_identifier])])
get_users_with_name_identifier = classmethod(get_users_with_name_identifier)
def get_users_with_email(cls, email):
return cls.select([st.Equal('email', email)])
get_users_with_email = classmethod(get_users_with_email)
def get_substitution_variables(self, prefix='session_'):
d = {
prefix+'user': self,
prefix+'user_display_name': self.display_name,
prefix+'user_email': self.email,
}
formdef = self.get_formdef()
if formdef:
from formdata import get_dict_with_varnames
data = get_dict_with_varnames(formdef.fields, self.form_data)
for k, v in data.items():
d[prefix+'user_'+k] = v
d[prefix + 'user_admin_access'] = self.can_go_in_admin()
d[prefix + 'user_backoffice_access'] = self.can_go_in_backoffice()
for i, name_identifier in enumerate(self.name_identifiers):
d[prefix + 'user_name_identifier_%d' % i] = name_identifier
return d
def get_substitution_variables_list(cls, prefix='session_'):
formdef = cls.get_formdef()
if not formdef:
return []
variables = []
for field in formdef.fields:
# we only advertise fields with a varname, as they can be
# considered stable
if field.varname:
variables.append((
_('User'), prefix+'user_var_'+field.varname,
_('Session User Field: %s') % field.label))
return variables
get_substitution_variables_list = classmethod(get_substitution_variables_list)
Substitutions.register('session_user', category=N_('User'), comment=N_('Session User'))
Substitutions.register('session_user_display_name', category=N_('User'), comment=N_('Session User Display Name'))
Substitutions.register('session_user_email', category=N_('User'), comment=N_('Session User Email'))
Substitutions.register_dynamic_source(User)