-
-
Notifications
You must be signed in to change notification settings - Fork 25
[Question] How to modify response message for is_active
= False
accounts?
#122
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Give up, I've tried many methods but they can't do anything. They have an internal definition error and cannot be caught globally unless you redo this function method |
I found the solution |
@Anning01 That really did dig a bit in a right direction, but I'm still stuck. The problem is to get the user from token before inner check for Here is what I'm currently at: def api_exception_handler(request: HttpRequest, exc: exceptions.APIException) -> HttpResponse:
"""
# `APIException` handler
"""
headers: dict = {}
extra: dict = {}
if (
exc.status_code == 401
and (path := request.get_full_path()).startswith("/api/")
and (
(
path.endswith(("/token/pair", "/token/refresh"))
and request.body
and (username := json.loads(request.body or "{}").get("username"))
)
or (token := request.headers.get("X-API-Key")) # stuck here
)
):
extra["reason"] = (
f"User is blocked. Reason: {reason.reason}"
if (reason := User_Block_Reason.objects.get_or_none(user__username=username))
else "User is not active."
)
data: list[exceptions.ErrorDetail] | dict[Any, exceptions.ErrorDetail] = (
exc.detail
if isinstance(exc.detail, list)
else ({**exc.detail, **extra} if isinstance(exc.detail, dict) else {"detail": exc.detail, **extra})
)
response: HttpResponse = api.create_response(request, data, status=exc.status_code)
for k, v in headers.items():
response.setdefault(k, v)
return response So, what I did is add Now, if request comes not from login, then I can't get user from here to proceed further. |
@XCanG @Anning01 Sorry I am late to the show. Reason #123 Regarding your issue, did you try NINJA_JWT = {
'USER_AUTHENTICATION_RULE': 'ninja_jwt.authentication.default_user_authentication_rule',
}
# ninja_jwt.authentication.default_user_authentication_rule
def default_user_authentication_rule(user) -> bool:
return user is not None and user.is_active
# This function is called after authentication is successful to check if the user is active Also, when overriding from django.http import HttpRequest, HttpResponse
from django.contrib.auth import get_user_model
from ninja_extra import exceptions
from ninja_jwt import exceptions as jwt_exceptions
from ninja_extra import service_resolver
from ninja_extra.context import RouteContext
user_name_field = get_user_model().USERNAME_FIELD
def api_exception_handler(request: HttpRequest, exc: exceptions.APIException) -> HttpResponse:
"""
# `APIException` handler
"""
headers: dict = {}
extra: dict = {}
route_context: RouteContext = service_resolver(RouteContext)
if isinstance(exc, jwt_exceptions.AuthenticationFailed):
username = route_context.kwargs[user_name_field]
extra["reason"] = (
f"User is blocked. Reason: {reason.reason}"
if (reason := User_Block_Reason.objects.get_or_none(user__username=username))
else "User is not active."
)
data: list[exceptions.ErrorDetail] | dict[Any, exceptions.ErrorDetail] = (
exc.detail
if isinstance(exc.detail, list)
else ({**exc.detail, **extra} if isinstance(exc.detail, dict) else {"detail": exc.detail, **extra})
)
response: HttpResponse = api.create_response(request, data, status=exc.status_code)
for k, v in headers.items():
response.setdefault(k, v)
return response |
Not yet, didn't think it could solve my case. I will try your proposed code on Monday and come back with reply. If it wouldn't solve 2nd case I will look if this rule will able to handle check later down the line in some util function. Also a little proposal: enable Github Discussions in this repo, so that questions can be asked here instead of creating issues (for bug reports), unless you fine with it. |
In my project
is_active
used to block accounts and external table is used to provide reason. I used that functionality in DRF without issues, but I couldn't port it to Django Ninja JWT, because it's implementation is hidden.What ninja return:
urls.py
:I need a way to change the output and provide block reason from external table.
The text was updated successfully, but these errors were encountered: