Add filter for aliases and permissions

This commit is contained in:
TehomCD 2020-03-01 01:07:00 -05:00
parent e687f63ab7
commit c83567c95e
3 changed files with 57 additions and 18 deletions

View file

@ -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

View file

@ -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"]

View file

@ -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):
"""