Skip to content

Commit fa8a429

Browse files
authored
fix(auth): resolve DetachedInstanceError on User.identity during registration (#686)
* ci: add test branch trigger to verify drone pipeline * ci: trigger pipeline test * ci: add docker-compose.ci.yml for pipeline deploy test * ci: remove redundant apk packages, only install bash * ci: drop --no-cache flag from apk add * fix(auth): resolve DetachedInstanceError on User.identity during registration * fix(auth): reject register_init for passwordless/synced identities
1 parent 6a54b22 commit fa8a429

4 files changed

Lines changed: 78 additions & 2 deletions

File tree

.github/drone.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ steps:
105105
- name: docker-socket
106106
path: /var/run/docker.sock
107107
commands:
108-
- apk add --no-cache docker-cli-compose curl bash
108+
- apk add bash
109109
- echo "========================================"
110110
- echo "本地部署测试 全新部署验证"
111111
- echo "========================================"
@@ -159,7 +159,7 @@ steps:
159159
- name: docker-socket
160160
path: /var/run/docker.sock
161161
commands:
162-
- apk add --no-cache docker-cli-compose curl bash
162+
- apk add bash
163163
- echo "========================================"
164164
- echo "本地升级测试 旧版 → 新版数据库迁移验证"
165165
- echo "========================================"
@@ -292,6 +292,7 @@ trigger:
292292
branch:
293293
- main
294294
- release
295+
- ci/test-drone # 临时添加,测试完成后删除
295296
event:
296297
- push
297298
- pull_request

backend/app/api/auth.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,13 @@ async def register_init(
175175
detail="Username already taken. Please choose a different username.",
176176
)
177177

178+
# Reject registration if the identity exists but has no password set (SSO/synced users)
179+
if identity.password_hash is None:
180+
raise HTTPException(
181+
status_code=status.HTTP_400_BAD_REQUEST,
182+
detail="Email already registered via SSO/sync. Please use password reset to set a password, or log in via SSO.",
183+
)
184+
178185
# Verify password outside transaction
179186
if identity.password_hash and not await verify_password_async(data.password, identity.password_hash):
180187
raise HTTPException(
@@ -223,6 +230,8 @@ async def register_init(
223230
user.is_active = is_first_user # Active immediately if first user
224231
user.email_verified = identity.email_verified
225232
await session.flush()
233+
else:
234+
user.identity = identity
226235

227236
# 5. Generate token outside transaction
228237
token = create_access_token(str(user.id), user.role)

backend/app/services/registration_service.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ async def create_user_with_identity(
182182
"registration_source": registration_source,
183183
"is_active": is_active or identity.is_platform_admin,
184184
})
185+
user.identity = identity
185186

186187
# Link to OrgMember if exists
187188
await self.bind_org_member(user)

docker-compose.ci.yml

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# ============================================================
2+
# CI 专用 Docker Compose
3+
# 用于 Drone CI 的本地部署测试和升级测试
4+
# 使用预构建镜像,不构建、不挂载持久化卷
5+
# ============================================================
6+
7+
services:
8+
postgres:
9+
image: postgres:15-alpine
10+
networks:
11+
- default
12+
environment:
13+
POSTGRES_USER: clawith
14+
POSTGRES_PASSWORD: clawith
15+
POSTGRES_DB: clawith
16+
healthcheck:
17+
test: ["CMD-SHELL", "pg_isready -U clawith"]
18+
interval: 5s
19+
timeout: 5s
20+
retries: 5
21+
22+
redis:
23+
image: redis:7-alpine
24+
networks:
25+
- default
26+
healthcheck:
27+
test: ["CMD", "redis-cli", "ping"]
28+
interval: 5s
29+
timeout: 5s
30+
retries: 5
31+
32+
backend:
33+
image: clawith-backend:${IMAGE_TAG:-new}
34+
environment:
35+
DATABASE_URL: postgresql+asyncpg://clawith:clawith@postgres:5432/clawith
36+
REDIS_URL: redis://redis:6379/0
37+
AGENT_DATA_DIR: /data/agents
38+
AGENT_TEMPLATE_DIR: /app/agent_template
39+
SECRET_KEY: ci-test-secret
40+
JWT_SECRET_KEY: ci-test-jwt-secret
41+
PROCESS_ROLE: all
42+
CORS_ORIGINS: '["*"]'
43+
networks:
44+
- default
45+
depends_on:
46+
postgres:
47+
condition: service_healthy
48+
redis:
49+
condition: service_healthy
50+
51+
frontend:
52+
image: clawith-frontend:${IMAGE_TAG:-new}
53+
ports:
54+
- "3008:3000"
55+
environment:
56+
VITE_API_URL: http://localhost:8000
57+
API_UPSTREAM: backend:8000
58+
networks:
59+
- default
60+
depends_on:
61+
- backend
62+
63+
networks:
64+
default:
65+
name: clawith_network

0 commit comments

Comments
 (0)