Djangorestframework-simplejwt: Can't delete users if using token blacklist app

Created on 7 Jul 2020  路  29Comments  路  Source: jazzband/djangorestframework-simplejwt

I can't delete a user from the admin when using the blackilst app. I get the following error:

Deleting the selected account would result in deleting related objects, but your account doesn't have permission to delete the following types of objects:

-outstanding token

I found out this is due to the has_delete_permission in token_blacklist/admin.py being overwritten and set to false.

Is there a reason for this?
Thanks

bug

Most helpful comment

This is my highly questionable solution until now:
I have the following in my User ModelAdmin

    def BE_AWARE_NO_WARNING_clear_tokens_and_delete(self, request, queryset):
        users = queryset.values("id")
        OutstandingToken.objects.filter(user__id__in=users).delete()
        queryset.delete()

    actions = ["BE_AWARE_NO_WARNING_clear_tokens_and_delete"]

All 29 comments

@adriangzz It's become a huge annoyance for a lot of people. I'll look into the commit history and find out when this happened. If you don't mind also helping me search through the file's history, that'd be helpful.

Edit: nvm found it 3648e642ffed493918c40a450015ae098b77ed19

That way, I can file a regression report to perhaps remove it. At this point, I can't really give a solid answer myself.

Hm I can't remember if this is still the case for superusers and/or staff users. In any case, Dave's comment was that these were "Read-only behavior".

However, here you can see that, when a user is deleted, the on_delete method should be models.SET_NULL.

https://github.com/SimpleJWT/django-rest-framework-simplejwt/blob/master/rest_framework_simplejwt/token_blacklist/models.py#L6

I'll file a PR for you. It should come in next patch or minor release.

Awesome, thank you.

Any update on this? Just faced the same issue.

Any update? i got the same issue

