add better member name validation, add debug user create endpoint
This commit is contained in:
parent
1bd07dd771
commit
afadffbaac
3 changed files with 66 additions and 14 deletions
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue