1import logging
2
3from plain.auth.requests import get_request_user
4from plain.auth.views import AuthView
5from plain.http import RedirectResponse, Response
6from plain.templates.views import TemplateView
7from plain.views import View
8
9from .exceptions import (
10 OAuthError,
11)
12from .providers import get_oauth_provider_instance
13
14logger = logging.getLogger(__name__)
15
16
17class OAuthLoginView(View):
18 def post(self) -> Response:
19 request = self.request
20 provider = self.url_kwargs["provider"]
21 if get_request_user(request):
22 return RedirectResponse("/")
23
24 provider_instance = get_oauth_provider_instance(provider_key=provider)
25 return provider_instance.handle_login_request(request=request)
26
27
28class OAuthCallbackView(TemplateView):
29 """
30 The callback view is used for signup, login, and connect.
31 """
32
33 template_name = "oauth/error.html"
34
35 def get(self) -> Response:
36 provider = self.url_kwargs["provider"]
37 provider_instance = get_oauth_provider_instance(provider_key=provider)
38 try:
39 return provider_instance.handle_callback_request(request=self.request)
40 except OAuthError as e:
41 logger.warning("OAuth error: %s", e.message)
42 self.oauth_error = e
43
44 response = super().get()
45 response.status_code = 400
46 return response
47
48 def get_template_names(self) -> list[str]:
49 names = []
50 if oauth_error := getattr(self, "oauth_error", None):
51 if oauth_error.template_name:
52 names.append(oauth_error.template_name)
53 names.append(self.template_name)
54 return names
55
56 def get_template_context(self) -> dict:
57 context = super().get_template_context()
58 context["oauth_error"] = getattr(self, "oauth_error", None)
59 return context
60
61
62class OAuthConnectView(AuthView):
63 def post(self) -> Response:
64 request = self.request
65 provider = self.url_kwargs["provider"]
66 provider_instance = get_oauth_provider_instance(provider_key=provider)
67 return provider_instance.handle_connect_request(request=request)
68
69
70class OAuthDisconnectView(AuthView):
71 def post(self) -> Response:
72 request = self.request
73 provider = self.url_kwargs["provider"]
74 provider_instance = get_oauth_provider_instance(provider_key=provider)
75 # try:
76 return provider_instance.handle_disconnect_request(request=request)
77 # except OAuthCannotDisconnectError:
78 # return render(
79 # request,
80 # "oauth/error.html",
81 # {
82 # "oauth_error": "This connection can't be removed. You must have a usable password or at least one active connection."
83 # },
84 # status_code=400,
85 # )