Source code for geonode.people.admin

#########################################################################
#
# Copyright (C) 2016 OSGeo
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#########################################################################

from django.conf import settings
from django.conf.urls import url
from django.contrib import admin
from django.contrib import messages
from django.contrib.auth import get_user_model
from django.contrib.auth.forms import AdminPasswordChangeForm
from django.utils.translation import ugettext_lazy as _
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_protect
from django.db import transaction
from django.views.decorators.debug import sensitive_post_parameters
from django.contrib.admin.options import IS_POPUP_VAR
from django.shortcuts import get_object_or_404
from django.utils.html import escape
from django.template.response import TemplateResponse
from django.http import HttpResponseRedirect, Http404
from django.core.exceptions import PermissionDenied
from django.forms import modelform_factory
from geonode.base.admin import set_user_and_group_dataset_permission

from .models import Profile
from .forms import ProfileCreationForm, ProfileChangeForm


[docs] csrf_protect_m = method_decorator(csrf_protect)
[docs] sensitive_post_parameters_m = method_decorator(sensitive_post_parameters())
[docs] class ProfileAdmin(admin.ModelAdmin): modelform_factory(get_user_model(), fields="__all__")
[docs] add_form_template = "admin/auth/user/add_form.html"
[docs] change_user_password_template = None
[docs] fieldsets = ( (None, {"fields": ("username", "password")}), (_("Personal info"), {"fields": ("first_name", "last_name", "email")}), (_("Permissions"), {"fields": ("is_active", "is_staff", "is_superuser", "groups")}), (_("Important dates"), {"fields": ("last_login", "date_joined")}), ( _("Extended profile"), { "fields": ( "organization", "profile", "position", "voice", "fax", "delivery", "city", "area", "zipcode", "country", "keywords", ) }, ), )
[docs] add_fieldsets = ((None, {"classes": ("wide",), "fields": ("username", "password1", "password2")}),)
[docs] form = ProfileChangeForm
[docs] add_form = ProfileCreationForm
[docs] change_password_form = AdminPasswordChangeForm
[docs] list_display = ("id", "username", "organization", "email", "first_name", "last_name", "is_staff", "is_active")
[docs] list_filter = ("is_staff", "is_superuser", "is_active", "groups")
[docs] search_fields = ("username", "organization", "profile", "first_name", "last_name", "email")
# readonly_fields = ("groups", )
[docs] ordering = ("username",)
[docs] filter_horizontal = ( "groups", "user_permissions", )
[docs] actions = [set_user_and_group_dataset_permission]
[docs] def get_fieldsets(self, request, obj=None): if not obj: return self.add_fieldsets return super().get_fieldsets(request, obj)
[docs] def get_form(self, request, obj=None, **kwargs): """ Use special form during user creation """ defaults = {} if obj is None: defaults.update( { "form": self.add_form, "fields": admin.utils.flatten_fieldsets(self.add_fieldsets), } ) defaults.update(kwargs) return super().get_form(request, obj, **defaults)
[docs] def get_urls(self): return [ # '', url(r"^(\d+)/password/$", self.admin_site.admin_view(self.user_change_password)) ] + super().get_urls()
[docs] def lookup_allowed(self, lookup, value): # See #20078: we don't want to allow any lookups involving passwords. if lookup.startswith("password"): return False return super().lookup_allowed(lookup, value)
@sensitive_post_parameters_m @csrf_protect_m @transaction.atomic
[docs] def add_view(self, request, form_url="", extra_context=None): # It's an error for a user to have add permission but NOT change # permission for users. If we allowed such users to add users, they # could create superusers, which would mean they would essentially have # the permission to change users. To avoid the problem entirely, we # disallow users from adding users if they don't have change # permission. if not self.has_change_permission(request): if self.has_add_permission(request) and settings.DEBUG: # Raise Http404 in debug mode so that the user gets a helpful # error message. raise Http404( 'Your user does not have the "Change user" permission. In ' "order to add users, Django requires that your user " 'account have both the "Add user" and "Change user" ' "permissions set." ) raise PermissionDenied if extra_context is None: extra_context = {} username_field = self.model._meta.get_field(self.model.USERNAME_FIELD) defaults = { "auto_populated_fields": (), "username_help_text": username_field.help_text, } extra_context.update(defaults) return super().add_view(request, form_url, extra_context)
@sensitive_post_parameters_m
[docs] def user_change_password(self, request, id, form_url=""): if not self.has_change_permission(request): raise PermissionDenied user = get_object_or_404(self.get_queryset(request), pk=id) if request.method == "POST": form = self.change_password_form(user, request.POST) if form.is_valid(): form.save() change_message = self.construct_change_message(request, form, None) self.log_change(request, user, change_message) msg = _("Password changed successfully.") messages.success(request, msg) return HttpResponseRedirect("..") else: form = self.change_password_form(user) fieldsets = [(None, {"fields": list(form.base_fields)})] adminForm = admin.helpers.AdminForm(form, fieldsets, {}) context = { "title": _("Change password: %s") % escape(user.get_username()), "adminForm": adminForm, "form_url": form_url, "form": form, "is_popup": IS_POPUP_VAR in request.GET, "add": True, "change": False, "has_delete_permission": False, "has_change_permission": True, "has_absolute_url": False, "opts": self.model._meta, "original": user, "save_as": False, "show_save": True, } return TemplateResponse( request, self.change_user_password_template or "admin/auth/user/change_password.html", context ) # , using=self.admin_site.name)
[docs] def response_add(self, request, obj, post_url_continue=None): """ Determines the HttpResponse for the add_view stage. It mostly defers to its superclass implementation but is customized because the User model has a slightly different workflow. """ # We should allow further modification of the user just added i.e. the # 'Save' button should behave like the 'Save and continue editing' # button except in two scenarios: # * The user has pressed the 'Save and add another' button # * We are adding a user in a popup if "_addanother" not in request.POST and IS_POPUP_VAR not in request.POST: mutable = request.POST._mutable request.POST._mutable = True request.POST["_continue"] = 1 request.POST._mutable = mutable return super().response_add(request, obj, post_url_continue)
admin.site.register(Profile, ProfileAdmin)