Merge pull request #50 from unslothai/fix/auth-setup-rollback
Auth Setup Failure: `auth.db` Created Before Token Generation
This commit is contained in:
commit
b10b303f4e
2 changed files with 26 additions and 8 deletions
|
|
@ -84,6 +84,20 @@ def create_initial_user(username: str, password: str, jwt_secret: str) -> None:
|
|||
conn.close()
|
||||
|
||||
|
||||
def delete_user(username: str) -> None:
|
||||
"""
|
||||
Delete a user from the database.
|
||||
|
||||
Used for rollback when setup fails after user creation.
|
||||
"""
|
||||
conn = get_connection()
|
||||
try:
|
||||
conn.execute("DELETE FROM auth_user WHERE username = ?", (username,))
|
||||
conn.commit()
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
def get_user_and_secret(username: str) -> Optional[Tuple[str, str, str]]:
|
||||
"""
|
||||
Get user's password salt, hash, and JWT secret.
|
||||
|
|
|
|||
|
|
@ -57,25 +57,29 @@ async def setup_auth(payload: AuthSetupRequest) -> Token:
|
|||
# Generate a strong random JWT secret for this installation
|
||||
jwt_secret = secrets.token_urlsafe(64)
|
||||
|
||||
# Save username/password hash and secret in SQLite
|
||||
# Create user + generate tokens atomically — rollback if anything fails
|
||||
try:
|
||||
storage.create_initial_user(
|
||||
username=payload.username,
|
||||
password=payload.password,
|
||||
jwt_secret=jwt_secret,
|
||||
)
|
||||
|
||||
# Reload JWT secret from DB (so authentication.py picks it up)
|
||||
reload_secret()
|
||||
|
||||
# Issue access + refresh tokens for the new user
|
||||
access_token = create_access_token(subject=payload.username)
|
||||
refresh_token = create_refresh_token(subject=payload.username)
|
||||
|
||||
except Exception as e:
|
||||
# Rollback: remove the user row so setup can be retried
|
||||
storage.delete_user(payload.username)
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail=f"Failed to create user: {str(e)}",
|
||||
detail=f"Setup failed (rolled back): {str(e)}",
|
||||
)
|
||||
|
||||
# Reload JWT secret from DB (so authentication.py picks it up)
|
||||
reload_secret()
|
||||
|
||||
# Issue access + refresh tokens for the new user
|
||||
access_token = create_access_token(subject=payload.username)
|
||||
refresh_token = create_refresh_token(subject=payload.username)
|
||||
return Token(
|
||||
access_token=access_token,
|
||||
refresh_token=refresh_token,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue