diff --git a/.gitignore b/.gitignore index 87dd4e7..c32082d 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,5 @@ setup.py pyjondb.ico pypi.readme /PyJONDB.egg-info +/database-viewer/src/build/PyJONDB Viewer/localpycs +database-viewer/src/convert.bat diff --git a/database-viewer/src/PyJONDB Viewer.py b/database-viewer/src/PyJONDB Viewer.py index 00b143b..1711b17 100644 --- a/database-viewer/src/PyJONDB Viewer.py +++ b/database-viewer/src/PyJONDB Viewer.py @@ -1,9 +1,11 @@ import os import json import sys -import pyjondb import tkinter as tk from tkinter import filedialog, messagebox, scrolledtext +from pyjondb import database +from pyjondb import session + def decrypt_and_show(): key = key_entry.get() @@ -15,9 +17,11 @@ def decrypt_and_show(): return db_name = os.path.splitext(os.path.basename(database_path))[0] print(db_name) - db = pyjondb.database(db_name, key, absolute=True) + auth = session.start() + session_id = auth.authenticate('pyjondb.viewer', 'pyjondbviewtool') + db = database.init(db_name, key, auth, absolute=True) try: - data = db.read() + data = db.read(session_id) show_data(data) except Exception as e: messagebox.showerror("Error", f"Failed to read the database: {e}") diff --git a/database-viewer/src/dist/PyJONDB Viewer.exe b/database-viewer/src/dist/PyJONDB Viewer.exe new file mode 100644 index 0000000..495a212 Binary files /dev/null and b/database-viewer/src/dist/PyJONDB Viewer.exe differ diff --git a/example.py b/example.py index 199d43f..4439a42 100644 --- a/example.py +++ b/example.py @@ -2,8 +2,8 @@ from pyjondb import session # Initialize authentication -auth = session.start() -auth.create_user('admin', 'adminpass', roles=['admin']) +auth = session.start(work_in_db_dir=False, support_view_tool=True) +#auth.create_user('admin', 'adminpass', roles=['admin']) # Authenticate and get a session ID session_id = auth.authenticate('admin', 'adminpass') diff --git a/pyjondb/__init__.py b/pyjondb/__init__.py new file mode 100644 index 0000000..ef4f0f8 --- /dev/null +++ b/pyjondb/__init__.py @@ -0,0 +1,2 @@ +from .database import init +from .session import start \ No newline at end of file diff --git a/pyjondb/session.py b/pyjondb/session.py index 646cce0..8e9a835 100644 --- a/pyjondb/session.py +++ b/pyjondb/session.py @@ -16,28 +16,43 @@ - import hashlib import os import json import uuid import datetime +databasepath = None + class start: - def __init__(self, user_file='users.json', absolute=False, session_timeout=3600): + def __init__(self, user_file='users.json', work_in_db_dir=True, session_timeout=3600, support_view_tool=False): """ Initializes a new instance for the database handling. Args: user_file (str, optional): The path to the user file. Defaults to 'users.json'. - absolute (bool, optional): Whether to use an absolute path for the user file. Defaults to False. + work_in_db_dir (bool, optional): Whether to work in the databases directory for the user data. Defaults to 'True' session_timeout (int, optional): The session timeout in seconds. Defaults to 3600. + support_view_tool (bool, optional): Whether to support the view tool. Defaults to 'False'. Set to false for production. + - Enabling the view tool support will create a PyJONDB user in your user file in order to view the database. This means + that anyone with the PyJONDB View Tool name and password can view your database. """ + global databasepath self.user_file = user_file + self.support_view_tool = support_view_tool + self.work_in_db_dir = work_in_db_dir self.users = self.load_users() - self.absolute = absolute self.sessions = {} + self.absolute = databasepath self.session_timeout = session_timeout + if self.support_view_tool == True: + hashed_password = self.hash_password("pyjondbviewtool") + self.users["pyjondb.viewtool"] = { + 'password': hashed_password, + 'roles': ["user"] + } + self.save_users() + def load_users(self): """ Loads the users from the user file if it exists. @@ -46,22 +61,40 @@ def load_users(self): dict: A dictionary containing the users loaded from the user file. If the user file does not exist, an empty dictionary is returned. """ - if os.path.exists(self.user_file): - with open(self.user_file, 'r') as f: + user_file_path = self.get_user_file_path() + if os.path.exists(user_file_path): + with open(user_file_path, 'r') as f: return json.load(f) return {} + def save_users(self): - if self.absolute == True: - with open(self.user_file, 'w') as f: - json.dump(self.users, f) - else: - if not os.path.exists("./databases"): - os.makedirs("./databases") - with open("./databases/" + self.user_file, 'w') as f: - json.dump(self.users, f) + """ + Saves the current users to the user file. + """ + user_file_path = self.get_user_file_path() + if not os.path.exists(os.path.dirname(user_file_path)): + if os.path.dirname(user_file_path) == "": + with open(user_file_path, 'w') as f: + json.dump(self.users, f) + return + os.makedirs(os.path.dirname(user_file_path)) + with open(user_file_path, 'w') as f: + json.dump(self.users, f) + + def get_user_file_path(self): + """ + Determines the correct file path for storing or loading users. + + Returns: + str: The file path to be used for storing or loading users. + """ + if self.work_in_db_dir: + return os.path.join("databases", self.user_file) + return self.user_file def hash_password(self, password): return hashlib.sha256(password.encode()).hexdigest() + def create_user(self, username, password, roles=None): """ Creates a new user with the given username, password, and optional roles. @@ -85,6 +118,7 @@ def create_user(self, username, password, roles=None): 'roles': roles or [] } self.save_users() + def authenticate(self, username, password): """ Authenticates a user with the given username and password. @@ -106,6 +140,7 @@ def authenticate(self, username, password): 'created_at': datetime.datetime.now().timestamp() } return session_id + def is_authenticated(self, session_id): session = self.sessions.get(session_id) if not session: @@ -114,6 +149,7 @@ def is_authenticated(self, session_id): del self.sessions[session_id] return False return True + def authorize(self, session_id, role): session = self.sessions.get(session_id) if not session: