From fdf3186be6fa5ccfc27cd1814971a0c50d5bf24a Mon Sep 17 00:00:00 2001 From: mungai-njoroge Date: Fri, 3 May 2024 23:22:09 +0300 Subject: [PATCH] salt passwords using userid --- app/api/__init__.py | 9 +++++---- app/api/settings.py | 6 +++--- app/arg_handler.py | 12 ++++++------ app/config.py | 5 ++--- app/plugins/lyrics.py | 2 +- app/settings.py | 11 +++++++---- app/setup/__init__.py | 6 ++++-- app/start_info_logger.py | 4 ++-- app/utils/auth.py | 10 ++++++++-- manage.py | 7 ++++--- 10 files changed, 42 insertions(+), 30 deletions(-) diff --git a/app/api/__init__.py b/app/api/__init__.py index 5c3e7f64..3a7e1afb 100644 --- a/app/api/__init__.py +++ b/app/api/__init__.py @@ -9,8 +9,9 @@ from flask_compress import Compress from flask_openapi3 import Info from flask_openapi3 import OpenAPI from flask_jwt_extended import JWTManager +from app.config import UserConfig -from app.settings import Keys +from app.settings import Info as AppInfo from .plugins import lyrics as lyrics_plugin from app.db.sqlite.auth import SQLiteAuthMethods as authdb from app.api import ( @@ -57,14 +58,14 @@ def create_api(): """ api_info = Info( title=f"Swing Music", - version=f"v{Keys.SWINGMUSIC_APP_VERSION}", + version=f"v{AppInfo.SWINGMUSIC_APP_VERSION}", description=open_api_description, ) app = OpenAPI(__name__, info=api_info, doc_prefix="/docs") - + print("userid", UserConfig().userId) # JWT CONFIGS - app.config["JWT_SECRET_KEY"] = Keys.JWT_SECRET_KEY + app.config["JWT_SECRET_KEY"] = UserConfig().userId app.config["JWT_TOKEN_LOCATION"] = ["cookies"] app.config["JWT_COOKIE_CSRF_PROTECT"] = False app.config["JWT_ACCESS_TOKEN_EXPIRES"] = datetime.timedelta(days=1) diff --git a/app/api/settings.py b/app/api/settings.py index 65ff0a0b..78ecad82 100644 --- a/app/api/settings.py +++ b/app/api/settings.py @@ -10,7 +10,7 @@ from app.db.sqlite.settings import SettingsSQLMethods as sdb from app.lib import populate from app.lib.watchdogg import Watcher as WatchDog from app.logger import log -from app.settings import Keys, Paths, SessionVarKeys, set_flag +from app.settings import Info, Paths, SessionVarKeys, set_flag from app.store.albums import AlbumStore from app.store.artists import ArtistStore from app.store.tracks import TrackStore @@ -193,7 +193,7 @@ def get_all_settings(): root_dirs = sdb.get_root_dirs() s["root_dirs"] = root_dirs s["plugins"] = plugins - s["version"] = Keys.SWINGMUSIC_APP_VERSION + s["version"] = Info.SWINGMUSIC_APP_VERSION return { "settings": s, @@ -292,4 +292,4 @@ def update_config(body: UpdateConfigBody): return { "msg": "Config updated!", - } \ No newline at end of file + } diff --git a/app/arg_handler.py b/app/arg_handler.py index dec203ac..02b06919 100644 --- a/app/arg_handler.py +++ b/app/arg_handler.py @@ -45,7 +45,7 @@ class HandleArgs: print("https://www.youtube.com/watch?v=wZv62ShoStY") sys.exit(0) - config_keys = [ + info_keys = [ "SWINGMUSIC_APP_VERSION", "GIT_LATEST_COMMIT_HASH", "GIT_CURRENT_BRANCH", @@ -53,8 +53,8 @@ class HandleArgs: lines = [] - for key in config_keys: - value = settings.Keys.get(key) + for key in info_keys: + value = settings.Info.get(key) if not value: log.error(f"WARNING: {key} not set in environment") @@ -88,7 +88,7 @@ class HandleArgs: finally: # revert and remove the api keys for dev mode with open("./app/configs.py", "w", encoding="utf-8") as file: - lines = [f'{key} = ""\n' for key in config_keys] + lines = [f'{key} = ""\n' for key in info_keys] file.writelines(lines) sys.exit(0) @@ -184,8 +184,8 @@ class HandleArgs: @staticmethod def handle_version(): if any((a in ARGS for a in ALLARGS.version)): - print(f"VERSION: v{settings.Keys.SWINGMUSIC_APP_VERSION}") + print(f"VERSION: v{settings.Info.SWINGMUSIC_APP_VERSION}") print( - f"COMMIT#: {settings.Keys.GIT_CURRENT_BRANCH}/{settings.Keys.GIT_LATEST_COMMIT_HASH}" + f"COMMIT#: {settings.Info.GIT_CURRENT_BRANCH}/{settings.Info.GIT_LATEST_COMMIT_HASH}" ) sys.exit(0) diff --git a/app/config.py b/app/config.py index 6f7e773c..4d4d997b 100644 --- a/app/config.py +++ b/app/config.py @@ -1,7 +1,6 @@ from dataclasses import dataclass, asdict, field import json import os -import time from typing import Any from .settings import Paths @@ -14,6 +13,8 @@ class UserConfig: # TODO: Move the rest of the settings to the config file # auth stuff + # NOTE: Don't expose the userId via the API + userId: str = "" usersOnLogin: bool = True enableGuest: bool = False @@ -57,8 +58,6 @@ class UserConfig: Creates the config file with the default settings if it doesn't exist """ - print("config path: ", self._config_path) - # if not exists, create the config file if not os.path.exists(self._config_path): self.write_to_file(asdict(self)) diff --git a/app/plugins/lyrics.py b/app/plugins/lyrics.py index 330693ec..81c73b59 100644 --- a/app/plugins/lyrics.py +++ b/app/plugins/lyrics.py @@ -8,7 +8,7 @@ import requests from app.db.sqlite.plugins import PluginsMethods from app.plugins import Plugin, plugin_method -from app.settings import Keys, Paths +from app.settings import Paths class LRCProvider: diff --git a/app/settings.py b/app/settings.py index d8a05ea4..cbaf0b35 100644 --- a/app/settings.py +++ b/app/settings.py @@ -268,13 +268,16 @@ def getCurrentBranch(): return "" -class Keys: +class Info: + """ + Contains information about the app + + NOTE: This class initially written to load keys when running in build mode. + TODO: Remove this class entirely, and implement functionality where needed. + """ SWINGMUSIC_APP_VERSION = os.environ.get("SWINGMUSIC_APP_VERSION") GIT_LATEST_COMMIT_HASH = "" GIT_CURRENT_BRANCH = "" - JWT_SECRET_KEY = ( - "swingmusic_secret_key" # REVIEW: This should be set in the environment - ) @classmethod def load(cls): diff --git a/app/setup/__init__.py b/app/setup/__init__.py index 5b741782..7a8ed41e 100644 --- a/app/setup/__init__.py +++ b/app/setup/__init__.py @@ -1,8 +1,7 @@ """ Prepares the server for use. """ - -from dataclasses import asdict +import uuid from app.db.sqlite.settings import load_settings from app.setup.files import create_config_dir from app.setup.sqlite import run_migrations, setup_sqlite @@ -28,6 +27,9 @@ def run_setup(): config = UserConfig() config.setup_config_file() + if not config.userId: + config.userId = str(uuid.uuid4()) + instance_key = get_random_str() # INFO: Load all tracks, albums, and artists into memory diff --git a/app/start_info_logger.py b/app/start_info_logger.py index 45674b94..e27a361e 100644 --- a/app/start_info_logger.py +++ b/app/start_info_logger.py @@ -1,6 +1,6 @@ import os -from app.settings import FLASKVARS, TCOLOR, Keys, Paths +from app.settings import FLASKVARS, TCOLOR, Info, Paths from app.utils.network import get_ip @@ -10,7 +10,7 @@ def log_startup_info(): # os.system("cls" if os.name == "nt" else "echo -e \\\\033c") print(lines) - print(f"{TCOLOR.HEADER}SwingMusic {Keys.SWINGMUSIC_APP_VERSION} {TCOLOR.ENDC}") + print(f"{TCOLOR.HEADER}SwingMusic {Info.SWINGMUSIC_APP_VERSION} {TCOLOR.ENDC}") adresses = [FLASKVARS.get_flask_host()] diff --git a/app/utils/auth.py b/app/utils/auth.py index fac68e22..e8b909af 100644 --- a/app/utils/auth.py +++ b/app/utils/auth.py @@ -1,5 +1,8 @@ +import hmac import hashlib +from app.config import UserConfig + def encode_password(password: str) -> str: """ @@ -10,7 +13,10 @@ def encode_password(password: str) -> str: :return: The encoded password. """ - return hashlib.sha256(password.encode("utf-8")).hexdigest() + return hashlib.pbkdf2_hmac( + "sha256", password.encode("utf-8"), UserConfig().userId.encode("utf-8"), 100000 + ).hex() + def check_password(password: str, encoded: str) -> bool: """ @@ -22,4 +28,4 @@ def check_password(password: str, encoded: str) -> bool: :return: Whether the password matches. """ - return encode_password(password) == encoded \ No newline at end of file + return hmac.compare_digest(encode_password(password), encoded) diff --git a/manage.py b/manage.py index af47a766..b7068dfd 100644 --- a/manage.py +++ b/manage.py @@ -17,7 +17,7 @@ from app.arg_handler import HandleArgs from app.lib.watchdogg import Watcher as WatchDog from app.periodic_scan import run_periodic_scans from app.plugins.register import register_plugins -from app.settings import FLASKVARS, TCOLOR, Keys +from app.settings import FLASKVARS, TCOLOR, Info from app.setup import run_setup from app.start_info_logger import log_startup_info from app.utils.filesystem import get_home_res_path @@ -40,6 +40,8 @@ mimetypes.add_type("application/manifest+json", ".webmanifest") werkzeug = logging.getLogger("werkzeug") werkzeug.setLevel(logging.ERROR) +HandleArgs() + app = create_api() app.static_folder = get_home_res_path("client") @@ -155,8 +157,7 @@ def run_swingmusic(): if __name__ == "__main__": - Keys.load() - HandleArgs() + Info.load() run_swingmusic() host = FLASKVARS.get_flask_host()