* some stuff moved to UtilityModule(old DoctrineExpressiveModule)
* api auth in place
This commit is contained in:
@@ -7,6 +7,7 @@ namespace App\Handler\Api;
|
||||
use App\Service\AwardeeManager;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use UtilityModule\Handler\AbstractCrudHandler;
|
||||
use Zend\Diactoros\Response\JsonResponse;
|
||||
|
||||
class AwardeeHandler extends AbstractCrudHandler
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace App\Handler\Api;
|
||||
use App\Service\JudgeManager;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use UtilityModule\Handler\AbstractCrudHandler;
|
||||
use Zend\Diactoros\Response\JsonResponse;
|
||||
|
||||
class JudgesHandler extends AbstractCrudHandler
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace App\Handler\Api;
|
||||
use App\Service\YearManager;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use UtilityModule\Handler\AbstractCrudHandler;
|
||||
use Zend\Diactoros\Response\JsonResponse;
|
||||
|
||||
class YearsHandler extends AbstractCrudHandler
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace App\Service;
|
||||
|
||||
use App\Entity\Awardee;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use DoctrineExpressiveModule\Hydrator\DoctrineObject;
|
||||
use UtilityModule\Hydrator\DoctrineObject;
|
||||
|
||||
class AwardeeManager
|
||||
{
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
namespace App\Service;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use DoctrineExpressiveModule\Hydrator\DoctrineObject;
|
||||
use UtilityModule\Hydrator\DoctrineObject;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
class AwardeeManagerFactory
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace App\Service;
|
||||
|
||||
use App\Entity\Judge;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use DoctrineExpressiveModule\Hydrator\DoctrineObject;
|
||||
use UtilityModule\Hydrator\DoctrineObject;
|
||||
|
||||
class JudgeManager
|
||||
{
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
namespace App\Service;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use DoctrineExpressiveModule\Hydrator\DoctrineObject;
|
||||
use UtilityModule\Hydrator\DoctrineObject;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
class JudgeManagerFactory
|
||||
|
||||
34
src/UtilityModule/Command/GeneratePasswordHash.php
Normal file
34
src/UtilityModule/Command/GeneratePasswordHash.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace UtilityModule\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use UtilityModule\Service\AuthService;
|
||||
|
||||
class GeneratePasswordHash extends Command
|
||||
{
|
||||
/** @var AuthService */
|
||||
private $authService;
|
||||
|
||||
public function __construct(AuthService $authService)
|
||||
{
|
||||
$this->authService = $authService;
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('password:generate')
|
||||
->setDescription('Generate a password hash')
|
||||
->addArgument('password', InputArgument::REQUIRED, 'Password to hash');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$pass = $input->getArgument('password');
|
||||
$output->writeln($this->authService->createPasswordHash($pass));
|
||||
}
|
||||
}
|
||||
19
src/UtilityModule/Command/GeneratePasswordHashFactory.php
Normal file
19
src/UtilityModule/Command/GeneratePasswordHashFactory.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace UtilityModule\Command;
|
||||
|
||||
use Psr\Container\ContainerInterface;
|
||||
use UtilityModule\Service\AuthService;
|
||||
|
||||
class GeneratePasswordHashFactory
|
||||
{
|
||||
/**
|
||||
* @param ContainerInterface $container
|
||||
* @return GeneratePasswordHash
|
||||
*/
|
||||
public function __invoke(ContainerInterface $container)
|
||||
{
|
||||
$authService = $container->get(AuthService::class);
|
||||
return new GeneratePasswordHash($authService);
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,10 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineExpressiveModule;
|
||||
namespace UtilityModule;
|
||||
|
||||
use Tuupola\Middleware\CorsMiddleware;
|
||||
use Tuupola\Middleware\JwtAuthentication;
|
||||
use Zend\EventManager\EventManager;
|
||||
|
||||
/**
|
||||
@@ -25,6 +27,7 @@ class ConfigProvider
|
||||
return [
|
||||
'dependencies' => $this->getDependencies(),
|
||||
'form_elements' => $this->getFormElements(),
|
||||
'console' => $this->getConsoleCommands(),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -42,7 +45,15 @@ class ConfigProvider
|
||||
EventManager::class => EventManager::class,
|
||||
],
|
||||
'factories' => [
|
||||
Command\GeneratePasswordHash::class => Command\GeneratePasswordHashFactory::class,
|
||||
|
||||
Hydrator\DoctrineObject::class => Hydrator\DoctrineObjectFactory::class,
|
||||
|
||||
CorsMiddleware::class => Middleware\CorsMiddlewareFactory::class,
|
||||
JwtAuthentication::class => Middleware\JwtMiddlewareFactory::class,
|
||||
|
||||
Handler\AuthHandler::class => Handler\AuthHandlerFactory::class,
|
||||
Service\AuthService::class => Service\AuthServiceFactory::class,
|
||||
],
|
||||
];
|
||||
}
|
||||
@@ -61,4 +72,13 @@ class ConfigProvider
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function getConsoleCommands(): array
|
||||
{
|
||||
return [
|
||||
'commands' => [
|
||||
Command\GeneratePasswordHash::class,
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace DoctrineExpressiveModule\Form\Element;
|
||||
namespace UtilityModule\Form\Element;
|
||||
|
||||
use Interop\Container\ContainerInterface;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace DoctrineExpressiveModule\Form\Element\Exception;
|
||||
namespace UtilityModule\Form\Element\Exception;
|
||||
|
||||
use InvalidArgumentException;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace DoctrineExpressiveModule\Form\Element;
|
||||
namespace UtilityModule\Form\Element;
|
||||
|
||||
use DoctrineModule\Form\Element\Proxy;
|
||||
use Zend\Form\Element\MultiCheckbox;
|
||||
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace DoctrineExpressiveModule\Form\Element;
|
||||
namespace UtilityModule\Form\Element;
|
||||
|
||||
use DoctrineExpressiveModule\Form\Element\Proxy;
|
||||
use UtilityModule\Form\Element\Proxy;
|
||||
use Zend\Form\Element\Radio as RadioElement;
|
||||
use Zend\Form\Form;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace DoctrineExpressiveModule\Form\Element;
|
||||
namespace UtilityModule\Form\Element;
|
||||
|
||||
use DoctrineExpressiveModule\Form\Element\Proxy;
|
||||
use UtilityModule\Form\Element\Proxy;
|
||||
use Zend\Form\Element\Select as SelectElement;
|
||||
use Zend\Form\Form;
|
||||
use Zend\Stdlib\ArrayUtils;
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace DoctrineExpressiveModule\Form\Element;
|
||||
namespace UtilityModule\Form\Element;
|
||||
|
||||
use Traversable;
|
||||
use ReflectionMethod;
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Handler\Api;
|
||||
namespace UtilityModule\Handler;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
49
src/UtilityModule/Handler/AuthHandler.php
Normal file
49
src/UtilityModule/Handler/AuthHandler.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace UtilityModule\Handler;
|
||||
|
||||
use Doctrine\ORM\NoResultException;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use UtilityModule\Service\AuthService;
|
||||
use Zend\Diactoros\Response\JsonResponse;
|
||||
|
||||
class AuthHandler extends AbstractCrudHandler
|
||||
{
|
||||
/** @var AuthService */
|
||||
private $authService;
|
||||
|
||||
public function __construct(AuthService $authService) {
|
||||
$this->authService = $authService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Respond to POST (login) requests
|
||||
* @param ServerRequestInterface $request
|
||||
* @return \Zend\Diactoros\Response\JsonResponse
|
||||
*/
|
||||
public function create(ServerRequestInterface $request)
|
||||
{
|
||||
$data = $this->getRequestData($request);
|
||||
try {
|
||||
return new JsonResponse($this->authService->authenticate(
|
||||
$data['user'],
|
||||
$data['pass']
|
||||
));
|
||||
} catch (NoResultException $e) {
|
||||
return new JsonResponse("Access denied", 401);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Respond to GET (renew-token) requests
|
||||
* @param ServerRequestInterface $request
|
||||
* @return \Zend\Diactoros\Response\JsonResponse
|
||||
*/
|
||||
public function get(ServerRequestInterface $request)
|
||||
{
|
||||
$token = $request->getAttribute('token');
|
||||
return new JsonResponse($this->authService->renewToken($token));
|
||||
}
|
||||
}
|
||||
18
src/UtilityModule/Handler/AuthHandlerFactory.php
Normal file
18
src/UtilityModule/Handler/AuthHandlerFactory.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace UtilityModule\Handler;
|
||||
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Psr\Http\Server\RequestHandlerInterface;
|
||||
use UtilityModule\Service\AuthService;
|
||||
|
||||
class AuthHandlerFactory
|
||||
{
|
||||
public function __invoke(ContainerInterface $container) : RequestHandlerInterface
|
||||
{
|
||||
$authService = $container->get(AuthService::class);
|
||||
return new AuthHandler($authService);
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace DoctrineExpressiveModule\Hydrator;
|
||||
namespace UtilityModule\Hydrator;
|
||||
|
||||
use DateTime;
|
||||
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace DoctrineExpressiveModule\Hydrator;
|
||||
namespace UtilityModule\Hydrator;
|
||||
|
||||
use Interop\Container\ContainerInterface;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace DoctrineExpressiveModule\Hydrator\Filter;
|
||||
namespace UtilityModule\Hydrator\Filter;
|
||||
|
||||
use Zend\Hydrator\Filter\FilterInterface;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace DoctrineExpressiveModule\Hydrator\Strategy;
|
||||
namespace UtilityModule\Hydrator\Strategy;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
@@ -17,7 +17,7 @@
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace DoctrineExpressiveModule\Hydrator\Strategy;
|
||||
namespace UtilityModule\Hydrator\Strategy;
|
||||
|
||||
/**
|
||||
* When this strategy is used for Collections, if the new collection does not contain elements that are present in
|
||||
@@ -17,7 +17,7 @@
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace DoctrineExpressiveModule\Hydrator\Strategy;
|
||||
namespace UtilityModule\Hydrator\Strategy;
|
||||
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use LogicException;
|
||||
@@ -17,7 +17,7 @@
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace DoctrineExpressiveModule\Hydrator\Strategy;
|
||||
namespace UtilityModule\Hydrator\Strategy;
|
||||
|
||||
/**
|
||||
* When this strategy is used for Collections, if the new collection does not contain elements that are present in
|
||||
@@ -17,7 +17,7 @@
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace DoctrineExpressiveModule\Hydrator\Strategy;
|
||||
namespace UtilityModule\Hydrator\Strategy;
|
||||
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use LogicException;
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineExpressiveModule\Middleware;
|
||||
namespace UtilityModule\Middleware;
|
||||
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Tuupola\Middleware\CorsMiddleware;
|
||||
69
src/UtilityModule/Middleware/JwtMiddlewareFactory.php
Normal file
69
src/UtilityModule/Middleware/JwtMiddlewareFactory.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace UtilityModule\Middleware;
|
||||
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Tuupola\Middleware\JwtAuthentication;
|
||||
use Zend\Config\Config;
|
||||
use Zend\Diactoros\Response\JsonResponse;
|
||||
use Zend\Expressive\Application;
|
||||
use Zend\Expressive\Router\Route;
|
||||
|
||||
class JwtMiddlewareFactory
|
||||
{
|
||||
/** @var Config */
|
||||
private $aclConfig;
|
||||
|
||||
/**
|
||||
* @param ContainerInterface $container
|
||||
* @return JwtAuthentication
|
||||
*/
|
||||
public function __invoke(ContainerInterface $container): JwtAuthentication
|
||||
{
|
||||
$configArray = $container->get('config');
|
||||
/** @var Config $config */
|
||||
$config = new Config($configArray);
|
||||
$this->aclConfig = $config->get('acl_config');
|
||||
return new JwtAuthentication([
|
||||
"secret" => $this->aclConfig->get('hmac_key'),
|
||||
"path" => "/api",
|
||||
"ignore" => $this->getIgnoredRoutes($container),
|
||||
"secure" => true,
|
||||
"relaxed" => [
|
||||
"localhost",
|
||||
"granprize.dev.yvan.hu",
|
||||
],
|
||||
"error" => function (ResponseInterface $response, $arguments) {
|
||||
$data["status"] = "error";
|
||||
$data["message"] = $arguments["message"];
|
||||
return new JsonResponse($data, 401);
|
||||
}
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ContainerInterface $container
|
||||
* @return array
|
||||
*/
|
||||
private function getIgnoredRoutes(ContainerInterface $container): array
|
||||
{
|
||||
$passThroughRoutes = [];
|
||||
|
||||
/** @var Application $app */
|
||||
$app = $container->get(Application::class);
|
||||
$appRoutes = $app->getRoutes();
|
||||
|
||||
$unguardedRoutes = $this->aclConfig->get('unguarded_routes', new Config([]))->toArray();
|
||||
/** @var Route $route */
|
||||
foreach ($appRoutes as $route) {
|
||||
if (in_array($route->getName(), $unguardedRoutes)) {
|
||||
$passThroughRoutes[] = $route->getPath();
|
||||
}
|
||||
}
|
||||
|
||||
return $passThroughRoutes;
|
||||
}
|
||||
}
|
||||
97
src/UtilityModule/Service/AuthService.php
Normal file
97
src/UtilityModule/Service/AuthService.php
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
namespace UtilityModule\Service;
|
||||
|
||||
use Doctrine\ORM\NoResultException;
|
||||
use Firebase\JWT\JWT;
|
||||
use Zend\Config\Config;
|
||||
use Zend\Crypt\Password\Bcrypt;
|
||||
|
||||
class AuthService
|
||||
{
|
||||
const CONFIG_KEY_NAME = 'hmac_key';
|
||||
const PASSWORD_COST = 14;
|
||||
|
||||
/**
|
||||
* @var Config
|
||||
*/
|
||||
private $config;
|
||||
|
||||
public function __construct(
|
||||
Config $config
|
||||
) {
|
||||
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $user
|
||||
* @param string $pass
|
||||
* @return string
|
||||
* @throws NoResultException
|
||||
*/
|
||||
public function authenticate(string $user, string $pass): string
|
||||
{
|
||||
$cfgUser = $this->config->get('user');
|
||||
$cfgPass = $this->config->get('pass');
|
||||
|
||||
$crypt = new Bcrypt();
|
||||
$crypt->setCost(self::PASSWORD_COST);
|
||||
|
||||
if ($cfgUser===$user && $crypt->verify($pass, $cfgPass)) {
|
||||
return $this->generateJwt();
|
||||
}
|
||||
|
||||
throw new NoResultException();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $token
|
||||
* @return string
|
||||
*/
|
||||
public function renewToken($token): string
|
||||
{
|
||||
return $this->renewJWT($token);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function generateJwt(): string
|
||||
{
|
||||
/** @var string $hmacKey */
|
||||
$hmacKey = $this->config->get('hmac_key');
|
||||
return JWT::encode([
|
||||
"iat" => time(),
|
||||
"nbf" => time(),
|
||||
"exp" => time() + 3600,
|
||||
], $hmacKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $token
|
||||
* @return string
|
||||
*/
|
||||
private function renewJWT($token): string
|
||||
{
|
||||
/** @var string $hmacKey */
|
||||
$hmacKey = $this->config->get('hmac_key');
|
||||
return JWT::encode([
|
||||
"jti" => $token->jti,
|
||||
"iat" => time(),
|
||||
"nbf" => time(),
|
||||
"exp" => time() + 3600,
|
||||
], $hmacKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $password
|
||||
* @return string
|
||||
*/
|
||||
public function createPasswordHash(string $password): string
|
||||
{
|
||||
$crypt = new Bcrypt();
|
||||
$crypt->setCost(self::PASSWORD_COST);
|
||||
return $crypt->create($password);
|
||||
}
|
||||
}
|
||||
19
src/UtilityModule/Service/AuthServiceFactory.php
Normal file
19
src/UtilityModule/Service/AuthServiceFactory.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace UtilityModule\Service;
|
||||
|
||||
use Interop\Container\ContainerInterface;
|
||||
use Zend\Config\Config;
|
||||
|
||||
class AuthServiceFactory
|
||||
{
|
||||
/**
|
||||
* @param ContainerInterface $container
|
||||
* @return AuthService
|
||||
*/
|
||||
public function __invoke(ContainerInterface $container): AuthService
|
||||
{
|
||||
$configArr = $container->get('config')['acl_config'];
|
||||
return new AuthService(new Config($configArr));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user