Files
certctl/internal/service/issuer.go
T
2026-03-14 20:01:53 -04:00

171 lines
4.7 KiB
Go

package service
import (
"context"
"fmt"
"github.com/shankar0123/certctl/internal/domain"
"github.com/shankar0123/certctl/internal/repository"
)
// IssuerService provides business logic for certificate issuer management.
type IssuerService struct {
issuerRepo repository.IssuerRepository
auditService *AuditService
}
// NewIssuerService creates a new issuer service.
func NewIssuerService(
issuerRepo repository.IssuerRepository,
auditService *AuditService,
) *IssuerService {
return &IssuerService{
issuerRepo: issuerRepo,
auditService: auditService,
}
}
// List returns a paginated list of issuers.
func (s *IssuerService) List(ctx context.Context, page, perPage int) ([]*domain.Issuer, int64, error) {
if page < 1 {
page = 1
}
if perPage < 1 {
perPage = 50
}
offset := int64((page - 1) * perPage)
issuers, total, err := s.issuerRepo.List(ctx, offset, int64(perPage))
if err != nil {
return nil, 0, fmt.Errorf("failed to list issuers: %w", err)
}
return issuers, total, nil
}
// Get retrieves an issuer by ID.
func (s *IssuerService) Get(ctx context.Context, id string) (*domain.Issuer, error) {
issuer, err := s.issuerRepo.Get(ctx, id)
if err != nil {
return nil, fmt.Errorf("failed to get issuer %s: %w", id, err)
}
return issuer, nil
}
// Create validates and stores a new issuer.
func (s *IssuerService) Create(ctx context.Context, issuer *domain.Issuer, actor string) error {
if issuer.Name == "" {
return fmt.Errorf("issuer name is required")
}
issuer.ID = generateID("issuer")
if err := s.issuerRepo.Create(ctx, issuer); err != nil {
return fmt.Errorf("failed to create issuer: %w", err)
}
if s.auditService != nil {
_ = s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "create_issuer", "issuer", issuer.ID, nil)
}
return nil
}
// Update modifies an existing issuer.
func (s *IssuerService) Update(ctx context.Context, id string, issuer *domain.Issuer, actor string) error {
if issuer.Name == "" {
return fmt.Errorf("issuer name is required")
}
issuer.ID = id
if err := s.issuerRepo.Update(ctx, issuer); err != nil {
return fmt.Errorf("failed to update issuer %s: %w", id, err)
}
if s.auditService != nil {
_ = s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "update_issuer", "issuer", id, nil)
}
return nil
}
// Delete removes an issuer.
func (s *IssuerService) Delete(ctx context.Context, id string, actor string) error {
if err := s.issuerRepo.Delete(ctx, id); err != nil {
return fmt.Errorf("failed to delete issuer %s: %w", id, err)
}
if s.auditService != nil {
_ = s.auditService.RecordEvent(ctx, actor, domain.ActorTypeUser, "delete_issuer", "issuer", id, nil)
}
return nil
}
// TestConnection verifies the issuer connection.
func (s *IssuerService) TestConnection(ctx context.Context, id string) error {
issuer, err := s.issuerRepo.Get(ctx, id)
if err != nil {
return fmt.Errorf("issuer not found: %w", err)
}
// TODO: Implement actual connection test based on issuer type
if issuer == nil {
return fmt.Errorf("issuer not found")
}
return nil
}
// ListIssuers returns paginated issuers (handler interface method).
func (s *IssuerService) ListIssuers(page, perPage int) ([]domain.Issuer, int64, error) {
if page < 1 {
page = 1
}
if perPage < 1 {
perPage = 50
}
offset := int64((page - 1) * perPage)
issuers, total, err := s.issuerRepo.List(context.Background(), offset, int64(perPage))
if err != nil {
return nil, 0, fmt.Errorf("failed to list issuers: %w", err)
}
// Convert pointers to values for the handler interface
var result []domain.Issuer
for _, i := range issuers {
if i != nil {
result = append(result, *i)
}
}
return result, total, nil
}
// GetIssuer returns a single issuer (handler interface method).
func (s *IssuerService) GetIssuer(id string) (*domain.Issuer, error) {
return s.issuerRepo.Get(context.Background(), id)
}
// CreateIssuer creates a new issuer (handler interface method).
func (s *IssuerService) CreateIssuer(issuer domain.Issuer) (*domain.Issuer, error) {
issuer.ID = generateID("issuer")
if err := s.issuerRepo.Create(context.Background(), &issuer); err != nil {
return nil, fmt.Errorf("failed to create issuer: %w", err)
}
return &issuer, nil
}
// UpdateIssuer modifies an issuer (handler interface method).
func (s *IssuerService) UpdateIssuer(id string, issuer domain.Issuer) (*domain.Issuer, error) {
issuer.ID = id
if err := s.issuerRepo.Update(context.Background(), &issuer); err != nil {
return nil, fmt.Errorf("failed to update issuer: %w", err)
}
return &issuer, nil
}
// DeleteIssuer removes an issuer (handler interface method).
func (s *IssuerService) DeleteIssuer(id string) error {
return s.issuerRepo.Delete(context.Background(), id)
}