forked from baron/baron-sso
80 lines
1.9 KiB
Go
80 lines
1.9 KiB
Go
package service
|
|
|
|
import (
|
|
"baron-sso-backend/internal/domain"
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type IdentityUpdateRequest struct {
|
|
IdentityID string
|
|
Traits map[string]any
|
|
State string
|
|
Reason string
|
|
Source string
|
|
}
|
|
|
|
type IdentityWriteService interface {
|
|
GetIdentity(ctx context.Context, identityID string) (*KratosIdentity, error)
|
|
UpdateIdentity(ctx context.Context, req IdentityUpdateRequest) (*KratosIdentity, error)
|
|
}
|
|
|
|
type identityWriteService struct {
|
|
kratos KratosAdminService
|
|
redis domain.RedisRepository
|
|
}
|
|
|
|
func NewIdentityWriteService(kratos KratosAdminService, redis domain.RedisRepository) IdentityWriteService {
|
|
return &identityWriteService{
|
|
kratos: kratos,
|
|
redis: redis,
|
|
}
|
|
}
|
|
|
|
func (s *identityWriteService) GetIdentity(ctx context.Context, identityID string) (*KratosIdentity, error) {
|
|
if s == nil || s.kratos == nil {
|
|
return nil, fmt.Errorf("kratos admin service is required")
|
|
}
|
|
return s.kratos.GetIdentity(ctx, identityID)
|
|
}
|
|
|
|
func (s *identityWriteService) UpdateIdentity(ctx context.Context, req IdentityUpdateRequest) (*KratosIdentity, error) {
|
|
if s == nil || s.kratos == nil {
|
|
return nil, fmt.Errorf("kratos admin service is required")
|
|
}
|
|
updated, err := s.kratos.UpdateIdentity(ctx, req.IdentityID, req.Traits, req.State)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
_ = s.markIdentityMirrorStale(req)
|
|
return updated, nil
|
|
}
|
|
|
|
func (s *identityWriteService) markIdentityMirrorStale(req IdentityUpdateRequest) error {
|
|
if s == nil || s.redis == nil {
|
|
return nil
|
|
}
|
|
now := time.Now().UTC()
|
|
reason := strings.TrimSpace(req.Reason)
|
|
if reason == "" {
|
|
reason = "identity_write"
|
|
}
|
|
source := strings.TrimSpace(req.Source)
|
|
if source != "" {
|
|
reason = source + ": " + reason
|
|
}
|
|
state := domain.IdentityCacheStatus{
|
|
Status: "stale",
|
|
LastError: reason,
|
|
UpdatedAt: &now,
|
|
}
|
|
raw, err := json.Marshal(state)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return s.redis.Set("identity:mirror:state", string(raw), 0)
|
|
}
|