diff --git a/API.md b/API.md index 271e6ea..17f9dde 100644 --- a/API.md +++ b/API.md @@ -3,4 +3,7 @@ ## Disclaimer This is a technical page that only describes the API's functionality. For information about licensing, -setup and credits, please check out the README.md file included with the project. \ No newline at end of file +setup and credits, please check out the README.md file included with the project. + +__Note__: Rate limiting is performed on a per-IP basis. All endpoints report their limits so that client can act +accordingly \ No newline at end of file diff --git a/endpoints/media.py b/endpoints/media.py index 40e2e24..a6c37a5 100644 --- a/endpoints/media.py +++ b/endpoints/media.py @@ -24,7 +24,8 @@ router = FastAPI() @LIMITER.limit("2/second") async def get_media(request: Request, media_id: str, _user: UserModel = Depends(MANAGER)): """ - Gets a media object by its ID + Gets a media object by its ID. Endpoint is + limited to 2 hits per second """ if (m := await Media.select(Media.media_id).where(Media.media_id == media_id).first()) is None: @@ -58,7 +59,8 @@ async def report_media(request: Request, media_id: str, _user: UserModel = Depen """ Reports a piece of media by its ID. This creates a report that can be seen by admins, which can - then decide what to do + then decide what to do. Endpoint is limited to 2 + hits per second """ if (m := await Media.select(Media.media_id).where(Media.media_id == media_id).first()) is None: diff --git a/endpoints/users.py b/endpoints/users.py index ca745ad..84f14cf 100644 --- a/endpoints/users.py +++ b/endpoints/users.py @@ -221,7 +221,8 @@ async def get_self(request: Request, user: UserModel = Depends(UNVERIFIED_MANAGE @LIMITER.limit("30/second") async def get_user_by_name(request: Request, username: str, _auth: UserModel = Depends(MANAGER)): """ - Fetches a single user by its public username + Fetches a single user by its public username. + Endpoint is limited to 30 hits per second """ if not (user := await get_user_by_username(username)): @@ -259,7 +260,8 @@ async def get_user_by_name(request: Request, username: str, _auth: UserModel = D @LIMITER.limit("30/second") async def get_user_by_public_id(request: Request, public_id: str, _auth: UserModel = Depends(MANAGER)): """ - Fetches a single user by its public ID + Fetches a single user by its public ID. + Endpoint is limited to 30 hits per second """ if not (user := await get_user_by_id(UUID(public_id))): @@ -343,7 +345,9 @@ async def delete(request: Request, response: Response, user: UserModel = Depends """ Sets the user's deleted flag in the database, without actually deleting the associated - data + data. Note that calling this method will also + log you out, preventing any further action permanently. + Endpoint is limited to 1 hit per minute """ await User.update({User.deleted: True}).where(User.public_id == user.public_id) @@ -375,7 +379,8 @@ async def verify_email( user: UserModel = Depends(UNVERIFIED_MANAGER), ): """ - Verifies a user's email address + Verifies a user's email address. Endpoint is + limited to 3 hits per second """ if not ( @@ -419,7 +424,8 @@ async def reset_password( user: UserModel = Depends(UNVERIFIED_MANAGER), ): """ - Modifies a user's password + Modifies a user's password. Endpoint is limited + to 3 hits per second """ if not ( @@ -466,7 +472,8 @@ async def change_email( user: UserModel = Depends(UNVERIFIED_MANAGER), ): """ - Modifies a user's email + Modifies a user's email address. + Endpoint is limited to 3 hits per second """ if not ( @@ -514,7 +521,8 @@ async def change_email( @LIMITER.limit("6/minute") async def resend_email(request: Request, user: UserModel = Depends(UNVERIFIED_MANAGER)): """ - Resends the verification email to the user if the previous has expired + Resends the verification email to the user if the previous has expired. + Endpoint is limited to 6 hits per minute """ if user.email_verified: @@ -591,7 +599,8 @@ async def signup( locale: str = "en_US", ): """ - Endpoint used to create new users + Registers a new user. Endpoint is limited to 2 hits + per minute """ if request.cookies.get(SESSION_COOKIE_NAME): @@ -705,6 +714,7 @@ async def validate_profile_picture( 415: {"model": MediaTypeNotAcceptable}, }, ) +@LIMITER.limit("6/minute") async def update_user( request: Request, user: UserModel = Depends(UNVERIFIED_MANAGER), @@ -726,7 +736,7 @@ async def update_user( A similar procedure is required for resetting the password, requiring an email confirmation before said change is registered. Please also note that changing the email address undoes the account's email verification, which needs to be carried out again. When delete equals True, only the bio and profile_picture fields are considered - since they're the only ones that can be set to a null value + since they're the only ones that can be set to a null value. Endpoint is limited to 6 hits per minute """ if not delete and not any((first_name, last_name, username, profile_picture, email_address, bio, password)):