Depuis environ 2 semaines, ARN n’était plus en mesure de créer des comptes sans-nuage à cause d’un soucis de performance du code de YunoHost originellement prévu pour quelques dizaines de comptes maximum. La création de compte prenait plus de 10h avec 340 comptes et environ 40 permissions.
Durant l’ARN Camp, @mathilde et moi avons enquêté pour comprendre le soucis et un correctif a été trouvé lundi. C’était tant mieux parce qu’on se disait qu’il y en aurait peut être pour une voir des semaines de travail
Vu que pas mal de monde attendait son compte, hier, j’ai fait le choix d’adapter le correctif pour sans-nuage. Malheureusement, j’ai fait une petite erreur et sans le vouloir j’ai vidé le groupe all_users
qui donne les permissions d’accès à chaque app. Raison pour laquelle vous n’aviez plus accès aux apps que vous aviez fermées…
J’ai donc réintégré tout le monde dans le groupe (ce que YunoHost ne permet pas en tant normal) et voilà c’est réparé. Désolé pour hier soir, ce genre d’incident est plus susceptibles d’arriver lors des soirées slash.
Explications détaillées
Ci-dessous le code modifié, à comparer au patch officiel, ce code à l’avantage de ne pas nécessiter de changer partout des listes en set python, ce qui permet de maintenir le patch plus facilement. Seul une list dans la fonction qui synchronise les permissions a été remplacée par un set.
def modifyModlist_finegrained(old_entry: dict, new_entry: dict) -> list:
"""
Prepare an optimized modification list to give to ldap.modify_ext()
"""
ldif = []
for attribute, value in new_entry.items():
if not isinstance(value, (set, list)):
value = {value}
old_value = old_entry.get(attribute, set())
if not isinstance(old_value, (set, list)):
old_value = {old_value}
if value == set(old_value):
continue
if not old_value:
ldif.append((ldap.MOD_ADD, attribute, list(value)))
# Add or/and delete only needed values with unordered set
elif isinstance(value, set) or (attribute in ["mail", "maildrop"] and isinstance(value, (set, list))):
values_to_del = set(old_value) - value
if values_to_del == set(old_value):
ldif.append((ldap.MOD_REPLACE, attribute, list(value)))
continue
elif values_to_del:
ldif.append((ldap.MOD_DELETE, attribute, list(values_to_del)))
values_to_add = value - set(old_value)
if values_to_add:
ldif.append((ldap.MOD_ADD, attribute, list(values_to_add)))
# Add or/and delete only needed values with ordered list
else:
for i, v in enumerate(value):
if i >= len(old_value) or old_value[i] != v:
break
if i == 0:
ldif.append((ldap.MOD_REPLACE, attribute, value))
else:
if old_value[i:]:
ldif.append((ldap.MOD_DELETE, attribute, old_value[i:]))
if value[i:]:
ldif.append((ldap.MOD_ADD, attribute, value[i:]))
return ldif
Pour rajouter tout le monde dans all_users, j’ai ajouté une option --force
dans l’actionmap qui définit la commande yunohost user group add
.