- Refactored the dashboard html into seperate pages and all the necessary components - Added login and secured api routes / debugged getting system working on a tailnet. - added some functionality to the debugging and health endpoints - added in a new phone contact import and debugged.
183 lines
5.3 KiB
Python
Executable File
183 lines
5.3 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
User Management CLI Tool
|
|
Create, list, delete, and manage users for SMS Campaign Manager
|
|
"""
|
|
|
|
import sys
|
|
import os
|
|
import getpass
|
|
from pathlib import Path
|
|
|
|
# Add src to path
|
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src'))
|
|
|
|
from core.user_auth import UserManager
|
|
from core.config import config
|
|
|
|
def print_header(text):
|
|
"""Print a formatted header"""
|
|
print("\n" + "="*70)
|
|
print(f" {text}")
|
|
print("="*70 + "\n")
|
|
|
|
def create_user_interactive(user_manager):
|
|
"""Interactively create a new user"""
|
|
print_header("CREATE NEW USER")
|
|
|
|
username = input("Username: ").strip()
|
|
if not username:
|
|
print("❌ Username cannot be empty")
|
|
return
|
|
|
|
# Check if user exists
|
|
if user_manager.get_user_by_username(username):
|
|
print(f"❌ User '{username}' already exists")
|
|
return
|
|
|
|
password = getpass.getpass("Password (min 8 characters): ")
|
|
if len(password) < 8:
|
|
print("❌ Password must be at least 8 characters")
|
|
return
|
|
|
|
password_confirm = getpass.getpass("Confirm password: ")
|
|
if password != password_confirm:
|
|
print("❌ Passwords do not match")
|
|
return
|
|
|
|
print("\nSelect role:")
|
|
print(" 1. Admin (full access)")
|
|
print(" 2. User (regular access)")
|
|
role_choice = input("Choice [1-2]: ").strip()
|
|
|
|
role = 'admin' if role_choice == '1' else 'user'
|
|
|
|
email = input("Email (optional): ").strip() or None
|
|
full_name = input("Full name (optional): ").strip() or None
|
|
|
|
# Create user
|
|
success = user_manager.create_user(username, password, role, email, full_name)
|
|
|
|
if success:
|
|
print(f"\n✅ User '{username}' created successfully (role: {role})")
|
|
else:
|
|
print(f"\n❌ Failed to create user '{username}'")
|
|
|
|
def list_users(user_manager):
|
|
"""List all users"""
|
|
print_header("ALL USERS")
|
|
|
|
users = user_manager.list_users()
|
|
|
|
if not users:
|
|
print("No users found")
|
|
return
|
|
|
|
# Print table header
|
|
print(f"{'ID':<5} {'Username':<20} {'Role':<10} {'Created':<20} {'Last Login':<20}")
|
|
print("-" * 80)
|
|
|
|
for user in users:
|
|
user_id = user.get('id', 'N/A')
|
|
username = user.get('username', 'N/A')
|
|
role = user.get('role', 'N/A')
|
|
created = user.get('created_at', 'N/A')[:19] if user.get('created_at') else 'N/A'
|
|
last_login = user.get('last_login', 'Never')[:19] if user.get('last_login') else 'Never'
|
|
|
|
print(f"{user_id:<5} {username:<20} {role:<10} {created:<20} {last_login:<20}")
|
|
|
|
print(f"\nTotal users: {len(users)}")
|
|
|
|
def delete_user_interactive(user_manager):
|
|
"""Interactively delete a user"""
|
|
print_header("DELETE USER")
|
|
|
|
username = input("Username to delete: ").strip()
|
|
if not username:
|
|
print("❌ Username cannot be empty")
|
|
return
|
|
|
|
# Check if user exists
|
|
user = user_manager.get_user_by_username(username)
|
|
if not user:
|
|
print(f"❌ User '{username}' not found")
|
|
return
|
|
|
|
confirm = input(f"Are you sure you want to delete '{username}'? (yes/no): ").strip().lower()
|
|
if confirm != 'yes':
|
|
print("❌ Deletion cancelled")
|
|
return
|
|
|
|
success = user_manager.delete_user(username)
|
|
|
|
if success:
|
|
print(f"\n✅ User '{username}' deleted successfully")
|
|
else:
|
|
print(f"\n❌ Failed to delete user '{username}'")
|
|
|
|
def change_password_interactive(user_manager):
|
|
"""Interactively change user password"""
|
|
print_header("CHANGE PASSWORD")
|
|
|
|
username = input("Username: ").strip()
|
|
if not username:
|
|
print("❌ Username cannot be empty")
|
|
return
|
|
|
|
old_password = getpass.getpass("Current password: ")
|
|
new_password = getpass.getpass("New password (min 8 characters): ")
|
|
|
|
if len(new_password) < 8:
|
|
print("❌ New password must be at least 8 characters")
|
|
return
|
|
|
|
new_password_confirm = getpass.getpass("Confirm new password: ")
|
|
if new_password != new_password_confirm:
|
|
print("❌ Passwords do not match")
|
|
return
|
|
|
|
success = user_manager.change_password(username, old_password, new_password)
|
|
|
|
if success:
|
|
print(f"\n✅ Password changed successfully for '{username}'")
|
|
else:
|
|
print(f"\n❌ Failed to change password. Check the current password.")
|
|
|
|
def main():
|
|
"""Main CLI interface"""
|
|
print_header("📱 SMS Campaign Manager - User Management")
|
|
|
|
# Initialize user manager
|
|
try:
|
|
user_manager = UserManager(config.DATABASE)
|
|
except Exception as e:
|
|
print(f"❌ Failed to initialize user manager: {e}")
|
|
sys.exit(1)
|
|
|
|
while True:
|
|
print("\nChoose an option:")
|
|
print(" 1. Create new user")
|
|
print(" 2. List all users")
|
|
print(" 3. Delete user")
|
|
print(" 4. Change password")
|
|
print(" 5. Exit")
|
|
|
|
choice = input("\nChoice [1-5]: ").strip()
|
|
|
|
if choice == '1':
|
|
create_user_interactive(user_manager)
|
|
elif choice == '2':
|
|
list_users(user_manager)
|
|
elif choice == '3':
|
|
delete_user_interactive(user_manager)
|
|
elif choice == '4':
|
|
change_password_interactive(user_manager)
|
|
elif choice == '5':
|
|
print("\n👋 Goodbye!")
|
|
break
|
|
else:
|
|
print("❌ Invalid choice. Please select 1-5.")
|
|
|
|
if __name__ == '__main__':
|
|
main()
|