admin: add provider admin
This commit is contained in:
parent
755997a9c7
commit
c0c51981ba
|
@ -17,6 +17,9 @@
|
||||||
<li class="{% is_active 'passbook_admin:rules' 'passbook_admin:rule-create' 'passbook_admin:rule-update' 'passbook_admin:rule-delete' %}">
|
<li class="{% is_active 'passbook_admin:rules' 'passbook_admin:rule-create' 'passbook_admin:rule-update' 'passbook_admin:rule-delete' %}">
|
||||||
<a href="{% url 'passbook_admin:rules' %}">{% trans 'Rules' %}</a>
|
<a href="{% url 'passbook_admin:rules' %}">{% trans 'Rules' %}</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="{% is_active 'passbook_admin:providers' 'passbook_admin:provider-create' 'passbook_admin:provider-update' 'passbook_admin:provider-delete' %}">
|
||||||
|
<a href="{% url 'passbook_admin:providers' %}">{% trans 'Providers' %}</a>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="#">{% trans 'Users' %}</a>
|
<a href="#">{% trans 'Users' %}</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
{% extends "administration/base.html" %}
|
||||||
|
|
||||||
|
{% load i18n %}
|
||||||
|
{% load utils %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
{% title %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="container">
|
||||||
|
<h1>{% trans "Providers" %}</h1>
|
||||||
|
<div class="dropdown">
|
||||||
|
<button class="btn btn-primary dropdown-toggle" type="button" id="createDropdown" data-toggle="dropdown">
|
||||||
|
{% trans 'Create...' %}
|
||||||
|
<span class="caret"></span>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu" role="menu" aria-labelledby="createDropdown">
|
||||||
|
{% for type, name in types.items %}
|
||||||
|
<li role="presentation"><a role="menuitem" tabindex="-1" href="{% url 'passbook_admin:provider-create' %}?type={{ type }}">{{ name }}</a></li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<table class="table table-striped table-bordered">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>{% trans 'Name' %}</th>
|
||||||
|
<th>{% trans 'Class' %}</th>
|
||||||
|
<th></th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for provider in object_list %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ provider.name }}</td>
|
||||||
|
<td>{{ provider|fieldtype }}</td>
|
||||||
|
<td><a href="{% url 'passbook_admin:provider-update' pk=provider.uuid %}?back={{ request.get_full_path }}">{% trans 'Edit' %}</a></td>
|
||||||
|
<td><a href="{% url 'passbook_admin:provider-delete' pk=provider.uuid %}?back={{ request.get_full_path }}">{% trans 'Delete' %}</a></td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
|
@ -1,7 +1,8 @@
|
||||||
"""passbook URL Configuration"""
|
"""passbook URL Configuration"""
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
|
||||||
from passbook.admin.views import applications, overview, rules, sources
|
from passbook.admin.views import (applications, overview, providers, rules,
|
||||||
|
sources)
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', overview.AdministrationOverviewView.as_view(), name='overview'),
|
path('', overview.AdministrationOverviewView.as_view(), name='overview'),
|
||||||
|
@ -24,5 +25,13 @@ urlpatterns = [
|
||||||
path('rules/create/', rules.RuleCreateView.as_view(), name='rule-create'),
|
path('rules/create/', rules.RuleCreateView.as_view(), name='rule-create'),
|
||||||
path('rules/<uuid:pk>/update/', rules.RuleUpdateView.as_view(), name='rule-update'),
|
path('rules/<uuid:pk>/update/', rules.RuleUpdateView.as_view(), name='rule-update'),
|
||||||
path('rules/<uuid:pk>/delete/', rules.RuleDeleteView.as_view(), name='rule-delete'),
|
path('rules/<uuid:pk>/delete/', rules.RuleDeleteView.as_view(), name='rule-delete'),
|
||||||
|
# Providers
|
||||||
|
path('providers/', providers.ProviderListView.as_view(), name='providers'),
|
||||||
|
path('providers/create/',
|
||||||
|
providers.ProviderCreateView.as_view(), name='provider-create'),
|
||||||
|
path('providers/<uuid:pk>/update/',
|
||||||
|
providers.ProviderUpdateView.as_view(), name='provider-update'),
|
||||||
|
path('providers/<uuid:pk>/delete/',
|
||||||
|
providers.ProviderDeleteView.as_view(), name='provider-delete'),
|
||||||
# path('api/v1/', include('passbook.admin.api.v1.urls'))
|
# path('api/v1/', include('passbook.admin.api.v1.urls'))
|
||||||
]
|
]
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
"""passbook Provider administration"""
|
||||||
|
from django.contrib.messages.views import SuccessMessageMixin
|
||||||
|
from django.http import Http404
|
||||||
|
from django.urls import reverse_lazy
|
||||||
|
from django.utils.translation import ugettext as _
|
||||||
|
from django.views.generic import CreateView, DeleteView, ListView, UpdateView
|
||||||
|
|
||||||
|
from passbook.admin.mixins import AdminRequiredMixin
|
||||||
|
from passbook.core.models import Provider
|
||||||
|
from passbook.lib.utils.reflection import path_to_class
|
||||||
|
|
||||||
|
|
||||||
|
class ProviderListView(AdminRequiredMixin, ListView):
|
||||||
|
"""Show list of all providers"""
|
||||||
|
|
||||||
|
model = Provider
|
||||||
|
template_name = 'administration/provider/list.html'
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
kwargs['types'] = {
|
||||||
|
x.__name__: x._meta.verbose_name for x in Provider.__subclasses__()}
|
||||||
|
return super().get_context_data(**kwargs)
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return super().get_queryset().select_subclasses()
|
||||||
|
|
||||||
|
|
||||||
|
class ProviderCreateView(SuccessMessageMixin, AdminRequiredMixin, CreateView):
|
||||||
|
"""Create new Provider"""
|
||||||
|
|
||||||
|
template_name = 'generic/create_inheritance.html'
|
||||||
|
success_url = reverse_lazy('passbook_admin:providers')
|
||||||
|
success_message = _('Successfully created Provider')
|
||||||
|
|
||||||
|
def get_form_class(self):
|
||||||
|
provider_type = self.request.GET.get('type')
|
||||||
|
model = next(x for x in Provider.__subclasses__()
|
||||||
|
if x.__name__ == provider_type)
|
||||||
|
if not model:
|
||||||
|
raise Http404
|
||||||
|
return path_to_class(model.form)
|
||||||
|
|
||||||
|
|
||||||
|
class ProviderUpdateView(SuccessMessageMixin, AdminRequiredMixin, UpdateView):
|
||||||
|
"""Update provider"""
|
||||||
|
|
||||||
|
model = Provider
|
||||||
|
template_name = 'generic/update.html'
|
||||||
|
success_url = reverse_lazy('passbook_admin:providers')
|
||||||
|
success_message = _('Successfully updated Provider')
|
||||||
|
|
||||||
|
def get_form_class(self):
|
||||||
|
form_class_path = self.get_object().form
|
||||||
|
form_class = path_to_class(form_class_path)
|
||||||
|
return form_class
|
||||||
|
|
||||||
|
def get_object(self, queryset=None):
|
||||||
|
return Provider.objects.filter(pk=self.kwargs.get('pk')).select_subclasses().first()
|
||||||
|
|
||||||
|
|
||||||
|
class ProviderDeleteView(SuccessMessageMixin, AdminRequiredMixin, DeleteView):
|
||||||
|
"""Delete provider"""
|
||||||
|
|
||||||
|
model = Provider
|
||||||
|
template_name = 'generic/delete.html'
|
||||||
|
success_url = reverse_lazy('passbook_admin:providers')
|
||||||
|
success_message = _('Successfully updated Provider')
|
||||||
|
|
||||||
|
def get_object(self, queryset=None):
|
||||||
|
return Provider.objects.filter(pk=self.kwargs.get('pk')).select_subclasses().first()
|
|
@ -0,0 +1,15 @@
|
||||||
|
"""passbook OAuth2 IDP Forms"""
|
||||||
|
|
||||||
|
from django import forms
|
||||||
|
|
||||||
|
from passbook.oauth_provider.models import OAuth2Provider
|
||||||
|
|
||||||
|
|
||||||
|
class OAuth2ProviderForm(forms.ModelForm):
|
||||||
|
"""OAuth2 Provider form"""
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
|
||||||
|
model = OAuth2Provider
|
||||||
|
fields = ['name', 'user', 'redirect_uris', 'client_type',
|
||||||
|
'authorization_grant_type', 'client_id', 'client_secret', ]
|
|
@ -9,6 +9,8 @@ from passbook.core.models import Provider
|
||||||
class OAuth2Provider(Provider, AbstractApplication):
|
class OAuth2Provider(Provider, AbstractApplication):
|
||||||
"""Associate an OAuth2 Application with a Product"""
|
"""Associate an OAuth2 Application with a Product"""
|
||||||
|
|
||||||
|
form = 'passbook.oauth_provider.forms.OAuth2ProviderForm'
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
"""passbook SAML IDP Forms"""
|
||||||
|
|
||||||
|
from django import forms
|
||||||
|
|
||||||
|
from passbook.saml_idp.models import SAMLProvider
|
||||||
|
|
||||||
|
|
||||||
|
class SAMLProviderForm(forms.ModelForm):
|
||||||
|
"""SAML Provider form"""
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
|
||||||
|
model = SAMLProvider
|
||||||
|
fields = ['name', 'acs_url', 'processor_path', ]
|
|
@ -15,6 +15,8 @@ class SAMLProvider(Provider):
|
||||||
acs_url = models.URLField()
|
acs_url = models.URLField()
|
||||||
processor_path = models.CharField(max_length=255, choices=[])
|
processor_path = models.CharField(max_length=255, choices=[])
|
||||||
|
|
||||||
|
form = 'passbook.saml_idp.forms.SAMLProviderForm'
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
processors = [(class_to_path(x), x.__name__) for x in Processor.__subclasses__()]
|
processors = [(class_to_path(x), x.__name__) for x in Processor.__subclasses__()]
|
||||||
|
|
Reference in New Issue