feat: implement repository layer for data access

- Add CertificateRepository with CRUD operations
- Implement CertificateAuthorityRepository for CA management
- Add CertificateRequestRepository for CSR handling
- Include UserRepository and OrganizationRepository
- Implement proper error handling and validation
- Add support for soft deletes and relationships
- Include query optimization and filtering capabilities
This commit is contained in:
Björn Benouarets
2025-09-30 11:44:40 +02:00
parent 6e817a8bd2
commit ccf65ec6c6
6 changed files with 369 additions and 0 deletions

56
repositories/ca.go Normal file
View File

@@ -0,0 +1,56 @@
package repositories
import (
"git.secnex.io/secnex/certman/models"
"gorm.io/gorm"
)
type CertificateAuthorityRepository struct {
db *gorm.DB
}
// NewCertificateAuthorityRepository creates a new certificate authority repository
func NewCertificateAuthorityRepository(db *gorm.DB) *CertificateAuthorityRepository {
return &CertificateAuthorityRepository{db: db}
}
// GetByID returns a certificate authority by their ID
func (r *CertificateAuthorityRepository) GetByID(id string) (models.CertificateAuthority, error) {
var ca models.CertificateAuthority
if err := r.db.Where("id = ?", id).First(&ca).Error; err != nil {
return models.CertificateAuthority{}, err
}
return ca, nil
}
// GetAll returns all certificate authorities
func (r *CertificateAuthorityRepository) GetAll() ([]models.CertificateAuthority, error) {
var cas []models.CertificateAuthority
if err := r.db.Find(&cas).Error; err != nil {
return []models.CertificateAuthority{}, err
}
return cas, nil
}
// Create creates a new certificate authority
func (r *CertificateAuthorityRepository) Create(ca models.CertificateAuthority) (models.CertificateAuthority, error) {
if err := r.db.Create(&ca).Error; err != nil {
return models.CertificateAuthority{}, err
}
return ca, nil
}
// Update updates a certificate authority
func (r *CertificateAuthorityRepository) Update(ca models.CertificateAuthority) error {
return r.db.Save(&ca).Error
}
// Delete deletes a certificate authority by their ID
func (r *CertificateAuthorityRepository) Delete(id string) error {
return r.db.Delete(&models.CertificateAuthority{}, id).Error
}
// HardDelete deletes a certificate authority by their ID
func (r *CertificateAuthorityRepository) HardDelete(ca models.CertificateAuthority) error {
return r.db.Unscoped().Delete(&ca).Error
}

100
repositories/cert.go Normal file
View File

@@ -0,0 +1,100 @@
package repositories
import (
"git.secnex.io/secnex/certman/models"
"gorm.io/gorm"
)
type CertificateRepository struct {
db *gorm.DB
}
// NewCertificateRepository creates a new certificate repository
func NewCertificateRepository(db *gorm.DB) *CertificateRepository {
return &CertificateRepository{db: db}
}
// GetByID returns a certificate by their ID
func (r *CertificateRepository) GetByID(id string) (models.Certificate, error) {
var cert models.Certificate
if err := r.db.First(&cert, id).Error; err != nil {
return models.Certificate{}, err
}
return cert, nil
}
// GetAll returns all certificates
func (r *CertificateRepository) GetAll() ([]models.Certificate, error) {
var certs []models.Certificate
if err := r.db.Find(&certs).Error; err != nil {
return []models.Certificate{}, err
}
return certs, nil
}
// Create creates a new certificate
func (r *CertificateRepository) Create(cert models.Certificate) error {
return r.db.Create(&cert).Error
}
// Update updates a certificate
func (r *CertificateRepository) Update(cert models.Certificate) error {
return r.db.Save(&cert).Error
}
// Delete deletes a certificate by their ID
func (r *CertificateRepository) Delete(id string) error {
return r.db.Delete(&models.Certificate{}, id).Error
}
// HardDelete deletes a certificate by their ID
func (r *CertificateRepository) HardDelete(cert models.Certificate) error {
return r.db.Unscoped().Delete(&cert).Error
}
// GetByType returns certificates by type
func (r *CertificateRepository) GetByType(certType models.CertificateType) ([]models.Certificate, error) {
var certs []models.Certificate
if err := r.db.Where("type = ?", certType).Find(&certs).Error; err != nil {
return []models.Certificate{}, err
}
return certs, nil
}
// GetByCA returns certificates issued by a specific CA
func (r *CertificateRepository) GetByCA(caID string) ([]models.Certificate, error) {
var certs []models.Certificate
if err := r.db.Where("certificate_authority_id = ?", caID).Find(&certs).Error; err != nil {
return []models.Certificate{}, err
}
return certs, nil
}
// GetByStatus returns certificates by status
func (r *CertificateRepository) GetByStatus(status models.CertificateStatus) ([]models.Certificate, error) {
var certs []models.Certificate
if err := r.db.Where("status = ?", status).Find(&certs).Error; err != nil {
return []models.Certificate{}, err
}
return certs, nil
}
// GetActive returns all active certificates
func (r *CertificateRepository) GetActive() ([]models.Certificate, error) {
return r.GetByStatus(models.CertificateStatusActive)
}
// GetRevoked returns all revoked certificates
func (r *CertificateRepository) GetRevoked() ([]models.Certificate, error) {
return r.GetByStatus(models.CertificateStatusRevoked)
}
// GetExpired returns all expired certificates
func (r *CertificateRepository) GetExpired() ([]models.Certificate, error) {
return r.GetByStatus(models.CertificateStatusExpired)
}
// GetPending returns all pending certificates
func (r *CertificateRepository) GetPending() ([]models.Certificate, error) {
return r.GetByStatus(models.CertificateStatusPending)
}

