async def post(self) -> None: lexer = self.get_body_argument("lexer") raw = self.get_body_argument("code") expiry = self.get_body_argument("expiry") if not raw: log.info("APINew.post: a paste was submitted without content") raise tornado.web.HTTPError(400) if lexer not in utility.list_languages(): log.info( "APINew.post: a paste was submitted with an invalid lexer") raise tornado.web.HTTPError(400) if expiry not in utility.expiries: log.info( "APINew.post: a paste was submitted with an invalid expiry") raise tornado.web.HTTPError(400) paste = database.Paste(raw, lexer, utility.expiries[expiry]) with database.session() as session: session.add(paste) session.commit() self.write({ "paste_id": paste.paste_id, "removal_id": paste.removal_id })
async def post(self) -> None: lexer = self.get_body_argument("lexer") raw = self.get_body_argument("code") expiry = self.get_body_argument("expiry") if lexer not in utility.list_languages(): log.info("Paste.post: a paste was submitted with an invalid lexer") raise tornado.web.HTTPError(400) # Guard against empty strings if not raw: return self.redirect(f"/+{lexer}") if expiry not in utility.expiries: log.info( "Paste.post: a paste was submitted with an invalid expiry") raise tornado.web.HTTPError(400) paste = database.Paste(raw, lexer, utility.expiries[expiry]) with database.session() as session: session.add(paste) session.commit() # The removal cookie is set for the specific path of the paste it is # related to self.set_cookie("removal", str(paste.removal_id), path=f"/show/{paste.paste_id}") # Send the client to the paste self.redirect(f"/show/{paste.paste_id}")
def post(self) -> None: # type: ignore """POST handler for the 'web' side of things.""" expiry = self.get_body_argument("expiry") if expiry not in utility.expiries: log.info( "CreateAction.post: a paste was submitted with an invalid expiry" ) raise error.ValidationError() auto_scale = self.get_body_argument("long", None) is None lexers = self.get_body_arguments("lexer") raws = self.get_body_arguments("raw", strip=False) filenames = self.get_body_arguments("filename") if not all([lexers, raws, filenames]): # Prevent empty argument lists from making it through raise error.ValidationError() if not all(raw.strip() for raw in raws): # Prevent empty raws from making it through raise error.ValidationError() with database.session() as session: paste = database.Paste(utility.expiries[expiry], "web", auto_scale) if any(len(L) != len(lexers) for L in [lexers, raws, filenames]): log.info("CreateAction.post: mismatching argument lists") raise error.ValidationError() for (lexer, raw, filename) in zip(lexers, raws, filenames): if lexer not in utility.list_languages(): log.info("CreateAction.post: a file had an invalid lexer") raise error.ValidationError() if not raw: log.info("CreateAction.post: a file had an empty raw") raise error.ValidationError() paste.files.append( database.File( raw, lexer, filename if filename else None, auto_scale ) ) session.add(paste) session.commit() # The removal cookie is set for the specific path of the paste it is # related to self.set_cookie( "removal", str(paste.removal), path=f"/{paste.slug}" ) # Send the client to the paste self.redirect(f"/{paste.slug}")
def post(self) -> None: if defensive.ratelimit(self.request, area="create"): self.set_status(429) self.write("Enhance your calm, you have exceeded the ratelimit.") return lexer = self.get_body_argument("lexer", "text") raw = self.get_body_argument("raw", "", strip=False) expiry = self.get_body_argument("expiry", "1day") self.set_header("Content-Type", "text/plain") if lexer not in utility.list_languages(): log.info( "CurlCreate.post: a paste was submitted with an invalid lexer") self.set_status(400) self.write("Invalid `lexer` supplied.\n") return # Guard against empty strings if not raw or not raw.strip(): log.info("CurlCreate.post: a paste was submitted without raw") self.set_status(400) self.write("Invalid `raw` supplied.\n") return if expiry not in configuration.expiries: log.info("CurlCreate.post: a paste was submitted without raw") self.set_status(400) self.write("Invalid `expiry` supplied.\n") return paste = database.Paste(utility.slug_create(), configuration.expiries[expiry], "curl") file = database.File(paste.slug, raw, lexer) paste.files.append(file) with database.session() as session: session.add(paste) session.commit() # The removal cookie is set for the specific path of the paste it is # related to self.set_cookie("removal", str(paste.removal), path=f"/{paste.slug}") url_request = self.request.full_url() url_paste = urljoin(url_request, f"/{paste.slug}") url_removal = urljoin(url_request, f"/remove/{paste.removal}") url_raw = urljoin(url_request, f"/raw/{file.slug}") self.write( f"Paste URL: {url_paste}\nRaw URL: {url_raw}\nRemoval URL: {url_removal}\n" )
async def post(self) -> None: try: data = tornado.escape.json_decode(self.request.body) except json.decoder.JSONDecodeError: raise tornado.web.HTTPError(400, "could not parse json body") expiry = data.get("expiry") if expiry not in utility.expiries: log.info( "Paste.post: a paste was submitted with an invalid expiry") raise tornado.web.HTTPError(400, "invalid expiry") auto_scale = data.get("long", None) is None files = data.get("files", []) if not files: raise tornado.web.HTTPError(400, "no files provided") with database.session() as session: paste = database.Paste(utility.expiries[expiry], "v1-api", auto_scale) for file in files: lexer = file.get("lexer", "") content = file.get("content") filename = file.get("name") if lexer not in utility.list_languages(): raise tornado.web.HTTPError(400, "invalid lexer") if not content: raise tornado.web.HTTPError(400, "invalid content (empty)") try: paste.files.append( database.File(content, lexer, filename, auto_scale)) except error.ValidationError: raise tornado.web.HTTPError( 400, "invalid content (exceeds size limit)") paste.files[0].slug = paste.slug session.add(paste) session.commit() # Send the client to the paste url_request = self.request.full_url() url_paste = urljoin(url_request, f"/{paste.slug}") url_removal = urljoin(url_request, f"/remove/{paste.removal}") self.write({"link": url_paste, "removal": url_removal})
async def post(self) -> None: """This is a historical endpoint to create pastes, pastes are marked as old-web and will get a warning on top of them to remove any access to this route. pinnwand has since evolved with an API which should be used and a multi-file paste. See the 'CreateAction' for the new-style creation of pastes.""" lexer = self.get_body_argument("lexer") raw = self.get_body_argument("code", strip=False) expiry = self.get_body_argument("expiry") if defensive.ratelimit(self.request, area="create"): raise error.RatelimitError() if lexer not in utility.list_languages(): log.info("Paste.post: a paste was submitted with an invalid lexer") raise tornado.web.HTTPError(400) # Guard against empty strings if not raw or not raw.strip(): return self.redirect(f"/+{lexer}") if expiry not in configuration.expiries: log.info( "Paste.post: a paste was submitted with an invalid expiry") raise tornado.web.HTTPError(400) paste = database.Paste( utility.slug_create(), configuration.expiries[expiry], "deprecated-web", ) file = database.File(paste.slug, raw, lexer) paste.files.append(file) with database.session() as session: session.add(paste) session.commit() # The removal cookie is set for the specific path of the paste it is # related to self.set_cookie("removal", str(paste.removal), path=f"/{paste.slug}") # Send the client to the paste self.redirect(f"/{paste.slug}")
def add(lexer: str) -> None: """Add a paste to pinnwand's database from stdin.""" if lexer not in utility.list_languages(): log.error("add: unknown lexer") return paste = database.Paste(expiry=timedelta(days=1)) file = database.File(sys.stdin.read(), lexer=lexer) paste.files.append(file) with database.session() as session: session.add(paste) session.commit() log.info("add: paste created: %s", paste.slug)
async def post(self) -> None: if defensive.ratelimit(self.request, area="create"): raise error.RatelimitError() lexer = self.get_body_argument("lexer") raw = self.get_body_argument("code", strip=False) expiry = self.get_body_argument("expiry") filename = self.get_body_argument("filename", None) if not raw or not raw.strip(): log.info("APINew.post: a paste was submitted without content") raise tornado.web.HTTPError(400) if lexer not in utility.list_languages(): log.info( "APINew.post: a paste was submitted with an invalid lexer") raise tornado.web.HTTPError(400) if expiry not in configuration.expiries: log.info( "APINew.post: a paste was submitted with an invalid expiry") raise tornado.web.HTTPError(400) paste = database.Paste( utility.slug_create(), configuration.expiries[expiry], "deprecated-api", ) paste.files.append(database.File(paste.slug, raw, lexer, filename)) with database.session() as session: session.add(paste) session.commit() req_url = self.request.full_url() location = paste.slug if filename: location += "#" + url_escape(filename) self.write({ "paste_id": paste.slug, "removal_id": paste.removal, "paste_url": urljoin(req_url, f"/{location}"), "raw_url": urljoin(req_url, f"/raw/{paste.files[0].slug}"), })
async def post(self) -> None: lexer = self.get_body_argument("lexer") raw = self.get_body_argument("code") expiry = self.get_body_argument("expiry") filename = self.get_body_argument("filename", None) if not raw: log.info("APINew.post: a paste was submitted without content") raise tornado.web.HTTPError(400) if lexer not in utility.list_languages(): log.info( "APINew.post: a paste was submitted with an invalid lexer") raise tornado.web.HTTPError(400) if expiry not in utility.expiries: log.info( "APINew.post: a paste was submitted with an invalid expiry") raise tornado.web.HTTPError(400) paste = database.Paste(raw, lexer, utility.expiries[expiry], "api", filename) with database.session() as session: session.add(paste) session.commit() req_url = self.request.full_url() location = paste.paste_id if filename: location += "#" + url_escape(filename) self.write({ "paste_id": paste.paste_id, "removal_id": paste.removal_id, "paste_url": urljoin(req_url, f"/show/{location}"), "raw_url": urljoin(req_url, f"/raw/{location}"), })
def post(self) -> None: # type: ignore """POST handler for the 'web' side of things.""" expiry = self.get_body_argument("expiry") if expiry not in utility.expiries: log.info( "CreateAction.post: a paste was submitted with an invalid expiry" ) raise error.ValidationError() auto_scale = self.get_body_argument("long", None) is None lexers = self.get_body_arguments("lexer") raws = self.get_body_arguments("raw", strip=False) filenames = self.get_body_arguments("filename") if not all([lexers, raws, filenames]): # Prevent empty argument lists from making it through raise error.ValidationError() if not all(raw.strip() for raw in raws): # Prevent empty raws from making it through raise error.ValidationError() with database.session() as session: paste = database.Paste(utility.expiries[expiry], "web", auto_scale) if any(len(L) != len(lexers) for L in [lexers, raws, filenames]): log.info("CreateAction.post: mismatching argument lists") raise error.ValidationError() for (lexer, raw, filename) in zip(lexers, raws, filenames): if lexer == 'AUTO': try: lexer = guess_lexer(raw).name except ValueError: # Fall back to plain text lexer = "text" if lexer not in utility.list_languages(): log.info("CreateAction.post: a file had an invalid lexer") raise error.ValidationError() if not raw: log.info("CreateAction.post: a file had an empty raw") raise error.ValidationError() paste.files.append( database.File(raw, lexer, filename if filename else None, auto_scale)) # For the first file we will always use the same slug as the paste, # since slugs are generated to be unique over both pastes and files # this can be done safely. paste.files[0].slug = paste.slug session.add(paste) session.commit() # The removal cookie is set for the specific path of the paste it is # related to self.set_cookie("removal", str(paste.removal), path=f"/{paste.slug}") # Send the client to the paste self.redirect(f"/{paste.slug}")
async def post(self) -> None: if defensive.ratelimit(self.request, area="create"): raise error.RatelimitError() try: data = tornado.escape.json_decode(self.request.body) except json.decoder.JSONDecodeError: raise tornado.web.HTTPError(400, "could not parse json body") expiry = data.get("expiry") if expiry not in configuration.expiries: log.info( "Paste.post: a paste was submitted with an invalid expiry") raise tornado.web.HTTPError(400, "invalid expiry") auto_scale = data.get("long", None) is None files = data.get("files", []) if not files: raise tornado.web.HTTPError(400, "no files provided") with database.session() as session, utility.SlugContext( auto_scale) as slug_context: paste = database.Paste( next(slug_context), configuration.expiries[expiry], "v1-api", ) for file in files: lexer = file.get("lexer", "") content = file.get("content") filename = file.get("name") if lexer not in utility.list_languages(): raise tornado.web.HTTPError(400, "invalid lexer") if not content: raise tornado.web.HTTPError(400, "invalid content (empty)") try: paste.files.append( database.File( next(slug_context), content, lexer, filename, )) except error.ValidationError: raise tornado.web.HTTPError( 400, "invalid content (exceeds size limit)") if sum(len(f.fmt) for f in paste.files) > configuration.paste_size: raise tornado.web.HTTPError( 400, "invalid content (exceeds size limit)") paste.files[0].slug = paste.slug session.add(paste) try: session.commit() except Exception: # XXX be more precise log.warning("%r", slug_context._slugs) raise # Send the client to the paste url_request = self.request.full_url() url_paste = urljoin(url_request, f"/{paste.slug}") url_removal = urljoin(url_request, f"/remove/{paste.removal}") self.write({"link": url_paste, "removal": url_removal})
def post(self) -> None: # type: ignore """POST handler for the 'web' side of things.""" expiry = self.get_body_argument("expiry") if expiry not in configuration.expiries: log.info( "CreateAction.post: a paste was submitted with an invalid expiry" ) raise error.ValidationError() auto_scale = self.get_body_argument("long", None) is None lexers = self.get_body_arguments("lexer") raws = self.get_body_arguments("raw", strip=False) filenames = self.get_body_arguments("filename") if not all([lexers, raws, filenames]): # Prevent empty argument lists from making it through raise error.ValidationError() if not all(raw.strip() for raw in raws): # Prevent empty raws from making it through raise error.ValidationError() if any(len(L) != len(lexers) for L in [lexers, raws, filenames]): log.info("CreateAction.post: mismatching argument lists") raise error.ValidationError() if any(lexer not in utility.list_languages() for lexer in lexers): log.info("CreateAction.post: a file had an invalid lexer") raise error.ValidationError() with database.session() as session, utility.SlugContext( auto_scale ) as slug_context: paste = database.Paste( next(slug_context), configuration.expiries[expiry], "web" ) for (lexer, raw, filename) in zip(lexers, raws, filenames): paste.files.append( database.File( next(slug_context), raw, lexer, filename if filename else None, ) ) if sum(len(f.fmt) for f in paste.files) > configuration.paste_size: log.info("CreateAction.post: sum of files was too large") raise error.ValidationError() # For the first file we will always use the same slug as the paste, # since slugs are generated to be unique over both pastes and files # this can be done safely. paste.files[0].slug = paste.slug session.add(paste) session.commit() # The removal cookie is set for the specific path of the paste it is # related to self.set_cookie( "removal", str(paste.removal), path=f"/{paste.slug}" ) # Send the client to the paste self.redirect(f"/{paste.slug}")