jazzband / django-auditlog

A Django app that keeps a log of changes made to an object.
MIT License
1.09k stars 404 forks source link

Automatic Logging doesn't log the Actor #115

Open Aalphones opened 7 years ago

Aalphones commented 7 years ago

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?

umangbisht commented 10 months ago

In my case when i am using your code my user variable is printing AnonymousUser which again lead to the same problem showing system value of actor field @magdumsuraj07

esorribas commented 9 months ago

The problem is the INSTALLED_APPS's order, you just need to put auditlog app above djangorestframework app on settings.py file and @mcanu middleware, that's it.

Hope this helps!

boardshepherd commented 7 months ago

Putting 'auditlog.middleware.AuditlogMiddleware', as the last item in MIDDLEWARE in settings.py solved the issue for me.

ashuvik03 commented 5 months ago

In my case I solved this by modifying the AuditlogMiddleware and making the user a lazy object.

from auditlog.context import set_actor
from auditlog.middleware import AuditlogMiddleware as _AuditlogMiddleware
from django.utils.functional import SimpleLazyObject

class AuditlogMiddleware(_AuditlogMiddleware):
    def __call__(self, request):
        remote_addr = self._get_remote_addr(request)

        user = SimpleLazyObject(lambda: getattr(request, "user", None))

        context = set_actor(actor=user, remote_addr=remote_addr)

        with context:
            return self.get_response(request)

And then use this custom middleware in settings.MIDDLEWARE.

@mcanu This is working for me. Thank you for solution.

qurm commented 3 months ago

Works well for me too, with auditlog 2.5.0 and Django 5.02.
To clarify how to apply this (if not familiar with middleware) the above code is in a file /myapp/middleware.py and settings.py has this:

MIDDLEWARE = [
    ...
    'myapp.middleware.AuditlogMiddleware', # custom patch
]

I am not clear if this is fixed in the upcoming release 3, per comment here https://github.com/jazzband/django-auditlog/pull/613 @hramezani ?

hramezani commented 3 months ago

Works well for me too, with auditlog 2.5.0 and Django 5.02. To clarify how to apply this (if not familiar with middleware) the above code is in a file /myapp/middleware.py and settings.py has this:

MIDDLEWARE = [
    ...
    'myapp.middleware.AuditlogMiddleware', # custom patch
]

I am not clear if this is fixed in the upcoming release 3, per comment here #613 @hramezani ?

I need someone to check it on V3 beta and if it isn't fixed there create a patch for fixing

jforsman commented 1 month ago

@hramezani Not working auditlog 3.0.0 and django 4.2.13. I will try with adding call to my custom middleware and let you if it works or not.

hramezani commented 1 month ago

@jforsman Yes, this is not working. I am still waiting for a PR that fixes the problem in django-auditlog. There are some workarounds here but we need a PR.

jforsman commented 1 month ago

I don't actually think that there should be anything done to auditlog as it is DRF design decision (faulty one in my opinion) to do the authentication at view level so it should be somehow fixed there.

I think I am gonna go with the custom DRF authentication classes.

jforsman commented 1 month ago

Well, don't think there will be any fixes to anywhere soon, this DRF bug https://github.com/encode/django-rest-framework/issues/760 (yes an old one but still valid) states in the last comment that you should write separate authentication middlewares. That was my approach in the end.

ChandraprakashGajwani commented 1 week ago

In my case I solved this by modifying the AuditlogMiddleware and making the user a lazy object.

from auditlog.context import set_actor
from auditlog.middleware import AuditlogMiddleware as _AuditlogMiddleware
from django.utils.functional import SimpleLazyObject

class AuditlogMiddleware(_AuditlogMiddleware):
    def __call__(self, request):
        remote_addr = self._get_remote_addr(request)

        user = SimpleLazyObject(lambda: getattr(request, "user", None))

        context = set_actor(actor=user, remote_addr=remote_addr)

        with context:
            return self.get_response(request)

And then use this custom middleware in settings.MIDDLEWARE.

IT worked for me also, Thank you so much @mcanu