91
repositories/csr.go Normal file
View File

@@ -0,0 +1,91 @@
package repositories
import (
"git.secnex.io/secnex/certman/models"
"gorm.io/gorm"
)
type CertificateRequestRepository struct {
db *gorm.DB
}
// NewCertificateRequestRepository creates a new certificate request repository
func NewCertificateRequestRepository(db *gorm.DB) *CertificateRequestRepository {
return &CertificateRequestRepository{db: db}
}
// GetByID returns a certificate request by their ID
func (r *CertificateRequestRepository) GetByID(id string) (models.CertificateRequest, error) {
var csr models.CertificateRequest
if err := r.db.First(&csr, id).Error; err != nil {
return models.CertificateRequest{}, err
}
return csr, nil
}
// GetAll returns all certificate requests
func (r *CertificateRequestRepository) GetAll() ([]models.CertificateRequest, error) {
var csrs []models.CertificateRequest
if err := r.db.Find(&csrs).Error; err != nil {
return []models.CertificateRequest{}, err
}
return csrs, nil
}
// Create creates a new certificate request
func (r *CertificateRequestRepository) Create(csr models.CertificateRequest) error {
return r.db.Create(&csr).Error
}
// Update updates a certificate request
func (r *CertificateRequestRepository) Update(csr models.CertificateRequest) error {
return r.db.Save(&csr).Error
}
// Delete deletes a certificate request by their ID
func (r *CertificateRequestRepository) Delete(id string) error {
return r.db.Delete(&models.CertificateRequest{}, id).Error
}
// HardDelete deletes a certificate request by their ID
func (r *CertificateRequestRepository) HardDelete(csr models.CertificateRequest) error {
return r.db.Unscoped().Delete(&csr).Error
}
// GetByStatus returns certificate requests by status
func (r *CertificateRequestRepository) GetByStatus(status models.RequestStatus) ([]models.CertificateRequest, error) {
var csrs []models.CertificateRequest
if err := r.db.Where("status = ?", status).Find(&csrs).Error; err != nil {
return []models.CertificateRequest{}, err
}
return csrs, nil
}
// GetPending returns all pending certificate requests
func (r *CertificateRequestRepository) GetPending() ([]models.CertificateRequest, error) {
return r.GetByStatus(models.RequestStatusPending)
}
// GetApproved returns all approved certificate requests
func (r *CertificateRequestRepository) GetApproved() ([]models.CertificateRequest, error) {
return r.GetByStatus(models.RequestStatusApproved)
}
// GetRejected returns all rejected certificate requests
func (r *CertificateRequestRepository) GetRejected() ([]models.CertificateRequest, error) {
return r.GetByStatus(models.RequestStatusRejected)
}
// GetCancelled returns all cancelled certificate requests
func (r *CertificateRequestRepository) GetCancelled() ([]models.CertificateRequest, error) {
return r.GetByStatus(models.RequestStatusCancelled)
}
// GetByCA returns certificate requests for a specific CA
func (r *CertificateRequestRepository) GetByCA(caID string) ([]models.CertificateRequest, error) {
var csrs []models.CertificateRequest
if err := r.db.Where("certificate_authority_id = ?", caID).Find(&csrs).Error; err != nil {
return []models.CertificateRequest{}, err
}
return csrs, nil
}

