From 3ab341a4733bce6f64841774f8d4961a6104d6a9 Mon Sep 17 00:00:00 2001 From: Santiago Lamora Date: Wed, 29 Nov 2023 10:38:18 +0100 Subject: [PATCH] Add missing import and properly raise PermissionDenied --- orchestra/admin/actions.py | 19 +++++++------- orchestra/admin/options.py | 52 ++++++++++++++++++-------------------- 2 files changed, 35 insertions(+), 36 deletions(-) diff --git a/orchestra/admin/actions.py b/orchestra/admin/actions.py index 9bec0488..dadc93df 100644 --- a/orchestra/admin/actions.py +++ b/orchestra/admin/actions.py @@ -1,12 +1,13 @@ from functools import partial from django.contrib import admin +from django.core.exceptions import PermissionDenied from django.core.mail import send_mass_mail from django.shortcuts import render -from django.utils.translation import ngettext, gettext_lazy as _ +from django.utils.translation import gettext_lazy as _ +from django.utils.translation import ngettext from .. import settings - from .decorators import action_with_confirmation from .forms import SendEmailForm @@ -18,7 +19,7 @@ class SendEmail(object): template = 'admin/orchestra/generic_confirmation.html' default_from = settings.ORCHESTRA_DEFAULT_SUPPORT_FROM_EMAIL __name__ = 'semd_email' - + def __call__(self, modeladmin, request, queryset): """ make this monster behave like a function """ self.modeladmin = modeladmin @@ -34,10 +35,10 @@ class SendEmail(object): 'action_checkbox_name': admin.helpers.ACTION_CHECKBOX_NAME, } return self.write_email(request) - + def write_email(self, request): if not request.user.is_superuser: - raise PermissionDenied + raise PermissionDenied() initial={ 'email_from': self.default_from, 'to': ' '.join(self.get_email_addresses()) @@ -51,7 +52,7 @@ class SendEmail(object): 'extra_to': form.cleaned_data['extra_to'], 'subject': form.cleaned_data['subject'], 'message': form.cleaned_data['message'], - + } return self.confirm_email(request, **options) self.context.update({ @@ -62,10 +63,10 @@ class SendEmail(object): }) # Display confirmation page return render(request, self.template, self.context) - + def get_email_addresses(self): return self.queryset.values_list('email', flat=True) - + def confirm_email(self, request, **options): email_from = options['email_from'] extra_to = options['extra_to'] @@ -88,7 +89,7 @@ class SendEmail(object): ) self.modeladmin.message_user(request, msg) return None - + form = self.form(initial={ 'email_from': email_from, 'extra_to': ', '.join(extra_to), diff --git a/orchestra/admin/options.py b/orchestra/admin/options.py index 3849bc20..079565a2 100644 --- a/orchestra/admin/options.py +++ b/orchestra/admin/options.py @@ -1,16 +1,16 @@ from urllib import parse from django import forms -from django.urls import re_path as url from django.contrib import admin, messages from django.contrib.admin.options import IS_POPUP_VAR from django.contrib.admin.utils import unquote from django.contrib.auth import update_session_auth_hash from django.core.exceptions import PermissionDenied -from django.http import HttpResponseRedirect, Http404, HttpResponse from django.forms.models import BaseInlineFormSet +from django.http import Http404, HttpResponse, HttpResponseRedirect from django.shortcuts import get_object_or_404 from django.template.response import TemplateResponse +from django.urls import re_path as url from django.utils.decorators import method_decorator from django.utils.encoding import force_str from django.utils.html import escape @@ -19,14 +19,12 @@ from django.views.decorators.debug import sensitive_post_parameters from orchestra.models.utils import has_db_field -from ..utils.python import random_ascii, pairwise - +from ..utils.python import pairwise, random_ascii from .forms import AdminPasswordChangeForm #, AdminRawPasswordChangeForm #from django.contrib.auth.forms import AdminPasswordChangeForm from .utils import action_to_view - sensitive_post_parameters_m = method_decorator(sensitive_post_parameters()) @@ -37,7 +35,7 @@ class ChangeListDefaultFilter(object): default_changelist_filters = (('my_nodes', 'True'),) """ default_changelist_filters = () - + def changelist_view(self, request, extra_context=None): # defaults = [] # for key, value in self.default_changelist_filters: @@ -79,7 +77,7 @@ class EnhaceSearchMixin(object): if 'password' in lookup: return False return True - + def get_search_results(self, request, queryset, search_term): """ allows to specify field : """ search_fields = self.get_search_fields(request) @@ -109,7 +107,7 @@ class ChangeViewActionsMixin(object): """ Makes actions visible on the admin change view page. """ change_view_actions = () change_form_template = 'orchestra/admin/change_form.html' - + def get_urls(self): """Returns the additional urls for the change view links""" urls = super(ChangeViewActionsMixin, self).get_urls() @@ -124,7 +122,7 @@ class ChangeViewActionsMixin(object): ) ) return new_urls + urls - + def get_change_view_actions(self, obj=None): """ allow customization on modelamdin """ views = [] @@ -145,7 +143,7 @@ class ChangeViewActionsMixin(object): view.hidden = getattr(action, 'hidden', False) views.append(view) return views - + def change_view(self, request, object_id, **kwargs): if kwargs.get('extra_context', None) is None: kwargs['extra_context'] = {} @@ -165,21 +163,21 @@ class ChangeAddFieldsMixin(object): change_readonly_fields = () change_form = None add_inlines = None - + def get_prepopulated_fields(self, request, obj=None): if not obj: return super(ChangeAddFieldsMixin, self).get_prepopulated_fields(request, obj) return {} - + def get_change_readonly_fields(self, request, obj=None): return self.change_readonly_fields - + def get_readonly_fields(self, request, obj=None): fields = super(ChangeAddFieldsMixin, self).get_readonly_fields(request, obj) if obj: return fields + self.get_change_readonly_fields(request, obj) return fields - + def get_fieldsets(self, request, obj=None): if not obj: if self.add_fieldsets: @@ -187,7 +185,7 @@ class ChangeAddFieldsMixin(object): elif self.add_fields: return [(None, {'fields': self.add_fields})] return super(ChangeAddFieldsMixin, self).get_fieldsets(request, obj) - + def get_inline_instances(self, request, obj=None): """ add_inlines and inline.parent_object """ if obj: @@ -198,7 +196,7 @@ class ChangeAddFieldsMixin(object): for inline in inlines: inline.parent_object = obj return inlines - + def get_form(self, request, obj=None, **kwargs): """ Use special form during user creation """ defaults = {} @@ -218,13 +216,13 @@ class ExtendedModelAdmin(ChangeViewActionsMixin, EnhaceSearchMixin, admin.ModelAdmin): list_prefetch_related = None - + def get_queryset(self, request): qs = super(ExtendedModelAdmin, self).get_queryset(request) if self.list_prefetch_related: qs = qs.prefetch_related(*self.list_prefetch_related) return qs - + def get_object(self, request, object_id, from_field=None): obj = super(ExtendedModelAdmin, self).get_object(request, object_id, from_field) if obj is None: @@ -237,7 +235,7 @@ class ExtendedModelAdmin(ChangeViewActionsMixin, class ChangePasswordAdminMixin(object): change_password_form = AdminPasswordChangeForm change_user_password_template = 'admin/orchestra/change_password.html' - + def get_urls(self): opts = self.model._meta info = opts.app_label, opts.model_name @@ -249,14 +247,14 @@ class ChangePasswordAdminMixin(object): self.admin_site.admin_view(self.show_hash), name='%s_%s_show_hash' % info) ] + super().get_urls() - + def get_change_password_username(self, obj): return str(obj) - + @sensitive_post_parameters_m def change_password(self, request, id, form_url=''): if not self.has_change_permission(request): - raise PermissionDenied + raise PermissionDenied() # TODO use this insetad of self.get_object(), in other places obj = get_object_or_404(self.get_queryset(request), pk=id) raw = request.GET.get('raw', '0') == '1' @@ -281,7 +279,7 @@ class ChangePasswordAdminMixin(object): for rel in account.get_related_passwords(db_field=raw): if not isinstance(obj, type(rel)): related.append(rel) - + if request.method == 'POST': form = self.change_password_form(obj, request.POST, related=related, raw=raw) if form.is_valid(): @@ -293,7 +291,7 @@ class ChangePasswordAdminMixin(object): return HttpResponseRedirect('..') else: form = self.change_password_form(obj, related=related, raw=raw) - + fieldsets = [ (obj._meta.verbose_name.capitalize(), { 'classes': ('wide',), @@ -305,7 +303,7 @@ class ChangePasswordAdminMixin(object): 'classes': ('wide',), 'fields': ('password_%i' % ix,) if raw else ('password1_%i' % ix, 'password2_%i' % ix) })) - + obj_username = self.get_change_password_username(obj) adminForm = admin.helpers.AdminForm(form, fieldsets, {}) context = { @@ -331,9 +329,9 @@ class ChangePasswordAdminMixin(object): } context.update(admin.site.each_context(request)) return TemplateResponse(request, self.change_user_password_template, context) - + def show_hash(self, request, id): if not request.user.is_superuser: - raise PermissionDenied + raise PermissionDenied() obj = get_object_or_404(self.get_queryset(request), pk=id) return HttpResponse(obj.password)