diff --git a/apps/gooyal_oauth2/filters.py b/apps/gooyal_oauth2/filters.py index cdb6249..eed291d 100644 --- a/apps/gooyal_oauth2/filters.py +++ b/apps/gooyal_oauth2/filters.py @@ -4,7 +4,7 @@ from django.contrib.contenttypes.models import ContentType from jalali_date.widgets import AdminJalaliDateWidget from jalali_date.fields import JalaliDateField -from .models import Application +from .models import Application, Scope class JalaliDateFilter(django_filters.DateFilter): @@ -15,6 +15,14 @@ class ApplicationFilter(django_filters.FilterSet): class Meta: model = Application fields = { - 'name': ['contains'], - 'client_id': ['contains'], + 'name': ['icontains'], + 'client_id': ['icontains'], + } + +class ScopeFilter(django_filters.FilterSet): + class Meta: + model = Scope + fields = { + 'name': ['icontains'], + 'description': ['icontains'], } diff --git a/apps/gooyal_oauth2/forms.py b/apps/gooyal_oauth2/forms.py index 7f76470..87ef870 100644 --- a/apps/gooyal_oauth2/forms.py +++ b/apps/gooyal_oauth2/forms.py @@ -5,7 +5,7 @@ Django forms for use with the gooyal-restrict-scopes package. from django import forms from oauth2_provider.scopes import get_scopes_backend -from .models import Application +from .models import Application, Scope class DelimitedListField(forms.MultipleChoiceField): @@ -82,3 +82,12 @@ class ApplicationUpdateForm(forms.ModelForm): ] readonly_fields = ['name', 'client_id', 'client_secret'] + + +class ApplicationScopeCreateForm(forms.ModelForm): + class Meta: + model = Scope + fields = [ + 'name', + 'description' + ] diff --git a/apps/gooyal_oauth2/urls.py b/apps/gooyal_oauth2/urls.py index 1e647ff..7071dfd 100644 --- a/apps/gooyal_oauth2/urls.py +++ b/apps/gooyal_oauth2/urls.py @@ -21,12 +21,15 @@ router = routers.SimpleRouter() router.register(r'apis/applications', api_views.ApplicationViewSet, basename='application') management_urlpatterns = [ - # re_path(r"^applications/$", views.ApplicationList.as_view(), name="application_list"), path("applications/", pages.ApplicationListView.as_view(), name="application_list"), path('applications/register/', pages.ApplicationCreateView.as_view(), name='application_create'), path("applications//", pages.ApplicationDetailView.as_view(), name="application_detail"), - # re_path(r"^applications/(?P[\w-]+)/delete/$", views.ApplicationDelete.as_view(), name="delete"), path("applications//update/", pages.ApplicationUpdateView.as_view(), name="application_update"), + path("applications//scopes/", pages.ApplicationScopeListView.as_view(), name="application_scope_list"), + path("applications//scopes/register/", pages.ApplicationScopeCreateView.as_view(), name="application_scope_create"), + path("applications//scopes//", pages.ApplicationScopeDetailView.as_view(), name="application_scope_detail"), + path("applications//scopes//update/", pages.ApplicationScopeUpdateView.as_view(), name="application_scope_update"), + # Token management views # re_path(r"^authorized_tokens/$", views.AuthorizedTokensListView.as_view(), name="authorized-token-list"), # re_path( diff --git a/apps/gooyal_oauth2/views/pages.py b/apps/gooyal_oauth2/views/pages.py index cfeaceb..62bcc32 100644 --- a/apps/gooyal_oauth2/views/pages.py +++ b/apps/gooyal_oauth2/views/pages.py @@ -5,9 +5,9 @@ from django.utils.decorators import method_decorator from django.views.generic import CreateView, DetailView, ListView, UpdateView from oauth2_provider.models import get_application_model -from apps.gooyal_oauth2.filters import ApplicationFilter -from apps.gooyal_oauth2.forms import ApplicationCreateForm, ApplicationUpdateForm -from apps.gooyal_oauth2.models import Application +from apps.gooyal_oauth2.filters import ApplicationFilter, ScopeFilter +from apps.gooyal_oauth2.forms import ApplicationCreateForm, ApplicationUpdateForm, ApplicationScopeCreateForm +from apps.gooyal_oauth2.models import Application, Scope from utils.views import FilterMixin @@ -68,3 +68,88 @@ class ApplicationListView(FilterMixin, ListView): def get_queryset(self): qs = super().get_queryset() return qs.filter(user=self.request.user) + + +class ApplicationScopeMixin: + application = None + + def get_application(self): + if not self.application: + application_pk = self.kwargs['application_pk'] + application = Application.objects.get(pk=application_pk, user=self.request.user) + self.application = application + + return self.application + + def get_context_data(self, **kwargs): + application = self.get_application() + + context_data = super().get_context_data(**kwargs) + context_data['application'] = application + return context_data + + +@method_decorator(login_required, name='dispatch') +class ApplicationScopeListView(ApplicationScopeMixin, FilterMixin, ListView): + model = Scope + template_name = "gooyal_oauth2/application_scope_list.html" + paginate_by = settings.PAGE_SIZE + filterset_class = ScopeFilter + + def get_ordering(self): + ordering = self.request.GET.get('ordering', 'name') + return ordering + + def get_queryset(self): + qs = super().get_queryset() + application = self.get_application() + return qs.filter(application__user=self.request.user, application=application) + + +@method_decorator(login_required, name='dispatch') +class ApplicationScopeCreateView(ApplicationScopeMixin, CreateView): + template_name = "gooyal_oauth2/application_scope_create.html" + form_class = ApplicationScopeCreateForm + model = Scope + + def get_queryset(self): + qs = super().get_queryset() + application = self.get_application() + return qs.filter(application__user=self.request.user, application=application) + + def get_success_url(self): + return reverse_lazy("gooyal_oauth2:application_scope_detail", kwargs={"pk": self.object.pk, "application_pk": self.get_application().pk}) + + def form_valid(self, form): + form.instance.application = self.get_application() + return super().form_valid(form) + + +@method_decorator(login_required, name='dispatch') +class ApplicationScopeDetailView(ApplicationScopeMixin, DetailView): + model = Scope + template_name = "gooyal_oauth2/application_scope_detail.html" + + def get_queryset(self): + application = self.get_application() + return Scope.objects.filter(application=application) + + +@method_decorator(login_required, name='dispatch') +class ApplicationScopeUpdateView(ApplicationScopeMixin, UpdateView): + template_name = "gooyal_oauth2/application_scope_update.html" + form_class = ApplicationScopeCreateForm + model = Scope + + def get_queryset(self): + qs = super().get_queryset() + application = self.get_application() + return qs.filter(application__user=self.request.user, application=application) + + def get_success_url(self): + return reverse_lazy("gooyal_oauth2:application_scope_detail", kwargs={"pk": self.object.pk, "application_pk": self.get_application().pk}) + + def form_valid(self, form): + # form.instance.user = self.request.user + # form.instance.client_type = Application.CLIENT_PUBLIC + return super().form_valid(form) diff --git a/templates/gooyal_oauth2/application_detail.html b/templates/gooyal_oauth2/application_detail.html index 53597c6..408b1c3 100644 --- a/templates/gooyal_oauth2/application_detail.html +++ b/templates/gooyal_oauth2/application_detail.html @@ -14,6 +14,13 @@ + {% endblock %} diff --git a/templates/gooyal_oauth2/application_list.html b/templates/gooyal_oauth2/application_list.html index f4e15a5..8e89b8c 100644 --- a/templates/gooyal_oauth2/application_list.html +++ b/templates/gooyal_oauth2/application_list.html @@ -25,12 +25,14 @@ name{% if request.GET.ordering and 'name' in request.GET.ordering %}{% endif %} client id{% if request.GET.ordering and 'client_id' in request.GET.ordering %}{% endif %} + type actions {% for obj in object_list %} {{ obj.name }} {{ obj.client_id }} + {{ obj.allows_grant_type }}
diff --git a/templates/gooyal_oauth2/application_scope_create.html b/templates/gooyal_oauth2/application_scope_create.html new file mode 100644 index 0000000..315c839 --- /dev/null +++ b/templates/gooyal_oauth2/application_scope_create.html @@ -0,0 +1,24 @@ +{% extends "base.html" %} +{% load static %} +{% load crispy_forms_tags %} +{% load jalali_tags %} + +{% block title %}Application Scope Register{% endblock %} +{% block page_title %}Application Scope Register{% endblock %} + +{% block content %} +
+ {% csrf_token %} +
+ {{ form|crispy }} +
+
+
+
+ انصراف + +
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/templates/gooyal_oauth2/application_scope_detail.html b/templates/gooyal_oauth2/application_scope_detail.html new file mode 100644 index 0000000..90d5b42 --- /dev/null +++ b/templates/gooyal_oauth2/application_scope_detail.html @@ -0,0 +1,33 @@ +{% extends "base.html" %} +{% load static %} +{% load crispy_forms_tags %} +{% load jalali_tags %} + +{% block title %}Application Scope Detail: {{ object.name }}{% endblock %} +{% block page_title %}Application Scope Detail: {{ object.name }}{% endblock %} + +{% block page_action %} + +{% endblock %} + + +{% block content %} +

application: {{ object.name }}!

+

client id: {{ object.client_id }}!

+

allowed_scopes:

+ {% for scope in object.allowed_scopes %} +
{{ scope }}
+ {% endfor %} +

own_scopes:

+ {% for scope in object.scopes.all %} +
{{ scope }}
+ {% endfor %} + + +{% endblock %} diff --git a/templates/gooyal_oauth2/application_scope_list.html b/templates/gooyal_oauth2/application_scope_list.html new file mode 100644 index 0000000..c97f3fd --- /dev/null +++ b/templates/gooyal_oauth2/application_scope_list.html @@ -0,0 +1,61 @@ +{% extends "base.html" %} +{% load static %} +{% load jalali_tags %} +{% load crispy_forms_tags %} +{% load tags %} + + +{% block title %}Application Scope List: {{ application }}{% endblock %} +{% block page_title %}Application Scope List: {{ application }}{% endblock %} +{% block page_action %} + {% include "include/filter_action.html" %} + + +{% endblock %} + + +{% block content %} + + + +{# #} + + + + {% for obj in object_list %} + + +{# #} + + + + {% endfor %} +
name{% if request.GET.ordering and 'name' in request.GET.ordering %}{% endif %}client id{% if request.GET.ordering and 'client_id' in request.GET.ordering %}{% endif %}descriptionactions
{{ obj.name }}{{ obj.client_id }}{{ obj.description }} +
+
+ +{# #} +
+
+
+ {% include 'include/paginator.html' %} + +{% endblock %} \ No newline at end of file diff --git a/templates/gooyal_oauth2/application_scope_update.html b/templates/gooyal_oauth2/application_scope_update.html new file mode 100644 index 0000000..f91b4bc --- /dev/null +++ b/templates/gooyal_oauth2/application_scope_update.html @@ -0,0 +1,24 @@ +{% extends "base.html" %} +{% load static %} +{% load crispy_forms_tags %} +{% load jalali_tags %} + +{% block title %}Application Update: {{ object.name }}{% endblock %} +{% block page_title %}Application Update: {{ object.name }}{% endblock %} + +{% block content %} +
+ {% csrf_token %} +
+ {{ form|crispy }} +
+
+
+
+ انصراف + +
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/templates/gooyal_oauth2/application_update.html b/templates/gooyal_oauth2/application_update.html index 838e3b6..e3b78b6 100644 --- a/templates/gooyal_oauth2/application_update.html +++ b/templates/gooyal_oauth2/application_update.html @@ -3,8 +3,8 @@ {% load crispy_forms_tags %} {% load jalali_tags %} -{% block title %}Application Update: {{ object }}{% endblock %} -{% block page_title %}Application Update: {{ object }}{% endblock %} +{% block title %}Application Update: {{ object.name }}{% endblock %} +{% block page_title %}Application Update: {{ object.name }}{% endblock %} {% block content %}