v0.150.0
 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        #     )