mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
Add filter for aliases and permissions
This commit is contained in:
parent
e687f63ab7
commit
c83567c95e
3 changed files with 57 additions and 18 deletions
|
|
@ -1,6 +1,6 @@
|
|||
# Evennia API
|
||||
|
||||
## What's an 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
|
||||
|
|
@ -8,7 +8,6 @@ and communicates with the 'backend' server through an API so that it can retriev
|
|||
information to populate web pages or process actions when users click buttons on
|
||||
a web page.
|
||||
|
||||
|
||||
The API contained within the web/api/ package is an implementation of the
|
||||
[Django Rest Framework][drf]. It provides tools to allow you to quickly process
|
||||
requests for resources and generate responses. URLs, called endpoints, are
|
||||
|
|
@ -24,7 +23,7 @@ that largely automate the process of serializing your in-game objects into
|
|||
JSON representations for sending them to a client, or for turning a JSON string
|
||||
into a model for updating or creating it.
|
||||
|
||||
## What is it for?
|
||||
## Motivations For Using An API
|
||||
|
||||
Having an API can allow you to have richer interactions with client applications. For
|
||||
example, suppose you want to allow players to send and receive in-game messages from
|
||||
|
|
@ -35,7 +34,7 @@ displays it on the page. You also provide a form to let them send messages, wher
|
|||
submit button uses AJAX to make a POST request to that endpoint, sending along the
|
||||
JSON data from the form, and then returns the response of the results. This works,
|
||||
but then a tech-savvy player might ask if they can have their own application that
|
||||
will retrieve messages periodically for their own computer. By having a [REST][REST] API that
|
||||
will retrieve messages periodically for their own computer. By having a [REST][rest] API that
|
||||
they can use, they can create client applications of their own to retrieve or change
|
||||
data.
|
||||
|
||||
|
|
@ -88,8 +87,8 @@ a request to update the object with the specified data you pass along.
|
|||
In most cases, you won't be making API requests to the backend with python,
|
||||
but with Javascript from your frontend application.
|
||||
There are many Javascript libraries which are meant to make this process
|
||||
easier for requests from the frontend, such as [AXIOS][AXIOS], or using
|
||||
the native [Fetch][Fetch].
|
||||
easier for requests from the frontend, such as [AXIOS][axios], or using
|
||||
the native [Fetch][fetch].
|
||||
|
||||
[wiki-api]: https://en.wikipedia.org/wiki/Application_programming_interface
|
||||
[drf]: https://www.django-rest-framework.org/
|
||||
|
|
@ -97,7 +96,7 @@ the native [Fetch][Fetch].
|
|||
[crud]: https://en.wikipedia.org/wiki/Create,_read,_update_and_delete
|
||||
[serializers]: https://www.django-rest-framework.org/api-guide/serializers/
|
||||
[ajax]: https://en.wikipedia.org/wiki/Ajax_(programming)
|
||||
[REST]: https://en.wikipedia.org/wiki/Representational_state_transfer
|
||||
[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
|
||||
[axios]: https://github.com/axios/axios
|
||||
[fetch]: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
|
||||
|
|
@ -1,27 +1,67 @@
|
|||
"""
|
||||
FilterSets allow clients to specify querystrings that will determine the data
|
||||
that is retrieved in GET requests. By default, Django Rest Framework uses the
|
||||
'django-filter' package as its backend. Django-filter also has a section in its
|
||||
documentation specifically regarding DRF integration.
|
||||
|
||||
https://django-filter.readthedocs.io/en/latest/guide/rest_framework.html
|
||||
"""
|
||||
from django.db.models import Q
|
||||
from django_filters.rest_framework.filterset import FilterSet
|
||||
from django_filters.filters import CharFilter
|
||||
|
||||
from evennia.objects.models import ObjectDB
|
||||
from evennia.accounts.models import AccountDB
|
||||
from evennia.scripts.models import ScriptDB
|
||||
|
||||
|
||||
class TagTypeFilter(CharFilter):
|
||||
"""
|
||||
This class lets you create different filters for tags of a specified db_tagtype.
|
||||
"""
|
||||
tag_type = None
|
||||
|
||||
def filter(self, qs, value):
|
||||
return qs.filter(Q(db_tags__db_tagtype=self.tag_type) & Q(db_tags__db_key=value))
|
||||
|
||||
|
||||
class AliasFilter(TagTypeFilter):
|
||||
"""A filter for objects by their aliases (tags with a tagtype of 'alias'"""
|
||||
tag_type = "alias"
|
||||
|
||||
|
||||
class PermissionFilter(TagTypeFilter):
|
||||
"""A filter for objects by their permissions (tags with a tagtype of 'permission'"""
|
||||
tag_type = "permission"
|
||||
|
||||
|
||||
SHARED_FIELDS = ["db_key", "db_typeclass_path", "db_tags__db_key", "db_tags__db_category"]
|
||||
|
||||
|
||||
class ObjectDBFilterSet(FilterSet):
|
||||
class BaseTypeclassFilterSet(FilterSet):
|
||||
"""A parent class with filters for aliases and permissions"""
|
||||
alias = AliasFilter(lookup_expr="iexact")
|
||||
permission = PermissionFilter(lookup_expr="iexact")
|
||||
|
||||
|
||||
class ObjectDBFilterSet(BaseTypeclassFilterSet):
|
||||
"""This adds filters for ObjectDB instances - characters, rooms, exits, etc"""
|
||||
class Meta:
|
||||
model = ObjectDB
|
||||
fields = SHARED_FIELDS + ["db_location__db_key", "db_home__db_key", "db_location__id",
|
||||
"db_home__id"]
|
||||
|
||||
|
||||
class AccountDBFilterSet(FilterSet):
|
||||
class AccountDBFilterSet(BaseTypeclassFilterSet):
|
||||
"""This adds filters for Account objects"""
|
||||
class Meta:
|
||||
model = AccountDB
|
||||
fields = SHARED_FIELDS + ["username", "db_is_connected", "db_is_bot"]
|
||||
|
||||
|
||||
class ScriptDBFilterSet(FilterSet):
|
||||
class ScriptDBFilterSet(BaseTypeclassFilterSet):
|
||||
"""This adds filters for Script objects"""
|
||||
class Meta:
|
||||
model = ScriptDB
|
||||
fields = SHARED_FIELDS + ["db_desc", "db_obj__db_key", "db_obj__id", "db_account__id",
|
||||
"db_account__username", "db_is_active", "db_persistent"]
|
||||
"db_account__username", "db_is_active", "db_persistent", "db_interval"]
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@ class EvenniaPermission(permissions.BasePermission):
|
|||
view, we'll check a corresponding Evennia access/lock check.
|
||||
"""
|
||||
# subclass this to change these permissions
|
||||
MINIMUM_LIST_PERMISSION = settings.REST_FRAMEWORK["DEFAULT_LIST_PERMISSION"]
|
||||
MINIMUM_CREATE_PERMISSION = settings.REST_FRAMEWORK["DEFAULT_CREATE_PERMISSION"]
|
||||
view_locks = settings.REST_FRAMEWORK["DEFAULT_VIEW_LOCKS"]
|
||||
destroy_locks = settings.REST_FRAMEWORK["DEFAULT_DESTROY_LOCKS"]
|
||||
update_locks = settings.REST_FRAMEWORK["DEFAULT_UPDATE_LOCKS"]
|
||||
MINIMUM_LIST_PERMISSION = settings.REST_FRAMEWORK.get("DEFAULT_LIST_PERMISSION", "builder")
|
||||
MINIMUM_CREATE_PERMISSION = settings.REST_FRAMEWORK.get("DEFAULT_CREATE_PERMISSION", "builder")
|
||||
view_locks = settings.REST_FRAMEWORK.get("DEFAULT_VIEW_LOCKS", ["examine"])
|
||||
destroy_locks = settings.REST_FRAMEWORK.get("DEFAULT_DESTROY_LOCKS", ["delete"])
|
||||
update_locks = settings.REST_FRAMEWORK.get("DEFAULT_UPDATE_LOCKS", ["control", "edit"])
|
||||
|
||||
def has_permission(self, request, view):
|
||||
"""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue