用户 API Key 管理:增删查、启用签名凭据;升级 SDK
CI / test (push) Successful in 48s

This commit is contained in:
2026-07-22 19:38:14 +08:00
parent 8894330eba
commit a95a8255bf
13 changed files with 1032 additions and 4 deletions
+4
View File
@@ -189,6 +189,10 @@ type Client interface {
ResetTenantUserPassword(ctx context.Context, cred Credentials, homeRegion, domainID, userID string) (string, error)
DeleteTenantUserMfaDevices(ctx context.Context, cred Credentials, homeRegion, domainID, userID string) (int, error)
DeleteTenantUserApiKeys(ctx context.Context, cred Credentials, homeRegion, userID string, includeCurrent bool) (int, error)
// 用户 API 签名 key 管理:列出(标注当前使用)、上传公钥(返回指纹)、按指纹删单把。
ListTenantUserApiKeys(ctx context.Context, cred Credentials, homeRegion, userID string) ([]TenantUserApiKey, error)
UploadTenantUserApiKey(ctx context.Context, cred Credentials, homeRegion, userID, publicKeyPEM string) (string, error)
DeleteTenantUserApiKey(ctx context.Context, cred Credentials, homeRegion, userID, fingerprint string) error
// 域设置:通知收件人、密码策略、身份设置。
GetNotificationRecipients(ctx context.Context, cred Credentials, region, domainID string) (NotificationRecipients, error)
UpdateNotificationRecipients(ctx context.Context, cred Credentials, region, domainID string, emails []string) (NotificationRecipients, error)
+60
View File
@@ -760,6 +760,66 @@ func (c *RealClient) DeleteTenantUserApiKeys(ctx context.Context, cred Credentia
return deleted, nil
}
// TenantUserApiKey 是用户名下的一把 API 签名 key。
type TenantUserApiKey struct {
Fingerprint string `json:"fingerprint"`
TimeCreated *time.Time `json:"timeCreated"`
// IsCurrent 表示该 key 正被当前配置用于签名请求
IsCurrent bool `json:"isCurrent"`
}
// ListTenantUserApiKeys 实现 Client:列出用户的 API 签名 key。
func (c *RealClient) ListTenantUserApiKeys(ctx context.Context, cred Credentials, homeRegion, userID string) ([]TenantUserApiKey, error) {
ic, err := c.identityClientAt(cred, homeRegion)
if err != nil {
return nil, err
}
resp, err := ic.ListApiKeys(ctx, identity.ListApiKeysRequest{UserId: &userID})
if err != nil {
return nil, fmt.Errorf("list api keys: %w", err)
}
keys := make([]TenantUserApiKey, 0, len(resp.Items))
for _, item := range resp.Items {
k := TenantUserApiKey{Fingerprint: deref(item.Fingerprint)}
if item.TimeCreated != nil {
t := item.TimeCreated.Time
k.TimeCreated = &t
}
k.IsCurrent = userID == cred.UserOCID && k.Fingerprint == cred.Fingerprint
keys = append(keys, k)
}
return keys, nil
}
// UploadTenantUserApiKey 实现 Client:为用户上传 RSA 公钥,返回 OCI 回填的指纹。
func (c *RealClient) UploadTenantUserApiKey(ctx context.Context, cred Credentials, homeRegion, userID, publicKeyPEM string) (string, error) {
ic, err := c.identityClientAt(cred, homeRegion)
if err != nil {
return "", err
}
resp, err := ic.UploadApiKey(ctx, identity.UploadApiKeyRequest{
UserId: &userID,
CreateApiKeyDetails: identity.CreateApiKeyDetails{Key: &publicKeyPEM},
})
if err != nil {
return "", fmt.Errorf("upload api key: %w", err)
}
return deref(resp.Fingerprint), nil
}
// DeleteTenantUserApiKey 实现 Client:按指纹删除用户的单把 API key。
func (c *RealClient) DeleteTenantUserApiKey(ctx context.Context, cred Credentials, homeRegion, userID, fingerprint string) error {
ic, err := c.identityClientAt(cred, homeRegion)
if err != nil {
return err
}
_, err = ic.DeleteApiKey(ctx, identity.DeleteApiKeyRequest{UserId: &userID, Fingerprint: &fingerprint})
if err != nil {
return fmt.Errorf("delete api key %s: %w", fingerprint, err)
}
return nil
}
// scimUserID 用经典 OCID 在 Identity Domain 中解析 SCIM 用户 ID。
func scimUserID(ctx context.Context, dc identitydomains.IdentityDomainsClient, classicOCID string) (string, error) {
u, found, err := domainUserByOcid(ctx, dc, classicOCID)