114 lines
2.8 KiB
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
|
|
}
|