Skip to content

Instantly share code, notes, and snippets.

@itsnotyoutoday
Last active November 17, 2019 00:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save itsnotyoutoday/ae72ec58e2cfb97f7bf4572bbfa8922a to your computer and use it in GitHub Desktop.
Save itsnotyoutoday/ae72ec58e2cfb97f7bf4572bbfa8922a to your computer and use it in GitHub Desktop.
CoinPayments Symfony4 IPN Firewall
<?php
namespace App\Payments\CoinPaymentsBundle\Security;
/**
* Very Simple Interface for HMAC Authentication for CoinPayments.
* Set this up somewhere. Add this class as a service and add the following to
* security.yaml in packages.
*
* coinpayments:
* memory:
* users:
* your_merchant_id: { password: your_ipn_secret_token }
*/
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
class CoinIPNAuth extends AbstractGuardAuthenticator
{
public function supports(Request $request)
{
$supported = !empty($request->headers->has('HMAC')) and ($request->get('ipn_mode') == 'hmac') and !empty($request->get('merchant'));
return $supported;
}
public function getCredentials(Request $request)
{
return ['hmac' => $request->headers->get('hmac'), 'merchant' => $request->get('merchant')];
}
public function getUser($credentials, UserProviderInterface $userProvider) {
$merchant = $credentials['merchant'];
if($merchant === null) {
return null;
}
return $userProvider->loadUserByUsername($merchant);
}
public function checkCredentials($credentials, UserInterface $user)
{
$request_data = file_get_contents('php://input');
$hmac = hash_hmac('sha512', $request_data, trim($user->getPassword()));
return hash_equals($credentials['hmac'], $hmac);
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
return null;
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
return new JsonResponse(['message' => 'no'], Response::HTTP_FORBIDDEN);
}
/**
* Called when authentication is needed, but it's not sent
*/
public function start(Request $request, AuthenticationException $authException = null)
{
$data = array(
'message' => 'Authentication Required'
);
return new JsonResponse($data, Response::HTTP_UNAUTHORIZED);
}
public function supportsRememberMe()
{
return false;
}
}
# Lines require to establish the IPN as your firewall
providers:
# Your existing providers...
coinpayments:
memory:
users:
your_merchant_id: { password: your_ipn_password }
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
hmac_secured:
pattern: ^/route/to/your/ipn/page/
provider: coinpayments
guard:
authenticators:
- App\Payments\CoinPaymentsBundle\Security\CoinIPNAuth
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment