<commit_before><?php

declare(strict_types=1);

namespace App\Security;

use App\Classes\SessionUserInterface;
use App\Service\JsonWebTokenManager;
use App\Service\SessionUserProvider;
use Exception;
use InvalidArgumentException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Generator\UrlGenerator;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
use UnexpectedValueException;

class JsonWebTokenAuthenticator extends AbstractGuardAuthenticator
{
    /**
     * Constructor
     */
    public function __construct(protected JsonWebTokenManager $jwtManager, protected RouterInterface $router)
    {
    }

    /**
     * @inheritdoc
     */
    public function start(Request $request, AuthenticationException $authException = null)
    {
        $apiDocsUrl = $this->router->generate(
            'ilios_swagger_index',
            [],
            UrlGenerator::ABSOLUTE_URL
        );
        return new Response(
            'X-JWT-Authorization header required with JWT token. See ' .
            "<a href='${apiDocsUrl}'>${apiDocsUrl}</a>",
            401
        );
    }

    /**
     * @inheritdoc
     */
    public function supports(Request $request)
    {
        if (!$request->headers->has('X-JWT-Authorization')) {
            return false;
        }

        $authorizationHeader = $request->headers->get('X-JWT-Authorization');
        return preg_match('/^Token \S+$/', $authorizationHeader);
    }

    /**
     * @inheritdoc
     */
    public function getCredentials(Request $request)
    {
        $authorizationHeader = $request->headers->get('X-JWT-Authorization');
        preg_match('/^Token (\S+)$/', $authorizationHeader, $matches);
        return $matches[1];
    }

    /**
     * @inheritdoc
     *
     * @param string $jwt the extracted JWT
     */
    public function getUser($jwt, UserProviderInterface $userProvider)
    {
        if (!$userProvider instanceof SessionUserProvider) {
            throw new InvalidArgumentException(
                sprintf(
                    'The user provider must be an instance of SessionUserProvider (%s was given).',
                    $userProvider::class
                )
            );
        }

        try {
            $username = $this->jwtManager->getUserIdFromToken($jwt);
        } catch (UnexpectedValueException $e) {
            throw new CustomUserMessageAuthenticationException('Invalid JSON Web Token: ' . $e->getMessage());
        } catch (Exception) {
            throw new CustomUserMessageAuthenticationException('Invalid JSON Web Token');
        }

        /* @var SessionUserInterface $user */
        $user = $userProvider->loadUserByUsername($username);


        return $user;
    }

    /**
     * @inheritdoc
     *
     * @param string $jwt the extracted JWT
     */
    public function checkCredentials($jwt, UserInterface $user)
    {
        /** @var $user SessionUserInterface */
        if (!$user->isEnabled()) {
            throw new CustomUserMessageAuthenticationException(
                'Invalid JSON Web Token: user is disabled'
            );
        }

        $tokenNotValidBefore = $user->tokenNotValidBefore();
        $issuedAt = $this->jwtManager->getIssuedAtFromToken($jwt);
        if ($tokenNotValidBefore) {
            if ($tokenNotValidBefore > $issuedAt) {
                throw new CustomUserMessageAuthenticationException(
                    'Invalid JSON Web Token: Not issued after ' . $tokenNotValidBefore->format('c') .
                    ' issued on ' . $issuedAt->format('c')
                );
            }
        }

        return true;
    }

    /**
     * @inheritdoc
     */
    public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
    {
        return new Response("Authentication Failed. " . $exception->getMessage(), 401);
    }

    /**
     * @inheritdoc
     */
    public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
    {
        // do nothing - continue with an authenticated user
    }

    /**
     * @inheritdoc
     */
    public function supportsRememberMe()
    {
        return false;
    }
}<commit_msg>Fix some type issues in authenticator<commit_after><?php

declare(strict_types=1);

namespace App\Security;

