add better member name validation, add debug user create endpoint

This commit is contained in:
sam 2024-03-22 21:37:09 +01:00
parent 1bd07dd771
commit afadffbaac
3 changed files with 66 additions and 14 deletions

View file

@ -8,9 +8,7 @@ from foxnouns.db import Member
from foxnouns.db.aio import async_session
from foxnouns.db.util import user_from_ref, is_self
from foxnouns.exceptions import NotFoundError, ErrorCode
from foxnouns.models import BasePatchModel
from foxnouns.models.member import FullMemberModel
from foxnouns.models.fields import ProfileField, FieldEntry, PronounEntry
from foxnouns.models.member import FullMemberModel, MemberPatchModel
from foxnouns.settings import BASE_DOMAIN
bp = Blueprint("members_v2", __name__)
@ -27,20 +25,19 @@ async def get_members(user_ref: str):
return [FullMemberModel.model_validate(m) for m in user.members]
class MemberPostData(BasePatchModel):
name: str = Field(min_length=1, max_length=100) # TODO: validate member names more
bio: str | None = Field(max_length=1024, default=None)
names: list[FieldEntry] = Field(default=[])
pronouns: list[PronounEntry] = Field(default=[])
fields: list[ProfileField] = Field(default=[])
class MemberCreateModel(MemberPatchModel):
name: str = Field(
min_length=1,
max_length=100,
pattern=r"^[^@\?!#\/\\\[\]\"\{\}'$%&()+<=>^|~`,\*]{1,100}$",
)
@bp.post("/api/v2/members", host=BASE_DOMAIN)
@require_auth(scope="member.create")
@validate_request(MemberPostData)
@validate_request(MemberCreateModel)
@validate_response(FullMemberModel, 200)
async def create_member(data: MemberPostData):
async def create_member(data: MemberCreateModel):
async with async_session() as session:
member = Member(
user_id=g.user.id,

View file

@ -6,7 +6,8 @@ from sqlalchemy import select
from foxnouns.auth import require_auth
from foxnouns.db import User
from foxnouns.db.aio import async_session
from foxnouns.db.util import user_from_ref, is_self
from foxnouns.db.snowflake import Snowflake
from foxnouns.db.util import user_from_ref, is_self, create_token, generate_token
from foxnouns.exceptions import NotFoundError, ErrorCode
from foxnouns.models import BasePatchModel
from foxnouns.models.user import UserModel, SelfUserModel, check_username
@ -48,6 +49,8 @@ class EditUserRequest(BasePatchModel):
@validate_request(EditUserRequest)
@validate_response(SelfUserModel, 200)
async def edit_user(data: EditUserRequest):
"""Updates the current user."""
async with async_session() as session:
user = await session.scalar(select(User).where(User.id == g.user.id))
@ -61,3 +64,32 @@ async def edit_user(data: EditUserRequest):
await session.commit()
return SelfUserModel.model_validate(user)
class DebugUserData(BasePatchModel):
username: str
class DebugUserResponse(SelfUserModel):
token: str
@bp.post("/api/v2/users/debug", host=BASE_DOMAIN)
@validate_request(DebugUserData)
@validate_response(DebugUserResponse, 200)
async def debug_create_user(data: DebugUserData):
"""Creates a user from just a username, and returns it along with a token.
FIXME: this must be removed **BEFORE** deploying to production (or even public testing)
"""
async with async_session() as session:
user = User(id=Snowflake.generate_int(), username=data.username)
await session.commit()
session.add(user)
token = await create_token(session, user, ["*"])
await session.commit()
await user.awaitable_attrs.members
user.token = generate_token(token)
return DebugUserResponse.model_validate(user)

View file

@ -1,7 +1,30 @@
from pydantic import Field
from pydantic import Field, field_validator
from . import BasePatchModel
from .fields import FieldEntry, ProfileField, PronounEntry
from .user import BaseMemberModel, BaseUserModel
class FullMemberModel(BaseMemberModel):
user: BaseUserModel
class MemberPatchModel(BasePatchModel):
name: str | None = Field(
min_length=1,
max_length=100,
default=None,
pattern=r"^[^@\?!#\/\\\[\]\"\{\}'$%&()+<=>^|~`,\*]{1,100}$",
)
bio: str | None = Field(max_length=1024, default=None)
names: list[FieldEntry] = Field(default=[])
pronouns: list[PronounEntry] = Field(default=[])
fields: list[ProfileField] = Field(default=[])
@field_validator("name")
@classmethod
def check_name(cls, value):
if value in [".", "..", "edit"]:
raise ValueError("Name is not allowed")
return value