<?php

/**
 * Lifestyle Webconsulting GmbH
 *
 * LICENSE: This Software is the property of Lifestyle Webconsulting GmbH (Aschaffenburg, Germany)
 * and is private 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  2018 Lifestyle Webconsulting GmbH
 * @link       http://www.life-style.de
 */

namespace LifeStyle\SamlAuthBundle\Security\Authentication\Provider;

use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use LifeStyle\SamlAuthBundle\Security\Authentication\Token\SamlToken;
use LifeStyle\SamlAuthBundle\Security\User\SamlUserProvider;
use LifeStyle\SamlAuthBundle\Database\Manager as DatabaseManager;
use LifeStyle\SamlAuthBundle\Security\User\SamlUser;

/**
 * Class SamlProvider
 * @package LifeStyle\SamlAuthBundle\Security\Authentication\Provider
 */
class SamlProvider implements AuthenticationProviderInterface
{
    /**
     * @var SamlUserProvider
     */
    private $userProvider;

    /**
     * @var DatabaseManager
     */
    private $database;

    /**
     * SamlProvider constructor.
     * @param UserProviderInterface $userProvider
     * @param DatabaseManager $database
     */
    public function __construct(
        UserProviderInterface $userProvider,
        DatabaseManager $database
    ) {
        $this->userProvider = $userProvider;
        $this->database = $database;
    }


    public function authenticate(TokenInterface $token)
    {
        $authenticatedToken = null;
        if (!($this->userProvider instanceof SamlUserProvider)) {
            throw new AuthenticationException('Unsupported userprovider.');
        }
        /** @var SamlUser $user */
        $user = $this->userProvider->loadUserFromDto($token->getUserDto());

        if (count($user->getRoles()) > 0) {
            $authenticatedToken = new SamlToken($user->getRoles());
            $authenticatedToken->setUser($user);
        }

        if (null === $authenticatedToken) {
            throw new AuthenticationException('SAML authentication failed.');
        }

        // Log user successful login
        $this->database->data()->user()->updateUserLogin($user);

        return $authenticatedToken;
    }


    public function supports(TokenInterface $token)
    {
        return $token instanceof SamlToken;
    }
}
