Skip to content

Commit

Permalink
docs
Browse files Browse the repository at this point in the history
  • Loading branch information
eshaan7 committed Sep 22, 2021
1 parent 13ed531 commit 0d97ad4
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 8 deletions.
2 changes: 1 addition & 1 deletion docs/source/faq.rst
Expand Up @@ -14,7 +14,7 @@ and might help you make a better decision too,

- If you'd like to use Django's Admin interface to manage the different clients which consume your API.
- If you want the token expiration to be dependent on what API client it is meant for.
For example, you might want to create tokens which never expire for a Command Line client but want a shorter expiry for a JavaScript (web) client.
For example, you might want to create tokens which never expire for a Command Line Client but want a shorter expiry for a JavaScript (web) client.
- If you want to limit number of tokens allowed per user.
- If you'd like to refresh token expiry without changing token key.
- If you or your organization are interested in Client Level Analytics such as keeping track of which user uses what client the most, etc.
Expand Down
34 changes: 34 additions & 0 deletions docs/source/settings.rst
Expand Up @@ -19,6 +19,9 @@ Example ``settings.py``::
"TOKEN_CACHE_TIMEOUT": 60,
"REFRESH_TOKEN_ON_LOGIN": False,
"AUTHTOKEN_SELECT_RELATED_LIST": ["user"],
"API_ACCESS_CLIENT_NAME": None,
"API_ACCESS_EXCLUDE_FROM_SESSIONS": False,
"API_ACCESS_RESPONSE_INCLUDE_TOKEN": False,
}
#...snip...

Expand Down Expand Up @@ -101,3 +104,34 @@ Example ``settings.py``::

.. Hint:: Refer to `Django's select_related docs <https://docs.djangoproject.com/en/3.2/ref/models/querysets/#select-related>`_
to see how this can boost performance by reducing number of SQL queries made.


.. data:: API_ACCESS_CLIENT_NAME

Default: ``None``

There may be an use-case where you want to issue API keys to your users so they can call your RESTful API
using cURL or a custom client.

Set this setting to the ``name` of the specific :class:`durin.models.Client` instance to issue these API keys against.
Note: The :class:`durin.views.APIAccessTokenView` view allows management of this.
.. data:: API_ACCESS_EXCLUDE_FROM_SESSIONS
Default: ``False``

If set to ``True``, the ``AuthToken`` instance for the specifc ``API_ACCESS_CLIENT_NAME``'s `Client`` instance
will be excluded from the overall "Sessions List"
(``GET /api/sessions/``) response.

This is useful because you may want the view to list only the "browser sessions".

.. data:: API_ACCESS_RESPONSE_INCLUDE_TOKEN

Default: ``False``

If set to ``False``, the ``token`` field would be omitted from the
:class:`durin.views.APIAccessTokenView` view's (``GET /api/apiaccess/``) response.

In case of ``POST`` request, the ``token`` field is always included despite of this setting.
6 changes: 2 additions & 4 deletions docs/source/sub_modules.rst
Expand Up @@ -10,13 +10,11 @@ Other submodules

.. automodule:: durin.admin
:members:
:undoc-members:
:show-inheritance:
:no-undoc-members:

``durin.serializers`` module
------------------------------

.. automodule:: durin.serializers
:members:
:undoc-members:
:show-inheritance:
:no-undoc-members:
6 changes: 6 additions & 0 deletions docs/source/urls.rst
Expand Up @@ -24,10 +24,16 @@ The views would then accessible as:
- ``/api/auth/refresh`` - ``RefreshView``
- ``/api/auth/logout`` -> ``LogoutView``
- ``/api/auth/logoutall`` -> ``LogoutAllView``
- ``/api/auth/sessions`` -> ``TokenSessionsViewSet``
- ``/api/auth/apiaccess`` -> ``APIAccessTokenView``

they can also be looked up by name::

from django.urls import reverse

reverse('durin_login')
reverse('durin_logout')
reverse('durin_refresh')
reverse('durin_logoutall')
reverse('durin_tokensessions-list')
reverse('durin_apiaccess')
28 changes: 27 additions & 1 deletion docs/source/views.rst
Expand Up @@ -2,6 +2,10 @@ Views (``durin.views``)
================================

