sources/oauth: split up single large "core" views
This commit is contained in:
parent
2d2b2d08f4
commit
c70310730a
|
@ -1,10 +1,10 @@
|
||||||
"""AzureAD OAuth2 Views"""
|
"""AzureAD OAuth2 Views"""
|
||||||
import uuid
|
|
||||||
from typing import Any, Dict
|
from typing import Any, Dict
|
||||||
|
from uuid import UUID
|
||||||
|
|
||||||
from passbook.sources.oauth.models import OAuthSource, UserOAuthSourceConnection
|
from passbook.sources.oauth.models import OAuthSource, UserOAuthSourceConnection
|
||||||
from passbook.sources.oauth.types.manager import MANAGER, RequestKind
|
from passbook.sources.oauth.types.manager import MANAGER, RequestKind
|
||||||
from passbook.sources.oauth.views.core import OAuthCallback
|
from passbook.sources.oauth.views.callback import OAuthCallback
|
||||||
|
|
||||||
|
|
||||||
@MANAGER.source(kind=RequestKind.callback, name="Azure AD")
|
@MANAGER.source(kind=RequestKind.callback, name="Azure AD")
|
||||||
|
@ -12,7 +12,7 @@ class AzureADOAuthCallback(OAuthCallback):
|
||||||
"""AzureAD OAuth2 Callback"""
|
"""AzureAD OAuth2 Callback"""
|
||||||
|
|
||||||
def get_user_id(self, source: OAuthSource, info: Dict[str, Any]) -> str:
|
def get_user_id(self, source: OAuthSource, info: Dict[str, Any]) -> str:
|
||||||
return str(uuid.UUID(info.get("objectId")).int)
|
return str(UUID(info.get("objectId")).int)
|
||||||
|
|
||||||
def get_user_enroll_context(
|
def get_user_enroll_context(
|
||||||
self,
|
self,
|
||||||
|
|
|
@ -3,7 +3,8 @@ from typing import Any, Dict
|
||||||
|
|
||||||
from passbook.sources.oauth.models import OAuthSource, UserOAuthSourceConnection
|
from passbook.sources.oauth.models import OAuthSource, UserOAuthSourceConnection
|
||||||
from passbook.sources.oauth.types.manager import MANAGER, RequestKind
|
from passbook.sources.oauth.types.manager import MANAGER, RequestKind
|
||||||
from passbook.sources.oauth.views.core import OAuthCallback, OAuthRedirect
|
from passbook.sources.oauth.views.callback import OAuthCallback
|
||||||
|
from passbook.sources.oauth.views.redirect import OAuthRedirect
|
||||||
|
|
||||||
|
|
||||||
@MANAGER.source(kind=RequestKind.redirect, name="Discord")
|
@MANAGER.source(kind=RequestKind.redirect, name="Discord")
|
||||||
|
|
|
@ -6,7 +6,8 @@ from facebook import GraphAPI
|
||||||
from passbook.sources.oauth.clients import OAuth2Client
|
from passbook.sources.oauth.clients import OAuth2Client
|
||||||
from passbook.sources.oauth.models import OAuthSource, UserOAuthSourceConnection
|
from passbook.sources.oauth.models import OAuthSource, UserOAuthSourceConnection
|
||||||
from passbook.sources.oauth.types.manager import MANAGER, RequestKind
|
from passbook.sources.oauth.types.manager import MANAGER, RequestKind
|
||||||
from passbook.sources.oauth.views.core import OAuthCallback, OAuthRedirect
|
from passbook.sources.oauth.views.callback import OAuthCallback
|
||||||
|
from passbook.sources.oauth.views.redirect import OAuthRedirect
|
||||||
|
|
||||||
|
|
||||||
@MANAGER.source(kind=RequestKind.redirect, name="Facebook")
|
@MANAGER.source(kind=RequestKind.redirect, name="Facebook")
|
||||||
|
|
|
@ -3,7 +3,7 @@ from typing import Any, Dict
|
||||||
|
|
||||||
from passbook.sources.oauth.models import OAuthSource, UserOAuthSourceConnection
|
from passbook.sources.oauth.models import OAuthSource, UserOAuthSourceConnection
|
||||||
from passbook.sources.oauth.types.manager import MANAGER, RequestKind
|
from passbook.sources.oauth.types.manager import MANAGER, RequestKind
|
||||||
from passbook.sources.oauth.views.core import OAuthCallback
|
from passbook.sources.oauth.views.callback import OAuthCallback
|
||||||
|
|
||||||
|
|
||||||
@MANAGER.source(kind=RequestKind.callback, name="GitHub")
|
@MANAGER.source(kind=RequestKind.callback, name="GitHub")
|
||||||
|
|
|
@ -3,7 +3,8 @@ from typing import Any, Dict
|
||||||
|
|
||||||
from passbook.sources.oauth.models import OAuthSource, UserOAuthSourceConnection
|
from passbook.sources.oauth.models import OAuthSource, UserOAuthSourceConnection
|
||||||
from passbook.sources.oauth.types.manager import MANAGER, RequestKind
|
from passbook.sources.oauth.types.manager import MANAGER, RequestKind
|
||||||
from passbook.sources.oauth.views.core import OAuthCallback, OAuthRedirect
|
from passbook.sources.oauth.views.callback import OAuthCallback
|
||||||
|
from passbook.sources.oauth.views.redirect import OAuthRedirect
|
||||||
|
|
||||||
|
|
||||||
@MANAGER.source(kind=RequestKind.redirect, name="Google")
|
@MANAGER.source(kind=RequestKind.redirect, name="Google")
|
||||||
|
|
|
@ -6,7 +6,8 @@ from django.utils.text import slugify
|
||||||
from structlog import get_logger
|
from structlog import get_logger
|
||||||
|
|
||||||
from passbook.sources.oauth.models import OAuthSource
|
from passbook.sources.oauth.models import OAuthSource
|
||||||
from passbook.sources.oauth.views.core import OAuthCallback, OAuthRedirect
|
from passbook.sources.oauth.views.callback import OAuthCallback
|
||||||
|
from passbook.sources.oauth.views.redirect import OAuthRedirect
|
||||||
|
|
||||||
LOGGER = get_logger()
|
LOGGER = get_logger()
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,8 @@ from typing import Any, Dict
|
||||||
|
|
||||||
from passbook.sources.oauth.models import OAuthSource, UserOAuthSourceConnection
|
from passbook.sources.oauth.models import OAuthSource, UserOAuthSourceConnection
|
||||||
from passbook.sources.oauth.types.manager import MANAGER, RequestKind
|
from passbook.sources.oauth.types.manager import MANAGER, RequestKind
|
||||||
from passbook.sources.oauth.views.core import OAuthCallback, OAuthRedirect
|
from passbook.sources.oauth.views.callback import OAuthCallback
|
||||||
|
from passbook.sources.oauth.views.redirect import OAuthRedirect
|
||||||
|
|
||||||
|
|
||||||
@MANAGER.source(kind=RequestKind.redirect, name="OpenID Connect")
|
@MANAGER.source(kind=RequestKind.redirect, name="OpenID Connect")
|
||||||
|
|
|
@ -6,7 +6,8 @@ from requests.auth import HTTPBasicAuth
|
||||||
from passbook.sources.oauth.clients import OAuth2Client
|
from passbook.sources.oauth.clients import OAuth2Client
|
||||||
from passbook.sources.oauth.models import OAuthSource, UserOAuthSourceConnection
|
from passbook.sources.oauth.models import OAuthSource, UserOAuthSourceConnection
|
||||||
from passbook.sources.oauth.types.manager import MANAGER, RequestKind
|
from passbook.sources.oauth.types.manager import MANAGER, RequestKind
|
||||||
from passbook.sources.oauth.views.core import OAuthCallback, OAuthRedirect
|
from passbook.sources.oauth.views.callback import OAuthCallback
|
||||||
|
from passbook.sources.oauth.views.redirect import OAuthRedirect
|
||||||
|
|
||||||
|
|
||||||
@MANAGER.source(kind=RequestKind.redirect, name="reddit")
|
@MANAGER.source(kind=RequestKind.redirect, name="reddit")
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
from typing import Any, Dict
|
from typing import Any, Dict
|
||||||
|
|
||||||
from passbook.sources.oauth.models import OAuthSource, UserOAuthSourceConnection
|
from passbook.sources.oauth.models import OAuthSource, UserOAuthSourceConnection
|
||||||
|
from passbook.sources.oauth.views.callback import OAuthCallback
|
||||||
|
|
||||||
# from passbook.sources.oauth.types.manager import MANAGER, RequestKind
|
# from passbook.sources.oauth.types.manager import MANAGER, RequestKind
|
||||||
from passbook.sources.oauth.views.core import OAuthCallback
|
|
||||||
|
|
||||||
|
|
||||||
# @MANAGER.source(kind=RequestKind.callback, name="Twitter")
|
# @MANAGER.source(kind=RequestKind.callback, name="Twitter")
|
||||||
|
|
|
@ -1,29 +1,30 @@
|
||||||
"""passbook oauth_client urls"""
|
"""passbook OAuth source urls"""
|
||||||
|
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
|
||||||
from passbook.sources.oauth.types.manager import RequestKind
|
from passbook.sources.oauth.types.manager import RequestKind
|
||||||
from passbook.sources.oauth.views import core, dispatcher, user
|
from passbook.sources.oauth.views.dispatcher import DispatcherView
|
||||||
|
from passbook.sources.oauth.views.user import DisconnectView, UserSettingsView
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path(
|
path(
|
||||||
"login/<slug:source_slug>/",
|
"login/<slug:source_slug>/",
|
||||||
dispatcher.DispatcherView.as_view(kind=RequestKind.redirect),
|
DispatcherView.as_view(kind=RequestKind.redirect),
|
||||||
name="oauth-client-login",
|
name="oauth-client-login",
|
||||||
),
|
),
|
||||||
path(
|
path(
|
||||||
"callback/<slug:source_slug>/",
|
"callback/<slug:source_slug>/",
|
||||||
dispatcher.DispatcherView.as_view(kind=RequestKind.callback),
|
DispatcherView.as_view(kind=RequestKind.callback),
|
||||||
name="oauth-client-callback",
|
name="oauth-client-callback",
|
||||||
),
|
),
|
||||||
path(
|
|
||||||
"disconnect/<slug:source_slug>/",
|
|
||||||
core.DisconnectView.as_view(),
|
|
||||||
name="oauth-client-disconnect",
|
|
||||||
),
|
|
||||||
path(
|
path(
|
||||||
"user/<slug:source_slug>/",
|
"user/<slug:source_slug>/",
|
||||||
user.UserSettingsView.as_view(),
|
UserSettingsView.as_view(),
|
||||||
name="oauth-client-user",
|
name="oauth-client-user",
|
||||||
),
|
),
|
||||||
|
path(
|
||||||
|
"user/<slug:source_slug>/disconnect/",
|
||||||
|
DisconnectView.as_view(),
|
||||||
|
name="oauth-client-disconnect",
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
"""OAuth Base views"""
|
||||||
|
from typing import Callable, Optional
|
||||||
|
|
||||||
|
from passbook.sources.oauth.clients import BaseOAuthClient, get_client
|
||||||
|
from passbook.sources.oauth.models import OAuthSource
|
||||||
|
|
||||||
|
|
||||||
|
# pylint: disable=too-few-public-methods
|
||||||
|
class OAuthClientMixin:
|
||||||
|
"Mixin for getting OAuth client for a source."
|
||||||
|
|
||||||
|
client_class: Optional[Callable] = None
|
||||||
|
|
||||||
|
def get_client(self, source: OAuthSource) -> BaseOAuthClient:
|
||||||
|
"Get instance of the OAuth client for this source."
|
||||||
|
if self.client_class is not None:
|
||||||
|
# pylint: disable=not-callable
|
||||||
|
return self.client_class(source)
|
||||||
|
return get_client(source)
|
|
@ -1,11 +1,10 @@
|
||||||
"""Core OAauth Views"""
|
"""OAuth Callback Views"""
|
||||||
from typing import Any, Callable, Dict, Optional
|
from typing import Any, Callable, Dict, Optional
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
|
||||||
from django.http import Http404, HttpRequest, HttpResponse
|
from django.http import Http404, HttpRequest, HttpResponse
|
||||||
from django.shortcuts import get_object_or_404, redirect, render
|
from django.shortcuts import redirect
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
from django.views.generic import RedirectView, View
|
from django.views.generic import RedirectView, View
|
||||||
|
@ -25,62 +24,13 @@ from passbook.policies.utils import delete_none_keys
|
||||||
from passbook.sources.oauth.auth import AuthorizedServiceBackend
|
from passbook.sources.oauth.auth import AuthorizedServiceBackend
|
||||||
from passbook.sources.oauth.clients import BaseOAuthClient, get_client
|
from passbook.sources.oauth.clients import BaseOAuthClient, get_client
|
||||||
from passbook.sources.oauth.models import OAuthSource, UserOAuthSourceConnection
|
from passbook.sources.oauth.models import OAuthSource, UserOAuthSourceConnection
|
||||||
|
from passbook.sources.oauth.views.base import OAuthClientMixin
|
||||||
from passbook.stages.password.stage import PLAN_CONTEXT_AUTHENTICATION_BACKEND
|
from passbook.stages.password.stage import PLAN_CONTEXT_AUTHENTICATION_BACKEND
|
||||||
from passbook.stages.prompt.stage import PLAN_CONTEXT_PROMPT
|
from passbook.stages.prompt.stage import PLAN_CONTEXT_PROMPT
|
||||||
|
|
||||||
LOGGER = get_logger()
|
LOGGER = get_logger()
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=too-few-public-methods
|
|
||||||
class OAuthClientMixin:
|
|
||||||
"Mixin for getting OAuth client for a source."
|
|
||||||
|
|
||||||
client_class: Optional[Callable] = None
|
|
||||||
|
|
||||||
def get_client(self, source: OAuthSource) -> BaseOAuthClient:
|
|
||||||
"Get instance of the OAuth client for this source."
|
|
||||||
if self.client_class is not None:
|
|
||||||
# pylint: disable=not-callable
|
|
||||||
return self.client_class(source)
|
|
||||||
return get_client(source)
|
|
||||||
|
|
||||||
|
|
||||||
class OAuthRedirect(OAuthClientMixin, RedirectView):
|
|
||||||
"Redirect user to OAuth source to enable access."
|
|
||||||
|
|
||||||
permanent = False
|
|
||||||
params = None
|
|
||||||
|
|
||||||
# pylint: disable=unused-argument
|
|
||||||
def get_additional_parameters(self, source: OAuthSource) -> Dict[str, Any]:
|
|
||||||
"Return additional redirect parameters for this source."
|
|
||||||
return self.params or {}
|
|
||||||
|
|
||||||
def get_callback_url(self, source: OAuthSource) -> str:
|
|
||||||
"Return the callback url for this source."
|
|
||||||
return reverse(
|
|
||||||
"passbook_sources_oauth:oauth-client-callback",
|
|
||||||
kwargs={"source_slug": source.slug},
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_redirect_url(self, **kwargs) -> str:
|
|
||||||
"Build redirect url for a given source."
|
|
||||||
slug = kwargs.get("source_slug", "")
|
|
||||||
try:
|
|
||||||
source = OAuthSource.objects.get(slug=slug)
|
|
||||||
except OAuthSource.DoesNotExist:
|
|
||||||
raise Http404(f"Unknown OAuth source '{slug}'.")
|
|
||||||
else:
|
|
||||||
if not source.enabled:
|
|
||||||
raise Http404(f"source {slug} is not enabled.")
|
|
||||||
client = self.get_client(source)
|
|
||||||
callback = self.get_callback_url(source)
|
|
||||||
params = self.get_additional_parameters(source)
|
|
||||||
return client.get_redirect_url(
|
|
||||||
self.request, callback=callback, parameters=params
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class OAuthCallback(OAuthClientMixin, View):
|
class OAuthCallback(OAuthClientMixin, View):
|
||||||
"Base OAuth callback view."
|
"Base OAuth callback view."
|
||||||
|
|
||||||
|
@ -258,46 +208,3 @@ class OAuthCallback(OAuthClientMixin, View):
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return self.handle_login_flow(source.enrollment_flow, **context)
|
return self.handle_login_flow(source.enrollment_flow, **context)
|
||||||
|
|
||||||
|
|
||||||
class DisconnectView(LoginRequiredMixin, View):
|
|
||||||
"""Delete connection with source"""
|
|
||||||
|
|
||||||
source = None
|
|
||||||
aas = None
|
|
||||||
|
|
||||||
def dispatch(self, request, source_slug):
|
|
||||||
self.source = get_object_or_404(OAuthSource, slug=source_slug)
|
|
||||||
self.aas = get_object_or_404(
|
|
||||||
UserOAuthSourceConnection, source=self.source, user=request.user
|
|
||||||
)
|
|
||||||
return super().dispatch(request, source_slug)
|
|
||||||
|
|
||||||
def post(self, request, source_slug):
|
|
||||||
"""Delete connection object"""
|
|
||||||
if "confirmdelete" in request.POST:
|
|
||||||
# User confirmed deletion
|
|
||||||
self.aas.delete()
|
|
||||||
messages.success(request, _("Connection successfully deleted"))
|
|
||||||
return redirect(
|
|
||||||
reverse(
|
|
||||||
"passbook_sources_oauth:oauth-client-user",
|
|
||||||
kwargs={"source_slug": self.source.slug},
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return self.get(request, source_slug)
|
|
||||||
|
|
||||||
# pylint: disable=unused-argument
|
|
||||||
def get(self, request, source_slug):
|
|
||||||
"""Show delete form"""
|
|
||||||
return render(
|
|
||||||
request,
|
|
||||||
"generic/delete.html",
|
|
||||||
{
|
|
||||||
"object": self.source,
|
|
||||||
"delete_url": reverse(
|
|
||||||
"passbook_sources_oauth:oauth-client-disconnect",
|
|
||||||
kwargs={"source_slug": self.source.slug},
|
|
||||||
),
|
|
||||||
},
|
|
||||||
)
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
"""OAuth Redirect Views"""
|
||||||
|
from typing import Any, Callable, Dict, Optional
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.contrib import messages
|
||||||
|
from django.http import Http404, HttpRequest, HttpResponse
|
||||||
|
from django.shortcuts import redirect
|
||||||
|
from django.urls import reverse
|
||||||
|
from django.utils.translation import ugettext as _
|
||||||
|
from django.views.generic import RedirectView, View
|
||||||
|
from structlog import get_logger
|
||||||
|
|
||||||
|
from passbook.audit.models import Event, EventAction
|
||||||
|
from passbook.core.models import User
|
||||||
|
from passbook.flows.models import Flow
|
||||||
|
from passbook.flows.planner import (
|
||||||
|
PLAN_CONTEXT_PENDING_USER,
|
||||||
|
PLAN_CONTEXT_SSO,
|
||||||
|
FlowPlanner,
|
||||||
|
)
|
||||||
|
from passbook.flows.views import SESSION_KEY_PLAN
|
||||||
|
from passbook.lib.utils.urls import redirect_with_qs
|
||||||
|
from passbook.policies.utils import delete_none_keys
|
||||||
|
from passbook.sources.oauth.auth import AuthorizedServiceBackend
|
||||||
|
from passbook.sources.oauth.clients import BaseOAuthClient, get_client
|
||||||
|
from passbook.sources.oauth.models import OAuthSource, UserOAuthSourceConnection
|
||||||
|
from passbook.sources.oauth.views.base import OAuthClientMixin
|
||||||
|
from passbook.stages.password.stage import PLAN_CONTEXT_AUTHENTICATION_BACKEND
|
||||||
|
from passbook.stages.prompt.stage import PLAN_CONTEXT_PROMPT
|
||||||
|
|
||||||
|
LOGGER = get_logger()
|
||||||
|
|
||||||
|
|
||||||
|
class OAuthRedirect(OAuthClientMixin, RedirectView):
|
||||||
|
"Redirect user to OAuth source to enable access."
|
||||||
|
|
||||||
|
permanent = False
|
||||||
|
params = None
|
||||||
|
|
||||||
|
# pylint: disable=unused-argument
|
||||||
|
def get_additional_parameters(self, source: OAuthSource) -> Dict[str, Any]:
|
||||||
|
"Return additional redirect parameters for this source."
|
||||||
|
return self.params or {}
|
||||||
|
|
||||||
|
def get_callback_url(self, source: OAuthSource) -> str:
|
||||||
|
"Return the callback url for this source."
|
||||||
|
return reverse(
|
||||||
|
"passbook_sources_oauth:oauth-client-callback",
|
||||||
|
kwargs={"source_slug": source.slug},
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_redirect_url(self, **kwargs) -> str:
|
||||||
|
"Build redirect url for a given source."
|
||||||
|
slug = kwargs.get("source_slug", "")
|
||||||
|
try:
|
||||||
|
source = OAuthSource.objects.get(slug=slug)
|
||||||
|
except OAuthSource.DoesNotExist:
|
||||||
|
raise Http404(f"Unknown OAuth source '{slug}'.")
|
||||||
|
else:
|
||||||
|
if not source.enabled:
|
||||||
|
raise Http404(f"source {slug} is not enabled.")
|
||||||
|
client = self.get_client(source)
|
||||||
|
callback = self.get_callback_url(source)
|
||||||
|
params = self.get_additional_parameters(source)
|
||||||
|
return client.get_redirect_url(
|
||||||
|
self.request, callback=callback, parameters=params
|
||||||
|
)
|
|
@ -1,7 +1,13 @@
|
||||||
"""passbook oauth_client user views"""
|
"""passbook oauth_client user views"""
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from django.contrib import messages
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
from django.shortcuts import get_object_or_404
|
from django.http import HttpRequest, HttpResponse
|
||||||
from django.views.generic import TemplateView
|
from django.shortcuts import get_object_or_404, redirect, render
|
||||||
|
from django.urls import reverse
|
||||||
|
from django.utils.translation import ugettext as _
|
||||||
|
from django.views.generic import TemplateView, View
|
||||||
|
|
||||||
from passbook.sources.oauth.models import OAuthSource, UserOAuthSourceConnection
|
from passbook.sources.oauth.models import OAuthSource, UserOAuthSourceConnection
|
||||||
|
|
||||||
|
@ -19,3 +25,46 @@ class UserSettingsView(LoginRequiredMixin, TemplateView):
|
||||||
kwargs["source"] = source
|
kwargs["source"] = source
|
||||||
kwargs["connections"] = connections
|
kwargs["connections"] = connections
|
||||||
return super().get_context_data(**kwargs)
|
return super().get_context_data(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class DisconnectView(LoginRequiredMixin, View):
|
||||||
|
"""Delete connection with source"""
|
||||||
|
|
||||||
|
source: Optional[OAuthSource] = None
|
||||||
|
aas: Optional[UserOAuthSourceConnection] = None
|
||||||
|
|
||||||
|
def dispatch(self, request: HttpRequest, source_slug: str) -> HttpResponse:
|
||||||
|
self.source = get_object_or_404(OAuthSource, slug=source_slug)
|
||||||
|
self.aas = get_object_or_404(
|
||||||
|
UserOAuthSourceConnection, source=self.source, user=request.user
|
||||||
|
)
|
||||||
|
return super().dispatch(request, source_slug)
|
||||||
|
|
||||||
|
def post(self, request: HttpRequest, source_slug: str) -> HttpResponse:
|
||||||
|
"""Delete connection object"""
|
||||||
|
if "confirmdelete" in request.POST:
|
||||||
|
# User confirmed deletion
|
||||||
|
self.aas.delete()
|
||||||
|
messages.success(request, _("Connection successfully deleted"))
|
||||||
|
return redirect(
|
||||||
|
reverse(
|
||||||
|
"passbook_sources_oauth:oauth-client-user",
|
||||||
|
kwargs={"source_slug": self.source.slug},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return self.get(request, source_slug)
|
||||||
|
|
||||||
|
# pylint: disable=unused-argument
|
||||||
|
def get(self, request: HttpRequest, source_slug: str) -> HttpResponse:
|
||||||
|
"""Show delete form"""
|
||||||
|
return render(
|
||||||
|
request,
|
||||||
|
"generic/delete.html",
|
||||||
|
{
|
||||||
|
"object": self.source,
|
||||||
|
"delete_url": reverse(
|
||||||
|
"passbook_sources_oauth:oauth-client-disconnect",
|
||||||
|
kwargs={"source_slug": self.source.slug},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
Reference in New Issue