From fa175b9c102aa894e2993365a0b270b58d32b730 Mon Sep 17 00:00:00 2001 From: lasseedfast Date: Fri, 19 Sep 2025 09:47:09 +0200 Subject: [PATCH] added db_name --- .gitignore | 1 + __init__.py | 2 +- __pycache__/arango.cpython-310.pyc | Bin 0 -> 9307 bytes arango.py => _arango.py | 99 +++++++++++++++++++++++------ 4 files changed, 80 insertions(+), 22 deletions(-) create mode 100644 .gitignore create mode 100644 __pycache__/arango.cpython-310.pyc rename arango.py => _arango.py (71%) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2eea525 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.env \ No newline at end of file diff --git a/__init__.py b/__init__.py index cda57b5..3f332e1 100644 --- a/__init__.py +++ b/__init__.py @@ -1 +1 @@ -from .arango import arango +from ._arango import arango diff --git a/__pycache__/arango.cpython-310.pyc b/__pycache__/arango.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7fe8652f8da0f3a5616bcb0d8db5e1e900e0c56a GIT binary patch literal 9307 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 Ks0?NqFaH;8?6Xz? literal 0 HcmV?d00001 diff --git a/arango.py b/_arango.py similarity index 71% rename from arango.py rename to _arango.py index 99802ec..a2080a0 100644 --- a/arango.py +++ b/_arango.py @@ -7,12 +7,10 @@ from dotenv import load_dotenv load_dotenv() -if "ARANGO_HOST" not in os.environ: +if "ARANGO_HOSTS" not in os.environ: import env_manager - env_manager.set_env() - class Arango: """ Provides a simple interface for connecting to and interacting with an ArangoDB database. @@ -28,13 +26,17 @@ class Arango: results = arango.execute_aql("FOR doc IN my_collection RETURN doc") """ - def __init__(self): + def __init__(self, db_name: str = None): """ Initializes the ArangoDB client and connects to the specified database using environment variables. """ - self.client = ArangoClient(hosts=os.environ.get("ARANGO_HOST")) + + self.client = ArangoClient(hosts=os.environ.get("ARANGO_HOSTS")) + + if db_name is None: + db_name = os.environ.get("ARANGO_DB") self.db = self.client.db( - os.environ.get("ARANGO_DB"), + db_name, username=os.environ.get("ARANGO_USERNAME"), password=os.environ.get("ARANGO_PWD"), ) @@ -102,8 +104,6 @@ class Arango: print(f"Collection '{name}' already exists.") -load_dotenv() - class AdminArango: """ @@ -121,11 +121,14 @@ class AdminArango: """ Initializes the AdminArango client and connects to the '_system' database using environment variables. """ - self.client = ArangoClient(hosts=os.environ.get("ARANGO_HOST")) + arango_hosts = os.environ.get("ARANGO_HOSTS") + if not arango_hosts: + raise RuntimeError("Missing ARANGO_HOSTS environment variable.") + self.client = ArangoClient(hosts=arango_hosts) self.sys_db = self.client.db( "_system", - username=os.environ.get("ARANGO_USERNAME"), - password=os.environ.get("ARANGO_PWD"), + username=os.environ.get("ARANGO_ADMIN_USERNAME"), + password=os.environ.get("ARANGO_ADMIN_PWD"), ) # --- Database Management --- @@ -140,11 +143,55 @@ class AdminArango: db_name (str): Name of the database to create. users (Optional[list[dict]]): List of user dicts to create with the database. """ - if not self.sys_db.has_database(db_name): - self.sys_db.create_database(db_name, users=users) - print(f"Created database: {db_name}") - else: - print(f"Database '{db_name}' already exists.") + # Check if database exists + try: + if self.sys_db.has_database(db_name): + print(f"Database '{db_name}' already exists.") + return + except Exception as e: + print(f"Error checking database existence: {e}") + return + + # Prepare users list for database creation + user_objs = [] + if users: + for user in users: + # Check if user exists + try: + if self.sys_db.has_user(user['username']): + print(f"User '{user['username']}' already exists. Will not create, but will grant permissions.") + else: + self.sys_db.create_user( + username=user['username'], + password=user.get('password'), + active=True + ) + print(f"User '{user['username']}' created.") + except Exception as e: + print(f"Error checking/creating user '{user['username']}': {e}") + # Add user object for database creation (even if already exists) + user_objs.append({ + 'username': user['username'], + 'password': user.get('password') + }) + + # Create database + try: + self.sys_db.create_database(db_name, users=user_objs if user_objs else None) + print(f"Database '{db_name}' created.") + except Exception as e: + print(f"Error creating database: {e}") + return + + # Grant user permissions on the new database + if users: + try: + db = self.client.db(db_name, username='root', password=os.environ.get("ARANGO_PWD")) + for user in users: + self.sys_db.update_permission(user['username'], 'rw', db_name) + print(f"Granted 'rw' permission to user '{user['username']}' on database '{db_name}'.") + except Exception as e: + print(f"Error setting permissions: {e}") def delete_database(self, db_name: str): """ @@ -237,6 +284,7 @@ def admin(): 1) Create a database 2) Create a user and set permissions """ + import getpass GREY = "\033[90m" RESET = "\033[0m" @@ -252,15 +300,24 @@ def admin(): users = [] if add_user == "y": username = input("Enter username: ").strip() - password = input("Enter password: ").strip() - users.append({"username": username, "password": password}) + # Check if user exists before asking for password + if admin.sys_db.has_user(username): + print(f"User '{username}' already exists. Will not prompt for password.") + users.append({"username": username}) + else: + password = getpass.getpass("Enter password: ") + users.append({"username": username, "password": password}) admin.create_database(db_name, users=users if users else None) elif choice == "2": username = input("Enter new username: ").strip() - password = input("Enter password: ").strip() - active = input("Should the user be active? (y/n): ").strip().lower() == "y" - admin.create_user(username, password=password, active=active) + # Check if user exists before asking for password + if admin.sys_db.has_user(username): + print(f"User '{username}' already exists. Skipping creation and password prompt.") + else: + password = getpass.getpass("Enter password: ") + active = input("Should the user be active? (y/n): ").strip().lower() == "y" + admin.create_user(username, password=password, active=active) db_name = input("Set permissions for which database?: ").strip() print( f"{GREY}Permission options:\n"