6262 __config = json .load (__f )
6363
6464del __p , __f # micro-opt, don't keep unneeded variables in-ram
65+ HAS_BUNNYCDN = bool (__config ["bunnycdn" ]["token" ])
6566
6667
6768def generate_paste_id (n : int = 3 ):
@@ -134,6 +135,15 @@ async def find_discord_tokens(request: MystbinRequest, pastes: payloads.PastePut
134135 return tokens or None
135136
136137
138+ def respect_dnt (request : MystbinRequest ):
139+ if request .headers .get ("DNT" , None ) == "1" :
140+ return "DNT"
141+
142+ if request .app .config ["paste" ]["log_ip" ]:
143+ return request .headers .get ("X-Forwarded-For" , request .client .host )
144+
145+ return None
146+
137147desc = f"""Post a paste.
138148
139149This endpoint falls under the `postpastes` ratelimit bucket.
@@ -177,9 +187,7 @@ async def put_pastes(
177187 expires = payload .expires ,
178188 author = author ,
179189 password = payload .password ,
180- origin_ip = request .headers .get ("x-forwarded-for" , request .client .host )
181- if request .app .config ["paste" ]["log_ip" ]
182- else None ,
190+ origin_ip = respect_dnt (request )
183191 )
184192
185193 paste ["notice" ] = notice
@@ -217,7 +225,7 @@ async def post_rich_paste(
217225
218226 paste_id = generate_paste_id ()
219227
220- if images :
228+ if images and HAS_BUNNYCDN :
221229 async def _partial (target , spool : UploadFile ):
222230 data = await spool .read ()
223231 await request .app .state .client .put (target , data = data , headers = headers ) # TODO figure out how to pass spooled object instead of load into memory
@@ -260,9 +268,7 @@ async def _partial(target, spool: UploadFile):
260268 expires = payload .expires ,
261269 author = author ,
262270 password = payload .password ,
263- origin_ip = request .headers .get ("x-forwarded-for" , request .client .host )
264- if request .app .config ["paste" ]["log_ip" ]
265- else None ,
271+ origin_ip = respect_dnt (request )
266272 )
267273
268274 paste ["notice" ] = notice
@@ -317,6 +323,7 @@ async def get_paste(request: MystbinRequest, paste_id: str, password: Optional[s
317323 response_model = List [responses .PasteGetAllResponse ],
318324 responses = {
319325 200 : {"model" : Optional [List [responses .PasteGetAllResponse ]]},
326+ 400 : {"content" : {"application/json" : {"example" : {"error" : "You have provided an invalid query argument" }}}},
320327 401 : {"model" : errors .Unauthorized },
321328 },
322329 name = "Get user pastes" ,
@@ -325,13 +332,17 @@ async def get_paste(request: MystbinRequest, paste_id: str, password: Optional[s
325332@limit ("getpaste" )
326333async def get_all_pastes (
327334 request : MystbinRequest ,
328- limit : Optional [int ] = None ,
335+ limit : int = 50 ,
336+ page : int = 1
329337) -> Union [UJSONResponse , Dict [str , List [Dict [str , str ]]]]:
330338 user = request .state .user
331339 if not user :
332340 return UJSONResponse ({"error" : "Unathorized" , "notice" : "You must be signed in to use this route" }, status_code = 401 )
341+
342+ if limit < 1 or page < 1 :
343+ return UJSONResponse ({"error" : "limit and page must be greater than 1" }, status_code = 400 )
333344
334- pastes = await request .app .state .db .get_all_user_pastes (user ["id" ], limit )
345+ pastes = await request .app .state .db .get_all_user_pastes (user ["id" ], limit , page )
335346 pastes = [dict (entry ) for entry in pastes ]
336347
337348 return UJSONResponse ({"pastes" : jsonable_encoder (pastes )})
@@ -450,7 +461,7 @@ async def delete_paste(request: MystbinRequest, paste_id: str) -> Union[UJSONRes
450461 403 : {"model" : errors .Forbidden },
451462 },
452463 status_code = 200 ,
453- name = "Delete multiple pastes" ,
464+ name = "Bulk delete pastes" ,
454465 description = desc ,
455466)
456467@limit ("deletepaste" )
@@ -490,18 +501,23 @@ async def delete_pastes(
490501 "/documents" ,
491502 tags = ["pastes" ],
492503 deprecated = True ,
493- response_description = '{"key": "string"}' ,
504+ responses = {
505+ 200 : {"application/json" : {"example" : {"key" : "string" }, "description" : "A key containing the slug for your paste" }},
506+ 400 : {"application/json" : {"example" : {"error" : "You have provided an invalid paste body" }}}
507+ },
494508 name = "Hastebin create paste" ,
495509 description = desc ,
496510)
497511@limit ("postpastes" )
498512async def compat_create_paste (request : MystbinRequest ):
499513 content = await request .body ()
514+ limit = request .app .config ["paste" ]["character_limit" ]
515+ if len (content ) > limit :
516+ return UJSONResponse ({"error" : f"body: file size exceeds character limit of { limit } " }, status_code = 400 )
517+
500518 paste : Record = await request .app .state .db .put_paste (
501519 paste_id = generate_paste_id (),
502520 pages = [payloads .PasteFile (filename = "file.txt" , content = content .decode ("utf8" ))],
503- origin_ip = request .headers .get ("x-forwarded-for" , request .client .host )
504- if request .app .config ["paste" ]["log_ip" ]
505- else None ,
521+ origin_ip = respect_dnt (request )
506522 )
507523 return UJSONResponse ({"key" : paste ["id" ]})
0 commit comments