12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- from django.conf import settings
- from django.contrib.auth.tokens import PasswordResetTokenGenerator
- from django.urls import re_path
- from django.utils.crypto import constant_time_compare
- from django.utils.http import base36_to_int
- from organizations.backends.defaults import InvitationBackend as BaseInvitationBackend
- from .models import Organization
- from .tasks import send_email_invite
- REGISTRATION_TIMEOUT_DAYS = getattr(settings, "REGISTRATION_TIMEOUT_DAYS", 15)
- class InvitationTokenGenerator(PasswordResetTokenGenerator):
- def _make_hash_value(self, user, timestamp):
- return str(user.pk) + str(timestamp)
- def check_token(self, user, token):
- """
- Check that a password reset token is correct for a given user.
- """
- # Parse the token
- try:
- ts_b36, _hash = token.split("-")
- except ValueError:
- return False
- try:
- ts = base36_to_int(ts_b36)
- except ValueError:
- return False
- # Check that the timestamp/uid has not been tampered with
- if not constant_time_compare(
- self._make_token_with_timestamp(user, ts, self.secret), token
- ):
- return False
- # Check the timestamp is within limit
- if (self._num_seconds(self._now()) - ts) > REGISTRATION_TIMEOUT_DAYS * 86400:
- return False
- return True
- class InvitationBackend(BaseInvitationBackend):
- """
- Based on django-organizations InvitationBackend but for org user instead of user
- """
- def __init__(self, org_model=None, namespace=None):
- self.user_model = None
- self.org_model = Organization
- self.namespace = namespace
- def get_urls(self):
- return [
- re_path(
- r"^(?P<user_id>[\d]+)/(?P<token>[0-9A-Za-z]{1,90}-[0-9A-Za-z]{1,90})/$",
- view=self.activate_view,
- name="invitations_register",
- ),
- ]
- def get_token(self, org_user, **kwargs):
- return InvitationTokenGenerator().make_token(org_user)
- def send_invitation(self, user, sender=None, **kwargs):
- kwargs.update(
- {
- "token": self.get_token(user),
- "organization": user.organization,
- }
- )
- send_email_invite.delay(user.pk, kwargs["token"])
- return True
|