Plain is headed towards 1.0! Subscribe for development updates →

 1import logging
 2
 3from plain.auth.views import AuthViewMixin
 4from plain.http import ResponseBadRequest, ResponseRedirect
 5from plain.templates import Template
 6from plain.views import View
 7
 8from .exceptions import (
 9    OAuthError,
10    OAuthStateMismatchError,
11    OAuthUserAlreadyExistsError,
12)
13from .providers import get_oauth_provider_instance
14
15logger = logging.getLogger(__name__)
16
17
18class OAuthLoginView(View):
19    def post(self):
20        request = self.request
21        provider = self.url_kwargs["provider"]
22        if request.user:
23            return ResponseRedirect("/")
24
25        provider_instance = get_oauth_provider_instance(provider_key=provider)
26        return provider_instance.handle_login_request(request=request)
27
28
29class OAuthCallbackView(View):
30    """
31    The callback view is used for signup, login, and connect.
32    """
33
34    def get(self):
35        request = self.request
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=request)
40        except OAuthUserAlreadyExistsError:
41            template = Template("oauth/error.html")
42            return ResponseBadRequest(
43                template.render(
44                    {
45                        "oauth_error": "A user already exists with this email address. Please log in first and then connect this OAuth provider to the existing account."
46                    }
47                )
48            )
49        except OAuthStateMismatchError:
50            template = Template("oauth/error.html")
51            return ResponseBadRequest(
52                template.render(
53                    {
54                        "oauth_error": "The state parameter did not match. Please try again."
55                    }
56                )
57            )
58        except OAuthError as e:
59            logger.exception("OAuth error")
60            template = Template("oauth/error.html")
61            return ResponseBadRequest(template.render({"oauth_error": str(e)}))
62
63
64class OAuthConnectView(AuthViewMixin, View):
65    def post(self):
66        request = self.request
67        provider = self.url_kwargs["provider"]
68        provider_instance = get_oauth_provider_instance(provider_key=provider)
69        return provider_instance.handle_connect_request(request=request)
70
71
72class OAuthDisconnectView(AuthViewMixin, View):
73    def post(self):
74        request = self.request
75        provider = self.url_kwargs["provider"]
76        provider_instance = get_oauth_provider_instance(provider_key=provider)
77        # try:
78        return provider_instance.handle_disconnect_request(request=request)
79        # except OAuthCannotDisconnectError:
80        #     return render(
81        #         request,
82        #         "oauth/error.html",
83        #         {
84        #             "oauth_error": "This connection can't be removed. You must have a usable password or at least one active connection."
85        #         },
86        #         status_code=400,
87        #     )