From 80cf981fdb85a1f98e7ef4698f2542106b0c3df2 Mon Sep 17 00:00:00 2001 From: chengkai3 Date: Thu, 18 Jun 2026 12:26:58 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20[FL-195][=E5=88=9B=E5=BB=BA=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E6=8A=A5=E9=94=99]=20=E4=B8=BA=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E4=BA=8B=E5=8A=A1=E6=B7=BB=E5=8A=A0=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=E5=A4=84=E7=90=86=E5=92=8C=E5=9B=9E=E6=BB=9A=E6=9C=BA?= =?UTF-8?q?=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 Co-authored-by: multica-agent --- api/app/services/user_service.py | 153 ++++++++++++++++++------------- 1 file changed, 87 insertions(+), 66 deletions(-) diff --git a/api/app/services/user_service.py b/api/app/services/user_service.py index 11d5218..f455b08 100644 --- a/api/app/services/user_service.py +++ b/api/app/services/user_service.py @@ -114,20 +114,24 @@ def create_user( status="ENABLED", ) - db.add(user) - db.flush() - _assign_legacy_roles(db, user_id, []) - write_audit_log( - db, - action="user.create", - actor_user_id=actor_user_id, - detail=compose_audit_detail( - f"target_user_id={user.id}", - f"target_username={user.username}", - f"target_status={user.status}", - ), - ) - db.commit() + try: + db.add(user) + db.flush() + _assign_legacy_roles(db, user_id, []) + write_audit_log( + db, + action="user.create", + actor_user_id=actor_user_id, + detail=compose_audit_detail( + f"target_user_id={user.id}", + f"target_username={user.username}", + f"target_status={user.status}", + ), + ) + db.commit() + except SQLAlchemyError: + db.rollback() + return None created = get_user_by_id(db, user_id) if created: @@ -150,18 +154,22 @@ def delete_user(db: Session, user_id: str, *, actor_user_id: str | None) -> bool return False target_username = user.username - revoke_active_sessions_for_user(db, user_id) - write_audit_log( - db, - action="user.delete", - actor_user_id=actor_user_id, - detail=compose_audit_detail( - f"target_user_id={user_id}", - f"target_username={target_username}", - ), - ) - db.delete(user) - db.commit() + try: + revoke_active_sessions_for_user(db, user_id) + write_audit_log( + db, + action="user.delete", + actor_user_id=actor_user_id, + detail=compose_audit_detail( + f"target_user_id={user_id}", + f"target_username={target_username}", + ), + ) + db.delete(user) + db.commit() + except SQLAlchemyError: + db.rollback() + return False _fire_and_forget( publish_topic( @@ -186,20 +194,24 @@ def reset_user_password( if not user: return None - user.password_hash = hash_password(payload.new_password) - revoke_active_sessions_for_user(db, user_id) - write_audit_log( - db, - action="user.password.reset", - actor_user_id=actor_user_id, - detail=compose_audit_detail( - f"target_user_id={user.id}", - f"target_username={user.username}", - "password_updated=true", - "sessions_revoked=true", - ), - ) - db.commit() + try: + user.password_hash = hash_password(payload.new_password) + revoke_active_sessions_for_user(db, user_id) + write_audit_log( + db, + action="user.password.reset", + actor_user_id=actor_user_id, + detail=compose_audit_detail( + f"target_user_id={user.id}", + f"target_username={user.username}", + "password_updated=true", + "sessions_revoked=true", + ), + ) + db.commit() + except SQLAlchemyError: + db.rollback() + return None updated = get_user_by_id(db, user_id) if updated: @@ -276,22 +288,27 @@ def update_user( if not changed_fields: return serialize_user(user) - write_audit_log( - db, - action="user.update", - actor_user_id=actor_user_id, - detail=compose_audit_detail( - f"target_user_id={user.id}", - f"target_username={user.username}", - describe_changed_fields(changed_fields), - ( - f"status_transition={previous_status}->{user.status}" - if status_changed - else None + try: + write_audit_log( + db, + action="user.update", + actor_user_id=actor_user_id, + detail=compose_audit_detail( + f"target_user_id={user.id}", + f"target_username={user.username}", + describe_changed_fields(changed_fields), + ( + f"status_transition={previous_status}->{user.status}" + if status_changed + else None + ), ), - ), - ) - db.commit() + ) + db.commit() + except SQLAlchemyError: + db.rollback() + return None + updated = get_user_by_id(db, user_id) if updated: queue_user_auth_refresh(updated, status_changed=status_changed) @@ -339,17 +356,21 @@ def set_user_roles( updated = get_user_by_id(db, user_id) if updated: authz = get_user_authorization(db, updated.id) - write_audit_log( - db, - action="user.roles.replace", - actor_user_id=actor_user_id, - detail=compose_audit_detail( - f"target_user_id={updated.id}", - f"target_username={updated.username}", - f"role_codes={summarize_values(sorted(authz.role_codes))}", - ), - ) - db.commit() + try: + write_audit_log( + db, + action="user.roles.replace", + actor_user_id=actor_user_id, + detail=compose_audit_detail( + f"target_user_id={updated.id}", + f"target_username={updated.username}", + f"role_codes={summarize_values(sorted(authz.role_codes))}", + ), + ) + db.commit() + except SQLAlchemyError: + db.rollback() + return None queue_user_auth_refresh(updated) _fire_and_forget( publish_topic(