forked from ScoDoc/ScoDoc
Extraction identifiant utilisateur EDT depuis la réponse CAS.
This commit is contained in:
parent
2c209313c6
commit
5d7d967cf2
@ -39,6 +39,15 @@ def after_cas_login():
|
||||
"scodoc_cas_login_date"
|
||||
] = datetime.datetime.now().isoformat()
|
||||
user.cas_last_login = datetime.datetime.utcnow()
|
||||
if flask.session.get("CAS_EDT_ID"):
|
||||
# essaie de récupérer l'edt_id s'il est présent
|
||||
# cet ID peut être renvoyé par le CAS et extrait par ScoDoc
|
||||
# via l'expression `cas_edt_id_from_xml_regexp`
|
||||
# voir flask_cas.routing
|
||||
edt_id = flask.session.get("CAS_EDT_ID")
|
||||
current_app.logger.info(f"""after_cas_login: storing edt_id for {
|
||||
user.user_name}: '{edt_id}'""")
|
||||
user.edt_id = edt_id
|
||||
db.session.add(user)
|
||||
db.session.commit()
|
||||
return flask.redirect(url_for("scodoc.index"))
|
||||
|
@ -185,18 +185,7 @@ class User(UserMixin, db.Model):
|
||||
return self._migrate_scodoc7_password(password)
|
||||
return False
|
||||
|
||||
password_ok = check_password_hash(self.password_hash, password)
|
||||
if password_ok and cas_enabled and flask.session.get("CAS_EDT_ID"):
|
||||
# essaie de récupérer l'edt_id s'il est présent
|
||||
# cet ID peut être renvoyé par le CAS et extrait par ScoDoc
|
||||
# via l'expression `cas_edt_id_from_xml_regexp`
|
||||
# voir flask_cas.routing
|
||||
edt_id = flask.session.get("CAS_EDT_ID")
|
||||
log(f"Storing edt_id for {self.user_name}: '{edt_id}'")
|
||||
self.edt_id = edt_id
|
||||
db.session.add(self)
|
||||
db.session.commit()
|
||||
return password_ok
|
||||
return check_password_hash(self.password_hash, password)
|
||||
|
||||
def _migrate_scodoc7_password(self, password) -> bool:
|
||||
"""After migration, rehash password."""
|
||||
|
@ -38,10 +38,14 @@ from app.models import ScoDocSiteConfig
|
||||
|
||||
|
||||
def check_cas_uid_from_mail_regexp(form, field):
|
||||
"Vérifie la regexp fournie pur l'extraction du CAS id"
|
||||
"Vérifie la regexp fournie pour l'extraction du CAS id"
|
||||
if not ScoDocSiteConfig.cas_uid_from_mail_regexp_is_valid(field.data):
|
||||
raise ValidationError("expression régulière invalide")
|
||||
|
||||
def check_cas_edt_id_from_xml_regexp(form, field):
|
||||
"Vérifie la regexp fournie pour l'extraction du CAS id"
|
||||
if not ScoDocSiteConfig.cas_edt_id_from_xml_regexp_is_valid(field.data):
|
||||
raise ValidationError("expression régulière pour edt_id invalide")
|
||||
|
||||
class ConfigCASForm(FlaskForm):
|
||||
"Formulaire paramétrage CAS"
|
||||
@ -58,18 +62,18 @@ class ConfigCASForm(FlaskForm):
|
||||
description="""url complète. Commence en général par <tt>https://</tt>.""",
|
||||
)
|
||||
cas_login_route = StringField(
|
||||
label="Route du login CAS",
|
||||
label="Optionnel: route du login CAS",
|
||||
description="""ajouté à l'URL du serveur: exemple <tt>/cas</tt>
|
||||
(si commence par <tt>/</tt>, part de la racine)""",
|
||||
default="/cas",
|
||||
)
|
||||
cas_logout_route = StringField(
|
||||
label="Route du logout CAS",
|
||||
label="Optionnel: route du logout CAS",
|
||||
description="""ajouté à l'URL du serveur: exemple <tt>/cas/logout</tt>""",
|
||||
default="/cas/logout",
|
||||
)
|
||||
cas_validate_route = StringField(
|
||||
label="Route de validation CAS",
|
||||
label="Optionnel: route de validation CAS",
|
||||
description="""ajouté à l'URL du serveur: exemple <tt>/cas/serviceValidate</tt>""",
|
||||
default="/cas/serviceValidate",
|
||||
)
|
||||
@ -81,7 +85,7 @@ class ConfigCASForm(FlaskForm):
|
||||
)
|
||||
|
||||
cas_uid_from_mail_regexp = StringField(
|
||||
label="Expression pour extraire l'identifiant utilisateur",
|
||||
label="Optionnel: expression pour extraire l'identifiant utilisateur",
|
||||
description="""regexp python appliquée au mail institutionnel de l'utilisateur,
|
||||
dont le premier groupe doit donner l'identifiant CAS.
|
||||
Si non fournie, le super-admin devra saisir cet identifiant pour chaque compte.
|
||||
@ -92,6 +96,17 @@ class ConfigCASForm(FlaskForm):
|
||||
validators=[Optional(), check_cas_uid_from_mail_regexp],
|
||||
)
|
||||
|
||||
cas_edt_id_from_xml_regexp = StringField(
|
||||
label="Optionnel: expression pour extraire l'identifiant edt",
|
||||
description="""regexp python appliquée à la réponse XML du serveur CAS pour
|
||||
retrouver l'id de l'utilisateur sur le SI de l'institution, et notamment sur les
|
||||
calendrier d'emploi du temps. Par exemple, si cet id est renvoyé dans le champ
|
||||
<b>supannEmpId</b>, utiliser:
|
||||
<tt><cas:supannEmpId>(.*?)</cas:supannEmpId></tt>
|
||||
""",
|
||||
validators=[Optional(), check_cas_edt_id_from_xml_regexp],
|
||||
)
|
||||
|
||||
cas_ssl_verify = BooleanField("Vérification du certificat SSL")
|
||||
cas_ssl_certificate_file = FileField(
|
||||
label="Certificat (PEM)",
|
||||
|
@ -286,7 +286,7 @@ class ScoDocSiteConfig(db.Model):
|
||||
@classmethod
|
||||
def set(cls, name: str, value: str) -> bool:
|
||||
"Set parameter, returns True if change. Commit session."
|
||||
value_str = str(value or "")
|
||||
value_str = str(value or "").strip()
|
||||
if (cls.get(name) or "") != value_str:
|
||||
cfg = ScoDocSiteConfig.query.filter_by(name=name).first()
|
||||
if cfg is None:
|
||||
@ -429,7 +429,17 @@ class ScoDocSiteConfig(db.Model):
|
||||
return False
|
||||
# and returns at least one group on a simple cannonical address
|
||||
match = pattern.search("emmanuel@exemple.fr")
|
||||
return len(match.groups()) > 0
|
||||
return match is not None and len(match.groups()) > 0
|
||||
|
||||
@classmethod
|
||||
def cas_edt_id_from_xml_regexp_is_valid(cls, exp: str) -> bool:
|
||||
"True si l'expression régulière semble valide"
|
||||
# check that it compiles
|
||||
try:
|
||||
_ = re.compile(exp)
|
||||
except re.error:
|
||||
return False
|
||||
return True
|
||||
|
||||
@classmethod
|
||||
def assi_get_rounded_time(cls, label: str, default: str) -> float:
|
||||
|
@ -24,6 +24,7 @@
|
||||
{{ wtf.form_field(form.cas_validate_route) }}
|
||||
{{ wtf.form_field(form.cas_attribute_id) }}
|
||||
{{ wtf.form_field(form.cas_uid_from_mail_regexp) }}
|
||||
{{ wtf.form_field(form.cas_edt_id_from_xml_regexp) }}
|
||||
<div class="cas_settings">
|
||||
{{ wtf.form_field(form.cas_ssl_verify) }}
|
||||
{{ wtf.form_field(form.cas_ssl_certificate_file) }}
|
||||
@ -40,8 +41,8 @@
|
||||
{{ wtf.form_field(form.cancel) }}
|
||||
</div>
|
||||
<div class="form-group" style="margin-top:16px;">
|
||||
ℹ️ <em>Note: si le CAS est forcé, le super-admin et les utilisateurs autorisés
|
||||
à "se connecter via ScoDoc" pourront toujours se
|
||||
ℹ️ <em>Note: si le CAS est forcé, le super-admin et les utilisateurs autorisés
|
||||
à "se connecter via ScoDoc" pourront toujours se
|
||||
connecter via l'adresse spéciale</em>
|
||||
<tt style="color: blue;">{{url_for("auth.login_scodoc", _external=True)}}</tt>
|
||||
</div>
|
||||
@ -50,6 +51,6 @@
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% endblock %}
|
||||
|
@ -273,6 +273,10 @@ def config_cas():
|
||||
"cas_uid_from_mail_regexp", form.data["cas_uid_from_mail_regexp"]
|
||||
):
|
||||
flash("Expression extraction identifiant CAS enregistrée")
|
||||
if ScoDocSiteConfig.set(
|
||||
"cas_edt_id_from_xml_regexp", form.data["cas_edt_id_from_xml_regexp"]
|
||||
):
|
||||
flash("Expression extraction identifiant edt enregistrée")
|
||||
if ScoDocSiteConfig.set("cas_ssl_verify", form.data["cas_ssl_verify"]):
|
||||
flash("Vérification SSL modifiée")
|
||||
if form.cas_ssl_certificate_file.data:
|
||||
@ -300,6 +304,9 @@ def config_cas():
|
||||
form.cas_uid_from_mail_regexp.data = ScoDocSiteConfig.get(
|
||||
"cas_uid_from_mail_regexp"
|
||||
)
|
||||
form.cas_edt_id_from_xml_regexp.data = ScoDocSiteConfig.get(
|
||||
"cas_edt_id_from_xml_regexp"
|
||||
)
|
||||
form.cas_ssl_verify.data = ScoDocSiteConfig.get("cas_ssl_verify")
|
||||
return render_template(
|
||||
"config_cas.j2",
|
||||
|
Loading…
Reference in New Issue
Block a user