-
Notifications
You must be signed in to change notification settings - Fork 4
New flow changes #100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
New flow changes #100
Changes from all commits
fbcb650
f87926c
2acf6c8
5f81d5f
96cf76c
3b21605
89c4490
4c0a8c1
b853163
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,15 +5,15 @@ meta { | |
} | ||
|
||
post { | ||
url: {{baseUrl}}/accounts/register | ||
url: http://localhost:8000/accounts/register | ||
body: json | ||
auth: none | ||
} | ||
|
||
body:json { | ||
{ | ||
"unique_identifier": "myname", | ||
"username": "My Name", | ||
"username": "Name", | ||
"password": "qweasd123", | ||
"email": "[email protected]" | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,14 +5,14 @@ meta { | |
} | ||
|
||
post { | ||
url: {{baseUrl}}/accounts/login-credentials | ||
url: http://127.0.0.1:8000/accounts/login-credentials | ||
body: json | ||
auth: none | ||
} | ||
|
||
body:json { | ||
{ | ||
"email": "[email protected]", | ||
"password": "admin" | ||
"email": "[email protected]", | ||
"password": "bob" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
meta { | ||
name: check token | ||
type: http | ||
seq: 2 | ||
} | ||
|
||
post { | ||
url: http://127.0.0.1:8000/accounts/check-SHA512-for-account/ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. baseUrl |
||
body: json | ||
auth: none | ||
} | ||
|
||
body:json { | ||
{ | ||
"sha512_token" : "AA", | ||
"unique_identifier" : "bob" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
meta { | ||
name: SHAChecks | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. don't commit bruno files. It was good before we had any auto documentation on the endpoints but now it will just confuse other developers. I'd say you can even remove the whole |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
meta { | ||
name: register token | ||
type: http | ||
seq: 1 | ||
} | ||
|
||
post { | ||
url: http://127.0.0.1:8000/accounts/register-SHA512-for-account/ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. baseUrl |
||
body: json | ||
auth: inherit | ||
} | ||
|
||
headers { | ||
Authorization: Token 894bf0bfd6ef6c05feb6a3447dfc2f3a2fb0147cd7da498d2843021794297cf0 | ||
} | ||
|
||
body:json { | ||
{ | ||
"sha512_token" : "AA" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
meta { | ||
name: Get charracter token | ||
type: http | ||
seq: 7 | ||
} | ||
|
||
post { | ||
url: http://127.0.0.1:8000/persistence/characters/GenForkToken | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. baseUrl |
||
body: json | ||
auth: none | ||
} | ||
|
||
headers { | ||
Authorization: Token 7cac756254c5574dbdd69e2129394337158b7929446576ede3fb2a43e179540c | ||
} | ||
|
||
body:json { | ||
{ | ||
"fork_compatibility": "UnityStationDevelop" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,11 +5,11 @@ meta { | |
} | ||
|
||
get { | ||
url: {{baseUrl}}/persistence/characters | ||
url: http://127.0.0.1:8000/persistence/characters | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. baseUrl |
||
body: none | ||
auth: none | ||
} | ||
|
||
headers { | ||
Authorization: Token 4963885504960842e61c6cadb4a9df05647e2c7bf1cfe08ea8cff57ab37058ac | ||
Authorization: Token a74030290fa0dbc6d85f2e8dd885bbb76d76d9dedfe7c82bc60d72e8bd09210c | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
meta { | ||
name: GetCompatible Token | ||
type: http | ||
seq: 8 | ||
} | ||
|
||
get { | ||
url: http://localhost:8000/persistence/characters/compatibleToken?character_sheet_version=1.0.0 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. baseUrl |
||
body: none | ||
auth: none | ||
} | ||
|
||
params:query { | ||
character_sheet_version: 1.0.0 | ||
} | ||
|
||
headers { | ||
X-Character-Token: eyJzZXJ2ZXJfaWQiOiJVbml0eVN0YXRpb25EZXZlbG9wIiwidXVpZCI6ImJvYiIsIm5vbmNlIjoiMTFkMTI3NzdhNTZlNWViZCJ9:1ukm1R:-l14SCkeDVJHIx9_J8fAUeQDIoHCcDavviBmqtpqcBo | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
meta { | ||
name: admin | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,10 +2,12 @@ | |
from knox import views as knox_views | ||
|
||
from .views import ( | ||
CheckSHA512ForAccountView, | ||
ConfirmAccountView, | ||
LoginWithCredentialsView, | ||
LoginWithTokenView, | ||
RegisterAccountView, | ||
RegisterSHA512ForAccount, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think Snep said SHA512 wasn't good enough for us. I would wait for his input here |
||
RequestPasswordResetView, | ||
RequestVerificationTokenView, | ||
ResendAccountConfirmationView, | ||
|
@@ -45,4 +47,6 @@ | |
name="reset-password-token", | ||
), | ||
path("reset-password/", RequestPasswordResetView.as_view(), name="reset-password"), | ||
path("register-SHA512-for-account/", RegisterSHA512ForAccount.as_view(), name="register-SHA512-for-account"), | ||
path("check-SHA512-for-account/", CheckSHA512ForAccountView.as_view(), name="check-SHA512-for-account"), | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,19 @@ | ||
import logging | ||
import secrets | ||
|
||
from datetime import timedelta | ||
from urllib.parse import urljoin | ||
from uuid import uuid4 | ||
|
||
from django.conf import settings | ||
from django.contrib.auth import authenticate | ||
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied | ||
from django.core.management import BaseCommand | ||
from django.utils import timezone | ||
from drf_spectacular.utils import extend_schema | ||
from knox.models import AuthToken | ||
from knox.views import LoginView as KnoxLoginView | ||
from rest_framework import status | ||
from rest_framework import serializers, status | ||
from rest_framework.generics import GenericAPIView | ||
from rest_framework.permissions import AllowAny | ||
from rest_framework.response import Response | ||
|
@@ -20,7 +23,7 @@ | |
from commons.error_response import ErrorResponse | ||
from commons.mail_wrapper import send_email_with_template | ||
|
||
from ..models import Account, AccountConfirmation, PasswordResetRequestModel | ||
from ..models import Account, AccountConfirmation, PasswordResetRequestModel, SHA512Token | ||
from .serializers import ( | ||
ConfirmAccountSerializer, | ||
EmailSerializer, | ||
|
@@ -369,3 +372,83 @@ def post(self, request, *args, **kwargs): | |
return Response(status=status.HTTP_200_OK) | ||
else: | ||
return ErrorResponse(serializer.errors, status.HTTP_400_BAD_REQUEST) | ||
|
||
|
||
class RegisterSHA512ForAccount(APIView): | ||
class InputSerializer(serializers.Serializer): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. don't create serializers inside the view class. There is a serializers file for this purpose. Everything on their own file There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also the name for this serializer sucks. Follow the convention of the other serializers in the project |
||
sha512_token = serializers.CharField(max_length=128) | ||
|
||
def post(self, request, *args, **kwargs): | ||
user: Account = request.user | ||
if not request.auth: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. since this view doesn't override the |
||
return ErrorResponse("Invalid or missing token.", status.HTTP_401_UNAUTHORIZED) | ||
|
||
if not user.is_confirmed: | ||
return ErrorResponse( | ||
"You must confirm your email before performing this action.", | ||
status.HTTP_403_FORBIDDEN, | ||
) | ||
|
||
serializer = self.InputSerializer(data=request.data) | ||
if not serializer.is_valid(): | ||
return ErrorResponse(serializer.errors, status.HTTP_400_BAD_REQUEST) | ||
|
||
SHA512Token.objects.create(account=user, token=serializer.validated_data["sha512_token"]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. wait, who creates the token? We can receive whatever here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeha, Token is made by server and hub, so theoretically it can be anything, As long as they both agree |
||
|
||
return Response( | ||
{"detail": "SHA512 token registered successfully."}, | ||
status=status.HTTP_200_OK, | ||
) | ||
|
||
|
||
class CheckSHA512ForAccountView(APIView): | ||
""" | ||
Given an account unique_identifier and a SHA512 token, | ||
checks if the token is associated with that account. | ||
Deletes the token after checking. | ||
**Public endpoint** | ||
""" | ||
|
||
permission_classes = (AllowAny,) | ||
|
||
class InputSerializer(serializers.Serializer): | ||
unique_identifier = serializers.CharField(max_length=28) | ||
sha512_token = serializers.CharField(max_length=128) | ||
|
||
def post(self, request, *args, **kwargs): | ||
serializer = self.InputSerializer(data=request.data) | ||
if not serializer.is_valid(): | ||
return ErrorResponse(serializer.errors, status.HTTP_400_BAD_REQUEST) | ||
|
||
unique_id = serializer.validated_data["unique_identifier"] | ||
token = serializer.validated_data["sha512_token"] | ||
|
||
try: | ||
account = Account.objects.get(unique_identifier=unique_id) | ||
except Account.DoesNotExist: | ||
return Response({"exists": False}, status=status.HTTP_200_OK) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. even tho a 404 here would explain everything already, I think it is more sensible to respond with 401 unaunthenticated and the message |
||
|
||
valid_cutoff = timezone.now() - timedelta(minutes=3) | ||
matching_token = SHA512Token.objects.filter( | ||
account=account, | ||
token=token, | ||
created_at__gte=valid_cutoff, | ||
).first() | ||
|
||
if matching_token: | ||
matching_token.delete() | ||
return Response( | ||
{"exists": True, "account": PublicAccountDataSerializer(account, context={"request": request}).data}, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. just return 200 here. If you got a 200 it means everything is fine, no need for the |
||
status=status.HTTP_200_OK, | ||
) | ||
else: | ||
return Response({"exists": False}, status=status.HTTP_200_OK) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. return 401 here, unauthenticated. You can add the message |
||
|
||
|
||
class Command(BaseCommand): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove, this doesn't go here |
||
help = "Delete expired SHA512 tokens (older than 3 minutes)" | ||
|
||
def handle(self, *args, **kwargs): | ||
cutoff = timezone.now() - timedelta(minutes=3) | ||
deleted, _ = SHA512Token.objects.filter(created_at__lt=cutoff).delete() | ||
self.stdout.write(f"Deleted {deleted} expired SHA512 tokens.") |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Generated by Django 3.2.25 on 2025-08-03 16:41 | ||
|
||
from django.conf import settings | ||
from django.db import migrations, models | ||
import django.db.models.deletion | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
('accounts', '0004_alter_account_username'), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name='SHA512Token', | ||
fields=[ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. are these all the fields that we migrate? or are there more? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. idk,This is automatically generated code |
||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('token', models.CharField(max_length=128)), | ||
('created_at', models.DateTimeField(auto_now_add=True)), | ||
('account', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='sha512_tokens', to=settings.AUTH_USER_MODEL)), | ||
], | ||
), | ||
] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
needs to use {{baseUrl}}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doeesn't seem to pull it automatically though, It's better just to use the One that is going to be most often used with in development?