Remove deprecated LoginFormAuthenticator.php, fix phpunit tests

Fix User.php
pull/3924/head
Julio Montoya 5 years ago
parent a4ad40d86d
commit 93e8b6d3b5
  1. 12
      src/CoreBundle/Entity/User.php
  2. 4
      src/CoreBundle/Security/Authorization/Voter/ResourceNodeVoter.php
  3. 214
      src/CoreBundle/Security/LoginFormAuthenticator.php
  4. 2
      tests/CoreBundle/Repository/Node/PersonalFileRepositoryTest.php
  5. 11
      tests/CourseBundle/Repository/CDocumentRepositoryTest.php

@ -66,8 +66,8 @@ use UserManager;
'lastname' => 'partial',
])]
#[ApiFilter(BooleanFilter::class, properties: ['isActive'])]
class User implements UserInterface, EquatableInterface, ResourceInterface, ResourceIllustrationInterface, PasswordAuthenticatedUserInterface
//EquatableInterface,
class User implements UserInterface, ResourceInterface, ResourceIllustrationInterface, PasswordAuthenticatedUserInterface
{
use TimestampableEntity;
use UserCreatorTrait;
@ -254,7 +254,7 @@ class User implements UserInterface, EquatableInterface, ResourceInterface, Reso
* @Groups({"user:read"})
* @ORM\Column(name="last_login", type="datetime", nullable=true)
*/
protected ?DateTime $lastLogin;
protected ?DateTime $lastLogin = null;
/**
* Random string sent to the user email address in order to verify it.
@ -649,7 +649,7 @@ class User implements UserInterface, EquatableInterface, ResourceInterface, Reso
/**
* @ORM\Column(name="expiration_date", type="datetime", nullable=true, unique=false)
*/
protected ?DateTime $expirationDate;
protected ?DateTime $expirationDate = null;
/**
* @ORM\Column(name="active", type="boolean")
@ -1659,7 +1659,7 @@ class User implements UserInterface, EquatableInterface, ResourceInterface, Reso
return $this;
}
public function isEqualTo(UserInterface $user): bool
/*public function isEqualTo(UserInterface $user): bool
{
if ($this->password !== $user->getPassword()) {
return false;
@ -1674,7 +1674,7 @@ class User implements UserInterface, EquatableInterface, ResourceInterface, Reso
}
return true;
}
}*/
public function getSentMessages(): Collection
{

@ -18,6 +18,7 @@ use Laminas\Permissions\Acl\Role\GenericRole;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Security\Acl\Permission\MaskBuilder;
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
use Symfony\Component\Security\Core\Authentication\Token\NullToken;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\Security;
@ -431,7 +432,8 @@ class ResourceNodeVoter extends Voter
$acl->allow($admin);
$acl->allow($superAdmin);
if ($token instanceof AnonymousToken) {
//if ($token instanceof AnonymousToken) {
if ($token instanceof NullToken) {
return $acl->isAllowed('IS_AUTHENTICATED_ANONYMOUSLY', $linkId, $askedMask);
}

@ -1,214 +0,0 @@
<?php
declare(strict_types=1);
/* For licensing terms, see /license.txt */
namespace Chamilo\CoreBundle\Security;
use Chamilo\CoreBundle\Entity\User;
use Chamilo\CoreBundle\Hook\HookFactory;
use Chamilo\CoreBundle\Repository\Node\UserRepository;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
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\Exception\InvalidCsrfTokenException;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Csrf\CsrfToken;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
use Symfony\Component\Security\Guard\PasswordAuthenticatedInterface;
use Symfony\Component\Security\Http\Util\TargetPathTrait;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\SerializerInterface;
class LoginFormAuthenticator extends AbstractGuardAuthenticator implements PasswordAuthenticatedInterface
{
use TargetPathTrait;
private const LOGIN_ROUTE = 'login_json';
public SerializerInterface $serializer;
public RouterInterface $router;
private UserPasswordHasherInterface $passwordHasher;
private UserRepository $userRepository;
private CsrfTokenManagerInterface $csrfTokenManager;
private UrlGeneratorInterface $urlGenerator;
public function __construct(
//EntityManagerInterface $entityManager,
UrlGeneratorInterface $urlGenerator,
RouterInterface $router,
UserPasswordHasherInterface $passwordHasher,
//FormFactoryInterface $formFactory,
//HookFactory $hookFactory,
UserRepository $userRepository,
CsrfTokenManagerInterface $csrfTokenManager,
SerializerInterface $serializer
) {
$this->router = $router;
$this->passwordHasher = $passwordHasher;
//$this->formFactory = $formFactory;
//$this->hookFactory = $hookFactory;
$this->userRepository = $userRepository;
$this->csrfTokenManager = $csrfTokenManager;
//$this->entityManager = $entityManager;
$this->urlGenerator = $urlGenerator;
$this->serializer = $serializer;
}
public function supports(Request $request): bool
{
return self::LOGIN_ROUTE === $request->attributes->get('_route') && $request->isMethod('POST');
}
public function getCredentials(Request $request): array
{
$data = null;
$token = null;
if (0 === strpos($request->headers->get('Content-Type'), 'application/json')) {
$data = json_decode($request->getContent(), true);
$username = $data['username'];
$password = $data['password'];
//$token = $data['csrf_token'];
} else {
$username = $request->request->get('username');
$password = $request->request->get('password');
$token = $request->request->get('csrf_token');
}
$credentials = [
'username' => $username,
'password' => $password,
'csrf_token' => $token,
];
$request->getSession()->set(
Security::LAST_USERNAME,
$credentials['username']
);
return $credentials;
}
/**
* @param array $credentials
*
* @return null|UserInterface
*/
public function getUser($credentials, UserProviderInterface $userProvider)
{
/*$token = new CsrfToken('authenticate', $credentials['csrf_token']);
if (!$this->csrfTokenManager->isTokenValid($token)) {
throw new InvalidCsrfTokenException();
}*/
/** @var null|User $user */
$user = $this->userRepository->findOneBy([
'username' => $credentials['username'],
]);
if (null === $user) {
// fail authentication with a custom error
throw new CustomUserMessageAuthenticationException('username could not be found.');
}
return $user;
}
public function checkCredentials($credentials, $user): bool
{
//error_log('login form');
return $this->passwordHasher->isPasswordValid($user, $credentials['password']);
/*$hook = $this->hookFactory->build(CheckLoginCredentialsHook::class);
if (empty($hook)) {
return false;
}
$hook->setEventData(['user' => $user, 'credentials' => $credentials]);
return $hook->notifyLoginCredentials();*/
}
/**
* Used to upgrade (rehash) the user's password automatically over time.
*/
public function getPassword($credentials): ?string
{
return $credentials['password'];
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
/*$request->getSession()->set(Security::AUTHENTICATION_ERROR, $exception);
return new RedirectResponse($this->router->generate('login'));*/
$data = [
// you may want to customize or obfuscate the message first
'message' => strtr($exception->getMessageKey(), $exception->getMessageData()),
// or to translate this message
// $this->translator->trans($exception->getMessageKey(), $exception->getMessageData())
];
return new JsonResponse($data, Response::HTTP_UNAUTHORIZED);
}
public function start(Request $request, AuthenticationException $authException = null)
{
/*$session = $request->getSession();
// I am choosing to set a FlashBag message with my own custom message.
// Alternatively, you could use AuthenticationException's generic message
// by calling $authException->getMessage()
$session->getFlashBag()->add('warning', 'You must be logged in to access that page');*/
$data = [
// you might translate this message
'message' => 'Authentication Required',
];
return new JsonResponse($data, Response::HTTP_UNAUTHORIZED);
}
/**
* @param string $providerKey
*/
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
/*if ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) {
return new RedirectResponse($targetPath);
}
return new RedirectResponse($this->urlGenerator->generate('home'));*/
/** @var User $user */
$user = $token->getUser();
if ($user) {
$userClone = clone $user;
$userClone->setPassword('');
$data = $this->serializer->serialize($userClone, JsonEncoder::FORMAT);
return new JsonResponse($data, Response::HTTP_OK, [], true);
}
}
public function getLoginUrl(): string
{
return $this->urlGenerator->generate(self::LOGIN_ROUTE);
}
public function supportsRememberMe()
{
return false;
}
}

@ -79,7 +79,7 @@ class PersonalFileRepositoryTest extends AbstractApiTest
'GET',
$url
);
$this->assertResponseStatusCodeSame(403); // forbidden
$this->assertResponseStatusCodeSame(403); // unauthorized
// Access with the same user should be allowed.
$client = $this->getClientWithGuiCredentials($username, $password);

@ -91,6 +91,7 @@ class CDocumentRepositoryTest extends AbstractApiTest
$file = $this->getUploadedFile();
$token = $this->getUserToken([]);
// Upload file.
$response = $this->createClientWithCredentials($token)->request(
'POST',
@ -169,7 +170,7 @@ class CDocumentRepositoryTest extends AbstractApiTest
'headers' => ['Content-Type' => 'application/json'],
]
);
$this->assertResponseStatusCodeSame(403); // Forbidden
$this->assertResponseStatusCodeSame(403); // Unauthorized
// Test access with another user. He CAN see the file, the cid is pass as a parameter
// and the course is open to the world by default.
@ -201,7 +202,7 @@ class CDocumentRepositoryTest extends AbstractApiTest
],
]
);
$this->assertResponseStatusCodeSame(403);
$this->assertResponseStatusCodeSame(401);
// Update course visibility to CLOSED
$courseRepo = self::getContainer()->get(CourseRepository::class);
@ -219,7 +220,7 @@ class CDocumentRepositoryTest extends AbstractApiTest
],
]
);
$this->assertResponseStatusCodeSame(403);
$this->assertResponseStatusCodeSame(401);
// Update course visibility to HIDDEN
$courseRepo = self::getContainer()->get(CourseRepository::class);
@ -237,7 +238,7 @@ class CDocumentRepositoryTest extends AbstractApiTest
],
]
);
$this->assertResponseStatusCodeSame(403);
$this->assertResponseStatusCodeSame(401);
// Change visibility of the document to DRAFT
$documentRepo = self::getContainer()->get(CDocumentRepository::class);
@ -260,7 +261,7 @@ class CDocumentRepositoryTest extends AbstractApiTest
],
]
);
$this->assertResponseStatusCodeSame(403);
$this->assertResponseStatusCodeSame(401);
}
public function testUploadFileInSideASubFolder(): void

Loading…
Cancel
Save