forked from ScoDoc/ScoDoc
debut form editition utilisateur
This commit is contained in:
parent
d40a2b43cd
commit
46cef02b39
@ -20,6 +20,8 @@ from app import db, login
|
|||||||
|
|
||||||
from app.scodoc.sco_permissions import Permission
|
from app.scodoc.sco_permissions import Permission
|
||||||
from app.scodoc.sco_roles_default import SCO_ROLES_DEFAULTS
|
from app.scodoc.sco_roles_default import SCO_ROLES_DEFAULTS
|
||||||
|
import app.scodoc.sco_utils as scu
|
||||||
|
from app.scodoc import sco_etud # a deplacer dans scu
|
||||||
|
|
||||||
|
|
||||||
class User(UserMixin, db.Model):
|
class User(UserMixin, db.Model):
|
||||||
@ -207,6 +209,21 @@ class User(UserMixin, db.Model):
|
|||||||
def is_administrator(self):
|
def is_administrator(self):
|
||||||
return self.active and self.has_permission(Permission.ScoSuperAdmin, None)
|
return self.active and self.has_permission(Permission.ScoSuperAdmin, None)
|
||||||
|
|
||||||
|
# Some useful strings:
|
||||||
|
def get_nomplogin(self):
|
||||||
|
"""nomplogin est le nom en majuscules suivi du prénom et du login
|
||||||
|
e.g. Dupont Pierre (dupont)
|
||||||
|
"""
|
||||||
|
if self.nom:
|
||||||
|
n = sco_etud.format_nom(self.nom)
|
||||||
|
else:
|
||||||
|
n = scu.strupper(self.user_name)
|
||||||
|
return "%s %s (%s)" % (
|
||||||
|
n,
|
||||||
|
sco_etud.format_prenom(self.prenom),
|
||||||
|
self.user_name,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class AnonymousUser(AnonymousUserMixin):
|
class AnonymousUser(AnonymousUserMixin):
|
||||||
def has_permission(self, perm, dept=None):
|
def has_permission(self, perm, dept=None):
|
||||||
|
@ -18,7 +18,6 @@ from flask_login import login_required
|
|||||||
from flask import current_app
|
from flask import current_app
|
||||||
|
|
||||||
import app
|
import app
|
||||||
from app.auth.models import Permission
|
|
||||||
|
|
||||||
|
|
||||||
class ZUser(object):
|
class ZUser(object):
|
||||||
@ -111,6 +110,8 @@ def permission_required(permission):
|
|||||||
|
|
||||||
|
|
||||||
def admin_required(f):
|
def admin_required(f):
|
||||||
|
from app.auth.models import Permission
|
||||||
|
|
||||||
return permission_required(Permission.ScoSuperAdmin)(f)
|
return permission_required(Permission.ScoSuperAdmin)(f)
|
||||||
|
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ def sidebar_common(context, REQUEST=None):
|
|||||||
"authuser": str(authuser),
|
"authuser": str(authuser),
|
||||||
}
|
}
|
||||||
H = [
|
H = [
|
||||||
'<a class="scodoc_title" href="about">ScoDoc</a>',
|
'<a class="scodoc_title" href="about">ScoDoc 8</a>',
|
||||||
'<div id="authuser"><a id="authuserlink" href="%(ScoURL)s/Users/user_info_page">%(authuser)s</a><br/><a id="deconnectlink" href="%(ScoURL)s/acl_users/logout">déconnexion</a></div>'
|
'<div id="authuser"><a id="authuserlink" href="%(ScoURL)s/Users/user_info_page">%(authuser)s</a><br/><a id="deconnectlink" href="%(ScoURL)s/acl_users/logout">déconnexion</a></div>'
|
||||||
% params,
|
% params,
|
||||||
sidebar_dept(context, REQUEST),
|
sidebar_dept(context, REQUEST),
|
||||||
|
@ -140,10 +140,10 @@ def do_formsemestre_createwithmodules(context, REQUEST=None, edit=False):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Liste des enseignants avec forme pour affichage / saisie avec suggestion
|
# Liste des enseignants avec forme pour affichage / saisie avec suggestion
|
||||||
userlist = [sco_users.user_info(u) for u in sco_users.get_user_list()]
|
userlist = sco_users.get_user_list()
|
||||||
login2display = {} # user_name : forme pour affichage = "NOM Prenom (login)"
|
login2display = {} # user_name : forme pour affichage = "NOM Prenom (login)"
|
||||||
for u in userlist:
|
for u in userlist:
|
||||||
login2display[u["user_name"]] = u["nomplogin"]
|
login2display[u.user_name] = u.get_nomplogin()
|
||||||
allowed_user_names = login2display.values() + [""]
|
allowed_user_names = login2display.values() + [""]
|
||||||
#
|
#
|
||||||
formation_id = REQUEST.form["formation_id"]
|
formation_id = REQUEST.form["formation_id"]
|
||||||
|
@ -261,7 +261,7 @@ def _user_list(user_name):
|
|||||||
|
|
||||||
|
|
||||||
def user_info(user_name=None, user=None):
|
def user_info(user_name=None, user=None):
|
||||||
"""Donne infos sur l'utilisateur (qui peut ne pas etre dans notre base).
|
"""Dict avec infos sur l'utilisateur (qui peut ne pas etre dans notre base).
|
||||||
Si user_name est specifie, interroge la BD. Sinon, user doit etre un dict.
|
Si user_name est specifie, interroge la BD. Sinon, user doit etre un dict.
|
||||||
"""
|
"""
|
||||||
if user_name:
|
if user_name:
|
||||||
@ -294,10 +294,7 @@ def user_info(user_name=None, user=None):
|
|||||||
if "password_hash" in info:
|
if "password_hash" in info:
|
||||||
del info["password_hash"]
|
del info["password_hash"]
|
||||||
#
|
#
|
||||||
if info["prenom"]:
|
p = format_prenom(info["prenom"])
|
||||||
p = format_prenom(info["prenom"])
|
|
||||||
else:
|
|
||||||
p = ""
|
|
||||||
if info["nom"]:
|
if info["nom"]:
|
||||||
n = format_nom(
|
n = format_nom(
|
||||||
info["nom"], uppercase=False
|
info["nom"], uppercase=False
|
||||||
|
@ -663,6 +663,7 @@ sco_publish(
|
|||||||
"/formsemestre_edit_options",
|
"/formsemestre_edit_options",
|
||||||
sco_formsemestre_edit.formsemestre_edit_options,
|
sco_formsemestre_edit.formsemestre_edit_options,
|
||||||
Permission.ScoView,
|
Permission.ScoView,
|
||||||
|
methods=["GET", "POST"],
|
||||||
)
|
)
|
||||||
sco_publish(
|
sco_publish(
|
||||||
"/formsemestre_change_lock",
|
"/formsemestre_change_lock",
|
||||||
|
@ -34,8 +34,11 @@ Vues s'appuyant sur auth et sco_users
|
|||||||
Emmanuel Viennet, 2021
|
Emmanuel Viennet, 2021
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import jaxml
|
||||||
|
|
||||||
from flask import g
|
from flask import g
|
||||||
from flask import current_app, request
|
from flask import current_app, request
|
||||||
|
from flask_login import current_user
|
||||||
|
|
||||||
from app.auth.models import Permission
|
from app.auth.models import Permission
|
||||||
from app.auth.models import User
|
from app.auth.models import User
|
||||||
@ -48,8 +51,10 @@ from app.decorators import (
|
|||||||
ZRequest,
|
ZRequest,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from app.scodoc import html_sco_header
|
||||||
from app.scodoc import sco_users
|
from app.scodoc import sco_users
|
||||||
from app.scodoc import sco_utils as scu
|
from app.scodoc import sco_utils as scu
|
||||||
|
from app.scodoc.notes_log import log
|
||||||
|
|
||||||
from app.views import users_bp as bp
|
from app.views import users_bp as bp
|
||||||
|
|
||||||
@ -79,9 +84,320 @@ def user_info(user_name, format="json", REQUEST=None):
|
|||||||
return scu.sendResult(REQUEST, info, name="user", format=format)
|
return scu.sendResult(REQUEST, info, name="user", format=format)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/create_user_form")
|
@bp.route("/create_user_form", methods=["GET", "POST"])
|
||||||
def create_user_form():
|
@permission_required(Permission.ScoUsersAdmin)
|
||||||
raise NotImplementedError()
|
@scodoc7func(context)
|
||||||
|
def create_user_form(context, REQUEST, user_name=None, edit=0):
|
||||||
|
"form. creation ou edit utilisateur"
|
||||||
|
auth_dept = current_user.dept
|
||||||
|
initvalues = {}
|
||||||
|
edit = int(edit)
|
||||||
|
H = [html_sco_header.sco_header(context, REQUEST, bodyOnLoad="init_tf_form('')")]
|
||||||
|
F = html_sco_header.sco_footer(context, REQUEST)
|
||||||
|
if edit:
|
||||||
|
if not user_name:
|
||||||
|
raise ValueError("missing argument: user_name")
|
||||||
|
initvalues = sco_users._user_list(user_name)
|
||||||
|
H.append("<h2>Modification de l'utilisateur %s</h2>" % user_name)
|
||||||
|
else:
|
||||||
|
H.append("<h2>Création d'un utilisateur</h2>")
|
||||||
|
|
||||||
|
is_super_admin = False
|
||||||
|
if current_user.has_permission(Permission.ScoSuperAdmin, g.scodoc_dept):
|
||||||
|
H.append("""<p class="warning">Vous êtes super administrateur !</p>""")
|
||||||
|
is_super_admin = True
|
||||||
|
|
||||||
|
# Noms de roles pouvant etre attribues aux utilisateurs via ce dialogue
|
||||||
|
# si pas SuperAdmin, restreint aux rôles EnsX, SecrX, AdminX
|
||||||
|
#
|
||||||
|
editable_roles = Role.query.all()
|
||||||
|
if is_super_admin:
|
||||||
|
log("create_user_form called by %s (super admin)" % (current_user.user_name,))
|
||||||
|
else:
|
||||||
|
editable_roles = [
|
||||||
|
r for r in editable_roles if r.name in {u"Ens", u"Secr", u"Admin"}
|
||||||
|
]
|
||||||
|
#
|
||||||
|
if not edit:
|
||||||
|
submitlabel = "Créer utilisateur"
|
||||||
|
orig_roles = set()
|
||||||
|
else:
|
||||||
|
submitlabel = "Modifier utilisateur"
|
||||||
|
initvalues["roles"] = initvalues["roles"].split(",") or []
|
||||||
|
orig_roles = set(initvalues["roles"])
|
||||||
|
if initvalues["status"] == "old":
|
||||||
|
editable_roles = set() # can't change roles of a disabled user
|
||||||
|
# add existing user roles
|
||||||
|
displayed_roles = list(editable_roles.union(orig_roles))
|
||||||
|
displayed_roles.sort()
|
||||||
|
disabled_roles = {} # pour desactiver les roles que l'on ne peut pas editer
|
||||||
|
for i in range(len(displayed_roles)):
|
||||||
|
if displayed_roles[i] not in editable_roles:
|
||||||
|
disabled_roles[i] = True
|
||||||
|
|
||||||
|
# log('create_user_form: displayed_roles=%s' % displayed_roles)
|
||||||
|
|
||||||
|
descr = [
|
||||||
|
("edit", {"input_type": "hidden", "default": edit}),
|
||||||
|
("nom", {"title": "Nom", "size": 20, "allow_null": False}),
|
||||||
|
("prenom", {"title": "Prénom", "size": 20, "allow_null": False}),
|
||||||
|
]
|
||||||
|
if auth_name != user_name: # no one can't change its own status
|
||||||
|
descr.append(
|
||||||
|
(
|
||||||
|
"status",
|
||||||
|
{
|
||||||
|
"title": "Statut",
|
||||||
|
"input_type": "radio",
|
||||||
|
"labels": ("actif", "ancien"),
|
||||||
|
"allowed_values": ("", "old"),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if not edit:
|
||||||
|
descr += [
|
||||||
|
(
|
||||||
|
"user_name",
|
||||||
|
{
|
||||||
|
"title": "Pseudo (login)",
|
||||||
|
"size": 20,
|
||||||
|
"allow_null": False,
|
||||||
|
"explanation": "nom utilisé pour la connexion. Doit être unique parmi tous les utilisateurs.",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"passwd",
|
||||||
|
{
|
||||||
|
"title": "Mot de passe",
|
||||||
|
"input_type": "password",
|
||||||
|
"size": 14,
|
||||||
|
"allow_null": False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"passwd2",
|
||||||
|
{
|
||||||
|
"title": "Confirmer mot de passe",
|
||||||
|
"input_type": "password",
|
||||||
|
"size": 14,
|
||||||
|
"allow_null": False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
descr += [
|
||||||
|
(
|
||||||
|
"user_name",
|
||||||
|
{"input_type": "hidden", "default": initvalues["user_name"]},
|
||||||
|
),
|
||||||
|
("user_id", {"input_type": "hidden", "default": initvalues["user_id"]}),
|
||||||
|
]
|
||||||
|
descr += [
|
||||||
|
(
|
||||||
|
"email",
|
||||||
|
{
|
||||||
|
"title": "e-mail",
|
||||||
|
"input_type": "text",
|
||||||
|
"explanation": "vivement recommandé: utilisé pour contacter l'utilisateur",
|
||||||
|
"size": 20,
|
||||||
|
"allow_null": True,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
if not auth_dept:
|
||||||
|
# si auth n'a pas de departement (admin global)
|
||||||
|
# propose de choisir le dept du nouvel utilisateur
|
||||||
|
# sinon, il sera créé dans le même département que auth
|
||||||
|
descr.append(
|
||||||
|
(
|
||||||
|
"dept",
|
||||||
|
{
|
||||||
|
"title": "Département",
|
||||||
|
"input_type": "text",
|
||||||
|
"size": 12,
|
||||||
|
"allow_null": True,
|
||||||
|
"explanation": """département d\'appartenance de l\'utilisateur (s'il s'agit d'un administrateur, laisser vide si vous voulez qu'il puisse créer des utilisateurs dans d'autres départements)""",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
can_choose_dept = True
|
||||||
|
else:
|
||||||
|
can_choose_dept = False
|
||||||
|
if edit:
|
||||||
|
descr.append(
|
||||||
|
(
|
||||||
|
"d",
|
||||||
|
{
|
||||||
|
"input_type": "separator",
|
||||||
|
"title": "L'utilisateur appartient au département %s"
|
||||||
|
% auth_dept,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
descr.append(
|
||||||
|
(
|
||||||
|
"d",
|
||||||
|
{
|
||||||
|
"input_type": "separator",
|
||||||
|
"title": "L'utilisateur sera crée dans le département %s"
|
||||||
|
% auth_dept,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
descr += [
|
||||||
|
(
|
||||||
|
"date_expiration",
|
||||||
|
{
|
||||||
|
"title": "Date d'expiration", # j/m/a
|
||||||
|
"input_type": "date",
|
||||||
|
"explanation": "j/m/a, laisser vide si pas de limite",
|
||||||
|
"size": 9,
|
||||||
|
"allow_null": True,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"roles",
|
||||||
|
{
|
||||||
|
"title": "Rôles",
|
||||||
|
"input_type": "checkbox",
|
||||||
|
"vertical": True,
|
||||||
|
"allowed_values": displayed_roles,
|
||||||
|
"disabled_items": disabled_roles,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"force",
|
||||||
|
{
|
||||||
|
"title": "Ignorer les avertissements",
|
||||||
|
"input_type": "checkbox",
|
||||||
|
"explanation": "passer outre les avertissements (homonymes, etc)",
|
||||||
|
"labels": ("",),
|
||||||
|
"allowed_values": ("1",),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
if "tf-submitted" in REQUEST.form and not "roles" in REQUEST.form:
|
||||||
|
REQUEST.form["roles"] = []
|
||||||
|
if "tf-submitted" in REQUEST.form:
|
||||||
|
# Ajoute roles existants mais non modifiables (disabled dans le form)
|
||||||
|
# orig_roles - editable_roles
|
||||||
|
REQUEST.form["roles"] = list(
|
||||||
|
set(REQUEST.form["roles"]).union(orig_roles - editable_roles)
|
||||||
|
)
|
||||||
|
|
||||||
|
tf = TrivialFormulator(
|
||||||
|
REQUEST.URL0,
|
||||||
|
REQUEST.form,
|
||||||
|
descr,
|
||||||
|
initvalues=initvalues,
|
||||||
|
submitlabel=submitlabel,
|
||||||
|
cancelbutton="Annuler",
|
||||||
|
)
|
||||||
|
if tf[0] == 0:
|
||||||
|
return "\n".join(H) + "\n" + tf[1] + F
|
||||||
|
elif tf[0] == -1:
|
||||||
|
return REQUEST.RESPONSE.redirect(context.UsersURL())
|
||||||
|
else:
|
||||||
|
vals = tf[2]
|
||||||
|
roles = set(vals["roles"]).intersection(editable_roles)
|
||||||
|
if REQUEST.form.has_key("edit"):
|
||||||
|
edit = int(REQUEST.form["edit"])
|
||||||
|
else:
|
||||||
|
edit = 0
|
||||||
|
try:
|
||||||
|
force = int(vals["force"][0])
|
||||||
|
except:
|
||||||
|
force = 0
|
||||||
|
|
||||||
|
if edit:
|
||||||
|
user_name = initvalues["user_name"]
|
||||||
|
else:
|
||||||
|
user_name = vals["user_name"]
|
||||||
|
# ce login existe ?
|
||||||
|
err = None
|
||||||
|
users = _user_list(user_name)
|
||||||
|
if edit and not users: # safety net, le user_name ne devrait pas changer
|
||||||
|
err = "identifiant %s inexistant" % user_name
|
||||||
|
if not edit and users:
|
||||||
|
err = "identifiant %s déjà utilisé" % user_name
|
||||||
|
if err:
|
||||||
|
H.append(tf_error_message("""Erreur: %s""" % err))
|
||||||
|
return "\n".join(H) + "\n" + tf[1] + F
|
||||||
|
|
||||||
|
if not force:
|
||||||
|
ok, msg = context._check_modif_user(
|
||||||
|
edit,
|
||||||
|
user_name=user_name,
|
||||||
|
nom=vals["nom"],
|
||||||
|
prenom=vals["prenom"],
|
||||||
|
email=vals["email"],
|
||||||
|
roles=vals["roles"],
|
||||||
|
)
|
||||||
|
if not ok:
|
||||||
|
H.append(
|
||||||
|
tf_error_message(
|
||||||
|
"""Attention: %s (vous pouvez forcer l'opération en cochant "<em>Ignorer les avertissements</em>" en bas de page)"""
|
||||||
|
% msg
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
return "\n".join(H) + "\n" + tf[1] + F
|
||||||
|
|
||||||
|
if edit: # modif utilisateur (mais pas passwd)
|
||||||
|
if (not can_choose_dept) and vals.has_key("dept"):
|
||||||
|
del vals["dept"]
|
||||||
|
if vals.has_key("passwd"):
|
||||||
|
del vals["passwd"]
|
||||||
|
if vals.has_key("date_modif_passwd"):
|
||||||
|
del vals["date_modif_passwd"]
|
||||||
|
if vals.has_key("user_name"):
|
||||||
|
del vals["user_name"]
|
||||||
|
if (auth_name == user_name) and vals.has_key("status"):
|
||||||
|
del vals["status"] # no one can't change its own status
|
||||||
|
|
||||||
|
# traitement des roles: ne doit pas affecter les roles
|
||||||
|
# que l'on en controle pas:
|
||||||
|
for role in orig_roles:
|
||||||
|
if role and not role in editable_roles:
|
||||||
|
roles.add(role)
|
||||||
|
|
||||||
|
vals["roles"] = ",".join(roles)
|
||||||
|
|
||||||
|
# ok, edit
|
||||||
|
log("sco_users: editing %s by %s" % (user_name, auth_name))
|
||||||
|
# log('sco_users: previous_values=%s' % initvalues)
|
||||||
|
# log('sco_users: new_values=%s' % vals)
|
||||||
|
context._user_edit(user_name, vals)
|
||||||
|
return REQUEST.RESPONSE.redirect(
|
||||||
|
"userinfo?user_name=%s&head_message=Utilisateur %s modifié"
|
||||||
|
% (user_name, user_name)
|
||||||
|
)
|
||||||
|
else: # creation utilisateur
|
||||||
|
vals["roles"] = ",".join(vals["roles"])
|
||||||
|
# check identifiant
|
||||||
|
if not re.match(r"^[a-zA-Z0-9@\\\-_\\\.]+$", vals["user_name"]):
|
||||||
|
msg = tf_error_message(
|
||||||
|
"identifiant invalide (pas d'accents ni de caractères spéciaux)"
|
||||||
|
)
|
||||||
|
return "\n".join(H) + msg + "\n" + tf[1] + F
|
||||||
|
# check passwords
|
||||||
|
if vals["passwd"] != vals["passwd2"]:
|
||||||
|
msg = tf_error_message(
|
||||||
|
"""Les deux mots de passes ne correspondent pas !"""
|
||||||
|
)
|
||||||
|
return "\n".join(H) + msg + "\n" + tf[1] + F
|
||||||
|
if not sco_users.is_valid_password(vals["passwd"]):
|
||||||
|
msg = tf_error_message("""Mot de passe trop simple, recommencez !""")
|
||||||
|
return "\n".join(H) + msg + "\n" + tf[1] + F
|
||||||
|
if not can_choose_dept:
|
||||||
|
vals["dept"] = auth_dept
|
||||||
|
# ok, go
|
||||||
|
log("sco_users: new_user %s by %s" % (vals["user_name"], auth_name))
|
||||||
|
context.create_user(vals, REQUEST=REQUEST)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/import_users_form")
|
@bp.route("/import_users_form")
|
||||||
@ -90,6 +406,34 @@ def import_users_form():
|
|||||||
|
|
||||||
|
|
||||||
@bp.route("/user_info_page")
|
@bp.route("/user_info_page")
|
||||||
|
@permission_required(Permission.ScoUsersView)
|
||||||
@scodoc7func(context)
|
@scodoc7func(context)
|
||||||
def user_info_page(user_name, REQUEST=None):
|
def user_info_page(user_name, REQUEST=None):
|
||||||
return sco_users.user_info_page(context, user_name=user_name, REQUEST=REQUEST)
|
return sco_users.user_info_page(context, user_name=user_name, REQUEST=REQUEST)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/get_user_list_xml")
|
||||||
|
@permission_required(Permission.ScoView)
|
||||||
|
@scodoc7func(context)
|
||||||
|
def get_user_list_xml(context, dept=None, start="", limit=25, REQUEST=None):
|
||||||
|
"""Returns XML list of users with name (nomplogin) starting with start.
|
||||||
|
Used for forms auto-completion."""
|
||||||
|
userlist = sco_users.get_user_list(dept=dept)
|
||||||
|
start = scu.suppression_diacritics(unicode(start, "utf-8"))
|
||||||
|
start = scu.strlower(str(start))
|
||||||
|
# TODO : à refaire avec une requete SQL #py3
|
||||||
|
# (et en json)
|
||||||
|
userlist = [
|
||||||
|
user
|
||||||
|
for user in userlist
|
||||||
|
if scu.suppress_accents(scu.strlower(user.nom)).startswith(start)
|
||||||
|
]
|
||||||
|
if REQUEST:
|
||||||
|
REQUEST.RESPONSE.setHeader("content-type", scu.XML_MIMETYPE)
|
||||||
|
doc = jaxml.XML_document(encoding=scu.SCO_ENCODING)
|
||||||
|
doc.results()
|
||||||
|
for user in userlist[:limit]:
|
||||||
|
doc._push()
|
||||||
|
doc.rs(user["nomplogin"], id=user["user_id"], info="")
|
||||||
|
doc._pop()
|
||||||
|
return repr(doc)
|
||||||
|
Loading…
Reference in New Issue
Block a user