mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-04-25 19:28:23 +00:00
Add new application structure: - app/main.py - application entry point - app/plugins/ - plugin system with auth plugin: - api/ - REST API endpoints and schemas - authorization/ - auth policies, providers, hooks - domain/ - business logic (service, models, jwt, password) - injection/ - route injection and guards - ops/ - operational utilities - runtime/ - runtime configuration - security/ - middleware, CSRF, dependencies - storage/ - user repositories and models - app/static/ - static assets (scalar.js for API docs) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
75 lines
2.5 KiB
Python
75 lines
2.5 KiB
Python
"""CLI tool to reset an admin password."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import asyncio
|
|
import secrets
|
|
import sys
|
|
|
|
from sqlalchemy import select
|
|
|
|
from app.plugins.auth.domain.password import hash_password
|
|
from app.plugins.auth.ops.credential_file import write_initial_credentials
|
|
from app.plugins.auth.storage import DbUserRepository
|
|
from app.plugins.auth.storage.models import User as UserModel
|
|
|
|
|
|
async def _run(email: str | None) -> int:
|
|
from store.persistence import create_persistence
|
|
|
|
app_persistence = await create_persistence()
|
|
await app_persistence.setup()
|
|
try:
|
|
if email:
|
|
async with app_persistence.session_factory() as session:
|
|
repo = DbUserRepository(session)
|
|
user = await repo.get_user_by_email(email)
|
|
else:
|
|
async with app_persistence.session_factory() as session:
|
|
stmt = select(UserModel).where(UserModel.system_role == "admin").limit(1)
|
|
row = (await session.execute(stmt)).scalar_one_or_none()
|
|
if row is None:
|
|
user = None
|
|
else:
|
|
repo = DbUserRepository(session)
|
|
user = await repo.get_user_by_id(row.id)
|
|
|
|
if user is None:
|
|
print(f"Error: user '{email}' not found." if email else "Error: no admin user found.", file=sys.stderr)
|
|
return 1
|
|
|
|
new_password = secrets.token_urlsafe(16)
|
|
updated_user = user.model_copy(
|
|
update={
|
|
"password_hash": hash_password(new_password),
|
|
"token_version": user.token_version + 1,
|
|
"needs_setup": True,
|
|
}
|
|
)
|
|
async with app_persistence.session_factory() as session:
|
|
repo = DbUserRepository(session)
|
|
await repo.update_user(updated_user)
|
|
await session.commit()
|
|
|
|
cred_path = write_initial_credentials(user.email, new_password, label="reset")
|
|
print(f"Password reset for: {user.email}")
|
|
print(f"Credentials written to: {cred_path} (mode 0600)")
|
|
print("Next login will require setup (new email + password).")
|
|
return 0
|
|
finally:
|
|
await app_persistence.aclose()
|
|
|
|
|
|
def main() -> None:
|
|
parser = argparse.ArgumentParser(description="Reset admin password")
|
|
parser.add_argument("--email", help="Admin email (default: first admin found)")
|
|
args = parser.parse_args()
|
|
|
|
exit_code = asyncio.run(_run(args.email))
|
|
sys.exit(exit_code)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|