Files
cloud-services/services/depot/services/cert.go

114 lines
2.8 KiB
Go

package services
import (
"bytes"
"encoding/json"
"net/http"
"sync"
"time"
"github.com/fiskerinc/cloud-services/pkg/common"
"github.com/fiskerinc/cloud-services/pkg/logger"
"github.com/fiskerinc/cloud-services/pkg/utils/envtool"
"github.com/go-pg/pg/v10"
"github.com/pkg/errors"
)
var (
certService CertServiceInterface
certOnce sync.Once
)
func GetCertService() CertServiceInterface {
certOnce.Do(func() {
if certService != nil {
return
}
certService = NewCertService()
})
return certService
}
func SetCertService(cs CertServiceInterface) {
certService = cs
}
func NewCertService() CertServiceInterface {
return &CertService{
certURL: envtool.GetEnv("CERT_URL", "REPLACE_ME"),
certAPIToken: envtool.GetEnv("CERTIFICATE_API_KEY", "REPLACE_ME"),
}
}
type CertServiceInterface interface {
CheckCertificateNeedsRenewal(vin string, certType string) (bool, error)
RenewCertificate(vin string, certType string) (*common.Certificate, error)
}
type CertService struct {
certURL string
certAPIToken string
}
func (cs *CertService) CheckCertificateNeedsRenewal(vin string, certType string) (bool, error) {
logger.Debug().Msg("checking " + certType + " cert for vin " + vin)
cert, err := GetDB().GetCertificates().SelectMostRecent(vin, certType)
if err != nil && !errors.Is(err, pg.ErrNoRows) {
return false, err
}
if cert == nil {
logger.Debug().Msg("no existing " + certType + " cert to renew for vin " + vin)
return false, nil
}
var daysBeforeExp = 183 // six months
switch certType {
case common.CertTBOX:
daysBeforeExp = envtool.GetEnvInt("TBOX_CERT_RENEW_DAYS_BEFORE_EXP", daysBeforeExp)
case common.CertICC:
daysBeforeExp = envtool.GetEnvInt("ICC_CERT_RENEW_DAYS_BEFORE_EXP", daysBeforeExp)
}
logger.Debug().Msg("checking validity of " + certType + " cert with serial number " + cert.SerialNumber + " for vin " + vin)
return cert.IsExpiredOrInvalidAtTime(time.Now(), daysBeforeExp)
}
func (cs *CertService) RenewCertificate(vin string, certType string) (*common.Certificate, error) {
logger.Debug().Msg("renewing " + certType + " cert for vin " + vin)
jsonBytes, err := json.Marshal(common.CertificateRenewRequest{
Type: certType,
CommonName: vin,
})
if err != nil {
return nil, err
}
request, err := http.NewRequest(http.MethodPost, cs.certURL+"renew", bytes.NewReader(jsonBytes))
if err != nil {
return nil, err
}
request.Header.Add("Api-Key", cs.certAPIToken)
resp, err := http.DefaultClient.Do(request)
if err != nil {
return nil, errors.WithStack(err)
}
if resp.StatusCode != http.StatusOK {
return nil, errors.New("renew " + certType + " certificate returned " + resp.Status + " for vin " + vin)
}
defer resp.Body.Close()
var cert common.Certificate
err = json.NewDecoder(resp.Body).Decode(&cert)
if err != nil {
return nil, err
}
return &cert, err
}