use App\Classes\SessionUserInterface;
use App\Service\JsonWebTokenManager;
use App\Service\SessionUserProvider;
use Exception;
use InvalidArgumentException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Generator\UrlGenerator;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
use UnexpectedValueException;

class JsonWebTokenAuthenticator extends AbstractGuardAuthenticator
{
    /**
     * Constructor
     */
    public function __construct(protected JsonWebTokenManager $jwtManager, protected RouterInterface $router)
    {
    }

    /**
     * @inheritdoc
     */
    public function start(Request $request, AuthenticationException $authException = null)
    {
        $apiDocsUrl = $this->router->generate(
            'ilios_swagger_index',
            [],
            UrlGenerator::ABSOLUTE_URL
        );
        return new Response(
            'X-JWT-Authorization header required with JWT token. See ' .
            "<a href='${apiDocsUrl}'>${apiDocsUrl}</a>",
            401
        );
    }

    /**
     * @inheritdoc
     */
    public function supports(Request $request)
    {
        if (!$request->headers->has('X-JWT-Authorization')) {
            return false;
        }

        $authorizationHeader = $request->headers->get('X-JWT-Authorization');
        return preg_match('/^Token \S+$/', $authorizationHeader);
    }

    /**
     * @inheritdoc
     */
    public function getCredentials(Request $request)
    {
        $authorizationHeader = $request->headers->get('X-JWT-Authorization');
        preg_match('/^Token (\S+)$/', $authorizationHeader, $matches);
        return $matches[1];
    }

    /**
     * @inheritdoc
     *
     * @param string $jwt the extracted JWT
     */
    public function getUser($jwt, UserProviderInterface $userProvider)
    {
        if (!$userProvider instanceof SessionUserProvider) {
            throw new InvalidArgumentException(
                sprintf(
                    'The user provider must be an instance of SessionUserProvider (%s was given).',
                    $userProvider::class
                )
            );
        }

        try {
            $username = $this->jwtManager->getUserIdFromToken($jwt);
        } catch (UnexpectedValueException $e) {
            throw new CustomUserMessageAuthenticationException('Invalid JSON Web Token: ' . $e->getMessage());
        } catch (Exception) {
            throw new CustomUserMessageAuthenticationException('Invalid JSON Web Token');
        }

        /* @var SessionUserInterface $user */
        $user = $userProvider->loadUserByUsername($username);


        return $user;
    }

    /**
     * @inheritdoc
     *
     * @param string $jwt the extracted JWT
     * @param SessionUserInterface $user
     *
     * @return bool
     */
    public function checkCredentials($jwt, UserInterface $user)
    {
        if (!$user->isEnabled()) {
            throw new CustomUserMessageAuthenticationException(
                'Invalid JSON Web Token: user is disabled'
            );
        }

        $tokenNotValidBefore = $user->tokenNotValidBefore();
        $issuedAt = $this->jwtManager->getIssuedAtFromToken($jwt);
        if ($tokenNotValidBefore) {
            if ($tokenNotValidBefore > $issuedAt) {
                throw new CustomUserMessageAuthenticationException(
                    'Invalid JSON Web Token: Not issued after ' . $tokenNotValidBefore->format('c') .
                    ' issued on ' . $issuedAt->format('c')
                );
            }
        }

        return true;
    }

    /**
     * @inheritdoc
     */
    public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
    {
        return new Response("Authentication Failed. " . $exception->getMessage(), 401);
    }

    /**
     * @inheritdoc
     */
    public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
    {
        // do nothing - continue with an authenticated user
        return null;
    }

    /**
     * @inheritdoc
     */
    public function supportsRememberMe()
    {
        return false;
    }
}
{'fraction_non_alphanumeric': 0.10762331838565023, 'fraction_numerical': 0.001708306641042067, 'mean_word_length': 2.464127218934911, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4728425', 'n_tokens_mistral': 2460, 'n_tokens_neox': 2414, 'n_words': 507}