Files

109 lines
3.4 KiB
Python

"""Тесты аутентификации."""
from datetime import datetime, timedelta, timezone
from uuid import uuid4
from app.models.enums import MessengerType, RoleCode
from app.models.user import LoginToken, Role, User, UserRole
def _seed_admin(db) -> User:
for code, name in [(RoleCode.ADMIN, "Админ"), (RoleCode.COORDINATOR, "Координатор")]:
if not db.query(Role).filter(Role.code == code).first():
db.add(Role(code=code, name=name))
db.commit()
admin = (
db.query(User)
.filter(User.messenger_type == MessengerType.TELEGRAM, User.messenger_id == "1")
.first()
)
if not admin:
admin = User(messenger_type=MessengerType.TELEGRAM, messenger_id="1", full_name="Админ")
db.add(admin)
db.flush()
role = db.query(Role).filter(Role.code == RoleCode.ADMIN).first()
if not db.query(UserRole).filter(
UserRole.user_id == admin.id, UserRole.role_id == role.id
).first():
db.add(UserRole(user_id=admin.id, role_id=role.id))
db.commit()
return admin
def _make_login_token(db, value: str) -> None:
db.add(
LoginToken(
id=str(uuid4()),
token=value,
expires_at=datetime.now(timezone.utc) + timedelta(minutes=30),
)
)
db.commit()
def test_login_flow(client, db):
_seed_admin(db)
_make_login_token(db, "tok-1")
# вход
r = client.post(
"/api/v1/auth/login",
json={"token": "tok-1", "messenger_type": "telegram", "messenger_id": "1"},
)
assert r.status_code == 200, r.text
data = r.json()
assert data["user"]["roles"][0]["code"] == "admin"
access, refresh = data["access_token"], data["refresh_token"]
# повторное использование ссылки
r2 = client.post(
"/api/v1/auth/login",
json={"token": "tok-1", "messenger_type": "telegram", "messenger_id": "1"},
)
assert r2.status_code == 409
# профиль
r3 = client.get("/api/v1/auth/me", headers={"Authorization": f"Bearer {access}"})
assert r3.status_code == 200
# выдача новой ссылки (как админ)
r4 = client.post(
"/api/v1/auth/login-token",
json={"ttl_minutes": 15},
headers={"Authorization": f"Bearer {access}"},
)
assert r4.status_code == 201, r4.text
assert "token=" in r4.json()["url"]
# refresh
r5 = client.post("/api/v1/auth/refresh", json={"refresh_token": refresh})
assert r5.status_code == 200, r5.text
new_access = r5.json()["access_token"]
# logout
r6 = client.post("/api/v1/auth/logout", headers={"Authorization": f"Bearer {new_access}"})
assert r6.status_code == 204
# после logout
r7 = client.get("/api/v1/auth/me", headers={"Authorization": f"Bearer {new_access}"})
assert r7.status_code == 401
def test_login_token_requires_role(client, db):
_seed_admin(db)
_make_login_token(db, "tok-2")
r = client.post(
"/api/v1/auth/login",
json={"token": "tok-2", "messenger_type": "telegram", "messenger_id": "999"},
)
assert r.status_code == 200
access = r.json()["access_token"]
# обычный пользователь без роли не может выдавать ссылки
r2 = client.post(
"/api/v1/auth/login-token",
json={"ttl_minutes": 15},
headers={"Authorization": f"Bearer {access}"},
)
assert r2.status_code == 403