VerifactuMidAPI/internal/cert/storage.go

113 lines
2.1 KiB
Go

package cert
import (
"crypto/sha256"
"encoding/hex"
"fmt"
"os"
"path/filepath"
"sync"
)
type Storage struct {
basePath string
certs map[string]*Certificate
mu sync.RWMutex
}
type Certificate struct {
ID string
OriginalPath string
StoredPath string
Password string
}
func NewStorage(basePath string) *Storage {
if basePath == "" {
basePath = "./certs/"
}
return &Storage{
basePath: basePath,
certs: make(map[string]*Certificate),
}
}
func (s *Storage) Init() error {
if err := os.MkdirAll(s.basePath, 0700); err != nil {
return fmt.Errorf("creating cert storage directory: %w", err)
}
return nil
}
func (s *Storage) Store(id, origPath, password string) (string, error) {
s.mu.Lock()
defer s.mu.Unlock()
exists := false
for _, c := range s.certs {
if c.ID == id {
exists = true
break
}
}
if exists {
return "", fmt.Errorf("certificate already exists with this ID")
}
ext := filepath.Ext(origPath)
storedFilename := fmt.Sprintf("%s%s", id, ext)
storedPath := filepath.Join(s.basePath, storedFilename)
data, err := os.ReadFile(origPath)
if err != nil {
return "", fmt.Errorf("reading certificate file: %w", err)
}
if err := os.WriteFile(storedPath, data, 0600); err != nil {
return "", fmt.Errorf("storing certificate: %w", err)
}
cert := &Certificate{
ID: id,
OriginalPath: origPath,
StoredPath: storedPath,
Password: password,
}
s.certs[id] = cert
return storedPath, nil
}
func (s *Storage) Get(id string) (*Certificate, error) {
s.mu.RLock()
defer s.mu.RUnlock()
cert, ok := s.certs[id]
if !ok {
return nil, fmt.Errorf("certificate not found")
}
return cert, nil
}
func (s *Storage) Delete(id string) error {
s.mu.Lock()
defer s.mu.Unlock()
cert, ok := s.certs[id]
if !ok {
return fmt.Errorf("certificate not found")
}
if err := os.Remove(cert.StoredPath); err != nil {
return fmt.Errorf("removing certificate file: %w", err)
}
delete(s.certs, id)
return nil
}
func GenerateID() string {
hash := sha256.Sum256([]byte(fmt.Sprintf("%d", os.Getpid())))
return hex.EncodeToString(hash[:])[:16]
}