sts-sponsors team mailing list archive
-
sts-sponsors team
-
Mailing list archive
-
Message #06744
[Merge] maas-site-manager:token-implementations into maas-site-manager:main
Jack Lloyd-Walters has proposed merging maas-site-manager:token-implementations into maas-site-manager:main.
Commit message:
token implementation changes
Requested reviews:
MAAS Committers (maas-committers)
For more details, see:
https://code.launchpad.net/~maas-committers/maas-site-manager/+git/site-manager/+merge/440330
add test for iso 8601 duration string (extendable to other supported formats in future)
add token field "created", modify token field "expiration" to "expired"
--
Your team MAAS Committers is requested to review the proposed merge of maas-site-manager:token-implementations into maas-site-manager:main.
diff --git a/Makefile b/Makefile
index e73f7f8..ad5452d 100644
--- a/Makefile
+++ b/Makefile
@@ -61,6 +61,10 @@ ci-backend-test:
env -C backend tox -e test -- --junit-xml=../junit-backend.xml
.PHONY: ci-test
+ci-backend-format:
+ env -C backend tox -e format
+.PHONY: ci-backend-format
+
# Frontend CI targets
diff --git a/backend/msm/db/_tables.py b/backend/msm/db/_tables.py
index 649a58b..14dddc4 100644
--- a/backend/msm/db/_tables.py
+++ b/backend/msm/db/_tables.py
@@ -56,7 +56,8 @@ Token = Table(
Column(
"value", UUID(as_uuid=True), nullable=False, index=True, default=uuid4
),
- Column("expiration", DateTime, nullable=False),
+ Column("expired", DateTime, nullable=False),
+ Column("created", DateTime, nullable=False),
)
diff --git a/backend/msm/db/queries.py b/backend/msm/db/queries.py
index 3aa13d4..eba2e60 100644
--- a/backend/msm/db/queries.py
+++ b/backend/msm/db/queries.py
@@ -154,7 +154,8 @@ async def get_tokens(
Token.c.id,
Token.c.site_id,
Token.c.value,
- Token.c.expiration,
+ Token.c.expired,
+ Token.c.created,
)
.select_from(Token)
.offset(offset)
@@ -166,14 +167,16 @@ async def get_tokens(
async def create_tokens(
session: AsyncSession, duration: timedelta, count: int = 1
) -> tuple[datetime, list[UUID]]:
- expiration = datetime.utcnow() + duration
+ created = datetime.utcnow()
+ expired = datetime.utcnow() + duration
result = await session.execute(
Token.insert().returning(Token.c.value),
[
{
- "expiration": expiration,
+ "expired": expired,
+ "created": created,
}
for _ in range(count)
],
)
- return expiration, [row[0] for row in result]
+ return expired, [row[0] for row in result]
diff --git a/backend/msm/schema.py b/backend/msm/schema.py
index 96312b2..d57933f 100644
--- a/backend/msm/schema.py
+++ b/backend/msm/schema.py
@@ -112,7 +112,8 @@ class CreateToken(BaseModel):
site_id: int | None
value: UUID
- expiration: datetime
+ expired: datetime
+ created: datetime
class Token(CreateToken):
@@ -140,5 +141,5 @@ class CreateTokensRequest(BaseModel):
class CreateTokensResponse(BaseModel):
"""List of created tokens, along with their duration."""
- expiration: datetime
+ expired: datetime
tokens: list[UUID]
diff --git a/backend/msm/user_api/_base.py b/backend/msm/user_api/_base.py
index 8a56be1..a3797a2 100644
--- a/backend/msm/user_api/_base.py
+++ b/backend/msm/user_api/_base.py
@@ -85,9 +85,9 @@ async def tokens_post(
Create one or more tokens.
Token duration (TTL) is expressed in seconds.
"""
- expiration, tokens = await queries.create_tokens(
+ expired, tokens = await queries.create_tokens(
session,
create_request.duration,
count=create_request.count,
)
- return schema.CreateTokensResponse(expiration=expiration, tokens=tokens)
+ return schema.CreateTokensResponse(expired=expired, tokens=tokens)
diff --git a/backend/msm/user_api/tests/test_handlers.py b/backend/msm/user_api/tests/test_handlers.py
index 0784840..c7a35ab 100644
--- a/backend/msm/user_api/tests/test_handlers.py
+++ b/backend/msm/user_api/tests/test_handlers.py
@@ -2,6 +2,8 @@ from datetime import (
datetime,
timedelta,
)
+from typing import Any
+from uuid import uuid4
# from fastapi.testclient import TestClient
from httpx import AsyncClient
@@ -10,6 +12,29 @@ import pytest
from ...testing.db import Fixture
+def datetime_format(time: datetime, time_format: str) -> str:
+ # check if the format matches any pre-defined forms
+ match time_format.lower().split()[0]:
+ case "ctime":
+ return time.ctime()
+ case "float":
+ return time.timestamp()
+ case "iso":
+ return time.isoformat()
+ case "ordinal":
+ return time.toordinal()
+ # Otherwise, attempr to parse with the format
+ return time.strftime(time_format)
+
+def duration_format(time: timedelta, time_format: str) -> str:
+ # check if the format matches any pre-defined forms
+ match time_format.lower().split()[0]:
+ case "float":
+ return str(int(time.total_seconds()))
+ case "iso":
+ d, s = time.days, time.seconds
+ return f"P{d//365}Y0M{d%365}DT{s//60//60}H{s//60%60}M{s%60}S"
+
@pytest.mark.asyncio
async def test_root(user_app_client: AsyncClient) -> None:
response = await user_app_client.get("/")
@@ -68,15 +93,18 @@ async def test_list_sites(
@pytest.mark.asyncio
-async def test_create_token(user_app_client: AsyncClient) -> None:
- seconds = 100
+@pytest.mark.parametrize("time_format", ["ISO 8601", "Float"])
+async def test_token_time_format(time_format: str, user_app_client: AsyncClient) -> None:
+ expiry = timedelta(seconds=100)
+ formatted_expiry = duration_format(expiry, time_format)
+
response = await user_app_client.post(
- "/tokens", json={"count": 5, "duration": seconds}
+ "/tokens", json={"count": 5, "duration": formatted_expiry}
)
assert response.status_code == 200
result = response.json()
- assert datetime.fromisoformat(result["expiration"]) < (
- datetime.utcnow() + timedelta(seconds=seconds)
+ assert datetime.fromisoformat(result["expired"]) < (
+ datetime.utcnow() + timedelta(seconds=formatted_expiry)
)
assert len(result["tokens"]) == 5
@@ -90,13 +118,15 @@ async def test_list_tokens(
"id": 1,
"site_id": None,
"value": "c54e5ba6-d214-40dd-b601-01ebb1019c07",
- "expiration": datetime.fromisoformat("2023-02-23T09:09:51.103703"),
+ "expired": datetime.fromisoformat("2023-02-23T09:09:51.103703"),
+ "created": datetime.fromisoformat("2023-02-22T03:14:15.926535")
},
{
"id": 2,
"site_id": None,
"value": "b67c449e-fcf6-4014-887d-909859f9fb70",
- "expiration": datetime.fromisoformat("2023-02-23T11:28:54.382456"),
+ "expired": datetime.fromisoformat("2023-02-23T11:28:54.382456"),
+ "created": datetime.fromisoformat("2023-02-22T03:14:15.926535")
},
]
await fixture.create("tokens", tokens)
diff --git a/test-data/import.sql b/test-data/import.sql
index a7198af..9c3ec1d 100644
--- a/test-data/import.sql
+++ b/test-data/import.sql
@@ -4,7 +4,7 @@ DELIMITER ','
QUOTE '"'
CSV HEADER;
-COPY tokens(site_id, value, expiration)
+COPY tokens(site_id, value, expired, created)
FROM '/tokens.csv'
DELIMITER ','
QUOTE '"'
diff --git a/test-data/tokens.csv b/test-data/tokens.csv
index 0a4848b..c77e2a2 100644
--- a/test-data/tokens.csv
+++ b/test-data/tokens.csv
@@ -1,12 +1,12 @@
-site_id,value,expiration
-1,c96abba0-9962-41e5-9f40-6e2b55578c06,2023-03-01 00:00:00
-2,8960d8a1-7c5e-4331-8f58-591cf145a313,2023-03-01 00:00:00
-3,dffa13fe-d2c5-43b4-81e1-1efde6eeec76,2023-03-01 00:00:00
-4,a31a7408-09ee-4403-98c1-5c59ca3534c2,2023-03-01 00:00:00
-5,4d015359-3093-4216-ac87-6dfa29d0d6c5,2023-03-01 00:00:00
-6,9f404751-a17b-456c-8fa9-46b7258cb471,2023-03-01 00:00:00
-7,269773b7-b47d-46e8-9825-eb25eda99771,2023-03-01 00:00:00
-8,fce21bd4-3a92-42af-adb4-6b46dc0aefd4,2023-03-01 00:00:00
-,0e846493-fde9-4d15-844c-2ca0341d1e84,2024-01-01 00:00:00
-,e15a7d3c-9df8-40c7-b81b-ed4796e777bc,2024-01-01 00:00:00
-,87a62d9a-7645-43b5-9dd4-eaf53e768c4a,2024-01-01 00:00:00
+site_id,value,expired,created
+1,c96abba0-9962-41e5-9f40-6e2b55578c06,2023-03-01 00:00:00,2023-02-28 00:00:00
+2,8960d8a1-7c5e-4331-8f58-591cf145a313,2023-03-01 00:00:00,2023-02-28 00:00:00
+3,dffa13fe-d2c5-43b4-81e1-1efde6eeec76,2023-03-01 00:00:00,2023-02-28 00:00:00
+4,a31a7408-09ee-4403-98c1-5c59ca3534c2,2023-03-01 00:00:00,2023-02-28 00:00:00
+5,4d015359-3093-4216-ac87-6dfa29d0d6c5,2023-03-01 00:00:00,2023-02-28 00:00:00
+6,9f404751-a17b-456c-8fa9-46b7258cb471,2023-03-01 00:00:00,2023-02-28 00:00:00
+7,269773b7-b47d-46e8-9825-eb25eda99771,2023-03-01 00:00:00,2023-02-28 00:00:00
+8,fce21bd4-3a92-42af-adb4-6b46dc0aefd4,2023-03-01 00:00:00,2023-02-28 00:00:00
+,0e846493-fde9-4d15-844c-2ca0341d1e84,2024-01-01 00:00:00,2023-02-28 00:00:00
+,e15a7d3c-9df8-40c7-b81b-ed4796e777bc,2024-01-01 00:00:00,2023-02-28 00:00:00
+,87a62d9a-7645-43b5-9dd4-eaf53e768c4a,2024-01-01 00:00:00,2023-02-28 00:00:00
Follow ups