10
repositories/index.go Normal file
View File

@@ -0,0 +1,10 @@
package repositories
type Repository interface {
GetByID(id string) (interface{}, error) // Get a single entity by ID
GetAll() ([]interface{}, error) // Get all entities
Create(entity interface{}) error // Create a new entity
Update(entity interface{}) error // Update an entity
Delete(id string) error // Delete an entity by ID
HardDelete(entity interface{}) error // Hard delete an entity
}

View File

@@ -0,0 +1,56 @@
package repositories
import (
"git.secnex.io/secnex/certman/models"
"gorm.io/gorm"
)
type OrganizationRepository struct {
db *gorm.DB
}
// NewOrganizationRepository creates a new organization repository
func NewOrganizationRepository(db *gorm.DB) *OrganizationRepository {
return &OrganizationRepository{db: db}
}
// GetByID returns an organization by their ID
func (r *OrganizationRepository) GetByID(id string) (models.Organization, error) {
var organization models.Organization
if err := r.db.Where("id = ?", id).First(&organization).Error; err != nil {
return models.Organization{}, err
}
return organization, nil
}
// GetAll returns all organizations
func (r *OrganizationRepository) GetAll() ([]models.Organization, error) {
var organizations []models.Organization
if err := r.db.Find(&organizations).Error; err != nil {
return []models.Organization{}, err
}
return organizations, nil
}
// Create creates a new organization
func (r *OrganizationRepository) Create(organization models.Organization) (models.Organization, error) {
if err := r.db.Create(&organization).Error; err != nil {
return models.Organization{}, err
}
return organization, nil
}
// Update updates an organization
func (r *OrganizationRepository) Update(organization models.Organization) error {
return r.db.Save(&organization).Error
}
// Delete deletes an organization by their ID
func (r *OrganizationRepository) Delete(id string) error {
return r.db.Delete(&models.Organization{}, id).Error
}
// HardDelete deletes an organization by their ID
func (r *OrganizationRepository) HardDelete(organization models.Organization) error {
return r.db.Unscoped().Delete(&organization).Error
}

56
repositories/user.go Normal file
View File

@@ -0,0 +1,56 @@
package repositories
import (
"git.secnex.io/secnex/certman/models"
"gorm.io/gorm"
)
type UserRepository struct {
db *gorm.DB
}
// NewUserRepository creates a new user repository
func NewUserRepository(db *gorm.DB) *UserRepository {
return &UserRepository{db: db}
}
// GetByID returns a user by their ID
func (r *UserRepository) GetByID(id string) (models.User, error) {
var user models.User
if err := r.db.Where("id = ?", id).First(&user).Error; err != nil {
return models.User{}, err
}
return user, nil
}
// GetAll returns all users
func (r *UserRepository) GetAll() ([]models.User, error) {
var users []models.User
if err := r.db.Find(&users).Error; err != nil {
return []models.User{}, err
}
return users, nil
}
// Create creates a new user
func (r *UserRepository) Create(user models.User) (models.User, error) {
if err := r.db.Create(&user).Error; err != nil {
return models.User{}, err
}
return user, nil
}
// Update updates a user
func (r *UserRepository) Update(user models.User) error {
return r.db.Save(&user).Error
}
// Delete deletes a user by their ID
func (r *UserRepository) Delete(id string) error {
return r.db.Delete(&models.User{}, id).Error
}
// HardDelete deletes a user by their ID
func (r *UserRepository) HardDelete(user models.User) error {
return r.db.Unscoped().Delete(&user).Error
}