b0y-101 Mini Shell


Current Path : E:/www/b-group.old/spfin/phppayment/src/
File Upload :
Current File : E:/www/b-group.old/spfin/phppayment/src/ActionRequest.php

<?php

namespace Paco\PhpDemo;

use Exception;
use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
use Jose\Component\Checker\AlgorithmChecker;
use Jose\Component\Checker\AudienceChecker;
use Jose\Component\Checker\ClaimCheckerManager;
use Jose\Component\Checker\ExpirationTimeChecker;
use Jose\Component\Checker\HeaderCheckerManager;
use Jose\Component\Checker\InvalidClaimException;
use Jose\Component\Checker\IssuerChecker;
use Jose\Component\Checker\MissingMandatoryClaimException;
use Jose\Component\Checker\NotBeforeChecker;
use Jose\Component\Core\AlgorithmManager;
use Jose\Component\Core\JWK;
use Jose\Component\Encryption\Algorithm\ContentEncryption\A128CBCHS256;
use Jose\Component\Encryption\Algorithm\KeyEncryption\RSAOAEP;
use Jose\Component\Encryption\Compression\CompressionMethodManager;
use Jose\Component\Encryption\JWEBuilder;
use Jose\Component\Encryption\JWEDecrypter;
use Jose\Component\Encryption\JWELoader;
use Jose\Component\Encryption\JWETokenSupport;
use Jose\Component\Encryption\Serializer\CompactSerializer as JWECompactSerializer;
use Jose\Component\Encryption\Serializer\JWESerializerManager;
use Jose\Component\KeyManagement\JWKFactory;
use Jose\Component\Signature\Algorithm\PS256;
use Jose\Component\Signature\JWSBuilder;
use Jose\Component\Signature\JWSLoader;
use Jose\Component\Signature\JWSTokenSupport;
use Jose\Component\Signature\JWSVerifier;
use Jose\Component\Signature\Serializer\CompactSerializer as JWSCompactSerializer;
use Jose\Component\Signature\Serializer\JWSSerializerManager;
use Jose\Easy\ContentEncryptionAlgorithmChecker;
use Psr\Http\Message\RequestInterface;

abstract class ActionRequest
{
    private const PaymentEndpoint = "https://core.demo-paco.2c2p.com/";

    protected Client $client;

    private JWSCompactSerializer $jwsCompactSerializer;
    private JWSBuilder $jwsBuilder;
    private JWSLoader $jwsLoader;
    private ClaimCheckerManager $claimCheckerManager;

    private JWECompactSerializer $jweCompactSerializer;
    private JWEBuilder $jweBuilder;
    private JWELoader $jweLoader;

    public function __construct()
    {
        $handler = HandlerStack::create();

        $handler->push(Middleware::mapRequest(function (RequestInterface $request) {
            return $request->withoutHeader('User-Agent');
        }));

        $this->client = new Client([
            'base_uri' => self::PaymentEndpoint,
            'handler' => $handler
        ]);

        $this->jwsCompactSerializer = new JWSCompactSerializer();
        $this->jwsBuilder = new JWSBuilder(
            signatureAlgorithmManager: new AlgorithmManager(
                algorithms: [
                    new PS256()
                ]
            )
        );
        $this->jwsLoader = new JWSLoader(
            serializerManager: new JWSSerializerManager(
                serializers: [
                    new JWSCompactSerializer()
                ]
            ),
            jwsVerifier: new JWSVerifier(
                signatureAlgorithmManager: new AlgorithmManager(
                    algorithms: [
                        new PS256()
                    ]
                )
            ),
            headerCheckerManager: new HeaderCheckerManager(
                checkers: [
                    new AlgorithmChecker(
                        supportedAlgorithms: [SecurityData::$JWSAlgorithm],
                        protectedHeader: true
                    ),
                ],
                tokenTypes: [
                    new JWSTokenSupport(),
                ]
            ),
        );
        $this->claimCheckerManager = new ClaimCheckerManager(
            checkers: [
                new NotBeforeChecker(),
                new ExpirationTimeChecker(),
                new AudienceChecker(SecurityData::$AccessToken),
                new IssuerChecker(["PacoIssuer"]),
            ]
        );

        $this->jweCompactSerializer = new JWECompactSerializer();
        $this->jweBuilder = new JWEBuilder(
            keyEncryptionAlgorithmManager: new AlgorithmManager(
                algorithms: [
                    new RSAOAEP()
                ]
            ),
            contentEncryptionAlgorithmManager: new AlgorithmManager(
                algorithms: [
                    new A128CBCHS256()
                ]
            ),
            compressionManager: new CompressionMethodManager(
                methods: []
            )
        );
        $this->jweLoader = new JWELoader(
            serializerManager: new JWESerializerManager(
                serializers: [
                    new JWECompactSerializer(),
                ]
            ),
            jweDecrypter: new JWEDecrypter(
                keyEncryptionAlgorithmManager: new AlgorithmManager(
                    algorithms: [
                        new RSAOAEP()
                    ]
                ),
                contentEncryptionAlgorithmManager: new AlgorithmManager(
                    algorithms: [
                        new A128CBCHS256()
                    ]
                ),
                compressionMethodManager: new CompressionMethodManager(
                    methods: [],
                )
            ),
            headerCheckerManager: new HeaderCheckerManager(
                checkers: [
                    new AlgorithmChecker(
                        supportedAlgorithms: [SecurityData::$JWEAlgorithm],
                        protectedHeader: true
                    ),
                    new ContentEncryptionAlgorithmChecker(
                        supportedAlgorithms: [SecurityData::$JWEEncrptionAlgorithm],
                        protectedHeader: true
                    )
                ],
                tokenTypes: [
                    new JWETokenSupport(),
                ]
            )
        );
    }

