From aaf196b4770ced3a6e59e5335b1896ef297c971e Mon Sep 17 00:00:00 2001 From: Adarnof Date: Sun, 26 Mar 2017 17:45:32 -0400 Subject: [PATCH] Apply username sanitizing upon creation Prevent purging of character ownerships when logging in Listen to state permission changes for service access verification --- authentication/backends.py | 2 ++ authentication/signals.py | 7 +++++-- services/signals.py | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/authentication/backends.py b/authentication/backends.py index 3812f532..014d5512 100644 --- a/authentication/backends.py +++ b/authentication/backends.py @@ -58,6 +58,8 @@ class StateBackend(ModelBackend): @staticmethod def iterate_username(name): + name = str.replace(name, "'", "") + name = str.replace(name, ' ', '_') if User.objects.filter(username__startswith=name).exists(): u = User.objects.filter(username__startswith=name) num = len(u) diff --git a/authentication/signals.py b/authentication/signals.py index 8f652d0e..b20b74f6 100644 --- a/authentication/signals.py +++ b/authentication/signals.py @@ -71,9 +71,12 @@ def create_required_models(sender, instance, created, *args, **kwargs): @receiver(post_save, sender=Token) def record_character_ownership(sender, instance, created, *args, **kwargs): if created: + if instance.user: + query = Q(owner_hash=instance.character_owner_hash) & Q(user=instance.user) + else: + query = Q(owner_hash=instance.character_owner_hash) # purge ownership records if the hash or auth user account has changed - CharacterOwnership.objects.filter(character__character_id=instance.character_id).exclude(Q( - owner_hash=instance.character_owner_hash) & Q(user=instance.user)).delete() + CharacterOwnership.objects.filter(character__character_id=instance.character_id).exclude(query).delete() # create character if needed if EveCharacter.objects.filter(character_id=instance.character_id).exists() is False: EveManager.create_character(instance.character_id) diff --git a/services/signals.py b/services/signals.py index 2c76d466..7612a5d6 100644 --- a/services/signals.py +++ b/services/signals.py @@ -11,6 +11,7 @@ from django.dispatch import receiver from services.hooks import ServicesHook from services.tasks import disable_user +from authentication.models import State logger = logging.getLogger(__name__) @@ -88,6 +89,39 @@ def m2m_changed_group_permissions(sender, instance, action, pk_set, *args, **kwa logger.debug("Permission change for group {} was not service permission, ignoring".format(instance)) +@receiver(m2m_changed, sender=State.permissions.through) +def m2m_changed_state_permissions(sender, instance, action, pk_set, *args, **kwargs): + logger.debug("Received m2m_changed from state %s permissions with action %s" % (instance, action)) + if instance.pk and (action == "post_remove" or action == "post_clear"): + logger.debug("Checking if service permission changed for state {}".format(instance)) + # As validating an entire groups service could lead to many thousands of permission checks + # first we check that one of the permissions changed is, in fact, a service permission. + perms = Permission.objects.filter(pk__in=pk_set) + got_change = False + service_perms = [svc.access_perm for svc in ServicesHook.get_services()] + for perm in perms: + natural_key = perm.natural_key() + path_perm = "{}.{}".format(natural_key[1], natural_key[0]) + if path_perm not in service_perms: + # Not a service permission, keep searching + continue + for svc in ServicesHook.get_services(): + if svc.access_perm == path_perm: + logger.debug("Permissions changed for state {} on " + "service {}, re-validating services for state users".format(instance, svc)) + + def validate_all_state_users_for_service(): + logger.debug("Performing validation for service {}".format(svc)) + for profile in instance.userprofile_set.all(): + svc.validate_user(profile.user) + + transaction.on_commit(validate_all_state_users_for_service) + got_change = True + break # Found service, break out of services iteration and go back to permission iteration + if not got_change: + logger.debug("Permission change for state {} was not service permission, ignoring".format(instance)) + + @receiver(pre_delete, sender=User) def pre_delete_user(sender, instance, *args, **kwargs): logger.debug("Received pre_delete from %s" % instance)