Ver Fonte

Start working on project.

Cixo Develop há 8 meses atrás
pai
commit
83eafdd671
9 ficheiros alterados com 167 adições e 0 exclusões
  1. 1 0
      .gitignore
  2. 4 0
      assets/__init__.py
  3. 4 0
      assets/database.py
  4. 94 0
      assets/password.py
  5. 10 0
      assets/user.py
  6. 20 0
      core.py
  7. 4 0
      static/core.html
  8. 9 0
      tests/000-sample.py
  9. 21 0
      tests/001-password.py

+ 1 - 0
.gitignore

@@ -3,6 +3,7 @@
 __pycache__/
 *.py[cod]
 *$py.class
+.venv/
 
 # C extensions
 *.so

+ 4 - 0
assets/__init__.py

@@ -0,0 +1,4 @@
+from .password import password
+from .user import user
+from .user import user_builder
+from .database import database

+ 4 - 0
assets/database.py

@@ -0,0 +1,4 @@
+from .user import user
+
+class database:
+    pass

+ 94 - 0
assets/password.py

@@ -0,0 +1,94 @@
+import os 
+import hashlib
+
+class password:
+    """
+    This class is responsible for managing passwords and passwords hashes
+    generating.
+    """
+
+    def __init__(self, target: str, lenght: int = 48) -> None:
+        """
+        This is password initialized. It generate new password hash
+        from the password. Lenght of the hash could be changed.
+        
+        target: str - Target password
+        lenght: int - Lenght of the password hash (default: 48)
+        """
+        self.__lenght = lenght
+        self.__target = target
+
+    @property
+    def lenght(self) -> int:
+        """
+        This return lenght of the hash.
+        """
+
+        return self.__lenght
+
+    @property
+    def __salt(self) -> str:
+        """
+        This return random salt with lenght of the hash."
+        """
+        
+        return os.urandom(self.lenght).hex()
+
+    @property
+    def separator(self) -> str:
+        """
+        This return separator between salt and hash.
+        """
+
+        return "."
+
+    def __generate(self, salt: str) -> str:
+        """
+        This generate new hash from the password and salt.
+
+        salt: str - Salt to use when generating
+        return: str - Password hash generated from given salt
+        """
+
+        salted = salt + self.__target
+        binary = hashlib.shake_256(salted.encode())
+        hashed = binary.hexdigest(self.lenght)
+        full = salt + self.separator + hashed
+
+        return full
+
+    @property
+    def result(self) -> str:
+        """
+        This generate new hash from the password.
+
+        return: str - New password hash with random salt
+        """
+
+        return self.__generate(self.__salt)
+
+    def validate(self, hashed: str) -> bool:
+        """
+        This function validate password hash. When passwords match, then
+        return True, when password from the class not match with given hash,
+        then return False.
+
+        hashed: str - Password hash to check
+        return: bool - True when passwords match, False if not
+        """
+
+        position = hashed.find(self.separator)
+
+        if position == -1:
+            return False
+
+        salt = hashed[:position]
+        full = hashed[position + len(self.separator):]
+
+        if len(salt) != len(full):
+            return False
+
+        if len(full) != self.lenght * 2:
+            return False
+
+        return self.__generate(salt) == hashed

+ 10 - 0
assets/user.py

@@ -0,0 +1,10 @@
+import sqlmodel
+
+class user(sqlmodel.SQLModel, table = True):
+    id: int | None = sqlmodel.Field(default = None, primary_key = True)
+    nick: str = sqlmodel.Field(index = True)
+    password: str = sqlmodel.Field(index = True)
+    apikey: str = sqlmodel.Field(index = True)
+
+class user_builder:
+    pass

+ 20 - 0
core.py

@@ -0,0 +1,20 @@
+import asyncio
+import fastapi
+import fastapi.responses
+import fastapi.staticfiles
+import pathlib
+
+from assets import database
+
+core_directory = pathlib.Path(__file__).parent
+
+api = fastapi.FastAPI()
+app_directory = fastapi.staticfiles.StaticFiles(
+    directory = str(core_directory) + "/static/"
+)
+
[email protected]("/")
+async def index():
+    return fastapi.responses.RedirectResponse("/app/core.html")
+
+api.mount("/app/", app_directory, name = "app_static")

+ 4 - 0
static/core.html

@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<html>
+    UwU
+</html>

+ 9 - 0
tests/000-sample.py

@@ -0,0 +1,9 @@
+import pathlib
+
+current = pathlib.Path(__file__).parent
+root = current.parent
+
+import sys
+sys.path.append(str(root))
+
+import assets

+ 21 - 0
tests/001-password.py

@@ -0,0 +1,21 @@
+import pathlib
+
+current = pathlib.Path(__file__).parent
+root = current.parent
+
+import sys
+sys.path.append(str(root))
+
+import assets
+
+pass1 = assets.password("UwU")
+pass2 = assets.password("OwO")
+
+sample_uwu = pass1.result
+
+print("Hash1 \"UwU\": " + pass1.result)
+print("Hash2 \"UwU\": " + pass1.result)
+print("Hash3 \"UwU\": " + pass1.result)
+print("Hash \"OwO\": " + pass2.result)
+print("\"UwU\" == \"UwU\": " + str(pass1.validate(sample_uwu)))
+print("\"OwO\" == \"UwU\": " + str(pass2.validate(sample_uwu)))