feat: implement main application with example usage

- Add main application demonstrating certificate management
- Include example of creating root and intermediate CAs
- Demonstrate certificate generation for enterprise use cases
- Add example certificate creation for AdGuard and Paperless NGX
- Implement proper database initialization and setup
- Include comprehensive logging and error handling
- Add helper functions for time management and certificate creation
This commit is contained in:
Björn Benouarets
2025-09-30 11:45:34 +02:00
parent 309e2794a1
commit 80606d962e

206
main.go Normal file
View File

@@ -0,0 +1,206 @@
package main
import (
"log"
"net"
"time"
"git.secnex.io/secnex/certman/certificate"
"git.secnex.io/secnex/certman/database"
"git.secnex.io/secnex/certman/models"
"git.secnex.io/secnex/certman/repositories"
"github.com/google/uuid"
)
func defaultData() (*models.User, *models.Organization, error) {
userRepository := repositories.NewUserRepository(database.GetDB())
adminUser := models.User{
Username: "admin",
Email: "admin@secnex.io",
Password: "password",
}
createdUser, err := userRepository.Create(adminUser)
if err != nil {
log.Printf("❌ Failed to create admin user: %v", err)
return nil, nil, err
}
log.Println("✅ Admin user created.")
organizationRepository := repositories.NewOrganizationRepository(database.GetDB())
createdOrganization, err := organizationRepository.Create(models.Organization{
Name: "SecNex",
Description: "SecNex",
Address: "In der Bellersbach 12",
City: "Altenkirchen",
State: "Rheinland-Pfalz",
Country: "DE",
Email: "info@secnex.io",
Website: "secnex.io",
CreatedBy: createdUser.ID,
UpdatedBy: createdUser.ID,
})
if err != nil {
log.Printf("❌ Failed to create default organization: %v", err)
return nil, nil, err
}
log.Println("✅ Default organization created.")
return &createdUser, &createdOrganization, nil
}
func defaultCA(createdOrganization *models.Organization) (*models.CertificateAuthority, *models.CertificateAuthority, error) {
ca := certificate.NewCertificateAuthorityService(database.GetDB(), "data/certs/ca", "data/private/ca")
reqRootCA := certificate.CreateRootCARequest{
Name: "SecNex Enterprise Root CA",
CommonName: "SecNex Enterprise Root CA",
Organization: "SecNex",
Country: "DE",
OrganizationID: createdOrganization.ID,
ValidityYears: 50, // 50 Jahre für Enterprise-Produktion
}
rootCA, err := ca.CreateRootCA(&reqRootCA)
if err != nil {
log.Printf("❌ Failed to create default root CA: %v", err)
return nil, nil, err
}
reqIntermediateCA := certificate.CreateIntermediateCARequest{
Name: "SecNex Enterprise Intermediate CA #1",
CommonName: "SecNex Enterprise Intermediate CA #1",
Organization: "SecNex",
Country: "DE",
OrganizationID: createdOrganization.ID,
ParentCAID: rootCA.ID,
ValidityYears: 30, // 30 Jahre für Enterprise-Produktion
}
intermediateCA, err := ca.CreateIntermediateCA(&reqIntermediateCA)
if err != nil {
log.Printf("❌ Failed to create default intermediate CA: %v", err)
return nil, nil, err
}
return rootCA, intermediateCA, nil
}
func createNewCertificate(intermediateCAID string, req certificate.CreateCertificateRequest) (*models.Certificate, error) {
caService := certificate.NewCertificateAuthorityService(database.GetDB(), "data/certs/ca", "data/private/ca")
certService := certificate.NewCertificateService(database.GetDB(), "data/certs", "data/private", caService)
cert, err := certService.CreateCertificate(&req)
if err != nil {
log.Printf("❌ Failed to create new certificate: %v", err)
return nil, err
}
return cert, nil
}
func createAdGuardCertificate(intermediateCA *models.CertificateAuthority) (*models.Certificate, error) {
caService := certificate.NewCertificateAuthorityService(database.GetDB(), "data/certs/ca", "data/private/ca")
certService := certificate.NewCertificateService(database.GetDB(), "data/certs", "data/private", caService)
// Create enterprise web certificate request for AdGuard
req := &certificate.CreateCertificateRequest{
Name: "AdGuard Certificate",
Description: "Enterprise HTTPS certificate for AdGuard DNS server",
CommonName: "adguard.secnex.internal",
Organization: "SecNex",
OrganizationalUnit: "Internal",
Country: "DE",
State: "Rheinland-Pfalz",
Locality: "Altenkirchen",
Street: "In der Bellersbach 12",
Address: "In der Bellersbach 12, 57610 Altenkirchen",
PostalCode: "57610",
Email: "admin@secnex.io",
Type: models.CertificateTypeWeb,
CertificateAuthorityID: intermediateCA.ID,
NotAfter: timePtr(time.Now().AddDate(2, 0, 0)), // 2 Jahre für Enterprise
DNSNames: []string{"adguard.secnex.internal", "adguard.cloud.lab", "*.secnex.internal"},
IPAddresses: []net.IP{net.ParseIP("10.2.2.3")},
KeyType: "rsa",
KeySize: 4096, // 4096 Bit für Enterprise-Sicherheit
ValidityYears: 1, // 2 Jahre für Enterprise-Produktion
}
cert, err := certService.CreateCertificate(req)
if err != nil {
log.Printf("❌ Failed to create AdGuard certificate: %v", err)
return nil, err
}
log.Println("✅ AdGuard web certificate created.")
log.Println("------------------------------------")
log.Println("🔎 Certificate ID:", cert.ID)
log.Println("🔎 Certificate Name:", cert.Name)
log.Println("🔎 Common Name:", cert.AttributeCommonName)
log.Println("🔎 Serial Number:", cert.SerialNumber)
log.Println("🔎 Valid From:", cert.AttributeNotBefore.Format("2006-01-02 15:04:05"))
log.Println("🔎 Valid Until:", cert.AttributeNotAfter.Format("2006-01-02 15:04:05"))
log.Println("🔎 Certificate Type:", cert.Type)
log.Println("🔎 Status:", cert.Status)
log.Println("🔎 Certificate File ID:", cert.FileID)
log.Println("🔎 Private Key File ID:", cert.PrivateKeyID)
log.Println("------------------------------------")
return cert, nil
}
func main() {
// Connect to database
database.Connect()
intermediateID := "3786b6af-39d4-4c10-a9d6-7f3603ecaf6b"
req := &certificate.CreateCertificateRequest{
Name: "Paperless NGX Certificate",
Description: "Paperless NGX Certificate",
CommonName: "paperless.services.internal",
Organization: "SecNex",
OrganizationalUnit: "Internal",
Country: "DE",
State: "Rheinland-Pfalz",
Locality: "Altenkirchen",
Street: "In der Bellersbach 12",
Address: "In der Bellersbach 12, 57610 Altenkirchen",
PostalCode: "57610",
Email: "admin@secnex.io",
Type: models.CertificateTypeWeb,
CertificateAuthorityID: uuid.MustParse(intermediateID),
NotAfter: timePtr(time.Now().AddDate(2, 0, 0)), // 2 Jahre für Enterprise
DNSNames: []string{"paperless.services.internal", "*.paperless.services.internal"},
IPAddresses: []net.IP{net.ParseIP("10.2.2.6")},
KeyType: "rsa",
KeySize: 4096, // 4096 Bit für Enterprise-Sicherheit
ValidityYears: 1, // 2 Jahre für Enterprise-Produktion
}
cert, err := createNewCertificate(
intermediateID,
*req,
)
if err != nil {
log.Printf("❌ Failed to create BetterBahn certificate: %v", err)
return
}
log.Println("✅ BetterBahn certificate created.")
log.Println("------------------------------------")
log.Println("🔎 Certificate ID:", cert.ID)
log.Println("🔎 Certificate Name:", cert.Name)
log.Println("🔎 Common Name:", cert.AttributeCommonName)
log.Println("🔎 Serial Number:", cert.SerialNumber)
log.Println("🔎 Valid From:", cert.AttributeNotBefore.Format("2006-01-02 15:04:05"))
log.Println("🔎 Valid Until:", cert.AttributeNotAfter.Format("2006-01-02 15:04:05"))
log.Println("🔎 Certificate Type:", cert.Type)
log.Println("🔎 Status:", cert.Status)
log.Println("🔎 Certificate File ID:", cert.FileID)
log.Println("🔎 Private Key File ID:", cert.PrivateKeyID)
log.Println("------------------------------------")
}
// Helper function to create time pointer
func timePtr(t time.Time) *time.Time {
return &t
}