github.com/mundipagg/boleto-api@v0.0.0-20230620145841-3f9ec742599f/certificate/azureVault.go (about)

     1  package certificate
     2  
     3  import (
     4  	"context"
     5  	"encoding/base64"
     6  	"errors"
     7  	"fmt"
     8  
     9  	"github.com/Azure/go-autorest/autorest/azure"
    10  
    11  	"strings"
    12  	"time"
    13  
    14  	"github.com/Azure/azure-sdk-for-go/services/keyvault/2016-10-01/keyvault"
    15  	"github.com/Azure/azure-sdk-for-go/services/keyvault/auth"
    16  	"github.com/mundipagg/boleto-api/log"
    17  )
    18  
    19  const azureVaultEnv = "vault"
    20  
    21  type azureKeyVaultCertificate struct {
    22  	Ctx           context.Context
    23  	VaultName     string
    24  	Client        keyvault.BaseClient
    25  	authenticated bool
    26  	vaultBaseURL  string
    27  }
    28  
    29  func InstanceStoreCertificatesFromAzureVault(vaultName string, certificatesName ...string) (err error) {
    30  	l := log.CreateLog()
    31  	l.Operation = "InstanceStoreCertificatesFromAzureVault"
    32  	ctx := context.Background()
    33  	configCertificate := azureKeyVaultCertificate{
    34  		Ctx:       ctx,
    35  		VaultName: vaultName,
    36  	}
    37  
    38  	if err = configCertificate.getKeyVaultClient(); err != nil {
    39  		return err
    40  	}
    41  
    42  	for _, certificateName := range certificatesName {
    43  		pfxCertificate, err := configCertificate.requestCertificatesPFX(certificateName)
    44  		if err != nil {
    45  			return err
    46  		}
    47  
    48  		err = loadCertificatesOnStorage(azureVaultEnv, certificateName, pfxCertificate)
    49  		if err != nil {
    50  			return err
    51  		}
    52  
    53  		l.InfoWithBasic(fmt.Sprintf("Success in load certificate [%s] from azureVault", certificateName), "LoadFromAzureVault", nil)
    54  	}
    55  
    56  	return nil
    57  }
    58  
    59  func (akv *azureKeyVaultCertificate) getKeyVaultClient() (err error) {
    60  
    61  	akv.Client = keyvault.New()
    62  	authorizer, err := auth.NewAuthorizerFromEnvironment()
    63  	if err != nil {
    64  		return err
    65  	}
    66  
    67  	akv.Client.Authorizer = authorizer
    68  	akv.authenticated = true
    69  
    70  	akv.vaultBaseURL = fmt.Sprintf("https://%s.%s", akv.VaultName, azure.PublicCloud.KeyVaultDNSSuffix)
    71  
    72  	return nil
    73  }
    74  
    75  func (akv *azureKeyVaultCertificate) requestCertificateVersion(certificateName string) (version string, err error) {
    76  
    77  	list, err := akv.Client.GetCertificateVersionsComplete(akv.Ctx, akv.vaultBaseURL, certificateName, nil)
    78  	if err != nil {
    79  		return "", err
    80  	}
    81  
    82  	var lastItemDate time.Time
    83  	var lastItemVersion string
    84  	for list.NotDone() {
    85  
    86  		item := list.Value()
    87  
    88  		if *item.Attributes.Enabled {
    89  
    90  			updatedTime := time.Time(*item.Attributes.Updated)
    91  			if lastItemDate.IsZero() || updatedTime.After(lastItemDate) {
    92  				lastItemDate = updatedTime
    93  
    94  				parts := strings.Split(*item.ID, "/")
    95  				lastItemVersion = parts[len(parts)-1]
    96  			}
    97  		}
    98  		list.Next()
    99  	}
   100  
   101  	return lastItemVersion, nil
   102  }
   103  
   104  func (akv *azureKeyVaultCertificate) requestCertificatesPFX(certificateName string) ([]byte, error) {
   105  
   106  	if !akv.authenticated {
   107  		return nil, errors.New("Need to invoke GetKeyVaultClient() first")
   108  	}
   109  
   110  	certificateVersion, err := akv.requestCertificateVersion(certificateName)
   111  	if err != nil {
   112  		return nil, err
   113  	}
   114  
   115  	pfx, err := akv.Client.GetSecret(akv.Ctx, akv.vaultBaseURL, certificateName, certificateVersion)
   116  	if err != nil {
   117  		return nil, err
   118  	}
   119  
   120  	pfxBytes, err := base64.StdEncoding.DecodeString(*pfx.Value)
   121  	if err != nil {
   122  		return nil, err
   123  	}
   124  
   125  	return pfxBytes, nil
   126  }