74 lines
2.6 KiB
Python
74 lines
2.6 KiB
Python
from django.utils.translation import gettext_lazy as _
|
|
from rest_framework.status import HTTP_200_OK
|
|
|
|
from rest_framework.views import APIView
|
|
from rest_framework.response import Response
|
|
from rest_framework import status
|
|
from rest_framework.authtoken.models import Token
|
|
|
|
from monerorpc.authproxy import JSONRPCException
|
|
|
|
from .models import Address, Challenge
|
|
from .forms import SimpleSignUpForm, SimpleLoginForm
|
|
from .utils import verify_signature
|
|
from .mixins import CreateUserMixin, CreateChallengeMixin
|
|
|
|
|
|
class CryptoLockAPITokenLoginView(CreateChallengeMixin, APIView):
|
|
"""Endpoint to login the user with cryptocurrency wallet address.
|
|
|
|
Using the default token backend.
|
|
"""
|
|
|
|
http_method_names = ["get", "post"]
|
|
|
|
def post(self, request, format=None):
|
|
"""Authenticates the user using the provided signature."""
|
|
form = SimpleLoginForm(request, request.data)
|
|
if not form.is_valid():
|
|
return Response(form.errors, status=status.HTTP_400_BAD_REQUEST)
|
|
|
|
challenge = form.cleaned_data["challenge"]
|
|
Challenge.objects.invalidate(challenge)
|
|
Challenge.objects.clean_expired()
|
|
|
|
token = Token.objects.create(user=form.user_cache)
|
|
return Response({"token": token.key}, status=HTTP_200_OK)
|
|
|
|
|
|
class CryptoLockAPISignUpView(CreateUserMixin, CreateChallengeMixin, APIView):
|
|
"""Endpoint to create a new user using cryptocurrency wallet address."""
|
|
|
|
http_method_names = ["get", "post"]
|
|
|
|
def post(self, request, format=None):
|
|
"""Verifies the signature and creates a new user account."""
|
|
form = SimpleSignUpForm(request, request.data)
|
|
if not form.is_valid():
|
|
return Response(form.errors, status=status.HTTP_400_BAD_REQUEST)
|
|
|
|
username = form.cleaned_data["username"]
|
|
address = form.cleaned_data["address"]
|
|
challenge = form.cleaned_data["challenge"]
|
|
signature = form.cleaned_data["signature"]
|
|
network = [n[1] for n in Address.NETWORKS if n[0] == form.network][0]
|
|
|
|
try:
|
|
valid_sig = verify_signature(
|
|
network, address, challenge, signature, self.request
|
|
)
|
|
except JSONRPCException:
|
|
return Response(
|
|
{"__all__": [_("Error connecting to Monero daemon")]},
|
|
status=status.HTTP_503_SERVICE_UNAVAILABLE,
|
|
)
|
|
|
|
if valid_sig:
|
|
self.create_user(username, challenge, address, form.network)
|
|
return Response({}, status=status.HTTP_201_CREATED)
|
|
else:
|
|
return Response(
|
|
{"signature": [_("Invalid signature")]},
|
|
status=status.HTTP_400_BAD_REQUEST,
|
|
)
|