@aasutossh @HarryNdegwa I need to ask David as to why this was not set to SET_NULL to begin with (even though there's an attribute that says null=True). I'm hesitant to continue with my PR in case I wasn't getting the point of this behavior.

Still seems to be an issue.

Still seems to be an issue.

Yes, can confirm that too.

When this will be solved, @Andrew-Chen-Wang?

This is my highly questionable solution until now:
I have the following in my User ModelAdmin

    def BE_AWARE_NO_WARNING_clear_tokens_and_delete(self, request, queryset):
        users = queryset.values("id")
        OutstandingToken.objects.filter(user__id__in=users).delete()
        queryset.delete()

    actions = ["BE_AWARE_NO_WARNING_clear_tokens_and_delete"]

My solution was to add an "is_active" property to my user model, so users aren't deleted, rather they can be marked as inactive.

Sorry, these should be quick emails; finished with exams so I can finally send them. I should get an answer within this week.

I have a custom user model. I still cant delete token and the user

Hello,

Is this already fixed? I still have the same issue.

A quick fix can be obtained by going to your environment packages and navigating to rest_framework_simplejwt/token_blacklist/admin.py and setting def has_delete_permission(self, *args, **kwargs): return False to True

I can recommend what @adriangzz commented, but instead of doing it in your virtual environment, I'd recommend using this resource: https://stackoverflow.com/a/9322007

Essentially, deregister our class, inherit the class for your custom code, then register it with the admin.

I can recommend what @adriangzz commented, but instead of doing it in your virtual environment, I'd recommend using this resource: https://stackoverflow.com/a/9322007

Essentially, deregister our class, inherit the class for your custom code, then register it with the admin.

This worked. Thank you Andrew.

I can recommend what @adriangzz commented, but instead of doing it in your virtual environment, I'd recommend using this resource: https://stackoverflow.com/a/9322007

Essentially, deregister our class, inherit the class for your custom code, then register it with the admin.

This also worked for us, thanks for the workaround! Below is a concrete example of what needs to happen inside of admin.py

from rest_framework_simplejwt import token_blacklist

class OutstandingTokenAdmin(token_blacklist.admin.OutstandingTokenAdmin):

    def has_delete_permission(self, *args, **kwargs):
        return True # or whatever logic you want

admin.site.unregister(token_blacklist.models.OutstandingToken)
admin.site.register(token_blacklist.models.OutstandingToken, OutstandingTokenAdmin)

I can recommend what @adriangzz commented, but instead of doing it in your virtual environment, I'd recommend using this resource: https://stackoverflow.com/a/9322007

Essentially, deregister our class, inherit the class for your custom code, then register it with the admin.

This also worked for us, thanks for the workaround! Below is a concrete example of what needs to happen inside of admin.py

from rest_framework_simplejwt import token_blacklist

class OutstandingTokenAdmin(token_blacklist.admin.OutstandingTokenAdmin):

    def has_delete_permission(self, *args, **kwargs):
        return True # or whatever logic you want

admin.site.unregister(token_blacklist.models.OutstandingToken)
admin.site.register(token_blacklist.models.OutstandingToken, OutstandingTokenAdmin)

This worked, thank you.

Definitely a better solution than mine, I'm always amazed by the things you can do in Django.

Sorry for this issue taking so long to resolve. Unfortunately, David has relieved ownership to Jazzband maintainers, and (fortunately) the head is now @auvipy from the celery project. The unfortunate part is I've never got an answer from David, so I'll try to debug the past and figure out how to go about this. In the meantime, @auvipy, do you mind taking a look at this issue, #267, and what we should do? Thanks!

@aliscie I think it's the ModelAdmin's actions

from rest_framework_simplejwt import token_blacklist

class OutstandingTokenAdmin(token_blacklist.admin.OutstandingTokenAdmin):

    def has_delete_permission(self, *args, **kwargs):
        return True # or whatever logic you want

admin.site.unregister(token_blacklist.models.OutstandingToken)
admin.site.register(token_blacklist.models.OutstandingToken, OutstandingTokenAdmin)

I tried that and got the error:
File "/home/rodrigo/PycharmProjects/backend/src/user/admin.py", line 7, in <module> class OutstandingTokenAdmin(token_blacklist.admin.OutstandingTokenAdmin): AttributeError: module 'rest_framework_simplejwt.token_blacklist' has no attribute 'admin'

and when changed to:

from rest_framework_simplejwt.token_blacklist.admin import OutstandingTokenAdmin
from rest_framework_simplejwt.token_blacklist import models

class NewOutstandingTokenAdmin(OutstandingTokenAdmin):

    def has_delete_permission(self, *args, **kwargs):
        return True

admin.site.unregister(OutstandingTokenAdmin)
admin.site.register(models.OutstandingToken, NewOutstandingTokenAdmin)

still getting error:

File "/home/rodrigo/PycharmProjects/backend/src/user/admin.py", line 14, in <module> admin.site.unregister(OutstandingTokenAdmin) File "/home/rodrigo/PycharmProjects/backend/venv/lib/python3.9/site-packages/django/contrib/admin/sites.py", line 144, in unregister for model in model_or_iterable: TypeError: 'MediaDefiningClass' object is not iterable

Anyone faced this issue and solved it? Any update on when the fix is coming to the package?

@Brechard you need to unregister ORM's model, not ModelAdmin

@dhvcc oh right, indeed, thanks

@dhvcc oh right, indeed, thanks

Hey, I am facing similar error, can you elaborate what you changed to get rid of that error !

@CharanpreetSingh056 please read the given example: https://github.com/jazzband/djangorestframework-simplejwt/issues/266#issuecomment-820745103

@CharanpreetSingh056 please read the given example: #266 (comment)

@Andrew-Chen-Wang , I went through that comment(example ) and tried it, but it gives me an error "AttributeError: module 'rest_framework_simplejwt.token_blacklist' has no attribute 'admin'", I saw the above conversation and @dhvcc commented to "unregister ORM's model and not AdminModel", could you please elaborate a bit more on what does it exactly mean to unregister ORM's model ?

@CharanpreetSingh056 please read the given example: #266 (comment)

@Andrew-Chen-Wang , I went through that comment(example ) and tried it, but it gives me an error "AttributeError: module 'rest_framework_simplejwt.token_blacklist' has no attribute 'admin'", I saw the above conversation and @dhvcc commented to "unregister ORM's model and not AdminModel", could you please elaborate a bit more on what does it exactly mean to unregister ORM's model ?

Well to really call admin.unregister(...) on a real Django modles.Model. For token_blacklist it's OustandingToken
Your problem is that you did not import admin. To use rest_framework_simplejwt.token_blacklist.admin you shloud import it. Are you sure you did it right?

@dhvcc oh right, indeed, thanks

Hey, I am facing similar error, can you elaborate what you changed to get rid of that error !

This is the full code of my admin.py in the user app

from django.contrib import admin
from rest_framework_simplejwt.token_blacklist import models
from rest_framework_simplejwt.token_blacklist.admin import OutstandingTokenAdmin

from .models import User


class NewOutstandingTokenAdmin(OutstandingTokenAdmin):

    def has_delete_permission(self, *args, **kwargs):
        return True


admin.site.unregister(models.OutstandingToken)
admin.site.register(models.OutstandingToken, NewOutstandingTokenAdmin)

admin.site.register(User)
Was this page helpful?
0 / 5 - 0 ratings