github.com/Ingenico-ePayments/connect-sdk-go@v0.0.0-20240318153750-1f8cd329b9c9/webhooks/Helper.go (about)

     1  package webhooks
     2  
     3  import (
     4  	"errors"
     5  	"github.com/Ingenico-ePayments/connect-sdk-go"
     6  	"github.com/Ingenico-ePayments/connect-sdk-go/communicator"
     7  	"github.com/Ingenico-ePayments/connect-sdk-go/communicator/communication"
     8  	"github.com/Ingenico-ePayments/connect-sdk-go/domain/webhooks"
     9  	"github.com/Ingenico-ePayments/connect-sdk-go/webhooks/validation"
    10  )
    11  
    12  var (
    13  	// ErrNilMarshaller occurs when the provided marshaller is nil
    14  	ErrNilMarshaller = errors.New("nil marshaller")
    15  	// ErrNilSecretKeyStore occurs when the provided secretKeyStore is nil
    16  	// Deprecated: use validation.ErrNilSecretKeyStore instead
    17  	ErrNilSecretKeyStore = validation.ErrNilSecretKeyStore
    18  )
    19  
    20  // Helper is the Ingenico ePayments platform webhooks helper. Immutable and thread-safe.
    21  type Helper struct {
    22  	marshaller         communicator.Marshaller
    23  	signatureValidator *validation.SignatureValidator
    24  }
    25  
    26  // Unmarshal unmarshalls the given body and validates it using the requestHeaders
    27  //
    28  // Can return any of the following errors:
    29  // SignatureValidationError if the body could not be validated successfully
    30  // APIVersionMismatchError if the resulting event has an API version that this version of the SDK does not support
    31  func (h *Helper) Unmarshal(body string, requestHeaders []communication.Header) (*webhooks.Event, error) {
    32  	err := h.signatureValidator.Validate(body, requestHeaders)
    33  	if err != nil {
    34  		if _, ok := err.(*validation.SignatureValidationError); ok {
    35  			// Return the right type but with the same error message
    36  			sve, _ := NewSignatureValidationError(err.Error())
    37  			return nil, sve
    38  		}
    39  
    40  		return nil, err
    41  	}
    42  
    43  	event, err := webhooks.NewEvent()
    44  	if err != nil {
    45  		return nil, err
    46  	}
    47  
    48  	err = h.marshaller.Unmarshal(body, event)
    49  	if err != nil {
    50  		return nil, err
    51  	}
    52  
    53  	err = validateAPIVersion(event)
    54  	if err != nil {
    55  		return nil, err
    56  	}
    57  
    58  	return event, nil
    59  }
    60  
    61  // NewHelper creates an Helper with the given marshaller and secretKeyStore
    62  func NewHelper(marshaller communicator.Marshaller, secretKeyStore SecretKeyStore) (*Helper, error) {
    63  	if marshaller == nil {
    64  		return nil, ErrNilMarshaller
    65  	}
    66  
    67  	signatureValidator, err := validation.NewSignatureValidator(secretKeyStore)
    68  	if err != nil {
    69  		return nil, err
    70  	}
    71  
    72  	return &Helper{marshaller, signatureValidator}, nil
    73  }
    74  
    75  func validateAPIVersion(event *webhooks.Event) error {
    76  	if *event.APIVersion != connectsdk.APIVersion {
    77  		ame, err := NewAPIVersionMismatchError(*event.APIVersion, connectsdk.APIVersion)
    78  		if err != nil {
    79  			return err
    80  		}
    81  
    82  		return ame
    83  	}
    84  
    85  	return nil
    86  }