*: providers and sources -> channels, PolicyModel to PolicyBindingModel that uses custom M2M through

This commit is contained in:
Jens Langhammer
2020-05-15 22:15:01 +02:00
parent 615cd7870d
commit 7ed3ceb960
293 changed files with 3236 additions and 4684 deletions

View File

@ -0,0 +1,4 @@
"""passbook core inlet form fields"""
INLET_FORM_FIELDS = ["name", "slug", "enabled"]
INLET_SERIALIZER_FIELDS = ["pk", "name", "slug", "enabled"]

View File

@ -1,4 +0,0 @@
"""passbook core source form fields"""
SOURCE_FORM_FIELDS = ["name", "slug", "enabled"]
SOURCE_SERIALIZER_FIELDS = ["pk", "name", "slug", "enabled"]

View File

@ -8,12 +8,12 @@ from passbook.admin.views import (
debug,
flows,
groups,
inlets,
invitations,
outlets,
overview,
policy,
policies,
property_mapping,
providers,
sources,
stages,
users,
)
@ -39,51 +39,49 @@ urlpatterns = [
applications.ApplicationDeleteView.as_view(),
name="application-delete",
),
# Sources
path("sources/", sources.SourceListView.as_view(), name="sources"),
path("sources/create/", sources.SourceCreateView.as_view(), name="source-create"),
# Inlets
path("inlets/", inlets.InletListView.as_view(), name="inlets"),
path("inlets/create/", inlets.InletCreateView.as_view(), name="inlet-create"),
path(
"sources/<uuid:pk>/update/",
sources.SourceUpdateView.as_view(),
name="source-update",
"inlets/<uuid:pk>/update/",
inlets.InletUpdateView.as_view(),
name="inlet-update",
),
path(
"sources/<uuid:pk>/delete/",
sources.SourceDeleteView.as_view(),
name="source-delete",
"inlets/<uuid:pk>/delete/",
inlets.InletDeleteView.as_view(),
name="inlet-delete",
),
# Policies
path("policies/", policy.PolicyListView.as_view(), name="policies"),
path("policies/create/", policy.PolicyCreateView.as_view(), name="policy-create"),
path("policies/", policies.PolicyListView.as_view(), name="policies"),
path("policies/create/", policies.PolicyCreateView.as_view(), name="policy-create"),
path(
"policies/<uuid:pk>/update/",
policy.PolicyUpdateView.as_view(),
policies.PolicyUpdateView.as_view(),
name="policy-update",
),
path(
"policies/<uuid:pk>/delete/",
policy.PolicyDeleteView.as_view(),
policies.PolicyDeleteView.as_view(),
name="policy-delete",
),
path(
"policies/<uuid:pk>/test/", policy.PolicyTestView.as_view(), name="policy-test"
"policies/<uuid:pk>/test/",
policies.PolicyTestView.as_view(),
name="policy-test",
),
# Providers
path("providers/", providers.ProviderListView.as_view(), name="providers"),
# Outlets
path("outlets/", outlets.OutletListView.as_view(), name="outlets"),
path("outlets/create/", outlets.OutletCreateView.as_view(), name="outlet-create",),
path(
"providers/create/",
providers.ProviderCreateView.as_view(),
name="provider-create",
"outlets/<int:pk>/update/",
outlets.OutletUpdateView.as_view(),
name="outlet-update",
),
path(
"providers/<int:pk>/update/",
providers.ProviderUpdateView.as_view(),
name="provider-update",
),
path(
"providers/<int:pk>/delete/",
providers.ProviderDeleteView.as_view(),
name="provider-delete",
"outlets/<int:pk>/delete/",
outlets.OutletDeleteView.as_view(),
name="outlet-delete",
),
# Stages
path("stages/", stages.StageListView.as_view(), name="stages"),

View File

