question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Automatic Logging doesn't log the Actor

See original GitHub issue

I have installed the plugin and on an Django Rest Framework instance. All the logging is working as expected, except the Logging of the Actor. I added the Middleware as Described in the Docs but its still not logging any Actor.

Here is my configuration:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'corsheaders',
    'oauth2_provider',
    'rest_framework',
    'auditlog',
    'stammdaten.apps.StammdatenConfig',
    'main.apps.MainConfig',
    'rest_framework_swagger',
]

OAUTH2_PROVIDER = {
    # this is the list of available scopes
    'SCOPES': {'read': 'Read scope', 'write': 'Write scope', 'groups': 'Access to your groups'},
    'ACCESS_TOKEN_EXPIRE_SECONDS': 43200
}

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'oauth2_provider.ext.rest_framework.OAuth2Authentication',
    ),
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
    'PAGE_SIZE': 10
}

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'oauth2_provider.middleware.OAuth2TokenMiddleware',
    'auditlog.middleware.AuditlogMiddleware'
]

What am I missing here? Is it a problem with the OAuth Toolkit or did I missconfig anything?

Issue Analytics

  • State:open
  • Created 6 years ago
  • Comments:43 (10 by maintainers)

github_iconTop GitHub Comments

10reactions
malderetecommented, Jan 9, 2020

Hello everyone!

I had the same issue when trying to integrate django-auditlog with Django Rest Framework (DRF).

I have been digging into the source code of both projects to understand the reason the actor is not being set and found a reason.

django-auditlog expects the user being logged at Django’s middleware layer as usual but DRF, for design decision, does not perform the authentication at middleware level instead it performs the authentication at View level by using tte configured mechanisms. It means just before executing the code which processes the request and generates a response. Here is the difference with Django itself! That is the reason why is_autenticated is always False at the middleware layer, as result the handler to set the actor on pre_save signal is not being connected.

I’ve created a glue code which works as integration between both projects. The approach I took is to use mixins as many components of DRF does . This integrations is not coupled with any AUTH mechanism which is good, it leaves that behavior to DRF, that is a big difference with the approach taken by @ivan-fedorov-probegin (Im not telling it is bad!) . I’ve been using this integration in production without issues at all 😃. I would like to know if you are open to merge some DRF integrations… In that case I’ll be happy to propose a pull request. (cc @jjkester )

Integration mixin

# mixins.py
from django.db.models.signals import pre_save
from django.utils.functional import curry

from auditlog.compat import is_authenticated
from auditlog.middleware import threadlocal, AuditlogMiddleware
from auditlog.models import LogEntry


class DRFDjangoAuditModelMixin:
    """
    Mixin to integrate django-auditlog with Django Rest Framework.

    This is needed because DRF does not perform the authentication at middleware layer
    instead it performs the authentication at View layer.

    This mixin adds behavior to connect/disconnect the signals needed by django-auditlog to auto
    log changes on models.
    It assumes that AuditlogMiddleware is activated in settings.MIDDLEWARE_CLASSES
    """

    def should_connect_signals(self, request):
        """Determines if the signals should be connected for the incoming request."""
        # By default only makes sense to audit when the user is authenticated
        return is_authenticated(request.user)

    def initial(self, request, *args, **kwargs):
        """Overwritten to use django-auditlog if needed."""
        super().initial(request, *args, **kwargs)

        if self.should_connect_signals(request):
            set_actor = curry(AuditlogMiddleware.set_actor, user=request.user,
                              signal_duid=threadlocal.auditlog['signal_duid'])
            pre_save.connect(set_actor, sender=LogEntry,
                             dispatch_uid=threadlocal.auditlog['signal_duid'], weak=False)

    def finalize_response(self, request, response, *args, **kwargs):
        """Overwritten to cleanup django-auditlog if needed."""
        response = super().finalize_response(request, response, *args, **kwargs)

        if hasattr(threadlocal, 'auditlog'):
            pre_save.disconnect(sender=LogEntry, dispatch_uid=threadlocal.auditlog['signal_duid'])
        return response

Minimal usage example

# views.py
from rest_framework import  viewsets

from some_app.mixins import DRFDjangoAuditModelMixin
from some_app import models, serializers


class SomeModelViewSet(DRFDjangoAuditModelMixin, viewsets.ReadOnlyModelViewSet):
    queryset = models.MyModel.objects.all()
    serializer_class = serializers.MyModelSerializer

I would like to hear feedback from the projects! Anyways, you could take this code/ideas for you projects.

Thanks in advance!

6reactions
steven-garcia18commented, Nov 23, 2020

for rest_framework_simplejwt

from django.contrib.auth.middleware import get_user
from django.utils.deprecation import MiddlewareMixin
from django.utils.functional import SimpleLazyObject

from rest_framework_simplejwt.authentication import JWTAuthentication


class JWTAuthenticationMiddleware(MiddlewareMixin):

    def process_request(self, request):
        request.user = SimpleLazyObject(
            lambda: self.__class__.get_jwt_user(request))

    @staticmethod
    def get_jwt_user(request):
        user = get_user(request)
        if user.is_authenticated:
            return user
        jwt_authentication = JWTAuthentication()
        if jwt_authentication.get_header(request):
            user, jwt = jwt_authentication.authenticate(request)
        return user
Read more comments on GitHub >

github_iconTop Results From Across the Web

Automatic Logging doesn't log the Actor · Issue #115 - GitHub
I have installed the plugin and on an Django Rest Framework instance. All the logging is working as expected, except the Logging of...
Read more >
scala - akka.actor.ActorLogging does not log the stack trace of ...
I am using Logback + SLF4J to do logging for those actors with trait of akka.actor.
Read more >
Manage automatic logging | New Relic Documentation
How to manage automatic logging when necessary for agents using APM logs in context.
Read more >
Logging - Documentation - Akka
The Logger via the ActorContext will automatically have a name that corresponds to the Behavior Behavior of the actor when the log is...
Read more >
Actor Logging with Akka .NET - Gigi Labs
We can adjust our actor's code to use a logger instead of writing directly to the console. The actor doesn't care what kind...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found