Fix bugs in API perm checking

This commit is contained in:
Griatch 2021-05-23 00:42:30 +02:00
parent 07f994ce91
commit 43d678d8ca
5 changed files with 41 additions and 8 deletions

View file

@ -167,7 +167,8 @@ def perm(accessing_obj, accessed_obj, *args, **kwargs):
try:
permission = args[0].lower()
perms_object = accessing_obj.permissions.all()
except (AttributeError, IndexError):
except (AttributeError, IndexError) as err:
print("accessing_obj err:", err)
return False
gtmode = kwargs.pop("_greater_than", False)

View file

@ -693,6 +693,29 @@ def check_lockstring(
access_type=access_type,
)
def check_perm(
obj, permission, no_superuser_bypass=False):
"""
Shortcut for checking if an object has the given `permission`. If the
permission is in `settings.PERMISSION_HIERARCHY`, the check passes
if the object has this permission or higher.
This is equivalent to calling the perm() lockfunc, but without needing
an accessed object.
Args:
obj (Object, Account): The object to check access. If this has a linked
Account, the account is checked instead (same rules as per perm()).
permission (str): The permission string to check.
no_superuser_bypass (bool, optional): If unset, the superuser
will always pass this check.
"""
from evennia.locks.lockfuncs import perm
if not no_superuser_bypass and obj.is_superuser:
return True
return perm(obj, None, permission)
def validate_lockstring(lockstring):
"""

View file

@ -1,6 +1,7 @@
# Evennia API
## Synopsis
An API, or [Application Programming Interface][wiki-api], is a way of establishing rules
through which external services can use your program. In web development, it's
often that case that the 'frontend' of a web app is written in HTML and Javascript
@ -141,4 +142,4 @@ the native [Fetch][fetch].
[rest]: https://en.wikipedia.org/wiki/Representational_state_transfer
[requests]: https://requests.readthedocs.io/en/master/
[axios]: https://github.com/axios/axios
[fetch]: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
[fetch]: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API

View file

@ -1,13 +1,20 @@
from rest_framework import permissions
"""
Sets up an api-access permission check using the in-game permission hierarchy.
"""
from rest_framework import permissions
from django.conf import settings
from evennia.locks.lockhandler import check_perm
class EvenniaPermission(permissions.BasePermission):
"""
A Django Rest Framework permission class that allows us to use
Evennia's permission structure. Based on the action in a given
view, we'll check a corresponding Evennia access/lock check.
A Django Rest Framework permission class that allows us to use Evennia's
permission structure. Based on the action in a given view, we'll check a
corresponding Evennia access/lock check.
"""
# subclass this to change these permissions
@ -40,9 +47,9 @@ class EvenniaPermission(permissions.BasePermission):
return True
# these actions don't support object-level permissions, so use the above definitions
if view.action == "list":
return request.user.has_permistring(self.MINIMUM_LIST_PERMISSION)
return check_perm(request.user, self.MINIMUM_LIST_PERMISSION)
if view.action == "create":
return request.user.has_permistring(self.MINIMUM_CREATE_PERMISSION)
return check_perm(request.user, self.MINIMUM_CREATE_PERMISSION)
return True # this means we'll check object-level permissions
@staticmethod

View file

@ -7,6 +7,7 @@ actions that it detects for a viewset. For example, below we create a DefaultRou
We then register ObjectDBViewSet, a viewset for CRUD operations for ObjectDB
instances, to the 'objects' base endpoint. That will generate a number of URLs
like the following:
list objects: action: GET, url: /objects/, view name: object-list
create object: action: POST, url: /objects/, view name: object-list
retrieve object: action: GET, url: /objects/<:pk>, view name: object-detail