    /**
     * Creates a JWK Private Key from PKCS#8 Encoded Private Key
     *
     * @param string $key
     * @param string|null $password
     * @param array $additional_values
     * @return JWK
     */
    protected function GetPrivateKey(string $key, ?string $password = null, array $additional_values = []): JWK
    {
        $privateKey = "-----BEGIN RSA PRIVATE KEY-----\n" . $key . "\n-----END RSA PRIVATE KEY-----";
        return JWKFactory::createFromKey($privateKey, $password, $additional_values);
    }

    /**
     * Creates a JWK Public Key from PKCS#8 Encoded Public Key
     *
     * @param string $key
     * @param string|null $password
     * @param array $additional_values
     * @return JWK
     */
    protected function GetPublicKey(string $key, ?string $password = null, array $additional_values = []): JWK
    {
        $publicKey = "-----BEGIN PUBLIC KEY-----\n" . $key . "\n-----END PUBLIC KEY-----";
        return JWKFactory::createFromKey($publicKey, $password, $additional_values);
    }

    /**
     * Creates an encrypted JOSE Token from given payload
     *
     * @param string $payload
     * @param JWK $signingKey
     * @param JWK $encryptingKey
     * @return string
     */
    protected function EncryptPayload(string $payload, JWK $signingKey, JWK $encryptingKey): string
    {
        //used third-party php jwt framework : https://github.com/web-token/jwt-framework
        $jws = $this->jwsBuilder
            ->create()
            ->withPayload($payload)
            ->addSignature($signingKey, [
                "alg" => SecurityData::$JWSAlgorithm,
                "typ" => SecurityData::$TokenType,
            ])
            ->build();

        //used third-party php jwt framework : https://github.com/web-token/jwt-framework
        $jwe = $this->jweBuilder
            ->create()
            ->withPayload($this->jwsCompactSerializer->serialize($jws))
            ->withSharedProtectedHeader([
                "alg" => SecurityData::$JWEAlgorithm,
                "enc" => SecurityData::$JWEEncrptionAlgorithm,
                "kid" => SecurityData::$EncryptionKeyId,
                "typ" => SecurityData::$TokenType,
            ])
            ->addRecipient($encryptingKey)
            ->build();

        return $this->jweCompactSerializer->serialize($jwe, 0);
    }

    /**
     * Decrypts a JOSE Token and returns plain text payload
     *
     * @param string $token
     * @param JWK $decryptingKey
     * @param JWK $signatureVerificationKey
     * @return string
     * @throws InvalidClaimException
     * @throws MissingMandatoryClaimException
     * @throws Exception
     */
    protected function DecryptToken(string $token, JWK $decryptingKey, JWK $signatureVerificationKey): string
    {
        $jwe = $this->jweLoader->loadAndDecryptWithKey($token, $decryptingKey, $recipient);

        $jws = $this->jwsLoader->loadAndVerifyWithKey($jwe->getPayload(), $signatureVerificationKey, $signature);

        $token = $jws->getPayload();

        $claims = json_decode($token, true);

        $this->claimCheckerManager->check($claims);

        return $token;
    }

    /**
     * Creates a GUID
     *
     * @return string
     */
    protected function Guid(): string
    {
        if (function_exists('com_create_guid')) {
            return com_create_guid();
        } else {
            $charId = strtoupper(md5(uniqid(rand(), true)));
            $hyphen = chr(45);// "-"
            $guid = substr($charId, 0, 8) . $hyphen
                . substr($charId, 8, 4) . $hyphen
                . substr($charId, 12, 4) . $hyphen
                . substr($charId, 16, 4) . $hyphen
                . substr($charId, 20, 12);
            return strtolower($guid);
        }
    }
}

Copyright © 2019 by b0y-101