forked from ScoDoc/ScoDoc
Création/édition d'utilisateurs: renforce warnings (mail inst., cas_id).
This commit is contained in:
parent
ea1e1a1ad1
commit
9205c17b7e
@ -12,7 +12,7 @@ from typing import Optional
|
|||||||
|
|
||||||
import cracklib # pylint: disable=import-error
|
import cracklib # pylint: disable=import-error
|
||||||
|
|
||||||
from flask import current_app, g
|
from flask import current_app, flash, g
|
||||||
from flask_login import UserMixin, AnonymousUserMixin
|
from flask_login import UserMixin, AnonymousUserMixin
|
||||||
from sqlalchemy.exc import (
|
from sqlalchemy.exc import (
|
||||||
IntegrityError,
|
IntegrityError,
|
||||||
@ -67,6 +67,14 @@ def is_valid_user_name(user_name: str) -> bool:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def is_new_cas_id(cas_id: str) -> bool:
|
||||||
|
"Check that cas_id is a valid new id (uniqueness, allow nulls)"
|
||||||
|
if not cas_id:
|
||||||
|
return True
|
||||||
|
nb_with_this_id = db.session.query(User).filter_by(cas_id=cas_id).count()
|
||||||
|
return nb_with_this_id == 0
|
||||||
|
|
||||||
|
|
||||||
class User(UserMixin, ScoDocModel):
|
class User(UserMixin, ScoDocModel):
|
||||||
"""ScoDoc users, handled by Flask / SQLAlchemy"""
|
"""ScoDoc users, handled by Flask / SQLAlchemy"""
|
||||||
|
|
||||||
@ -178,13 +186,16 @@ class User(UserMixin, ScoDocModel):
|
|||||||
raise ValueError("invalid user_id")
|
raise ValueError("invalid user_id")
|
||||||
return query.first_or_404() if not accept_none else query.first()
|
return query.first_or_404() if not accept_none else query.first()
|
||||||
|
|
||||||
def set_password(self, password):
|
def set_password(self, password: str):
|
||||||
"Set password"
|
"Set password"
|
||||||
log(f"set_password({self})")
|
log(f"set_password({self})")
|
||||||
|
previous_hash = self.password_hash
|
||||||
if password:
|
if password:
|
||||||
self.password_hash = generate_password_hash(password)
|
self.password_hash = generate_password_hash(password)
|
||||||
else:
|
else:
|
||||||
self.password_hash = None
|
self.password_hash = None
|
||||||
|
if self.password_hash != previous_hash:
|
||||||
|
self.date_modif_passwd = datetime.now()
|
||||||
# La création d'un mot de passe efface l'éventuel mot de passe historique
|
# La création d'un mot de passe efface l'éventuel mot de passe historique
|
||||||
self.password_scodoc7 = None
|
self.password_scodoc7 = None
|
||||||
self.passwd_temp = False
|
self.passwd_temp = False
|
||||||
@ -350,9 +361,7 @@ class User(UserMixin, ScoDocModel):
|
|||||||
date_expiration = args.get("date_expiration")
|
date_expiration = args.get("date_expiration")
|
||||||
if isinstance(date_expiration, str):
|
if isinstance(date_expiration, str):
|
||||||
args["date_expiration"] = (
|
args["date_expiration"] = (
|
||||||
datetime.fromisoformat(date_expiration)
|
datetime.fromisoformat(date_expiration) if date_expiration else None
|
||||||
if date_expiration
|
|
||||||
else None
|
|
||||||
)
|
)
|
||||||
# booléens:
|
# booléens:
|
||||||
for field in ("active", "cas_allow_login", "cas_allow_scodoc_login"):
|
for field in ("active", "cas_allow_login", "cas_allow_scodoc_login"):
|
||||||
@ -394,17 +403,43 @@ class User(UserMixin, ScoDocModel):
|
|||||||
role, dept = UserRole.role_dept_from_string(r_d)
|
role, dept = UserRole.role_dept_from_string(r_d)
|
||||||
self.add_role(role, dept)
|
self.add_role(role, dept)
|
||||||
|
|
||||||
super().from_dict(args, excluded={"user_name", "roles_string", "roles"})
|
# email_institutionnel may not be unique, but check and warns user
|
||||||
|
email_institutionnel = args.get("email_institutionnel")
|
||||||
|
if email_institutionnel and email_institutionnel != self.email_institutionnel:
|
||||||
|
nb_with_this_mail = (
|
||||||
|
db.session.query(User)
|
||||||
|
.filter_by(email_institutionnel=email_institutionnel)
|
||||||
|
.count()
|
||||||
|
)
|
||||||
|
if nb_with_this_mail > 0:
|
||||||
|
log(
|
||||||
|
"User.from_dict: plusieurs utilisateurs avec ce mail institutionnel"
|
||||||
|
)
|
||||||
|
flash(
|
||||||
|
"Attention: plusieurs utilisateurs avec ce mail institutionnel",
|
||||||
|
"warning",
|
||||||
|
)
|
||||||
|
|
||||||
|
super().from_dict(
|
||||||
|
args, excluded={"cas_id", "user_name", "roles_string", "roles"}
|
||||||
|
)
|
||||||
|
|
||||||
|
new_cas_id = args.get("cas_id")
|
||||||
if ScoDocSiteConfig.cas_uid_use_scodoc():
|
if ScoDocSiteConfig.cas_uid_use_scodoc():
|
||||||
self.cas_id = self.user_name
|
new_cas_id = self.user_name
|
||||||
else:
|
else:
|
||||||
# Set cas_id using regexp if configured:
|
# Set cas_id using regexp if configured:
|
||||||
exp = ScoDocSiteConfig.get("cas_uid_from_mail_regexp")
|
exp = ScoDocSiteConfig.get("cas_uid_from_mail_regexp")
|
||||||
if exp and self.email_institutionnel:
|
if exp and self.email_institutionnel:
|
||||||
cas_id = ScoDocSiteConfig.extract_cas_id(self.email_institutionnel)
|
cas_id = ScoDocSiteConfig.extract_cas_id(self.email_institutionnel)
|
||||||
if cas_id:
|
if cas_id:
|
||||||
self.cas_id = cas_id
|
new_cas_id = cas_id
|
||||||
|
if new_cas_id != self.cas_id:
|
||||||
|
if is_new_cas_id(new_cas_id):
|
||||||
|
self.cas_id = new_cas_id
|
||||||
|
else:
|
||||||
|
log(f"User.from_dict: CAS id invalide pour {self.user_name}")
|
||||||
|
raise ScoValueError(f"CAS id invalide pour {self.user_name}")
|
||||||
|
|
||||||
def get_token(self, expires_in=3600):
|
def get_token(self, expires_in=3600):
|
||||||
"Un jeton pour cet user. Stocké en base, non commité."
|
"Un jeton pour cet user. Stocké en base, non commité."
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="user_basics">
|
<div class="user_basics">
|
||||||
<b>Dernière modif mot de passe:</b>
|
<b>Dernière modif mot de passe:</b>
|
||||||
{{user.date_modif_passwd.strftime(scu.DATE_FMT) if user.date_modif_passwd else ""}}<br>
|
{{user.date_modif_passwd.strftime(scu.DATEATIME_FMT) if user.date_modif_passwd else ""}}<br>
|
||||||
<b>Date d'expiration:</b>
|
<b>Date d'expiration:</b>
|
||||||
{{user.date_expiration.strftime(scu.DATE_FMT) if user.date_expiration else "(sans limite)"}}
|
{{user.date_expiration.strftime(scu.DATE_FMT) if user.date_expiration else "(sans limite)"}}
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user