1
0
forked from baron/baron-sso
Files
baron-sso/backend/internal/service/identity_write_service.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)
}