<?php
/**
 * Webservice security listener
 *
 * LICENSE: This Software is the property of Lifestyle Webconsulting GmbH (Aschaffenburg, Germany)
 * and is protected by copyright law - it is NOT Freeware.
 *
 * Any unauthorized use of this software without a valid license
 * is a violation of the license agreement and will be prosecuted by
 * civil and criminal law.
 *
 * @copyright  2015 Lifestyle Webconsulting GmbH
 * @link       http://www.life-style.de
 */

namespace Sso\WebserviceBundle\EventListener;

use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Sso\WebserviceBundle\Error\Storage as ErrorStorage;
use Sso\WebserviceBundle\Event\FilterCredentialsEvent;
use Sso\WebserviceBundle\Event\Credentials;

/**
 * Webservice security listener
 *
 * Checks credentials
 */
class WsSecurityListener implements EventSubscriberInterface
{

    /**
     * The error storage
     *
     * @var ErrorStorage
     */
    protected $errors;

    /**
     * Event dispatcher
     *
     * @var EventDispatcherInterface
     */
    protected $eventDispatchter;

    /**
     * Credentials filter event
     *
     * @var FilterCredentialsEvent
     */
    protected $eventFilter;

    /**
     * Constructor
     *
     * @param ErrorStorage $errorStorage
     * @param EventDispatcherInterface $eventDispatcher
     */
    public function __construct(ErrorStorage $errorStorage, EventDispatcherInterface $eventDispatcher)
    {
        $this->errors = $errorStorage;
        $this->eventDispatchter = $eventDispatcher;
    }

    /**
     * Handle event
     *
     * @param FilterControllerEvent $event
     */
    public function onKernelController(FilterControllerEvent $event)
    {
        $request = $event->getRequest();
        if (!$configuration = $request->attributes->get('_wsSecurity')) {
            return;
        }

        $eventFilter = new FilterCredentialsEvent($this->getCredentials($request));
        $configuredEvents = $configuration->getTests();
        foreach (Credentials::getEventList() as $eventName => $eventRequired) {
            if ($eventRequired || in_array($eventName, $configuredEvents)) {
                $this->eventDispatchter->dispatch($eventName, $eventFilter);
            }
        }
    }

    /**
     * Get credentials from xml if exists
     *
     * @return \SimpleXMLElement|null
     */
    protected function getCredentials(Request $request)
    {
        $xmlRequest = $request->attributes->get('XmlRequest');
        return false !== $xmlRequest && isset($xmlRequest->Credentials) ? $xmlRequest->Credentials : null;
    }

    /**
     * Returns list of subscribed events
     *
     * @return array
     */
    public static function getSubscribedEvents()
    {
        return array(KernelEvents::CONTROLLER => ['onKernelController', -1]);
    }

}
