예제 #1
0
def principals_to_groups_cache_handler(sender=None,
                                       instance=None,
                                       action=None,
                                       reverse=None,
                                       model=None,
                                       pk_set=None,
                                       using=None,
                                       **kwargs):
    """Signal handler to purge caches when Group membership changes."""
    cache = AccessCache(connections[using].schema_name)
    if action in ("post_add", "pre_remove"):
        logger.info(
            "Handling signal for %s group membership change - invalidating policy cache",
            instance)
        if isinstance(instance, Group):
            # One or more principals was added to/removed from the group
            for principal in Principal.objects.filter(pk__in=pk_set):
                cache.delete_policy(principal.uuid)
        elif isinstance(instance, Principal):
            # One or more groups was added to/removed from the principal
            cache.delete_policy(instance.uuid)
    elif action == "pre_clear":
        logger.info(
            "Handling signal for %s group membership clearing - invalidating policy cache",
            instance)
        if isinstance(instance, Group):
            # All principals are being removed from this group
            for principal in instance.principals.all():
                cache.delete_policy(principal.uuid)
        elif isinstance(instance, Principal):
            # All groups are being removed from this principal
            cache.delete_policy(instance.uuid)
예제 #2
0
def on_complete(completed_log_message, tenant, future):
    """Explicitly close the connection for the thread."""
    logger.info("Purging policy cache.")
    cache = AccessCache(tenant.schema_name)
    cache.delete_all_policies_for_tenant()
    connections.close_all()
    logger.info(completed_log_message)
예제 #3
0
def policy_to_roles_cache_handler(sender=None, instance=None, action=None,  # noqa: C901
                                  reverse=None, model=None, pk_set=None, using=None,
                                  **kwargs):
    """Signal handler for Principal cache expiry on Policy/Role m2m change."""
    cache = AccessCache(connections[using].schema_name)
    if action in ('post_add', 'pre_remove'):
        logger.info('Handling signal for %s roles change - invalidating policy cache', instance)
        if isinstance(instance, Policy):
            # One or more roles was added to/removed from the policy
            if instance.group:
                for principal in instance.group.principals.all():
                    cache.delete_policy(principal.uuid)
        elif isinstance(instance, Role):
            # One or more policies was added to/removed from the role
            for policy in Policy.objects.filter(pk__in=pk_set):
                if policy.group:
                    for principal in policy.group.principals.all():
                        cache.delete_policy(principal.uuid)
    elif action == 'pre_clear':
        logger.info('Handling signal for %s policy-roles clearing - invalidating policy cache', instance)
        if isinstance(instance, Policy):
            # All roles are being removed from this policy
            if instance.group:
                for principal in instance.group.principals.all():
                    cache.delete_policy(principal.uuid)
        elif isinstance(instance, Role):
            # All policies are being removed from this role
            for principal in Principal.objects.filter(group__policies__roles__pk=instance.pk):
                cache.delete_policy(principal.uuid)
예제 #4
0
def policy_changed_cache_handler(sender=None, instance=None, using=None, **kwargs):
    """Signal handler for Principal cache expiry on Policy deletion."""
    logger.info('Handling signal for deleted policy %s - invalidating associated user cache keys', instance)
    cache = AccessCache(connections[using].schema_name)
    if instance.group:
        for principal in instance.group.principals.all():
            cache.delete_policy(principal.uuid)
예제 #5
0
def role_related_obj_change_cache_handler(sender=None, instance=None, using=None, **kwargs):
    """Signal handler for invalidating Principal cache on Role object change."""
    logger.info(
        "Handling signal for added/removed/changed role-related object %s - "
        "invalidating associated user cache keys",
        instance,
    )
    cache = AccessCache(connections[using].schema_name)
    if instance.role:
        for principal in Principal.objects.filter(group__policies__roles__pk=instance.role.pk):
            cache.delete_policy(principal.uuid)
예제 #6
0
def group_deleted_cache_handler(sender=None,
                                instance=None,
                                using=None,
                                **kwargs):
    """Signal handler to purge principal caches when a Group is deleted."""
    logger.info(
        "Handling signal for deleted group %s - invalidating policy cache for users in group",
        instance)
    cache = AccessCache(connections[using].schema_name)
    for principal in instance.principals.all():
        cache.delete_policy(principal.uuid)
예제 #7
0
    def get(self, request):
        """Provide access data for principal."""
        app = request.query_params.get(APPLICATION_KEY)
        principal = get_principal_from_request(request)
        cache = AccessCache(request.tenant.schema_name)
        access_policy = cache.get_policy(principal.uuid, app)
        if access_policy is None:
            queryset = self.get_queryset()
            access_policy = self.serializer_class(queryset, many=True).data
            cache.save_policy(principal.uuid, app, access_policy)
        page = self.paginate_queryset(access_policy)

        if page is not None:
            return self.get_paginated_response(access_policy)
        return Response({"data": access_policy})
예제 #8
0
    def get(self, request):
        """Provide access data for principal."""
        validate_limit_and_offset(request.query_params)
        sub_key = self.generate_sub_key(request)
        principal = get_principal_from_request(request)
        cache = AccessCache(request.tenant.schema_name)
        access_policy = cache.get_policy(principal.uuid, sub_key)
        if access_policy is None:
            queryset = self.get_queryset()
            page = self.paginate_queryset(queryset)
            access_policy = self.serializer_class(page, many=True).data
            cache.save_policy(principal.uuid, sub_key, access_policy)

        if self.paginate_queryset(access_policy) is not None:
            return self.get_paginated_response(access_policy)
        return Response({"data": access_policy})
예제 #9
0
    def get(self, request):
        """Provide access data for principal."""
        # Parameter extraction
        sub_key, ordering = self.validate_and_get_param(request.query_params)

        principal = get_principal_from_request(request)
        cache = AccessCache(request.tenant.schema_name)
        access_policy = cache.get_policy(principal.uuid, sub_key)
        if access_policy is None:
            queryset = self.get_queryset(ordering)
            access_policy = self.serializer_class(queryset, many=True).data
            cache.save_policy(principal.uuid, sub_key, access_policy)

        page = self.paginate_queryset(access_policy)
        if page is not None:
            return self.get_paginated_response(page)
        return Response({"data": access_policy})
예제 #10
0
def policy_changed_cache_handler(sender=None,
                                 instance=None,
                                 using=None,
                                 **kwargs):
    """Signal handler for Principal cache expiry on Policy deletion."""
    logger.info(
        "Handling signal for deleted policy %s - invalidating associated user cache keys",
        instance)
    cache = AccessCache(connections[using].schema_name)
    if instance.group:
        principals = instance.group.principals.all()
        if instance.group.platform_default:
            cache.delete_all_policies_for_tenant()
        for principal in principals:
            cache.delete_policy(principal.uuid)