Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 28 additions & 3 deletions backend/app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
from typing import Optional

from pydantic import BaseModel, Field
from app.utils import hash_value

from app.utils import from_base64, is_base64, to_base64


class PasteInputModel(BaseModel):
Expand Down Expand Up @@ -46,7 +47,31 @@ def __init__(
created_at: Optional[int] = None,
paste_id: str = None,
):
self.paste_id = hash_value(value=content) if paste_id is None else paste_id
self.content = content
self.paste_id = paste_id
self._content = content if is_base64(content) else to_base64(content)
self.client_id = client_id
self.created_at = int(time.time()) if created_at is None else created_at

@property
def encoded_content(self) -> str:
"""
Get the decoded content of the paste.

Returns:
str: The decoded content of the paste.
"""
return self._content if is_base64(self._content) else to_base64(self._content)

@property
def plain_content(self) -> str:
"""
Get the plain content of the paste.

Returns:
str: The plain content of the paste.
"""
return (
self._content
if not is_base64(self._content)
else from_base64(self._content)
)
2 changes: 1 addition & 1 deletion backend/app/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ async def get_paste(id: str, request: Request, db_client=Depends(get_db_client))
is_web_browser = "Mozilla" in user_agent or "AppleWebKit" in user_agent

paste_model = PasteModel(
content=paste.content,
content=paste.plain_content,
paste_id=paste.paste_id,
workspace=paste.client_id,
)
Expand Down
2 changes: 1 addition & 1 deletion backend/app/services/db_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ async def insert_paste(self, paste: PasteDataAware) -> str:
RETURNING id, paste_id;
"""
result = await conn.fetchrow(
insert_query, paste.content, paste.client_id, paste.created_at
insert_query, paste.encoded_content, paste.client_id, paste.created_at
)

return result["paste_id"]
Expand Down
52 changes: 46 additions & 6 deletions backend/app/utils.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,49 @@
import hashlib
DEFAULT_ENCODING = "utf-8"
import base64

DEFAULT_ENCODING = "utf-8"

def hash_value(value: str, encoding: str = "utf-8") -> str:

value_bytes = str(value).encode(encoding=encoding)
hash_object = hashlib.md5()
hash_object.update(value_bytes)
return hash_object.hexdigest()
def is_base64(s: str, encoding: str = DEFAULT_ENCODING) -> bool:
"""
Check if a string is valid Base64.

Args:
s (str): The string to check.

Returns:
bool: True if the string is valid Base64, False otherwise.
"""
try:
# Decode and re-encode to verify Base64 validity
return base64.b64encode(base64.b64decode(s)).decode(encoding=encoding) == s
except Exception:
return False


def to_base64(s: str, encoding: str = DEFAULT_ENCODING) -> str:
"""
Convert a string to Base64.

Args:
s (str): The string to convert.
encoding (str): The encoding to use. Defaults to 'utf-8'.

Returns:
str: The Base64 encoded string.
"""
return base64.b64encode(s.encode(encoding=encoding)).decode(encoding=encoding)


def from_base64(s: str, encoding: str = DEFAULT_ENCODING) -> str:
"""
Convert a Base64 string to its original form.

Args:
s (str): The Base64 string to convert.
encoding (str): The encoding to use. Defaults to 'utf-8'.

Returns:
str: The decoded string.
"""
return base64.b64decode(s.encode(encoding=encoding)).decode(encoding=encoding)