Initial commit
This commit is contained in:
1
webservice/apps/api/__init__.py
Normal file
1
webservice/apps/api/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
default_app_config = 'apps.api.apps.ApiConfig'
|
9
webservice/apps/api/admin.py
Normal file
9
webservice/apps/api/admin.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from django.contrib import admin
|
||||
from .models import Token
|
||||
|
||||
@admin.register(Token)
|
||||
class TokenAdmin(admin.ModelAdmin):
|
||||
list_display = ('key', 'user','is_supertoken', 'last_access')
|
||||
ordering = ('-last_access', 'user', )
|
||||
search_fields = ('key', 'user__username',)
|
||||
readonly_fields = ('created_at', 'updated_at')
|
66
webservice/apps/api/apps.py
Normal file
66
webservice/apps/api/apps.py
Normal file
@@ -0,0 +1,66 @@
|
||||
from django.apps import AppConfig
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
class ApiConfig(AppConfig):
|
||||
name = 'apps.api'
|
||||
label = 'api'
|
||||
verbose_name = _('API')
|
||||
verbose_name_plural = _('APIs')
|
||||
|
||||
try:
|
||||
assert settings.SWAGGER_SETTINGS
|
||||
except AttributeError:
|
||||
# We only load this setting, if it is not available in the overall settings.py file
|
||||
settings.SWAGGER_SETTINGS = {
|
||||
'SECURITY_DEFINITIONS': {
|
||||
'Hawk': {
|
||||
'type': 'apiKey',
|
||||
'description': 'HTTP Holder-Of-Key Authentication Scheme, https://github.com/hapijs/hawk, https://hawkrest.readthedocs.io/en/latest/<br /><strong>Ex header:</strong><br />\'Authorization\': \'Hawk mac="F4+S9cu7yZiZEgdtqzMpOOdudvqcV2V2Yzk2WcphECc=", hash="+7fKUX+djeQolvnLTxr0X47e//UHKbkRlajwMw3tx3w=", id="7FI5JET4", ts="1592905433", nonce="DlV-fL"\'',
|
||||
'name': 'Authorization',
|
||||
'in': 'header'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try:
|
||||
assert settings.REST_FRAMEWORK
|
||||
except AttributeError:
|
||||
# We only load this setting, if it is not available in the overall settings.py file
|
||||
# To protect all API views with Hawk by default, put this in your settings:
|
||||
# https://hawkrest.readthedocs.io/en/latest/usage.html#protecting-api-views-with-hawk
|
||||
settings.REST_FRAMEWORK = {
|
||||
|
||||
'DEFAULT_AUTHENTICATION_CLASSES': (
|
||||
'apps.api.authentication.APIHawk',
|
||||
),
|
||||
|
||||
'DEFAULT_PERMISSION_CLASSES': (
|
||||
'rest_framework.permissions.IsAuthenticated',
|
||||
),
|
||||
|
||||
# 'DEFAULT_AUTHENTICATION_CLASSES': (
|
||||
# 'rest_framework.authentication.TokenAuthentication',
|
||||
# ),
|
||||
|
||||
# 'DEFAULT_PERMISSION_CLASSES': (
|
||||
# 'rest_framework.permissions.IsAuthenticated', ),
|
||||
|
||||
# Use Django's standard `django.contrib.auth` permissions,
|
||||
# or allow read-only access for unauthenticated users.
|
||||
#'DEFAULT_PERMISSION_CLASSES': [
|
||||
# 'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
|
||||
#],
|
||||
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
|
||||
'PAGE_SIZE': 10
|
||||
}
|
||||
|
||||
try:
|
||||
assert settings.HAWK_MESSAGE_EXPIRATION
|
||||
except AttributeError:
|
||||
# We only load this setting, if it is not available in the overall settings.py file
|
||||
settings.HAWK_MESSAGE_EXPIRATION = 60
|
||||
|
||||
def ready(self):
|
||||
from . import signals
|
72
webservice/apps/api/authentication.py
Normal file
72
webservice/apps/api/authentication.py
Normal file
@@ -0,0 +1,72 @@
|
||||
# import the logging library
|
||||
import logging
|
||||
# Get an instance of a logger
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
import django.utils
|
||||
from rest_framework import exceptions
|
||||
from hawkrest import HawkAuthentication
|
||||
|
||||
from .models import Token
|
||||
class APIHawk(HawkAuthentication):
|
||||
"""This is the API authentication that is using the HAWK authentication mechanism.
|
||||
|
||||
This class will implement a custom credentials and user lookups so that we can dynamically add new users and update tokens.
|
||||
"""
|
||||
def hawk_credentials_lookup(self, id):
|
||||
"""This method will perform the check if the used token is an existing/known token in the database. This will not lookup a user. Only an existing token.
|
||||
|
||||
Args:
|
||||
id (string): The token key to lookup in the database for existing token.
|
||||
|
||||
Raises:
|
||||
exceptions.AuthenticationFailed: If the given token does not exists.
|
||||
|
||||
Returns:
|
||||
dict: The dictionary holds the token id, the token secret and the used hashing algoritem that is used.
|
||||
"""
|
||||
try:
|
||||
token = Token.objects.get(key=id)
|
||||
except Token.DoesNotExist:
|
||||
logger.warning('Requested to validate with invalid/non existing token: {}'.format(id))
|
||||
raise exceptions.AuthenticationFailed('No such token: {}'.format(id))
|
||||
|
||||
return {
|
||||
'id' : id,
|
||||
'key' : token.secret,
|
||||
'algorithm' : 'sha256'
|
||||
}
|
||||
|
||||
def hawk_user_lookup(self, request, credentials):
|
||||
"""Return the user account that is connected to the used token.
|
||||
|
||||
Args:
|
||||
request ([type]): The incoming HTTP/API request
|
||||
credentials (dict): The credentials from ~hawk_credentials_lookup
|
||||
|
||||
Raises:
|
||||
exceptions.AuthenticationFailed: If the given token does not exists to an existing user
|
||||
|
||||
Returns:
|
||||
tuple: Returns a tuple holding the user as first item
|
||||
"""
|
||||
user = None
|
||||
try:
|
||||
user = Token.objects.get(key=credentials['id']).user
|
||||
except Token.DoesNotExist:
|
||||
logger.warning('Requested to validate non existing user: {}'.format(id))
|
||||
raise exceptions.AuthenticationFailed('No user for token: {}'.format(credentials['id']))
|
||||
|
||||
# Update the date time stamp to now for last access data
|
||||
user.token.last_access = django.utils.timezone.now()
|
||||
user.token.save()
|
||||
|
||||
return (user,None)
|
||||
|
||||
def __repr__(self):
|
||||
"""Authentication identifier.
|
||||
|
||||
Returns:
|
||||
string: Returns the name of the used authentication mechanism.
|
||||
"""
|
||||
return 'Hawk authenticator'
|
BIN
webservice/apps/api/locale/en/LC_MESSAGES/django.mo
Normal file
BIN
webservice/apps/api/locale/en/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
67
webservice/apps/api/locale/en/LC_MESSAGES/django.po
Normal file
67
webservice/apps/api/locale/en/LC_MESSAGES/django.po
Normal file
@@ -0,0 +1,67 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-07-30 15:42+0200\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: apps/api/apps.py:9
|
||||
msgid "API"
|
||||
msgstr ""
|
||||
|
||||
#: apps/api/apps.py:10
|
||||
msgid "APIs"
|
||||
msgstr ""
|
||||
|
||||
#: apps/api/models.py:28
|
||||
msgid "token"
|
||||
msgstr ""
|
||||
|
||||
#: apps/api/models.py:29
|
||||
msgid "tokens"
|
||||
msgstr ""
|
||||
|
||||
#: apps/api/models.py:31
|
||||
msgid "Select the user for this token"
|
||||
msgstr ""
|
||||
|
||||
#: apps/api/models.py:32
|
||||
msgid "Key"
|
||||
msgstr ""
|
||||
|
||||
#: apps/api/models.py:32
|
||||
msgid "The key for this token. This is used for Hawk verification."
|
||||
msgstr ""
|
||||
|
||||
#: apps/api/models.py:33
|
||||
msgid "Secret"
|
||||
msgstr ""
|
||||
|
||||
#: apps/api/models.py:33
|
||||
msgid "The secret for this token. This is used for Hawk signing."
|
||||
msgstr ""
|
||||
|
||||
#: apps/api/models.py:34
|
||||
msgid "Last access"
|
||||
msgstr ""
|
||||
|
||||
#: apps/api/models.py:34
|
||||
msgid "The date and time when this token is last used."
|
||||
msgstr ""
|
||||
|
||||
#: apps/api/models.py:44
|
||||
msgid "Super token"
|
||||
msgstr ""
|
BIN
webservice/apps/api/locale/nl/LC_MESSAGES/django.mo
Normal file
BIN
webservice/apps/api/locale/nl/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
67
webservice/apps/api/locale/nl/LC_MESSAGES/django.po
Normal file
67
webservice/apps/api/locale/nl/LC_MESSAGES/django.po
Normal file
@@ -0,0 +1,67 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-07-30 15:42+0200\n"
|
||||
"PO-Revision-Date: 2020-05-27 16:25+0200\n"
|
||||
"Last-Translator: Joshua Rubingh <j.g.rubingh@rug.nl>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: nl\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Poedit 2.0.6\n"
|
||||
|
||||
#: apps/api/apps.py:9
|
||||
msgid "API"
|
||||
msgstr "API"
|
||||
|
||||
#: apps/api/apps.py:10
|
||||
msgid "APIs"
|
||||
msgstr "APIs"
|
||||
|
||||
#: apps/api/models.py:28
|
||||
msgid "token"
|
||||
msgstr ""
|
||||
|
||||
#: apps/api/models.py:29
|
||||
msgid "tokens"
|
||||
msgstr ""
|
||||
|
||||
#: apps/api/models.py:31
|
||||
msgid "Select the user for this token"
|
||||
msgstr ""
|
||||
|
||||
#: apps/api/models.py:32
|
||||
msgid "Key"
|
||||
msgstr ""
|
||||
|
||||
#: apps/api/models.py:32
|
||||
msgid "The key for this token. This is used for Hawk verification."
|
||||
msgstr ""
|
||||
|
||||
#: apps/api/models.py:33
|
||||
msgid "Secret"
|
||||
msgstr ""
|
||||
|
||||
#: apps/api/models.py:33
|
||||
msgid "The secret for this token. This is used for Hawk signing."
|
||||
msgstr ""
|
||||
|
||||
#: apps/api/models.py:34
|
||||
msgid "Last access"
|
||||
msgstr ""
|
||||
|
||||
#: apps/api/models.py:34
|
||||
msgid "The date and time when this token is last used."
|
||||
msgstr ""
|
||||
|
||||
#: apps/api/models.py:44
|
||||
msgid "Super token"
|
||||
msgstr ""
|
35
webservice/apps/api/migrations/0001_initial.py
Normal file
35
webservice/apps/api/migrations/0001_initial.py
Normal file
@@ -0,0 +1,35 @@
|
||||
# Generated by Django 3.0.8 on 2020-07-30 14:15
|
||||
|
||||
import apps.api.models
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import django_cryptography.fields
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Token',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True, help_text='The date and time this model has been created', verbose_name='Date created')),
|
||||
('updated_at', models.DateTimeField(auto_now=True, help_text='The date and time this model has been updated', verbose_name='Date updated')),
|
||||
('key', models.CharField(default=apps.api.models.get_random_key, help_text='The key for this token. This is used for Hawk verification.', max_length=16, unique=True, verbose_name='Key')),
|
||||
('secret', django_cryptography.fields.encrypt(models.CharField(default=apps.api.models.get_random_secret, help_text='The secret for this token. This is used for Hawk signing.', max_length=64, verbose_name='Secret'))),
|
||||
('last_access', models.DateTimeField(auto_now_add=True, help_text='The date and time when this token is last used.', verbose_name='Last access')),
|
||||
('user', models.OneToOneField(help_text='Select the user for this token', on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'token',
|
||||
'verbose_name_plural': 'tokens',
|
||||
},
|
||||
),
|
||||
]
|
0
webservice/apps/api/migrations/__init__.py
Normal file
0
webservice/apps/api/migrations/__init__.py
Normal file
70
webservice/apps/api/models.py
Normal file
70
webservice/apps/api/models.py
Normal file
@@ -0,0 +1,70 @@
|
||||
from django.contrib.auth.models import User
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from django_cryptography.fields import encrypt
|
||||
|
||||
from lib.utils.general import get_random_string
|
||||
from lib.models.base import MetaDataModel
|
||||
|
||||
|
||||
def get_random_key():
|
||||
return get_random_string(8)
|
||||
|
||||
def get_random_secret():
|
||||
return get_random_string(32)
|
||||
|
||||
class TokenManager(models.Manager):
|
||||
"""
|
||||
Custom queryset which will prefetch related user table data when requesting a token from the database as the user is mostly needed every time the token is requested.
|
||||
"""
|
||||
|
||||
def get_queryset(self):
|
||||
return super(TokenManager, self).get_queryset().select_related('user')
|
||||
|
||||
class Token(MetaDataModel):
|
||||
"""Token model that holds all the tokens that are used for the API authentication.
|
||||
|
||||
A new token is generated every time when a new user is created. So there is no need for manual token creating. This is done through a signal :attr:`~apps.api.signals.create_user_token`
|
||||
|
||||
Attributes
|
||||
----------
|
||||
user : :class:`~django.contrib.auth.models.User`
|
||||
The user to which this token belongs too
|
||||
key : str
|
||||
The key value that is used for token lookups
|
||||
secret : str
|
||||
The secret that is used for encrypting/signing the API messages
|
||||
last_access : datetime
|
||||
The date and time when the token is last used (logged in)
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('token')
|
||||
verbose_name_plural = _('tokens')
|
||||
|
||||
user = models.OneToOneField(User, on_delete=models.CASCADE, help_text=_('Select the user for this token'))
|
||||
key = models.CharField(_('Key') , unique=True, default=get_random_key, max_length=16, help_text=_('The key for this token. This is used for Hawk verification.'))
|
||||
secret = encrypt(models.CharField(_('Secret') ,max_length=64, default=get_random_secret, help_text=_('The secret for this token. This is used for Hawk signing.')))
|
||||
last_access = models.DateTimeField(_('Last access'),auto_now_add=True, help_text=_('The date and time when this token is last used.'))
|
||||
|
||||
# Custom manager that will retrieve the related user table as well.
|
||||
objects = TokenManager()
|
||||
|
||||
def is_supertoken(self):
|
||||
"""Boolean check if the token is belonging to a user with super user rights. Then this token is a super token.
|
||||
|
||||
Returns:
|
||||
bool: Returns true when the token belongs to a super user.
|
||||
"""
|
||||
# TODO: Is it allowed to be a super user and researcher? Could give conflict of interests. With the API token you can read other researchers data...
|
||||
return self.user.is_superuser == True
|
||||
|
||||
is_supertoken.boolean = True
|
||||
is_supertoken.short_description = _('Super token')
|
||||
|
||||
def __str__(self):
|
||||
"""
|
||||
Print the full name of the researcher based on the first and last name fields of the User model.
|
||||
"""
|
||||
return '{} ({})'.format(self.key,self.user.get_full_name())
|
24
webservice/apps/api/signals.py
Normal file
24
webservice/apps/api/signals.py
Normal file
@@ -0,0 +1,24 @@
|
||||
from django.conf import settings
|
||||
from django.db.models.signals import post_save
|
||||
from django.dispatch import receiver
|
||||
|
||||
from .models import Token
|
||||
|
||||
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
|
||||
def create_user_token(sender, instance=None, created=False, **kwargs):
|
||||
"""
|
||||
When a new user is created, this signal will also create a new API token for this user. So every user will have an API token.
|
||||
|
||||
Arguments
|
||||
----------
|
||||
sender : sender
|
||||
The model that has triggered the signal
|
||||
|
||||
instance: :attr:`~django.contrib.auth.models.User`
|
||||
The newly created user model data
|
||||
|
||||
created : boolean
|
||||
Wether the object was created (True) or updated (False).
|
||||
"""
|
||||
if created:
|
||||
Token.objects.create(user=instance)
|
3
webservice/apps/api/tests.py
Normal file
3
webservice/apps/api/tests.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
71
webservice/apps/api/urls.py
Normal file
71
webservice/apps/api/urls.py
Normal file
@@ -0,0 +1,71 @@
|
||||
from django.urls import path, re_path, include
|
||||
|
||||
from rest_framework import permissions, routers
|
||||
|
||||
from drf_yasg2.views import get_schema_view
|
||||
from drf_yasg2 import openapi
|
||||
|
||||
from . import views
|
||||
|
||||
from apps.dropoff.api.views import DatadropViewSet
|
||||
from apps.invitation.api.views import InvitationViewSet
|
||||
from apps.researcher.api.views import ResearcherViewSet
|
||||
from apps.storage.api.views import StorageEngineViewSet, StorageLocationViewSet
|
||||
from apps.study.api.views import StudyViewSet
|
||||
from apps.virtual_machine.api.views import (VirtualMachineViewSet,
|
||||
VirtualMachineOperatingSystemViewSet,
|
||||
VirtualMachineProfileViewSet,
|
||||
VirtualMachineMemoryViewSet,
|
||||
VirtualMachineNetworkViewSet,
|
||||
VirtualMachineStorageViewSet,
|
||||
VirtualMachineGPUViewSet)
|
||||
|
||||
schema_view = get_schema_view(
|
||||
openapi.Info(
|
||||
title="Virtual Research Environment API",
|
||||
default_version='v1',
|
||||
description="Here you can see a list of API endpoints and actions that are available to communicate with the VRE API",
|
||||
terms_of_service="https://www.rug.nl",
|
||||
contact=openapi.Contact(email="vre_team@rug.nl"),
|
||||
license=openapi.License(name="MIT License"),
|
||||
),
|
||||
public=True,
|
||||
permission_classes=(permissions.AllowAny,),
|
||||
)
|
||||
|
||||
api_router_v1 = routers.DefaultRouter()
|
||||
|
||||
api_router_v1.register(r'researchers', ResearcherViewSet)
|
||||
|
||||
api_router_v1.register(r'studies', StudyViewSet)
|
||||
|
||||
api_router_v1.register(r'dropoffs', DatadropViewSet)
|
||||
|
||||
api_router_v1.register(r'invitations', InvitationViewSet)
|
||||
|
||||
api_router_v1.register(r'storageengines', StorageEngineViewSet)
|
||||
api_router_v1.register(r'storagelocations', StorageLocationViewSet)
|
||||
|
||||
# Order is important for virtual machines. Longest match first
|
||||
api_router_v1.register(r'virtualmachines/profiles', VirtualMachineProfileViewSet)
|
||||
api_router_v1.register(r'virtualmachines/storage', VirtualMachineStorageViewSet)
|
||||
api_router_v1.register(r'virtualmachines/memory', VirtualMachineMemoryViewSet)
|
||||
api_router_v1.register(r'virtualmachines/network', VirtualMachineNetworkViewSet)
|
||||
api_router_v1.register(r'virtualmachines/gpu', VirtualMachineGPUViewSet)
|
||||
api_router_v1.register(r'virtualmachines/os', VirtualMachineOperatingSystemViewSet)
|
||||
api_router_v1.register(r'virtualmachines', VirtualMachineViewSet)
|
||||
|
||||
# Main namespace for the API urls
|
||||
app_name = 'api'
|
||||
urlpatterns = [
|
||||
re_path(r'^swagger(?P<format>\.json|\.yaml)$', schema_view.without_ui(cache_timeout=0), name='schema-json'),
|
||||
path('swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
|
||||
path('redoc/', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
|
||||
|
||||
# Extra /api/info path for checking if the Hawk authentication is working.
|
||||
# Also this will give the full url to the OpenAPI documentation
|
||||
path('info/', views.Info.as_view(), name='info'),
|
||||
|
||||
# Add extra namespace for versioning the API
|
||||
path('v1/', include((api_router_v1.urls,'api'),namespace='v1')),
|
||||
]
|
52
webservice/apps/api/views.py
Normal file
52
webservice/apps/api/views.py
Normal file
@@ -0,0 +1,52 @@
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.decorators import schema
|
||||
|
||||
from django.urls import reverse
|
||||
|
||||
from lib.utils.general import get_ip_address
|
||||
|
||||
@schema(None)
|
||||
class Info(APIView):
|
||||
"""
|
||||
Show some API information. Also this can be used to check if the Hawk credentials are working.
|
||||
|
||||
Make sure your request does contain the header 'Content-Type': 'application/json'
|
||||
"""
|
||||
|
||||
def get(self, request, format=None):
|
||||
"""
|
||||
Default API get action will return the following information in a dict:
|
||||
|
||||
- Connected user
|
||||
- Used authentication scheme
|
||||
- The remote IP of the connection
|
||||
- The used content type
|
||||
- The full url to the API documentation (OpenAPI)
|
||||
- If a super token is used
|
||||
"""
|
||||
|
||||
data = {
|
||||
'type' : 'anonymous',
|
||||
'auth' : 'none',
|
||||
'remote_ip' : get_ip_address(request),
|
||||
'content_type' : request.content_type,
|
||||
'openapi' : request.build_absolute_uri(reverse('api:schema-redoc')),
|
||||
}
|
||||
|
||||
if request.user.is_authenticated:
|
||||
|
||||
data['user'] = request.user.username
|
||||
data['type'] = 'authenticated'
|
||||
data['auth'] = str(request.successful_authenticator)
|
||||
|
||||
if request.user.token.is_supertoken:
|
||||
data['type'] = 'supertoken'
|
||||
else:
|
||||
try:
|
||||
assert request.user.researcher
|
||||
data['type'] = 'researcher'
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
return Response(data)
|
Reference in New Issue
Block a user