feat: Z38 grant Yuheng agents ready-to-use access

Complete permissions during every bind and token path, expose effective access in the console, and keep the platform return path globally available.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
whm
2026-08-07 16:11:13 +08:00
parent 4f9087bd38
commit 43dc708f1e
11 changed files with 285 additions and 145 deletions

View File

@@ -128,16 +128,17 @@ type BindCodeRedeemReq struct {
}
type BindCodeRedeemResp struct {
OK bool `json:"ok"`
TenantID int64 `json:"tenant_id"`
AgentID int64 `json:"agent_id"`
ClientID string `json:"client_id,omitempty"`
ClientSecret string `json:"client_secret,omitempty"` // Z28绑定成功回传便于直接换票
ChannelID string `json:"channel_id"`
OnlineDBID string `json:"online_db_id"`
DatabaseName string `json:"database_name,omitempty"`
SyncBound bool `json:"sync_bound"`
Message string `json:"message,omitempty"`
OK bool `json:"ok"`
TenantID int64 `json:"tenant_id"`
AgentID int64 `json:"agent_id"`
ClientID string `json:"client_id,omitempty"`
ClientSecret string `json:"client_secret,omitempty"` // Z28绑定成功回传便于直接换票
ChannelID string `json:"channel_id"`
OnlineDBID string `json:"online_db_id"`
DatabaseName string `json:"database_name,omitempty"`
SyncBound bool `json:"sync_bound"`
Permissions []string `json:"permissions"`
Message string `json:"message,omitempty"`
}
func (l *AuthLogic) RedeemBindCode(req BindCodeRedeemReq) (*BindCodeRedeemResp, error) {
@@ -175,6 +176,10 @@ func (l *AuthLogic) RedeemBindCode(req BindCodeRedeemReq) (*BindCodeRedeemResp,
if err != nil {
return nil, err
}
updated, err = l.ensureYuhengAgentPerms(updated)
if err != nil {
return nil, err
}
// Z28回传可换票凭证
secret, err := l.svcCtx.Agents.RotateSecret(l.ctx, updated.TenantID, updated.AgentID)
if err != nil {
@@ -193,7 +198,8 @@ func (l *AuthLogic) RedeemBindCode(req BindCodeRedeemReq) (*BindCodeRedeemResp,
OnlineDBID: updated.OnlineDBID,
DatabaseName: updated.DatabaseName,
SyncBound: true,
Message: "绑定成功;请保存 client_id/client_secret 用于换票",
Permissions: append([]string{}, updated.Perms...),
Message: "绑定并授权完成;请保存 client_id/client_secret 用于换票",
}, nil
}
@@ -320,16 +326,17 @@ type PhoneConfirmReq struct {
}
type PhoneConfirmResp struct {
OK bool `json:"ok"`
TenantID int64 `json:"tenant_id"`
AgentID int64 `json:"agent_id"`
ClientID string `json:"client_id,omitempty"`
ClientSecret string `json:"client_secret,omitempty"` // Z28绑定成功回传
ChannelID string `json:"channel_id"`
OnlineDBID string `json:"online_db_id"`
DatabaseName string `json:"database_name,omitempty"`
SyncBound bool `json:"sync_bound"`
Message string `json:"message,omitempty"`
OK bool `json:"ok"`
TenantID int64 `json:"tenant_id"`
AgentID int64 `json:"agent_id"`
ClientID string `json:"client_id,omitempty"`
ClientSecret string `json:"client_secret,omitempty"` // Z28绑定成功回传
ChannelID string `json:"channel_id"`
OnlineDBID string `json:"online_db_id"`
DatabaseName string `json:"database_name,omitempty"`
SyncBound bool `json:"sync_bound"`
Permissions []string `json:"permissions"`
Message string `json:"message,omitempty"`
}
func (l *AuthLogic) requirePhoneBindProof(phone string, attested bool, smsCode string) error {
@@ -386,11 +393,18 @@ func (l *AuthLogic) PhoneConfirm(req PhoneConfirmReq) (*PhoneConfirmResp, error)
if u.TenantID <= 0 {
return nil, fmt.Errorf("该账号尚未加入公司")
}
updated, secret, err := l.bindUserHostSync(u, hostKey, req.Name, req.LocalDBID, "phone-confirm")
updated, err := l.bindUserHostSync(u, hostKey, req.Name, req.LocalDBID, "phone-confirm")
if err != nil {
return nil, err
}
_ = l.ensureAgentSyncPerm(updated)
updated, err = l.ensureYuhengAgentPerms(updated)
if err != nil {
return nil, err
}
secret, err := l.svcCtx.Agents.RotateSecret(l.ctx, updated.TenantID, updated.AgentID)
if err != nil {
return nil, fmt.Errorf("rotate client_secret: %w", err)
}
_ = l.writeBindAudit("phone_confirm_bind", u.TenantID, updated.AgentID, map[string]any{
"phone": phone, "user_id": u.UserID, "channel_id": updated.ChannelID, "online_db_id": updated.OnlineDBID,
})
@@ -404,7 +418,8 @@ func (l *AuthLogic) PhoneConfirm(req PhoneConfirmReq) (*PhoneConfirmResp, error)
OnlineDBID: updated.OnlineDBID,
DatabaseName: updated.DatabaseName,
SyncBound: true,
Message: "绑定成功;请保存 client_id/client_secret 用于换票",
Permissions: append([]string{}, updated.Perms...),
Message: "绑定并授权完成;请保存 client_id/client_secret 用于换票",
}, nil
}