202 lines
8.1 KiB
Go
202 lines
8.1 KiB
Go
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
|
|
}
|
|
|
|
// IdentityDomains 列出租户全部 ACTIVE 身份域(域选择器数据源)。
|
|
func (s *OciConfigService) IdentityDomains(ctx context.Context, id uint) ([]oci.IdentityDomain, error) {
|
|
cred, homeRegion, err := s.credentialsAndHomeRegion(ctx, id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return s.client.ListIdentityDomains(ctx, cred, homeRegion)
|
|
}
|
|
|
|
// TenantUsers 列出租户 IAM 用户;domainID 非空只列该身份域。
|
|
func (s *OciConfigService) TenantUsers(ctx context.Context, id uint, domainID string) ([]oci.TenantUser, error) {
|
|
cred, homeRegion, err := s.credentialsAndHomeRegion(ctx, id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return s.client.ListTenantUsers(ctx, cred, homeRegion, domainID)
|
|
}
|
|
|
|
// TenantUserDetail 查用户的域档案与管理员状态(编辑表单预填充用)。
|
|
func (s *OciConfigService) TenantUserDetail(ctx context.Context, id uint, domainID, 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, domainID, userID)
|
|
}
|
|
|
|
// CreateTenantUser 新增用户;名字与姓氏必填(域用户档案要求),
|
|
// 描述缺省用「名 姓」。
|
|
func (s *OciConfigService) CreateTenantUser(ctx context.Context, id uint, domainID string, 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, domainID, in)
|
|
}
|
|
|
|
// UpdateTenantUser 编辑用户资料;nil 字段不修改,全 nil 报错。
|
|
func (s *OciConfigService) UpdateTenantUser(ctx context.Context, id uint, domainID, 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, domainID, userID, in)
|
|
}
|
|
|
|
// IdentitySetting 读取域身份设置(当前只透出主邮箱必填开关)。
|
|
func (s *OciConfigService) IdentitySetting(ctx context.Context, id uint, domainID string) (oci.IdentitySettingInfo, error) {
|
|
cred, homeRegion, err := s.credentialsAndHomeRegion(ctx, id)
|
|
if err != nil {
|
|
return oci.IdentitySettingInfo{}, err
|
|
}
|
|
return s.client.GetIdentitySetting(ctx, cred, homeRegion, domainID)
|
|
}
|
|
|
|
// UpdateIdentitySetting 修改「用户需要提供主电子邮件地址」开关。
|
|
func (s *OciConfigService) UpdateIdentitySetting(ctx context.Context, id uint, domainID string, 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, domainID, primaryEmailRequired)
|
|
}
|
|
|
|
// DeleteTenantUser 删除 IAM 用户;拒绝删除当前配置正在使用的用户。
|
|
func (s *OciConfigService) DeleteTenantUser(ctx context.Context, id uint, domainID, 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, domainID, userID)
|
|
}
|
|
|
|
// ResetTenantUserPassword 重置用户控制台密码,返回一次性新密码。
|
|
func (s *OciConfigService) ResetTenantUserPassword(ctx context.Context, id uint, domainID, userID string) (string, error) {
|
|
cred, homeRegion, err := s.credentialsAndHomeRegion(ctx, id)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return s.client.ResetTenantUserPassword(ctx, cred, homeRegion, domainID, userID)
|
|
}
|
|
|
|
// DeleteTenantUserMfa 清除用户全部 MFA,返回删除的经典 TOTP 设备数。
|
|
func (s *OciConfigService) DeleteTenantUserMfa(ctx context.Context, id uint, domainID, userID string) (int, error) {
|
|
cred, homeRegion, err := s.credentialsAndHomeRegion(ctx, id)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
return s.client.DeleteTenantUserMfaDevices(ctx, cred, homeRegion, domainID, 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, domainID string) (oci.NotificationRecipients, error) {
|
|
cred, homeRegion, err := s.credentialsAndHomeRegion(ctx, id)
|
|
if err != nil {
|
|
return oci.NotificationRecipients{}, err
|
|
}
|
|
return s.client.GetNotificationRecipients(ctx, cred, homeRegion, domainID)
|
|
}
|
|
|
|
// UpdateNotificationRecipients 把域通知改为只发给指定收件人;
|
|
// 收件人为空表示关闭 test mode 恢复默认发送。
|
|
func (s *OciConfigService) UpdateNotificationRecipients(ctx context.Context, id uint, domainID string, 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, domainID, 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, domainID string) ([]oci.PasswordPolicyInfo, error) {
|
|
cred, homeRegion, err := s.credentialsAndHomeRegion(ctx, id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return s.client.ListPasswordPolicies(ctx, cred, homeRegion, domainID)
|
|
}
|
|
|
|
// UpdatePasswordPolicy 修改域密码策略的过期天数或最小长度。
|
|
func (s *OciConfigService) UpdatePasswordPolicy(ctx context.Context, id uint, domainID, 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, domainID, policyID, in)
|
|
}
|