diff --git a/src/snek/system/security.py b/src/snek/system/security.py index 5449c50..43b61fe 100644 --- a/src/snek/system/security.py +++ b/src/snek/system/security.py @@ -1,9 +1,55 @@ import hashlib +import uuid -DEFAULT_SALT = b"snekker-de-snek-" +DEFAULT_SALT = "snekker-de-snek-" +DEFAULT_NS = "snekker-de-snek-" -async def hash(data, salt=DEFAULT_SALT): +class UIDNS: + def __init__(self, name: str) -> None: + """Initialize UIDNS with a name.""" + self.name = name + + @property + def bytes(self) -> bytes: + """Return the bytes representation of the name.""" + return self.name.encode() + + +def uid(value: str = None, ns: str = DEFAULT_NS) -> str: + """Generate a UUID based on the provided value and namespace. + + Args: + value (str): The value to generate the UUID from. If None, a new UUID is created. + ns (str): The namespace to use for UUID generation. + + Returns: + str: The generated UUID as a string. + """ + try: + ns = ns.decode() + except AttributeError: + pass + if not value: + value = str(uuid.uuid4()) + try: + value = value.decode() + except AttributeError: + pass + + return str(uuid.uuid5(UIDNS(ns), value)) + + +async def hash(data: str, salt: str = DEFAULT_SALT) -> str: + """Hash the given data with the specified salt using SHA-256. + + Args: + data (str): The data to hash. + salt (str): The salt to use for hashing. + + Returns: + str: The hexadecimal representation of the hashed data. + """ try: data = data.encode(errors="ignore") except AttributeError: @@ -18,5 +64,14 @@ async def hash(data, salt=DEFAULT_SALT): return obj.hexdigest() -async def verify(string: str, hashed: str): +async def verify(string: str, hashed: str) -> bool: + """Verify if the given string matches the hashed value. + + Args: + string (str): The string to verify. + hashed (str): The hashed value to compare against. + + Returns: + bool: True if the string matches the hashed value, False otherwise. + """ return await hash(string) == hashed diff --git a/src/snek/view/upload.py b/src/snek/view/upload.py index b32d94e..01c0ee7 100644 --- a/src/snek/view/upload.py +++ b/src/snek/view/upload.py @@ -18,8 +18,6 @@ from aiohttp import web from snek.system.view import BaseView -UPLOAD_DIR = pathlib.Path("./drive") - class UploadView(BaseView): @@ -37,8 +35,12 @@ class UploadView(BaseView): reader = await self.request.multipart() files = [] - UPLOAD_DIR.mkdir(parents=True, exist_ok=True) + user_uid = self.request.session.get("uid") + upload_dir = await self.services.user.get_home_folder(user_uid) + upload_dir = upload_dir.joinpath("upload") + upload_dir.mkdir(parents=True, exist_ok=True) + channel_uid = None drive = await self.services.drive.get_or_create( @@ -68,17 +70,17 @@ class UploadView(BaseView): name = str(uuid.uuid4()) + pathlib.Path(filename).suffix - file_path = pathlib.Path(UPLOAD_DIR).joinpath(name) + file_path = upload_dir.joinpath(name) files.append(file_path) - async with aiofiles.open(str(file_path.absolute()), "wb") as f: + async with aiofiles.open(str(file_path), "wb") as f: while chunk := await field.read_chunk(): await f.write(chunk) drive_item = await self.services.drive_item.create( drive["uid"], filename, - str(file_path.absolute()), + str(file_path), file_path.stat().st_size, file_path.suffix, )