@ -1,4 +1,4 @@
"""passbook Provider administration"""
"""passbook Inlet administration"""
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.mixins import (
@ -11,23 +11,23 @@ from django.utils.translation import ugettext as _
from django.views.generic import DeleteView, ListView, UpdateView
from guardian.mixins import PermissionListMixin, PermissionRequiredMixin
from passbook.core.models import Provider
from passbook.core.models import Inlet
from passbook.lib.utils.reflection import all_subclasses, path_to_class
from passbook.lib.views import CreateAssignPermView
class ProviderListView(LoginRequiredMixin, PermissionListMixin, ListView):
"""Show list of all providers"""
class InletListView(LoginRequiredMixin, PermissionListMixin, ListView):
"""Show list of all inlets"""
model = Provider
permission_required = "passbook_core.add_provider"
template_name = "administration/provider/list.html"
paginate_by = 10
ordering = "id"
model = Inlet
permission_required = "passbook_core.view_inlet"
ordering = "name"
paginate_by = 40
template_name = "administration/inlet/list.html"
def get_context_data(self, **kwargs):
kwargs["types"] = {
x.__name__: x._meta.verbose_name for x in all_subclasses(Provider)
x.__name__: x._meta.verbose_name for x in all_subclasses(Inlet)
}
return super().get_context_data(**kwargs)
@ -35,40 +35,40 @@ class ProviderListView(LoginRequiredMixin, PermissionListMixin, ListView):
return super().get_queryset().select_subclasses()
class ProviderCreateView(
class InletCreateView(
SuccessMessageMixin,
LoginRequiredMixin,
DjangoPermissionRequiredMixin,
CreateAssignPermView,
):
"""Create new Provider"""
"""Create new Inlet"""
model = Provider
permission_required = "passbook_core.add_provider"
model = Inlet
permission_required = "passbook_core.add_inlet"
template_name = "generic/create.html"
success_url = reverse_lazy("passbook_admin:providers")
success_message = _("Successfully created Provider")
success_url = reverse_lazy("passbook_admin:inlets")
success_message = _("Successfully created Inlet")
def get_form_class(self):
provider_type = self.request.GET.get("type")
model = next(x for x in all_subclasses(Provider) if x.__name__ == provider_type)
inlet_type = self.request.GET.get("type")
model = next(x for x in all_subclasses(Inlet) if x.__name__ == inlet_type)
if not model:
raise Http404
return path_to_class(model.form)
class ProviderUpdateView(
class InletUpdateView(
SuccessMessageMixin, LoginRequiredMixin, PermissionRequiredMixin, UpdateView
):
"""Update provider"""
"""Update inlet"""
model = Provider
permission_required = "passbook_core.change_provider"
model = Inlet
permission_required = "passbook_core.change_inlet"
template_name = "generic/update.html"
success_url = reverse_lazy("passbook_admin:providers")
success_message = _("Successfully updated Provider")
success_url = reverse_lazy("passbook_admin:inlets")
success_message = _("Successfully updated Inlet")
def get_form_class(self):
form_class_path = self.get_object().form
@ -77,29 +77,25 @@ class ProviderUpdateView(
def get_object(self, queryset=None):
return (
Provider.objects.filter(pk=self.kwargs.get("pk"))
.select_subclasses()
.first()
Inlet.objects.filter(pk=self.kwargs.get("pk")).select_subclasses().first()
)
class ProviderDeleteView(
class InletDeleteView(
SuccessMessageMixin, LoginRequiredMixin, PermissionRequiredMixin, DeleteView
):
"""Delete provider"""
"""Delete inlet"""
model = Provider
permission_required = "passbook_core.delete_provider"
model = Inlet
permission_required = "passbook_core.delete_inlet"
template_name = "generic/delete.html"
success_url = reverse_lazy("passbook_admin:providers")
success_message = _("Successfully deleted Provider")
success_url = reverse_lazy("passbook_admin:inlets")
success_message = _("Successfully deleted Inlet")
def get_object(self, queryset=None):
return (
Provider.objects.filter(pk=self.kwargs.get("pk"))
.select_subclasses()
.first()
Inlet.objects.filter(pk=self.kwargs.get("pk")).select_subclasses().first()
)
def delete(self, request, *args, **kwargs):

View File

@ -1,4 +1,4 @@
"""passbook Source administration"""
"""passbook Outlet administration"""
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.mixins import (
@ -11,23 +11,23 @@ from django.utils.translation import ugettext as _
from django.views.generic import DeleteView, ListView, UpdateView
from guardian.mixins import PermissionListMixin, PermissionRequiredMixin
from passbook.core.models import Source
from passbook.core.models import Outlet
from passbook.lib.utils.reflection import all_subclasses, path_to_class
from passbook.lib.views import CreateAssignPermView
class SourceListView(LoginRequiredMixin, PermissionListMixin, ListView):
"""Show list of all sources"""
class OutletListView(LoginRequiredMixin, PermissionListMixin, ListView):
"""Show list of all outlets"""
model = Source
permission_required = "passbook_core.view_source"
ordering = "name"
paginate_by = 40
template_name = "administration/source/list.html"
model = Outlet
permission_required = "passbook_core.add_outlet"
template_name = "administration/outlet/list.html"
paginate_by = 10
ordering = "id"
def get_context_data(self, **kwargs):
kwargs["types"] = {
x.__name__: x._meta.verbose_name for x in all_subclasses(Source)
x.__name__: x._meta.verbose_name for x in all_subclasses(Outlet)
}
return super().get_context_data(**kwargs)
@ -35,40 +35,40 @@ class SourceListView(LoginRequiredMixin, PermissionListMixin, ListView):
return super().get_queryset().select_subclasses()
class SourceCreateView(
class OutletCreateView(
SuccessMessageMixin,
LoginRequiredMixin,
DjangoPermissionRequiredMixin,
CreateAssignPermView,
):
"""Create new Source"""
"""Create new Outlet"""
model = Source
permission_required = "passbook_core.add_source"
model = Outlet
permission_required = "passbook_core.add_outlet"
template_name = "generic/create.html"
success_url = reverse_lazy("passbook_admin:sources")
success_message = _("Successfully created Source")
success_url = reverse_lazy("passbook_admin:outlets")
success_message = _("Successfully created Outlet")
def get_form_class(self):
source_type = self.request.GET.get("type")
model = next(x for x in all_subclasses(Source) if x.__name__ == source_type)
outlet_type = self.request.GET.get("type")
model = next(x for x in all_subclasses(Outlet) if x.__name__ == outlet_type)
if not model:
raise Http404
return path_to_class(model.form)
class SourceUpdateView(
class OutletUpdateView(
SuccessMessageMixin, LoginRequiredMixin, PermissionRequiredMixin, UpdateView
):
"""Update source"""
"""Update outlet"""
model = Source
permission_required = "passbook_core.change_source"
model = Outlet
permission_required = "passbook_core.change_outlet"
template_name = "generic/update.html"
success_url = reverse_lazy("passbook_admin:sources")
success_message = _("Successfully updated Source")
success_url = reverse_lazy("passbook_admin:outlets")
success_message = _("Successfully updated Outlet")
def get_form_class(self):
form_class_path = self.get_object().form
@ -77,25 +77,25 @@ class SourceUpdateView(
def get_object(self, queryset=None):
return (
Source.objects.filter(pk=self.kwargs.get("pk")).select_subclasses().first()
Outlet.objects.filter(pk=self.kwargs.get("pk")).select_subclasses().first()
)
class SourceDeleteView(
class OutletDeleteView(
SuccessMessageMixin, LoginRequiredMixin, PermissionRequiredMixin, DeleteView
):
"""Delete source"""
"""Delete outlet"""
model = Source
permission_required = "passbook_core.delete_source"
model = Outlet
permission_required = "passbook_core.delete_outlet"
template_name = "generic/delete.html"
success_url = reverse_lazy("passbook_admin:sources")
success_message = _("Successfully deleted Source")
success_url = reverse_lazy("passbook_admin:outlets")
success_message = _("Successfully deleted Outlet")
def get_object(self, queryset=None):
return (
Source.objects.filter(pk=self.kwargs.get("pk")).select_subclasses().first()
Outlet.objects.filter(pk=self.kwargs.get("pk")).select_subclasses().first()
)
def delete(self, request, *args, **kwargs):

View File

@ -5,8 +5,9 @@ from django.views.generic import TemplateView
from passbook import __version__
from passbook.admin.mixins import AdminRequiredMixin
from passbook.core.models import Application, Policy, Provider, Source, User
from passbook.core.models import Application, Inlet, Outlet, User
from passbook.flows.models import Flow, Stage
from passbook.policies.models import Policy
from passbook.root.celery import CELERY_APP
from passbook.stages.invitation.models import Invitation
@ -27,16 +28,14 @@ class AdministrationOverviewView(AdminRequiredMixin, TemplateView):
kwargs["application_count"] = len(Application.objects.all())
kwargs["policy_count"] = len(Policy.objects.all())
kwargs["user_count"] = len(User.objects.all())
kwargs["provider_count"] = len(Provider.objects.all())
kwargs["source_count"] = len(Source.objects.all())
kwargs["outlet_count"] = len(Outlet.objects.all())
kwargs["inlet_count"] = len(Inlet.objects.all())
kwargs["stage_count"] = len(Stage.objects.all())
kwargs["flow_count"] = len(Flow.objects.all())
kwargs["invitation_count"] = len(Invitation.objects.all())
kwargs["version"] = __version__
kwargs["worker_count"] = len(CELERY_APP.control.ping(timeout=0.5))
kwargs["providers_without_application"] = Provider.objects.filter(
application=None
)
kwargs["outlets_without_application"] = Outlet.objects.filter(application=None)
kwargs["policies_without_binding"] = len(
Policy.objects.filter(policymodel__isnull=True)
)

View File

@ -13,10 +13,10 @@ from django.views.generic.detail import DetailView
from guardian.mixins import PermissionListMixin, PermissionRequiredMixin
from passbook.admin.forms.policies import PolicyTestForm
from passbook.core.models import Policy
from passbook.lib.utils.reflection import all_subclasses, path_to_class
from passbook.lib.views import CreateAssignPermView
from passbook.policies.engine import PolicyEngine
from passbook.policies.models import Policy
class PolicyListView(LoginRequiredMixin, PermissionListMixin, ListView):

View File

@ -16,7 +16,7 @@ from guardian.mixins import (
)
from passbook.admin.forms.users import UserForm
from passbook.core.models import Nonce, User
from passbook.core.models import Token, User
from passbook.lib.views import CreateAssignPermView
@ -92,12 +92,12 @@ class UserPasswordResetView(LoginRequiredMixin, PermissionRequiredMixin, DetailV
permission_required = "passbook_core.reset_user_password"
def get(self, request, *args, **kwargs):
"""Create nonce for user and return link"""
"""Create token for user and return link"""
super().get(request, *args, **kwargs)
# TODO: create plan for user, get token
nonce = Nonce.objects.create(user=self.object)
token = Token.objects.create(user=self.object)
link = request.build_absolute_uri(
reverse("passbook_flows:default-recovery", kwargs={"nonce": nonce.uuid})
reverse("passbook_flows:default-recovery", kwargs={"token": token.uuid})
)
messages.success(
request, _("Password reset link: <pre>%(link)s</pre>" % {"link": link})