User: Allow anonymous users to public courses - refs BT#21198

pull/4995/head
christian 2 years ago
parent 80bf1f7769
commit d90b93c1c4
  1. 1
      public/main/lp/lp_view.php
  2. 2
      src/CoreBundle/Entity/TrackELogin.php
  3. 137
      src/CoreBundle/EventSubscriber/AnonymousUserSubscriber.php
  4. 4
      src/CoreBundle/Migrations/Schema/V200/Version20201212114910.php
  5. 0
      var/log/.gitkeep
  6. 10
      webpack.config.js

@ -123,6 +123,7 @@ if (isset($zoomOptions['options']) && !in_array($origin, ['embeddable', 'noheade
$allowLpItemTip = ('false' === api_get_setting('lp.hide_accessibility_label_on_lp_item'));
if ($allowLpItemTip) {
$htmlHeadXtra[] = api_get_asset('qtip2/dist/jquery.qtip.js');
$htmlHeadXtra[] = '<script>
$(function() {
$(".scorm_item_normal").qtip({

@ -23,7 +23,7 @@ class TrackELogin
#[ORM\GeneratedValue]
protected int $loginId;
#[ORM\ManyToOne(targetEntity: \Chamilo\CoreBundle\Entity\User::class, inversedBy: 'logins')]
#[ORM\ManyToOne(targetEntity: \Chamilo\CoreBundle\Entity\User::class, inversedBy: 'logins', cascade: ['persist'])]
#[ORM\JoinColumn(name: 'login_user_id', referencedColumnName: 'id', onDelete: 'CASCADE')]
protected User $user;

@ -5,14 +5,15 @@ declare(strict_types=1);
namespace Chamilo\CoreBundle\EventSubscriber;
use Chamilo\CoreBundle\Entity\TrackELogin;
use Chamilo\CoreBundle\Entity\User;
use Chamilo\CoreBundle\Settings\SettingsManager;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\Security;
use Doctrine\ORM\EntityManagerInterface;
use Chamilo\CoreBundle\Entity\User;
class AnonymousUserSubscriber implements EventSubscriberInterface
{
@ -20,7 +21,7 @@ class AnonymousUserSubscriber implements EventSubscriberInterface
private EntityManagerInterface $entityManager;
private SessionInterface $session;
private SettingsManager $settingsManager;
private const MAX_ANONYMOUS_USERS = 10;
private const MAX_ANONYMOUS_USERS = 5;
public function __construct(Security $security, EntityManagerInterface $entityManager, SessionInterface $session, SettingsManager $settingsManager)
{
@ -36,60 +37,104 @@ class AnonymousUserSubscriber implements EventSubscriberInterface
return;
}
if (!$this->session->isStarted()) {
$this->session->start();
$request = $event->getRequest();
$userIp = $request->getClientIp();
$anonymousUserId = $this->getOrCreateAnonymousUserId($userIp);
if ($anonymousUserId !== null) {
$trackLoginRepository = $this->entityManager->getRepository(TrackELogin::class);
// Check if a login record already exists for this user and IP
$existingLogin = $trackLoginRepository->findOneBy(['userIp' => $userIp, 'user' => $anonymousUserId]);
if (!$existingLogin) {
// Record the access if it does not exist
$trackLogin = new TrackELogin();
$trackLogin->setUserIp($userIp)
->setLoginDate(new \DateTime())
->setUser($this->entityManager->getReference(User::class, $anonymousUserId));
$this->entityManager->persist($trackLogin);
$this->entityManager->flush();
}
$userRepository = $this->entityManager->getRepository(User::class);
$user = $userRepository->find($anonymousUserId);
if ($user) {
// Store user information in the session
$userInfo = [
'user_id' => $user->getId(),
'username' => $user->getUsername(),
'firstname' => $user->getFirstname(),
'lastname' => $user->getLastname(),
'firstName' => $user->getFirstname(),
'lastName' => $user->getLastname(),
'email' => $user->getEmail(),
'official_code' => $user->getOfficialCode(),
'picture_uri' => $user->getPictureUri(),
'status' => $user->getStatus(),
'active' => $user->getActive(),
'auth_source' => $user->getAuthSource(),
'theme' => $user->getTheme(),
'language' => $user->getLocale(),
'registration_date' => $user->getRegistrationDate()->format('Y-m-d H:i:s'),
'expiration_date' => $user->getExpirationDate() ? $user->getExpirationDate()->format('Y-m-d H:i:s') : null,
'last_login' => $user->getLastLogin() ? $user->getLastLogin()->format('Y-m-d H:i:s') : null,
'is_anonymous' => true,
];
$this->session->set('_user', $userInfo);
}
}
}
private function getOrCreateAnonymousUserId(string $userIp): ?int {
$userRepository = $this->entityManager->getRepository(User::class);
$trackLoginRepository = $this->entityManager->getRepository(TrackELogin::class);
$maxAnonymousUsers = (int) $this->settingsManager->getSetting('admin.max_anonymous_users');
if (0 === $maxAnonymousUsers) {
$maxAnonymousUsers = self::MAX_ANONYMOUS_USERS;
}
$anonymousUsers = $userRepository->findBy(['status' => User::ANONYMOUS], ['registrationDate' => 'ASC']);
// Check in TrackELogin if there is an anonymous user with the same IP
foreach ($anonymousUsers as $user) {
$loginRecord = $trackLoginRepository->findOneBy(['userIp' => $userIp, 'user' => $user]);
if ($loginRecord) {
error_log('Existing login found for user ID: ' . $user->getId());
return $user->getId();
}
}
$userRepository = $this->entityManager->getRepository(User::class);
if (!$this->session->has('anonymous_user_id')) {
$anonymousUserCount = $userRepository->count(['status' => User::ANONYMOUS]);
// Check if maximum number of anonymous users has been reached or exceeded
if ($anonymousUserCount >= $maxAnonymousUsers) {
// Remove all existing anonymous users
$anonymousUsers = $userRepository->findBy(['status' => User::ANONYMOUS]);
foreach ($anonymousUsers as $user) {
$this->entityManager->remove($user);
}
// Delete excess anonymous users
while (count($anonymousUsers) >= $maxAnonymousUsers) {
$oldestAnonymousUser = array_shift($anonymousUsers);
if ($oldestAnonymousUser) {
error_log('Deleting oldest anonymous user: ' . $oldestAnonymousUser->getId());
$this->entityManager->remove($oldestAnonymousUser);
$this->entityManager->flush();
}
// Create a new anonymous user
$uniqueId = uniqid();
$anonymousUser = (new User())
->setSkipResourceNode(true)
->setLastname('Joe')
->setFirstname('Anonymous')
->setUsername('anon_' . $uniqueId)
->setStatus(User::ANONYMOUS)
->setPlainPassword('anon')
->setEmail('anon_' . $uniqueId . '@localhost.local')
->setOfficialCode('anonymous')
->setCreatorId(1);
$this->entityManager->persist($anonymousUser);
$this->entityManager->flush();
$anonymousUserId = $anonymousUser->getId();
$this->session->set('anonymous_user_id', $anonymousUserId);
}
if ($this->session->has('anonymous_user_id')) {
$anonymousUserId = $this->session->get('anonymous_user_id');
// Set or update the anonymous user information in the session
$userInfo = [
'user_id' => $anonymousUserId,
'status' => User::ANONYMOUS,
'is_anonymous' => true,
];
$this->session->set('_user', $userInfo);
}
// Create a new anonymous user
$uniqueId = uniqid();
$anonymousUser = (new User())
->setSkipResourceNode(true)
->setLastname('Joe')
->setFirstname('Anonymous')
->setUsername('anon_' . $uniqueId)
->setStatus(User::ANONYMOUS)
->setPlainPassword('anon')
->setEmail('anon_' . $uniqueId . '@localhost.local')
->setOfficialCode('anonymous')
->setCreatorId(1);
$this->entityManager->persist($anonymousUser);
$this->entityManager->flush();
error_log('New anonymous user created: ' . $anonymousUser->getId());
return $anonymousUser->getId();
}
public static function getSubscribedEvents()

@ -87,6 +87,10 @@ final class Version20201212114910 extends AbstractMigrationChamilo
$userEntity->addRole('ROLE_ADMIN');
}
if ($userEntity::ANONYMOUS === $userEntity->getStatus()) {
$userEntity->addRole('ROLE_ANONYMOUS');
}
$creatorId = $userEntity->getCreatorId();
$creator = null;
if (isset($userList[$adminId])) {

@ -88,6 +88,16 @@ Encore
pattern: /(js.cookie.js)$/,
to: 'libs/js-cookie/src/js.cookie.js'
},
{
from: './node_modules/qtip2/dist/basic',
pattern: /(jquery.qtip.js)$/,
to: 'libs/qtip2/dist/jquery.qtip.js'
},
{
from: './node_modules/qtip2/dist/basic',
pattern: /(jquery.qtip.css)$/,
to: 'libs/qtip2/dist/jquery.qtip.css'
},
//{from: './node_modules/ckeditor4/', to: 'libs/ckeditor/[path][name].[ext]', pattern: /\.(js|css)$/, includeSubdirectories: false},
//{from: './node_modules/ckeditor4/adapters', to: 'libs/ckeditor/adapters/[path][name].[ext]'},
//{from: './node_modules/ckeditor4/lang', to: 'libs/ckeditor/lang/[path][name].[ext]'},

Loading…
Cancel
Save