Skip to content

Services

hypha.apply.users.services

User module-attribute

User = get_user_model()

PasswordlessAuthService

PasswordlessAuthService(request, redirect_field_name='next', extended_session=False)

The service utilized to handle passwordless auth requests.

Determines if a user is logging in or signing up, and sends the appropriate magic links.

Parameters:

  • request (HttpRequest) –

    HttpRequest object.

  • redirect_field –

    The name of a field containing the redirect URL.

  • extended_session (Optional[bool], default: False ) –

    Include the remember-me param in the magic link, defaults to False.

Source code in hypha/apply/users/services.py
def __init__(
    self,
    request: HttpRequest,
    redirect_field_name: Optional[str] = "next",
    extended_session: Optional[bool] = False,
) -> None:
    """The service utilized to handle passwordless auth requests.

    Determines if a user is logging in or signing up, and sends the appropriate magic links.

    Args:
        request: HttpRequest object.
        redirect_field: The name of a field containing the redirect URL.
        extended_session: Include the `remember-me` param in the magic link, defaults to False.
    """
    self.redirect_field_name = redirect_field_name
    self.next_url = get_redirect_url(request, self.redirect_field_name)
    self.extended_session = extended_session
    self.request = request
    self.site = Site.find_for_request(request)

login_token_generator_class class-attribute instance-attribute

login_token_generator_class = PasswordlessLoginTokenGenerator

signup_token_generator_class class-attribute instance-attribute

signup_token_generator_class = PasswordlessSignupTokenGenerator

redirect_field_name instance-attribute

redirect_field_name = redirect_field_name

next_url class-attribute instance-attribute

next_url = get_redirect_url(request, redirect_field_name)

extended_session instance-attribute

extended_session = extended_session

request instance-attribute

request = request

site instance-attribute

site = find_for_request(request)

get_email_context

get_email_context()
Source code in hypha/apply/users/services.py
def get_email_context(self) -> dict:
    return {
        "org_long_name": settings.ORG_LONG_NAME,
        "org_email": settings.ORG_EMAIL,
        "org_short_name": settings.ORG_SHORT_NAME,
        "site": self.site,
    }

send_email_no_account_found

send_email_no_account_found(to)
Source code in hypha/apply/users/services.py
def send_email_no_account_found(self, to):
    context = self.get_email_context()
    subject = "Log in attempt at {org_long_name}".format(**context)
    # Force subject to a single line to avoid header-injection issues.
    subject = "".join(subject.splitlines())

    email = MarkdownMail("users/emails/passwordless_login_no_account_found.md")
    email.send(
        to=to,
        subject=subject,
        from_email=settings.DEFAULT_FROM_EMAIL,
        context=context,
    )

send_login_email

send_login_email(user)
Source code in hypha/apply/users/services.py
def send_login_email(self, user):
    login_path = self._get_login_path(user)
    timeout_minutes = self.login_token_generator_class().TIMEOUT // 60

    context = self.get_email_context()
    context.update(
        {
            "user": user,
            "is_active": user.is_active,
            "name": user.get_full_name(),
            "username": user.get_username(),
            "login_path": login_path,
            "timeout_minutes": timeout_minutes,
        }
    )

    subject = "Log in to {username} at {org_long_name}".format(**context)
    # Force subject to a single line to avoid header-injection issues.
    subject = "".join(subject.splitlines())

    email = MarkdownMail("users/emails/passwordless_login_email.md")
    email.send(
        to=user.email,
        subject=subject,
        from_email=settings.DEFAULT_FROM_EMAIL,
        context=context,
    )

send_new_account_login_email

send_new_account_login_email(signup_obj)
Source code in hypha/apply/users/services.py
def send_new_account_login_email(self, signup_obj):
    signup_path = self._get_signup_path(signup_obj)
    timeout_minutes = self.login_token_generator_class().TIMEOUT // 60

    context = self.get_email_context()
    context.update(
        {
            "signup_path": signup_path,
            "timeout_minutes": timeout_minutes,
        }
    )

    subject = "Welcome to {org_long_name}".format(**context)
    # Force subject to a single line to avoid header-injection issues.
    subject = "".join(subject.splitlines())

    email = MarkdownMail("users/emails/passwordless_new_account_login.md")
    email.send(
        to=signup_obj.email,
        subject=subject,
        from_email=settings.DEFAULT_FROM_EMAIL,
        context=context,
    )

initiate_login_signup

initiate_login_signup(email)

Send a passwordless login/signup email.

If the user exists, send a login email. If the user does not exist, send a signup invite email.

Parameters:

  • email (str) –

    Email address to send the email to.

Returns:

  • None –

    None

Source code in hypha/apply/users/services.py
def initiate_login_signup(self, email: str) -> None:
    """Send a passwordless login/signup email.

    If the user exists, send a login email. If the user does not exist, send a
    signup invite email.

    Args:
        email: Email address to send the email to.

    Returns:
        None
    """
    if user := get_user_by_email(email):
        self.send_login_email(user)
        return

    # No account found
    if not settings.ENABLE_PUBLIC_SIGNUP:
        self.send_email_no_account_found(email)
        return

    # Self registration is enabled
    signup_obj, _ = PendingSignup.objects.update_or_create(
        email=email,
        defaults={
            "token": get_random_string(32, "abcdefghijklmnopqrstuvwxyz0123456789")
        },
    )
    self.send_new_account_login_email(signup_obj)

    return True