1
0
forked from baron/baron-sso
Files
baron-sso/backend/internal/service/tenant_group_service.go

95 lines
3.0 KiB
Go

package service
import (
"baron-sso-backend/internal/domain"
"baron-sso-backend/internal/repository"
"context"
"log/slog"
)
type TenantGroupService interface {
CreateGroup(ctx context.Context, name, slug, description string) (*domain.TenantGroup, error)
GetGroup(ctx context.Context, id string) (*domain.TenantGroup, error)
ListGroups(ctx context.Context, limit, offset int) ([]domain.TenantGroup, int64, error)
UpdateGroup(ctx context.Context, id string, name, description string) (*domain.TenantGroup, error)
DeleteGroup(ctx context.Context, id string) error
AddTenantToGroup(ctx context.Context, groupID, tenantID string) error
RemoveTenantFromGroup(ctx context.Context, groupID, tenantID string) error
}
type tenantGroupService struct {
repo repository.TenantGroupRepository
keto KetoService
}
func NewTenantGroupService(repo repository.TenantGroupRepository, keto KetoService) TenantGroupService {
return &tenantGroupService{repo: repo, keto: keto}
}
func (s *tenantGroupService) CreateGroup(ctx context.Context, name, slug, description string) (*domain.TenantGroup, error) {
group := &domain.TenantGroup{
Name: name,
Slug: slug,
Description: description,
}
if err := s.repo.Create(ctx, group); err != nil {
return nil, err
}
return group, nil
}
func (s *tenantGroupService) GetGroup(ctx context.Context, id string) (*domain.TenantGroup, error) {
return s.repo.FindByID(ctx, id)
}
func (s *tenantGroupService) ListGroups(ctx context.Context, limit, offset int) ([]domain.TenantGroup, int64, error) {
return s.repo.List(ctx, limit, offset)
}
func (s *tenantGroupService) UpdateGroup(ctx context.Context, id string, name, description string) (*domain.TenantGroup, error) {
group, err := s.repo.FindByID(ctx, id)
if err != nil {
return nil, err
}
group.Name = name
group.Description = description
if err := s.repo.Update(ctx, group); err != nil {
return nil, err
}
return group, nil
}
func (s *tenantGroupService) DeleteGroup(ctx context.Context, id string) error {
return s.repo.Delete(ctx, id)
}
func (s *tenantGroupService) AddTenantToGroup(ctx context.Context, groupID, tenantID string) error {
if err := s.repo.AddTenant(ctx, groupID, tenantID); err != nil {
return err
}
// [Keto] ReBAC: Tenant -> Group membership
if s.keto != nil {
err := s.keto.CreateRelation(ctx, "Tenant", tenantID, "parent_group", groupID)
if err != nil {
slog.Error("Failed to sync Keto relation for tenant group", "tenantID", tenantID, "groupID", groupID, "error", err)
}
}
return nil
}
func (s *tenantGroupService) RemoveTenantFromGroup(ctx context.Context, groupID, tenantID string) error {
if err := s.repo.RemoveTenant(ctx, groupID, tenantID); err != nil {
return err
}
// [Keto] ReBAC: Remove Tenant -> Group membership
if s.keto != nil {
err := s.keto.DeleteRelation(ctx, "Tenant", tenantID, "parent_group", groupID)
if err != nil {
slog.Error("Failed to remove Keto relation for tenant group", "tenantID", tenantID, "groupID", groupID, "error", err)
}
}
return nil
}