1 <?php
  2   3   4 
  5 namespace Team3\PayU\SignatureCalculator\Validator;
  6 
  7 use Team3\PayU\Configuration\Credentials\CredentialsInterface;
  8 use Team3\PayU\SignatureCalculator\Encoder\Algorithms\AlgorithmInterface;
  9 use Team3\PayU\SignatureCalculator\Encoder\Algorithms\AlgorithmsProviderInterface;
 10 use Team3\PayU\SignatureCalculator\SignatureCalculatorException;
 11 use Team3\PayU\SignatureCalculator\SignatureCalculatorInterface;
 12 
 13  14  15  16  17  18 
 19 class SignatureValidator implements SignatureValidatorInterface
 20 {
 21      22  23 
 24     private $signatureCalculator;
 25 
 26      27  28 
 29     private $algorithmExtractor;
 30 
 31      32  33 
 34     private $algorithmsProvider;
 35 
 36      37  38  39  40 
 41     public function __construct(
 42         SignatureCalculatorInterface $signatureCalculator,
 43         AlgorithmExtractorInterface $algorithmExtractor,
 44         AlgorithmsProviderInterface $algorithmsProvider
 45     ) {
 46         $this->signatureCalculator = $signatureCalculator;
 47         $this->algorithmExtractor = $algorithmExtractor;
 48         $this->algorithmsProvider = $algorithmsProvider;
 49     }
 50 
 51      52  53  54  55  56  57  58 
 59     public function isSignatureValid(
 60         $data,
 61         $signatureHeader,
 62         CredentialsInterface $credentials
 63     ) {
 64         $calculatedSignature = $this
 65             ->signatureCalculator
 66             ->calculate(
 67                 json_decode($data, true),
 68                 $credentials,
 69                 $this->extractAlgorithm($signatureHeader)
 70             );
 71 
 72         return $this->compareSignatureStrings(
 73             $calculatedSignature,
 74             $this->extractSignature($signatureHeader)
 75         );
 76     }
 77 
 78      79  80  81  82  83 
 84     private function extractSignature($signature)
 85     {
 86         $matches = [];
 87         preg_match('/signature=([a-zA-Z0-9]+);/', $signature, $matches);
 88         if (!array_key_exists(1, $matches)) {
 89             throw new SignatureValidatorException(sprintf(
 90                 'Could not extract signature from string %s',
 91                 $signature
 92             ));
 93         }
 94 
 95         return $matches[1];
 96     }
 97 
 98      99 100 101 102 
103     private function extractAlgorithm($signature)
104     {
105         return $this
106             ->algorithmExtractor
107             ->extractAlgorithm($signature, $this->algorithmsProvider->getAlgorithms());
108     }
109 
110     111 112 113 114 115 
116     private function compareSignatureStrings($firstSignature, $secondSignature)
117     {
118         return 0 === strcasecmp($firstSignature, $secondSignature);
119     }
120 }
121