初始提交:OCI 面板后端(含 GenAI 网关一期)
This commit is contained in:
@@ -0,0 +1,192 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"oci-portal/internal/model"
|
||||
"oci-portal/internal/oci"
|
||||
)
|
||||
|
||||
// homeRegionOf 返回配置的 home region 名称;本地表查不到时退回默认区域。
|
||||
// 用户管理等 IAM 写操作必须发往 home region。
|
||||
func homeRegionOf(cfg *model.OciConfig) string {
|
||||
if info, ok := oci.RegionByKey(cfg.HomeRegionKey); ok {
|
||||
return info.Name
|
||||
}
|
||||
return cfg.Region
|
||||
}
|
||||
|
||||
// credentialsAndHomeRegion 一次取回凭据与 home region。
|
||||
func (s *OciConfigService) credentialsAndHomeRegion(ctx context.Context, id uint) (oci.Credentials, string, error) {
|
||||
cfg, err := s.Get(ctx, id)
|
||||
if err != nil {
|
||||
return oci.Credentials{}, "", err
|
||||
}
|
||||
cred, err := s.credentialsOf(cfg)
|
||||
if err != nil {
|
||||
return oci.Credentials{}, "", err
|
||||
}
|
||||
return cred, homeRegionOf(cfg), nil
|
||||
}
|
||||
|
||||
// TenantUsers 列出租户 IAM 用户。
|
||||
func (s *OciConfigService) TenantUsers(ctx context.Context, id uint) ([]oci.TenantUser, error) {
|
||||
cred, err := s.credentialsByID(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return s.client.ListTenantUsers(ctx, cred)
|
||||
}
|
||||
|
||||
// TenantUserDetail 查用户的域档案与管理员状态(编辑表单预填充用)。
|
||||
func (s *OciConfigService) TenantUserDetail(ctx context.Context, id uint, userID string) (oci.TenantUserDetail, error) {
|
||||
cred, homeRegion, err := s.credentialsAndHomeRegion(ctx, id)
|
||||
if err != nil {
|
||||
return oci.TenantUserDetail{}, err
|
||||
}
|
||||
return s.client.GetTenantUserDetail(ctx, cred, homeRegion, userID)
|
||||
}
|
||||
|
||||
// CreateTenantUser 新增用户;名字与姓氏必填(域用户档案要求),
|
||||
// 描述缺省用「名 姓」。
|
||||
func (s *OciConfigService) CreateTenantUser(ctx context.Context, id uint, in oci.CreateTenantUserInput) (oci.TenantUser, error) {
|
||||
if strings.TrimSpace(in.Name) == "" {
|
||||
return oci.TenantUser{}, fmt.Errorf("create tenant user: name is required")
|
||||
}
|
||||
if strings.TrimSpace(in.GivenName) == "" || strings.TrimSpace(in.FamilyName) == "" {
|
||||
return oci.TenantUser{}, fmt.Errorf("create tenant user: givenName and familyName are required")
|
||||
}
|
||||
if in.Description == "" {
|
||||
in.Description = strings.TrimSpace(in.GivenName + " " + in.FamilyName)
|
||||
}
|
||||
cred, homeRegion, err := s.credentialsAndHomeRegion(ctx, id)
|
||||
if err != nil {
|
||||
return oci.TenantUser{}, err
|
||||
}
|
||||
return s.client.CreateTenantUser(ctx, cred, homeRegion, in)
|
||||
}
|
||||
|
||||
// UpdateTenantUser 编辑用户资料;nil 字段不修改,全 nil 报错。
|
||||
func (s *OciConfigService) UpdateTenantUser(ctx context.Context, id uint, userID string, in oci.UpdateTenantUserInput) (oci.TenantUser, error) {
|
||||
hasField := in.Description != nil || in.Email != nil || in.GivenName != nil || in.FamilyName != nil
|
||||
hasAdmin := in.GrantDomainAdmin != nil || in.AddToAdminGroup != nil
|
||||
if !hasField && !hasAdmin {
|
||||
return oci.TenantUser{}, fmt.Errorf("update tenant user: nothing to update")
|
||||
}
|
||||
cred, homeRegion, err := s.credentialsAndHomeRegion(ctx, id)
|
||||
if err != nil {
|
||||
return oci.TenantUser{}, err
|
||||
}
|
||||
return s.client.UpdateTenantUser(ctx, cred, homeRegion, userID, in)
|
||||
}
|
||||
|
||||
// IdentitySetting 读取域身份设置(当前只透出主邮箱必填开关)。
|
||||
func (s *OciConfigService) IdentitySetting(ctx context.Context, id uint) (oci.IdentitySettingInfo, error) {
|
||||
cred, homeRegion, err := s.credentialsAndHomeRegion(ctx, id)
|
||||
if err != nil {
|
||||
return oci.IdentitySettingInfo{}, err
|
||||
}
|
||||
return s.client.GetIdentitySetting(ctx, cred, homeRegion)
|
||||
}
|
||||
|
||||
// UpdateIdentitySetting 修改「用户需要提供主电子邮件地址」开关。
|
||||
func (s *OciConfigService) UpdateIdentitySetting(ctx context.Context, id uint, primaryEmailRequired bool) (oci.IdentitySettingInfo, error) {
|
||||
cred, homeRegion, err := s.credentialsAndHomeRegion(ctx, id)
|
||||
if err != nil {
|
||||
return oci.IdentitySettingInfo{}, err
|
||||
}
|
||||
return s.client.UpdateIdentitySetting(ctx, cred, homeRegion, primaryEmailRequired)
|
||||
}
|
||||
|
||||
// DeleteTenantUser 删除 IAM 用户;拒绝删除当前配置正在使用的用户。
|
||||
func (s *OciConfigService) DeleteTenantUser(ctx context.Context, id uint, userID string) error {
|
||||
cred, homeRegion, err := s.credentialsAndHomeRegion(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if userID == cred.UserOCID {
|
||||
return fmt.Errorf("delete tenant user: refusing to delete the user this config signs requests with")
|
||||
}
|
||||
return s.client.DeleteTenantUser(ctx, cred, homeRegion, userID)
|
||||
}
|
||||
|
||||
// ResetTenantUserPassword 重置用户控制台密码,返回一次性新密码。
|
||||
func (s *OciConfigService) ResetTenantUserPassword(ctx context.Context, id uint, userID string) (string, error) {
|
||||
cred, homeRegion, err := s.credentialsAndHomeRegion(ctx, id)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return s.client.ResetTenantUserPassword(ctx, cred, homeRegion, userID)
|
||||
}
|
||||
|
||||
// DeleteTenantUserMfa 清除用户全部 MFA,返回删除的经典 TOTP 设备数。
|
||||
func (s *OciConfigService) DeleteTenantUserMfa(ctx context.Context, id uint, userID string) (int, error) {
|
||||
cred, homeRegion, err := s.credentialsAndHomeRegion(ctx, id)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return s.client.DeleteTenantUserMfaDevices(ctx, cred, homeRegion, userID)
|
||||
}
|
||||
|
||||
// DeleteTenantUserApiKeys 删除用户的 API Key;默认保留当前配置使用的指纹。
|
||||
func (s *OciConfigService) DeleteTenantUserApiKeys(ctx context.Context, id uint, userID string, includeCurrent bool) (int, error) {
|
||||
cred, homeRegion, err := s.credentialsAndHomeRegion(ctx, id)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return s.client.DeleteTenantUserApiKeys(ctx, cred, homeRegion, userID, includeCurrent)
|
||||
}
|
||||
|
||||
// NotificationRecipients 查询域通知收件人设置。
|
||||
func (s *OciConfigService) NotificationRecipients(ctx context.Context, id uint) (oci.NotificationRecipients, error) {
|
||||
cred, homeRegion, err := s.credentialsAndHomeRegion(ctx, id)
|
||||
if err != nil {
|
||||
return oci.NotificationRecipients{}, err
|
||||
}
|
||||
return s.client.GetNotificationRecipients(ctx, cred, homeRegion)
|
||||
}
|
||||
|
||||
// UpdateNotificationRecipients 把域通知改为只发给指定收件人;
|
||||
// 收件人为空表示关闭 test mode 恢复默认发送。
|
||||
func (s *OciConfigService) UpdateNotificationRecipients(ctx context.Context, id uint, emails []string) (oci.NotificationRecipients, error) {
|
||||
if err := validateEmails(emails); err != nil {
|
||||
return oci.NotificationRecipients{}, err
|
||||
}
|
||||
cred, homeRegion, err := s.credentialsAndHomeRegion(ctx, id)
|
||||
if err != nil {
|
||||
return oci.NotificationRecipients{}, err
|
||||
}
|
||||
return s.client.UpdateNotificationRecipients(ctx, cred, homeRegion, emails)
|
||||
}
|
||||
|
||||
func validateEmails(emails []string) error {
|
||||
for _, email := range emails {
|
||||
if !strings.Contains(email, "@") || strings.ContainsAny(email, " \t") {
|
||||
return fmt.Errorf("update notification recipients: invalid email %q", email)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PasswordPolicies 列出域密码策略。
|
||||
func (s *OciConfigService) PasswordPolicies(ctx context.Context, id uint) ([]oci.PasswordPolicyInfo, error) {
|
||||
cred, homeRegion, err := s.credentialsAndHomeRegion(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return s.client.ListPasswordPolicies(ctx, cred, homeRegion)
|
||||
}
|
||||
|
||||
// UpdatePasswordPolicy 修改域密码策略的过期天数或最小长度。
|
||||
func (s *OciConfigService) UpdatePasswordPolicy(ctx context.Context, id uint, policyID string, in oci.UpdatePasswordPolicyInput) (oci.PasswordPolicyInfo, error) {
|
||||
if in.PasswordExpiresAfter == nil && in.MinLength == nil {
|
||||
return oci.PasswordPolicyInfo{}, fmt.Errorf("update password policy: nothing to update")
|
||||
}
|
||||
cred, homeRegion, err := s.credentialsAndHomeRegion(ctx, id)
|
||||
if err != nil {
|
||||
return oci.PasswordPolicyInfo{}, err
|
||||
}
|
||||
return s.client.UpdatePasswordPolicy(ctx, cred, homeRegion, policyID, in)
|
||||
}
|
||||
Reference in New Issue
Block a user