Durin provides four views that handle token management for you.
And two additional views to allow sessions management.

Auth Management Views
###########

--------------------------

Expand Down Expand Up @@ -54,7 +58,7 @@ Here's an example snippet of how you can override this behaviour::
### urls.py:

from durin import views as durin_views
from yourapp.api.views import LoginView
from yourapp.views import LoginView

urlpatterns = [
url(r'login/', LoginView.as_view(), name='durin_login'),
Expand Down Expand Up @@ -91,3 +95,25 @@ LogoutAllView
.. Note:: It is not recommended to alter the Logout views. They are designed
specifically for token management, and to respond to durin authentication.
Modified forms of the class may cause unpredictable results.


Session Management Views
###########

--------------------------

TokenSessionsViewSet
--------------------------

.. autoclass:: durin.views.TokenSessionsViewSet
:show-inheritance:

--------------------------

APIAccessTokenView
--------------------------

.. autoclass:: durin.views.APIAccessTokenView
:show-inheritance:

--------------------------
13 changes: 13 additions & 0 deletions durin/admin.py
Expand Up @@ -24,6 +24,11 @@ class AuthTokenAdmin(admin.ModelAdmin):
readonly_fields = ("token", "expiry", "created", "expires_in")

def get_fieldsets(self, request, obj=None):
"""
Hook for specifying fieldsets.
:meta private:
"""
if not obj:
return [
(
Expand All @@ -45,9 +50,17 @@ def get_fieldsets(self, request, obj=None):
return super().get_fieldsets(request, obj)

def has_change_permission(self, request, obj=None):
"""
:meta private:
"""
return False

def save_model(self, request, obj, form, change):
"""
Given a model instance save it to the database.
:meta private:
"""
if not change:
created_obj = models.AuthToken.objects.create(
user=obj.user, client=obj.client
Expand Down
14 changes: 14 additions & 0 deletions durin/serializers.py
Expand Up @@ -15,6 +15,10 @@ class Meta:


class TokenSessionsSerializer(rfs.ModelSerializer):
"""
Used in :class:`durin.views.TokenSessionsViewSet`.
"""

class Meta:
model = AuthToken
fields = [
Expand Down Expand Up @@ -48,6 +52,10 @@ def get_is_current(self, obj: AuthToken) -> bool:


class APIAccessTokenSerializer(rfs.ModelSerializer):
"""
Used in :class:`durin.views.APIAccessTokenView`.
"""

class Meta:
model = AuthToken
fields = [
Expand All @@ -73,6 +81,9 @@ class Meta:
expires_in_str = rfs.CharField(source="expires_in", read_only=True)

def get_field_names(self, declared_fields, info):
"""
:meta private:
"""
fields = super().get_field_names(declared_fields, info)
if (
durin_settings.API_ACCESS_RESPONSE_INCLUDE_TOKEN
Expand All @@ -84,6 +95,9 @@ def get_field_names(self, declared_fields, info):
return fields

def create(self, validated_data):
"""
:meta private:
"""
user = self.context["request"].user
client_name = self.context["client_name"]
if AuthToken.objects.filter(user=user, client__name=client_name).exists():
Expand Down
5 changes: 3 additions & 2 deletions durin/views.py
Expand Up @@ -211,7 +211,7 @@ def post(self, request, *args, **kwargs):


class TokenSessionsViewSet(
mixins.DestroyModelMixin, mixins.ListModelMixin, GenericViewSet
mixins.ListModelMixin, mixins.DestroyModelMixin, GenericViewSet
):
"""Durin's TokenSessionsViewSet.\n
- Returns list of active sessions of authed user.
Expand All @@ -236,7 +236,8 @@ def get_queryset(self):

def perform_destroy(self, instance):
"""
Overwrite to prevent deletion of object against which current request was authed
Overwrite to prevent deletion of object
against which current request was authed.
"""
if instance.pk == self.request.auth.pk:
raise ValidationError(
Expand Down

0 comments on commit 0d97ad4

Please sign in to comment.