Skip to content
Snippets Groups Projects
Commit f8df5843 authored by David Schmitz's avatar David Schmitz
Browse files

feature/admin_user_delete_with_owned_rule_reassigning: allow admin deletion of...

feature/admin_user_delete_with_owned_rule_reassigning: allow admin deletion of users which are assigned as applier to some rules by re-assigning the rules to another remaining user of the same peer the user to be deleted pertains (only if the user is assigned to exactly 1 peer)
parent 3d217470
No related branches found
No related tags found
No related merge requests found
......@@ -21,7 +21,16 @@ from django.db import models
from django.conf import settings
from django.contrib.auth.models import AbstractBaseUser, User, BaseUserManager
from peers.models import Peer
from flowspec.models import Route
# TODO: dependency issue: move logging_utils to general package
import flowspec.logging_utils
logger = flowspec.logging_utils.logger_init_default(__name__, "accounts_model.log", False)
#
#
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
......@@ -46,8 +55,54 @@ class UserProfile(models.Model):
return False
return networks
# deleting of rules by this account is allowed
def is_delete_allowed(self):
user_is_admin = self.user.is_superuser
username = self.username
return (user_is_admin and settings.ALLOW_DELETE_FULL_FOR_ADMIN) or settings.ALLOW_DELETE_FULL_FOR_USER_ALL or (username in settings.ALLOW_DELETE_FULL_FOR_USER_LIST)
#
from django.dispatch import receiver
from django.db.models.signals import pre_delete
#@receiver(pre_delete, sender=UserProfile)
@receiver(pre_delete, sender=User)
def user_pre_delete_handler(sender, instance, **kwargs):
logger.info("user_pre_delete_handler(): pre_delete instance="+str(instance))
user_owned_rules_adopt_to_related_user(instance)
def user_owned_rules_adopt_to_related_user(user):
routes_owned = Route.objects.filter(applier=user)
logger.info("user_owned_rules_adopt_to_related_user(): => routes_owned="+str(routes_owned))
users_peers = user.userprofile.peers.all()
users_peers1 = None
logger.info("user_owned_rules_adopt_to_related_user(): => users_peers="+str(users_peers))
if len(users_peers)==1:
users_peers1 = users_peers[0]
logger.info("user_owned_rules_adopt_to_related_user(): => users_peers[0]="+str(users_peers1))
#peers1_userprofiles = users_peers[0].user_profile
#logger.info("user_owned_rules_adopt_to_related_user(): => peers1_userprofiles="+str(peers1_userprofiles))
users_related = User.objects.filter(userprofile__peers__in=users_peers)
logger.info("user_owned_rules_adopt_to_related_user(): => users_related="+str(users_related))
user_related1 = None
for user2 in users_related:
if user2 != user:
user_related1=user2
break
logger.info("user_owned_rules_adopt_to_related_user(): => user_related1="+str(user_related1))
if user_related1!=None:
if len(routes_owned)>0:
logger.info("user_owned_rules_adopt_to_related_user(): len="+str(len(routes_owned)))
for route in routes_owned:
logger.info("user_owned_rules_adopt_to_related_user(): owned route="+str(route))
route.applier = user_related1
logger.info("user_owned_rules_adopt_to_related_user(): reassigning owned route="+str(route)+" by user to be deleted ("+str(user)+") to new owner "+str(user_related1))
route.save()
return (routes_owned, user_related1, users_peers1)
......@@ -27,6 +27,14 @@ from django.contrib.auth.admin import UserAdmin
from peers.models import *
from longerusername.forms import UserCreationForm, UserChangeForm
from django.contrib import messages
from accounts.models import user_owned_rules_adopt_to_related_user
# TODO: dependency issue: move logging_utils to general package
import flowspec.logging_utils
logger = flowspec.logging_utils.logger_init_default(__name__, "flowspec_admin.log", False)
#
class RouteAdmin(admin.ModelAdmin):
form = RouteForm
......@@ -83,6 +91,21 @@ class UserProfileAdmin(UserAdmin):
queryset = queryset.update(is_active=True)
activate.short_description = "Activate Selected Users"
def delete_model(self, request, client):
if False:
messages.set_level(request, messages.ERROR)
messages.error(request, 'Blocking deletion')
else:
(adopted_rules, adoting_user, users_peer1) = user_owned_rules_adopt_to_related_user(client) # before actually calling the super.delete_model clean-up owned rules in order to get info about the cleanup which can be used for extra message to the admin UI
logger.info("delete_model() => adoting_user="+str(adoting_user))
logger.info("delete_model() => adopted_rules="+str(adopted_rules))
if len(adopted_rules)>0:
messages.set_level(request, messages.INFO)
messages.error(request, 'additional info: the rules '+str(adopted_rules)+' were re-assigned to remaining user '+str(adoting_user)+' of peer '+str(users_peer1))
super().delete_model(request, client)
def get_userprofile_peers(self, instance):
# instance is User instance
peers = instance.userprofile.peers.all()
......
......@@ -45,8 +45,13 @@ def get_matching_related_peer_for_rule_destination(ivaltrees_per_version, route)
peer_name_tmp = None
peer_name_tmp_not_applier_related = None
try:
if route.applier!=None:
route_applier__peers_related = set(route.applier.userprofile.peers.select_related())
applier = route.applier
except:
applier = None
try:
if applier!=None:
route_applier__peers_related = set(applier.userprofile.peers.select_related())
else:
route_applier__peers_related = None
......
......@@ -157,7 +157,8 @@ class ThenAction(models.Model):
class Route(models.Model):
name = models.SlugField(max_length=128, verbose_name=_("Name"))
applier = models.ForeignKey(User, blank=True, null=True, on_delete=models.CASCADE)
#applier = models.ForeignKey(User, blank=True, null=True, on_delete=models.CASCADE)
applier = models.ForeignKey(User, blank=True, null=True, on_delete=models.DO_NOTHING)
source = models.CharField(max_length=45+4, help_text=_("Network address. Use address/CIDR notation"), verbose_name=_("Source Address"))
sourceport = models.TextField(blank=True, null=True, verbose_name=_("Source Port"))
destination = models.CharField(max_length=45+4, help_text=_("Network address. Use address/CIDR notation"), verbose_name=_("Destination Address"))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment