<?php
/*
* Copyright (C) 2018 SPREAD WORKS Inc.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Plugin\Taba2FA;
use Eccube\Common\EccubeConfig;
use Eccube\Common\Constant;
use Eccube\Event\TemplateEvent;
use Eccube\Request\Context;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Doctrine\ORM\EntityManagerInterface;
use Plugin\Taba2FA\Common\UserConfig;
use Plugin\Taba2FA\Common\Constants;
class Taba2FAEvent implements EventSubscriberInterface
{
/**
* @var EntityManagerInterface
*/
protected $entityManager;
/**
* @var EventDispatcherInterface
*/
protected $eventDispatcher;
/**
* @var Context
*/
protected $requestContext;
/**
* @var CsrfTokenManagerInterface
*/
protected $csrfTokenManager;
/**
* @var AuthorizationCheckerInterface
*/
protected $authorizationChecker;
/**
* @var array
*/
private $eccubeConfig;
/**
* @var ContainerInterface
*/
private $container;
/**
* @var TokenStorage
*/
private $tokenStorage;
/**
* Taba2FAEvent constructor.
*
*/
public function __construct(
EntityManagerInterface $entityManager,
EventDispatcherInterface $eventDispatcher,
Context $requestContext,
AuthorizationCheckerInterface $authorizationChecker,
CsrfTokenManagerInterface $csrfTokenManager,
EccubeConfig $eccubeConfig,
ContainerInterface $container,
TokenStorage $tokenStorage
) {
$this->entityManager = $entityManager;
$this->eventDispatcher = $eventDispatcher;
$this->requestContext = $requestContext;
$this->authorizationChecker = $authorizationChecker;
$this->csrfTokenManager = $csrfTokenManager;
$this->eccubeConfig = $eccubeConfig;
$this->container = $container;
$this->tokenStorage = $tokenStorage;
}
/**
* {@inheritdoc}
*
* @return array
*/
public static function getSubscribedEvents()
{
return [
KernelEvents::CONTROLLER_ARGUMENTS => [['onKernelController', 100000000]],
];
}
/**
* 2段階認証の認証状態を確認
*
* @param FilterControllerEvent $event
*/
public function onKernelController(FilterControllerEvent $event)
{
// 管理画面
if (!$this->requestContext->isAdmin()) {
return;
}
// ログイン済み
if (!$this->authorizationChecker->isGranted('ROLE_ADMIN') ) {
return;
}
// 管理画面メニュー
if ($event->getRequest()->attributes->has('_template')) {
if ($event->getRequest()->attributes->has('_template')) {
$template = $event->getRequest()->attributes->get('_template');
$this->eventDispatcher->addListener($template->getTemplate(), function (TemplateEvent $templateEvent) {
// 管理画面のナビゲーションにtaba app のメニューを差し込みます。
$taba = $this->container->get(Constants::CONTAINER_KEY_NAME);
if (!$taba->get(Constants::PLUGIN_CATEGORY_ID . ".menu")) {
$templateEvent->addSnippet('@Taba2FA/admin/snippet/nav_taba_secure.twig');
$taba->set(Constants::PLUGIN_CATEGORY_ID . ".menu",true);
}
$templateEvent->addSnippet('@Taba2FA/admin/snippet/nav.twig');
});
}
}
// 2段階認証
// リクエスト取得
$request = $event->getRequest();
// ルートの取得
$route = $request->attributes->get('_route');
// 2段階認証画面にある画像ファイルは認証チェックしない
if ($route == Constants::ADMIN_BIND_PREFIX."logo"
|| $route == Constants::ADMIN_BIND_PREFIX."poweredby") {
return;
}
// plugin_enable.ymlを利用し、無効化する機能
if (UserConfig::getInstance()->get("plugin_enable") === true) {
// 認証画面の場合は、トップへリダイレクト
if ($route === Constants::ADMIN_BIND_PREFIX."auth") {
$url = $this->container->get('router')->generate("admin_homepage", $parameters = array(), $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH);
$event->setController(function() use ($url) {
return new RedirectResponse($url, $status=302);
});
}
// ファイルがある場合かつ、無効の場合は、処理を終了する。
return;
}
// メンバー情報取得
$Member = $this->tokenStorage->getToken()->getUser();
// 2段階認証の設定を確認
if ($Member->getTaba2FA() && $Member->getTaba2FA()->isEnable()) {
// セッション情報をチェック
$date = new \DateTime();
$timestamp = $date->format('U');
$session = $request->getSession();
if (!$session->get(Constants::LAST_AUTH) || $session->get(Constants::LAST_AUTH) < $timestamp) {
// 認証画面を除く
if ($route != Constants::ADMIN_BIND_PREFIX."auth") {
// 認証画面へリダイレクト
$url = $this->container->get('router')->generate(Constants::ADMIN_BIND_PREFIX."auth", $parameters = array(), $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH);
$event->setController(function() use ($url) {
return new RedirectResponse($url, $status=302);
});
}
}
}
}
}