You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
109 lines
3.8 KiB
109 lines
3.8 KiB
from django.urls import reverse |
|
from django.contrib.auth.models import User |
|
|
|
from rest_framework import exceptions |
|
from rest_framework.views import APIView |
|
from rest_framework.response import Response |
|
from rest_framework.decorators import schema |
|
from rest_framework.permissions import AllowAny |
|
|
|
from drf_yasg.utils import swagger_auto_schema |
|
from drf_yasg import openapi |
|
|
|
from .serializers import TokenSerializer, TokenLoginSerializer |
|
|
|
from lib.utils.general import get_ip_address |
|
|
|
|
|
class Login(APIView): |
|
"""This will let you login to the REST API. Login with your username and password, and get a key and a secret back that is used for further communication using HAWK signing of requests (https://github.com/hapijs/hawk). |
|
|
|
Args: |
|
username (string): The username to login with |
|
password (string): The password to for the login |
|
|
|
Raises: |
|
exceptions.AuthenticationFailed: An error will be given when the login failed |
|
|
|
Returns: |
|
Token: A token that holds a key and a secret to authenticate the other requests to this API |
|
""" |
|
|
|
authentication_classes = [] |
|
permission_classes = [AllowAny] |
|
|
|
token_response = openapi.Response('response description', TokenSerializer) |
|
|
|
@swagger_auto_schema(request_body=TokenLoginSerializer, responses={200: token_response}, security=authentication_classes) |
|
def post(self, request, format=None): |
|
login_data = TokenLoginSerializer(data=request.data) |
|
|
|
if not login_data.is_valid(): |
|
raise exceptions.AuthenticationFailed(f'Invalid form data posted') |
|
|
|
username = login_data.validated_data['username'] |
|
password = login_data.validated_data['password'] |
|
|
|
try: |
|
user = User.objects.get(username=username) |
|
if user.check_password(password): |
|
# Refresh tokens....? |
|
# user.token.key = generate_encryption_key(8) |
|
# user.token.secret = generate_encryption_key(32) |
|
# user.token.save() |
|
|
|
# Return the key and secret to use with all the other REST calls |
|
return Response({'key': user.token.key, 'secret': user.token.secret}) |
|
else: |
|
raise exceptions.AuthenticationFailed(f'Login failed for user {username}') |
|
|
|
except User.DoesNotExist: |
|
raise exceptions.AuthenticationFailed(f'Login failed for user {username}') |
|
|
|
|
|
@schema(None) |
|
class Info(APIView): |
|
""" |
|
Show some API information. Also this can be used to check if the Hawk credentials are working. |
|
|
|
If you used your Hawk credentials, you should see here your account information. |
|
""" |
|
|
|
permission_classes = [AllowAny] |
|
|
|
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'] = str(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)
|
|
|