Skip to content

Commit 06cde38

Browse files
committed
add support for /api/profile
1 parent 9e684aa commit 06cde38

File tree

2 files changed

+25
-7
lines changed

2 files changed

+25
-7
lines changed

nightwatch/auth/__init__.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,26 @@ def __init__(self) -> None:
3535
app: AuthenticationServer = AuthenticationServer()
3636

3737
# Routing
38+
@app.post(path = "/api/profile")
39+
async def route_api_profile(payload: models.BaseTokenModel) -> JSONResponse:
40+
"""Fetches a users profile. This method is POST to prevent query strings with account tokens
41+
from being logged via uvicorn or whatever HTTP server is running at the moment."""
42+
response: dict | None = app.db.tokens.find_one(filter = {"token": payload.token.get_secret_value()})
43+
if response is None:
44+
return JSONResponse(
45+
content = {"code": 403, "data": "Invalid account token."},
46+
status_code = 403
47+
)
48+
49+
return JSONResponse(content = {"code": 200, "data": {"username": response["username"]}})
50+
3851
@app.post(path = "/api/authorize")
3952
async def route_api_authorize(payload: models.AuthorizeModel) -> JSONResponse:
53+
"""Authorizes a new external Nightwatch server with a burner account token."""
4054
response: dict | None = app.db.users.find_one(filter = {"token": payload.token.get_secret_value()})
4155
if response is None:
4256
return JSONResponse(
43-
content = {"code": 403, "data": "Invalid account token."},
57+
content = {"comde": 403, "data": "Invalid account token."},
4458
status_code = 403
4559
)
4660

@@ -57,6 +71,7 @@ async def route_api_authorize(payload: models.AuthorizeModel) -> JSONResponse:
5771

5872
@app.post(path = "/api/signup")
5973
async def route_api_signup(payload: models.BaseAuthenticationModel) -> JSONResponse:
74+
"""Creates a new account and returns its token given a basic username and password."""
6075
response: dict | None = app.db.users.find_one(filter = {"username": payload.username})
6176
if response is not None:
6277
return JSONResponse(
@@ -75,14 +90,14 @@ async def route_api_signup(payload: models.BaseAuthenticationModel) -> JSONRespo
7590

7691
@app.post(path = "/api/login")
7792
async def route_api_login(payload: models.BaseAuthenticationModel) -> JSONResponse:
93+
"""Logs in and returns the master token for a given account."""
7894
response: dict | None = app.db.users.find_one(filter = {"username": payload.username})
7995
if response is None:
8096
return JSONResponse(
8197
content = {"code": 404, "data": "No account with that username exists."},
8298
status_code = 404
8399
)
84100

85-
# Check password
86101
try:
87102
app.hasher.verify(hash = response["password"], password = payload.password.get_secret_value())
88103
if app.hasher.check_needs_rehash(hash = response["password"]):

nightwatch/auth/models.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@
44
from typing import Annotated
55
from pydantic import BaseModel, HttpUrl, SecretStr, StringConstraints
66

7-
# Models
7+
# Base models
8+
class BaseTokenModel(BaseModel):
9+
10+
# Force token length to 64 characters thanks to 32 byte secret
11+
token: Annotated[SecretStr, StringConstraints(min_length = 64, max_length = 64)]
12+
813
class BaseAuthenticationModel(BaseModel):
914
username: Annotated[str, StringConstraints(min_length = 4, max_length = 36)]
1015
password: Annotated[SecretStr, StringConstraints(min_length = 8, max_length = 512)]
1116

12-
class AuthorizeModel(BaseModel):
17+
# Token-based models
18+
class AuthorizeModel(BaseTokenModel):
1319
server: HttpUrl
14-
15-
# Force token length to 64 characters thanks to 32 byte secret
16-
token: Annotated[SecretStr, StringConstraints(min_length = 64, max_length = 64)]

0 commit comments

Comments
 (0)