1from __future__ import annotations
2
3from typing import TYPE_CHECKING, Any
4
5from plain import forms
6from plain.auth import get_user_model
7from plain.email import TemplateEmail
8
9from .links import generate_link_url
10
11if TYPE_CHECKING:
12 from plain.http import Request
13
14
15class LoginLinkForm(forms.Form):
16 email = forms.EmailField()
17 next = forms.CharField(required=False)
18
19 def maybe_send_link(
20 self, request: Request, expires_in: int = 60 * 60
21 ) -> int | None:
22 user_model = get_user_model()
23 email = self.cleaned_data["email"]
24 try:
25 user = user_model.query.get(email__iexact=email)
26 except user_model.DoesNotExist:
27 user = None
28
29 if user:
30 url = generate_link_url(
31 request=request, user=user, email=email, expires_in=expires_in
32 )
33
34 if next_url := self.cleaned_data.get("next"):
35 url += f"?next={next_url}"
36
37 email = self.get_template_email(
38 email=email,
39 context={"user": user, "url": url, "expires_in": expires_in},
40 )
41 return email.send()
42
43 return None
44
45 def get_template_email(
46 self, *, email: str, context: dict[str, Any]
47 ) -> TemplateEmail:
48 return TemplateEmail(
49 template="loginlink",
50 to=[email],
51 context=context,
52 )