-
-
Notifications
You must be signed in to change notification settings - Fork 394
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
[proposal] Authorization ( permissions ) handling #156
Comments
Great proposal! Another idea would be to add an optional parameter to the For example # inherit from base class BasicAuth
class UserAuth(BasicAuth):
def authenticate(self, request, username, password):
....
# Ninja runs this for you if a `perm` is specified on init
def has_permission(self, request, perm):
return request.user.has_perm(perm)
@api.get("/apples", auth=UserAuth(perm="can_see_fruits"), response=List[AppleOut])
def list_apples(request):
return Apple.objects.all() |
I'm glad you like this proposal I think they are different things, one permission could be used for unauthenticated users too, or the same permission could be used for different authentication types What do you think about? |
I find myself repeating some sort of permission check against the authenticated user. It would be nice if Ninja supported permission checks like the following: @router.get(
url_name="resorce-get",
path="/{user}/resource",
response=ResourceSchema,
auth=[auth1(), auth2(), ....].
permissions=[perm1(), perm2(), ...] # <- This
)
def get_resource(
request: HttpRequest,
user: str,
**kwargs
):
.... This would hook nicely into If something like this is welcome, I wouldn't mind trying to submit a PR for it. |
So what's the best method to approach different levels of permissions for users in Django ninja? |
To throw out another idea; it would've been nice with an approach similar to Django's In case django ninja could support decorating an operation, it could look like something below (e.g. def email_check(user):
return user.email.endswith('@example.com')
@api.get("/apples", auth=UserAuth(), response=List[AppleOut])
@login_required
@user_passes_test(email_check)
@permission_required("can_see_fruits", raise_exception=True)
def list_apples(request):
return Apple.objects.all() |
And yes, I think we have to re-implement a few decorators here. I thought I could get around this with from django.contrib.auth.decorators import permission_required
from django.core.exceptions import PermissionDenied
from ninja import Router
api = NinjaAPI(auth=[some_auth()])
@api.exception_handler(PermissionDenied)
def django_permission_denied(
request: HttpRequest, exc: PermissionDenied
) -> HttpResponse:
return api.create_response(...)
...
@router.get("/") # <- mypy error
@permission_required('app.some_permission', raise_exception=True) # note: raise_exception=True
def get_something(request: HttpRequest) -> ...:
... But this is not going to work out, as I'm getting this mypy error:
due to And I actually think django-stubs is right in assuming the response to be of type |
I have made #776 as an alternative way to handle permissions :) that's mostly inspied from |
Why can't this be implemented using django builtin
This apparently doesn't work as of |
cause, permission_required redirects to a login-page, which is not really the best idea for API clients |
In the docs I can see how to handle Authentication but not how to handle Authorization ( permissions )
After I have identified a logged user I want to return 403 if that user hasn't enough permission to do it
DRF has a great way to handle it, using BasePermission.has_permission and BasePermission.has_object_permission
Maybe this library could handle permissions with something like this:
What do you think about it?
Thank you
The text was updated successfully, but these errors were encountered: