Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Empêcher les membres d’une structure de s’y maintenir via des invitations #5430

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

francoisfreitag
Copy link
Contributor

@francoisfreitag francoisfreitag commented Jan 20, 2025

🤔 Pourquoi ?

Sécurité.

🏝️ Comment tester

https://yeswehack.com/vulnerability-center/reports/310822

@francoisfreitag francoisfreitag added the no-changelog Ne doit pas figurer dans le journal des changements. label Jan 20, 2025
@francoisfreitag francoisfreitag self-assigned this Jan 20, 2025
Copy link
Member

@Scttpr Scttpr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Merci pour la PR !

@francoisfreitag francoisfreitag added the pending PR en attente, ne pas intégrer. label Jan 20, 2025
@francoisfreitag
Copy link
Contributor Author

En attente de #5429

@Scttpr
Copy link
Member

Scttpr commented Jan 23, 2025

Est-ce qu'il serait ok pour vous d'ajouter dans cette PR l'invalidation des invitations dans l'ensemble des scenarios metiers ?

On peut s'en parler rapidement si vous voulez pour faire le tour mais je crains que le self invitation ne soit pas suffisant.

Comme ca je m'aligne avec la proposition de Xav sur le traitement en deux temps :

  • Expulsion == invalidation de toute invitation, quelle qu'elle soit (sujet de securite clos du coup)
  • Limitation dans les regles de generation des invitations, dans une autre PR

@francoisfreitag
Copy link
Contributor Author

Je pense qu’il serait effectivement utile de s’en parler quelques minutes. Je viens d’envoyer une invitation pour demain matin 9h30.

@francoisfreitag francoisfreitag force-pushed the ff/YWH-PGM12163-6 branch 8 times, most recently from a137384 to c3edf06 Compare February 7, 2025 09:07
@francoisfreitag francoisfreitag marked this pull request as ready for review February 7, 2025 21:14
Comment on lines 81 to 89
def expire_invitations(self, user):
expired = self.invitations.pending().filter(Q(email=user.email) | Q(sender=user)).update(validity_days=0)
logger.info(
"Expired %(expired)d invitations to %(org_model)s %(org_id)d for user_id=%(user_id)d.",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

J'aurais bien vu des appels différents (et des logs différents) pour les deux différents cas expire_invitations_to_user/expire_invitations_from_user.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(soit 2 méthodes, soit expire_invitations(*, from_user=None, to_user=None) avec assert (from_user is None) != (to_user is None) (ou équivalent)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pour quelle raison ?
Lorsqu’on retire un utilisateur d’une structure, on veut bien retirer les invitations pour cet utilisateur et les invitations qu’il a émises. Lors de l’ajout ou de l’activation, je m’attends à ce qu’il n’y ait aucune invitation émise par l’utilisateur, donc les expirer ne me semble pas poser de problème.
Ce serait pour les logs ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oui, c'est principalement pour les logs.
Mais si on rajoute un if pour les logs on pourrait également le mettre pour la requête SQL.
Et enfin pour la compréhension je trouve cela plus clair pour comprendre ce que le code fait.
expire_invitations(from_user=user) permet de savoir tout de suite qu'on désactive les invitations envoyées.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C’est qu’on va devoir appeler de pair expire_invitations(from_user=user) et expire_invitations(to_user=user) au moins au moment du retrait d’un membre, et probablement à l’ajout pour la compatibilité avec l’ancien code qui n’expirait pas les invitations envoyées par l’utilisateur à la désactivation.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On pourrait mais a priori si l'utilisateur vient d'accepter l'invitation il n'a pas pu envoyer d'invitations ? 🤔
Après ça ne fait qu'une petite requête SQL et un log indiquant qu'on a rien désactivé avec le bénéfice d'enlever une option à la méthode donc ce n'est pas dramatique mais je trouve cela un peu bizarre 🤷‍♂️

Copy link
Contributor Author

@francoisfreitag francoisfreitag Feb 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S’il est réactivé ?
Jusqu’à maintenant, on n’expirait pas les invitations envoyées lorsqu’un utilisateur quittait une structure. Donc on a potentiellement en base des invitations valides envoyées par un utilisateur désactivé.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Une autre solution serait effectivement une migration pour les attraper et les corriger.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, mais finalement la solution ceinture-bretelle me va bien avec 2 requêtes et 2 logs.
Et on pourrait également rajouter des pinces à linge en vérifiant à l'acceptation d'une invitation que le sender est bien encore membre actif de l'organisation 😅

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

J’ai remis la solution ceinture bretelle, normalement on devrait être tranquilles sans les pinces à linge.

@francoisfreitag francoisfreitag force-pushed the ff/YWH-PGM12163-6 branch 3 times, most recently from 75318d8 to 9d0c1e3 Compare February 10, 2025 11:37
Copy link
Contributor

@xavfernandez xavfernandez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Ma relecture des tests est imparfaite, ils se ressemblent trop et ça commençait à se mélanger dans ma tête mais ça m'a l'air très bien 😁

itou/common_apps/organizations/admin.py Show resolved Hide resolved
@francoisfreitag
Copy link
Contributor Author

Ma relecture des tests est imparfaite, ils se ressemblent trop et ça commençait à se mélanger dans ma tête mais ça m'a l'air très bien 😁

Je me suis appliqué 😇
Une centralisation me démange depuis un bon moment... Je vais garder ça de côté et essayer de le faire dans la semaine.

Company and PrescriberOrganization all use `invitations`. A uniform
related name allows writing `self.invitations` in
`OrganizationAbstract`.
Facilitate future access to timezone.now() in tests.
Ensures a member is not reactivated as an admin.
Explain how to manage their organization to new administrators.
An email is now always sent when an administrator joins a structure.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
no-changelog Ne doit pas figurer dans le journal des changements. pending PR en attente, ne pas intégrer.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants