Add admin reset-password command
Features: - Add admin reset-password command to reset user passwords - Support SQLite, PostgreSQL, and MySQL databases - Use scrypt hashing compatible with CodiMD - Update README with reset-password usage examples
This commit is contained in:
@@ -708,6 +708,76 @@ def admin_user_notes(user_id, db_path):
|
||||
click.echo(f" {note_id} | {title[:50]} | [{permission}]")
|
||||
|
||||
|
||||
@admin.command("reset-password")
|
||||
@click.option("--db-type", type=click.Choice(["sqlite", "postgresql", "mysql"]), default="sqlite", help="Database type")
|
||||
@click.option("--db-path", type=Path, help="SQLite database path")
|
||||
@click.option("--db-host", help="Database host (for PostgreSQL/MySQL)")
|
||||
@click.option("--db-name", help="Database name (for PostgreSQL/MySQL)")
|
||||
@click.option("--db-user", help="Database user (for PostgreSQL/MySQL)")
|
||||
@click.option("--db-password", help="Database password (for PostgreSQL/MySQL)")
|
||||
@click.option("--db-port", type=int, default=5432, help="Database port")
|
||||
@click.option("--email", help="User email to reset password for")
|
||||
@click.option("--user-id", help="User ID to reset password for")
|
||||
@click.option("--password", help="New password (will prompt if not provided)")
|
||||
@click.confirmation_option(prompt="Are you sure you want to reset this user's password?")
|
||||
@handle_error
|
||||
def admin_reset_password(db_type, db_path, db_host, db_name, db_user, db_password, db_port, email, user_id, password):
|
||||
"""Reset a user's password."""
|
||||
from cli_anything.codimd.core import CodiMDDatabase
|
||||
|
||||
if not email and not user_id:
|
||||
raise ValueError("Either --email or --user-id must be specified")
|
||||
|
||||
if not password:
|
||||
password = click.prompt("New password", hide_input=True, confirmation_prompt=True)
|
||||
|
||||
if db_type == "sqlite":
|
||||
if not db_path:
|
||||
# Try default paths
|
||||
default_paths = [
|
||||
"./codimd/db.sqlite",
|
||||
"./db.sqlite",
|
||||
"/var/lib/codimd/db.sqlite"
|
||||
]
|
||||
for path in default_paths:
|
||||
if Path(path).exists():
|
||||
db_path = path
|
||||
break
|
||||
if not db_path:
|
||||
raise ValueError("SQLite database path not found. Use --db-path")
|
||||
|
||||
if user_id:
|
||||
CodiMDDatabase.reset_password_sqlite_by_id(str(db_path), user_id, password)
|
||||
click.echo(f"Password reset for user ID: {user_id}")
|
||||
else:
|
||||
CodiMDDatabase.reset_password_sqlite(str(db_path), email, password)
|
||||
click.echo(f"Password reset for: {email}")
|
||||
|
||||
elif db_type == "postgresql":
|
||||
if not all([db_host, db_name, db_user]):
|
||||
raise ValueError("--db-host, --db-name, and --db-user are required for PostgreSQL")
|
||||
if not db_password:
|
||||
db_password = click.prompt("Database password", hide_input=True)
|
||||
|
||||
CodiMDDatabase.reset_password_postgresql(
|
||||
db_host, db_name, db_user, db_password, db_port, email, password
|
||||
)
|
||||
click.echo(f"Password reset for: {email}")
|
||||
|
||||
elif db_type == "mysql":
|
||||
if not all([db_host, db_name, db_user]):
|
||||
raise ValueError("--db-host, --db-name, and --db-user are required for MySQL")
|
||||
if not db_password:
|
||||
db_password = click.prompt("Database password", hide_input=True)
|
||||
|
||||
CodiMDDatabase.reset_password_mysql(
|
||||
db_host, db_name, db_user, db_password, db_port, email, password
|
||||
)
|
||||
click.echo(f"Password reset for: {email}")
|
||||
|
||||
click.echo("✓ Password has been updated. The user can now log in with the new password.")
|
||||
|
||||
|
||||
# REPL mode
|
||||
@cli.command("repl")
|
||||
@handle_error
|
||||
|
||||
Reference in New Issue
Block a user