Skip to content

Commit

Permalink
decorate all request handler's callback functions with the ratelimiter
Browse files Browse the repository at this point in the history
  • Loading branch information
shtlrs committed Jan 20, 2024
1 parent 7008f97 commit 4f73294
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 64 deletions.
2 changes: 1 addition & 1 deletion src/pinnwand/error.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
class ValidationError(ValueError):
"""This exception is used to indicate that a certain requst is lacking or
"""This exception is used to indicate that a certain request is lacking or
has unacceptable data aboard."""

pass
Expand Down
4 changes: 1 addition & 3 deletions src/pinnwand/handler/api_curl.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,8 @@ def write_error(self, status_code: int, **kwargs: Any) -> None:
else:
super().write_error(status_code, **kwargs)

@defensive.ratelimit_endpoint(area="create")
def post(self) -> None:
if defensive.ratelimit(self.request, area="create"):
raise error.RatelimitError

lexer = self.get_body_argument("lexer", "text")
raw = self.get_body_argument("raw", "", strip=False)
expiry = self.get_body_argument("expiry", "1day")
Expand Down
20 changes: 5 additions & 15 deletions src/pinnwand/handler/api_deprecated.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,8 @@ async def post(self) -> None:
class Show(Base):
"""Show a paste on the deprecated API."""

@defensive.ratelimit_endpoint(area="read")
async def get(self, slug: str) -> None: # type: ignore
if defensive.ratelimit(self.request, area="read"):
raise error.RatelimitError()

with database.session() as session:
paste = (
session.query(database.Paste)
Expand Down Expand Up @@ -119,10 +117,8 @@ def check_xsrf_cookie(self) -> None:
async def get(self) -> None:
raise tornado.web.HTTPError(405)

@defensive.ratelimit_endpoint(area="create")
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")
Expand Down Expand Up @@ -174,10 +170,8 @@ def check_xsrf_cookie(self) -> None:
"""No XSRF cookies on the API."""
return

@defensive.ratelimit_endpoint(area="delete")
async def post(self) -> None:
if defensive.ratelimit(self.request, area="delete"):
raise error.RatelimitError()

with database.session() as session:
paste = (
session.query(database.Paste)
Expand Down Expand Up @@ -208,20 +202,16 @@ async def post(self) -> None:
class Lexer(Base):
"""List lexers through the deprecated API."""

@defensive.ratelimit_endpoint(area="read")
async def get(self) -> None:
if defensive.ratelimit(self.request, area="read"):
raise error.RatelimitError()

self.write(utility.list_languages())


class Expiry(Base):
"""List expiries through the deprecated API."""

@defensive.ratelimit_endpoint(area="read")
async def get(self) -> None:
if defensive.ratelimit(self.request, area="read"):
raise error.RatelimitError()

self.write(
{
name: str(timedelta(seconds=delta))
Expand Down
16 changes: 4 additions & 12 deletions src/pinnwand/handler/api_v1.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,14 @@ def write_error(self, status_code: int, **kwargs: Any) -> None:


class Lexer(Base):
@defensive.ratelimit_endpoint(area="read")
async def get(self) -> None:
if defensive.ratelimit(self.request, area="read"):
raise error.RatelimitError()

self.write(utility.list_languages())


class Expiry(Base):
@defensive.ratelimit_endpoint(area="read")
async def get(self) -> None:
if defensive.ratelimit(self.request, area="read"):
raise error.RatelimitError()

self.write(
{
name: str(timedelta(seconds=delta))
Expand All @@ -44,10 +40,8 @@ def check_xsrf_cookie(self) -> None:
async def get(self) -> None:
raise tornado.web.HTTPError(405)

@defensive.ratelimit_endpoint(area="create")
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:
Expand Down Expand Up @@ -124,10 +118,8 @@ async def post(self) -> None:


class PasteDetail(Base):
@defensive.ratelimit_endpoint(area="read")
async def get(self, slug: str) -> None:
if defensive.ratelimit(self.request, area="read"):
raise error.RatelimitError()

with database.session() as session:
paste = (
session.query(database.Paste)
Expand Down
44 changes: 11 additions & 33 deletions src/pinnwand/handler/website.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,11 @@ class Create(Base):
"""The index page shows the new paste page with a list of all available
lexers from Pygments."""

@defensive.ratelimit_endpoint(area="read")
async def get(self, lexers: str = "") -> None:
"""Render the new paste form, optionally have a lexer preselected from
the URL."""

if defensive.ratelimit(self.request, area="read"):
raise error.RatelimitError()

lexers_available = utility.list_languages()
lexers_selected = [
lexer for lexer in lexers.split("+") if lexer.strip()
Expand All @@ -112,6 +110,7 @@ async def get(self, lexers: str = "") -> None:
paste=None,
)

@defensive.ratelimit_endpoint(area="create")
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
Expand All @@ -126,9 +125,6 @@ async def post(self) -> None:
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)
Expand Down Expand Up @@ -175,12 +171,10 @@ class CreateAction(Base):
"""The create action is the 'new' way to create pastes and supports multi
file pastes."""

@defensive.ratelimit_endpoint(area="create")
def post(self) -> None: # type: ignore
"""POST handler for the 'web' side of things."""

if defensive.ratelimit(self.request, area="create"):
raise error.RatelimitError()

expiry = self.get_body_argument("expiry")

if expiry not in configuration.expiries:
Expand Down Expand Up @@ -262,13 +256,11 @@ class Repaste(Base):
"""Repaste is a specific case of the paste page. It only works for pre-
existing pastes and will prefill the textarea and lexer."""

@defensive.ratelimit_endpoint(area="read")
async def get(self, slug: str) -> None: # type: ignore
"""Render the new paste form, optionally have a lexer preselected from
the URL."""

if defensive.ratelimit(self.request, area="read"):
raise error.RatelimitError()

with database.session() as session:
paste = (
session.query(database.Paste)
Expand All @@ -295,12 +287,10 @@ async def get(self, slug: str) -> None: # type: ignore
class Show(Base):
"""Show a paste."""

@defensive.ratelimit_endpoint(area="read")
async def get(self, slug: str) -> None: # type: ignore
"""Fetch paste from database by slug and render the paste."""

if defensive.ratelimit(self.request, area="read"):
raise error.RatelimitError()

with database.session() as session:
paste = (
session.query(database.Paste)
Expand Down Expand Up @@ -364,12 +354,10 @@ async def get(self, slug: str) -> None: # type: ignore
class FileRaw(Base):
"""Show a file as plaintext."""

@defensive.ratelimit_endpoint(area="read")
async def get(self, file_id: str) -> None: # type: ignore
"""Get a file from the database and show it in the plain."""

if defensive.ratelimit(self.request, area="read"):
raise error.RatelimitError()

with database.session() as session:
file = (
session.query(database.File)
Expand Down Expand Up @@ -397,12 +385,10 @@ async def get(self, file_id: str) -> None: # type: ignore
class FileHex(Base):
"""Show a file as hexadecimal."""

@defensive.ratelimit_endpoint(area="read")
async def get(self, file_id: str) -> None: # type: ignore
"""Get a file from the database and show it in hex."""

if defensive.ratelimit(self.request, area="read"):
raise error.RatelimitError()

with database.session() as session:
file = (
session.query(database.File)
Expand Down Expand Up @@ -430,12 +416,10 @@ async def get(self, file_id: str) -> None: # type: ignore
class PasteDownload(Base):
"""Download an entire paste."""

@defensive.ratelimit_endpoint(area="read")
async def get(self, paste_id: str) -> None: # type: ignore
"""Get all files from the database and download them as a zipfile."""

if defensive.ratelimit(self.request, area="read"):
raise error.RatelimitError()

with database.session() as session:
paste = (
session.query(database.Paste)
Expand Down Expand Up @@ -479,12 +463,10 @@ async def get(self, paste_id: str) -> None: # type: ignore
class FileDownload(Base):
"""Download a file."""

@defensive.ratelimit_endpoint(area="read")
async def get(self, file_id: str) -> None: # type: ignore
"""Get a file from the database and download it in the plain."""

if defensive.ratelimit(self.request, area="read"):
raise error.RatelimitError()

with database.session() as session:
file = (
session.query(database.File)
Expand Down Expand Up @@ -523,13 +505,11 @@ async def get(self, file_id: str) -> None: # type: ignore
class Remove(Base):
"""Remove a paste."""

@defensive.ratelimit_endpoint(area="delete")
async def get(self, removal: str) -> None: # type: ignore
"""Look up if the user visiting this page has the removal id for a
certain paste. If they do they're authorized to remove the paste."""

if defensive.ratelimit(self.request, area="delete"):
raise error.RatelimitError()

with database.session() as session:
paste = (
session.query(database.Paste)
Expand Down Expand Up @@ -563,10 +543,8 @@ class RestructuredTextPage(Base):
def initialize(self, file: str) -> None:
self.file = file

@defensive.ratelimit_endpoint(area="read")
async def get(self) -> None:
if defensive.ratelimit(self.request, area="read"):
raise error.RatelimitError()

try:
with open(path.page / self.file) as f:
html = docutils.core.publish_parts(
Expand Down

0 comments on commit 4f73294

Please sign in to comment.