Skip to content

Commit 94f02fc

Browse files
Merge remote-tracking branch 'upstream/master' into GH-7121
2 parents 79cb4cc + 7245a0a commit 94f02fc

File tree

12 files changed

+71084
-39455
lines changed

12 files changed

+71084
-39455
lines changed

config/authentication.dist.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ parameters:
7777
referrals: false
7878
dn_string: '{user_identifier}'
7979
query_string: null
80-
base_dn: 'DC=cblue,DC=be'
81-
search_dn: 'CN=admin,dc=cblue,dc=be'
80+
base_dn: 'DC=chamilo,DC=org'
81+
search_dn: 'CN=admin,dc=chamilo,dc=org'
8282
search_password: 'pass'
8383
filter: null
8484
uid_key: 'uid'

public/documentation/installation_guide.html

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ <h2>1. Requirements</h2>
4040
<li>xml</li>
4141
<li>zip</li>
4242
<li>zlib</li>
43-
<li>ldap (optional, but mandatory in dev env)</li>
43+
<li>ldap</li>
4444
<li>redis (optional)</li>
4545
<li>xapian (optional)</li>
4646
</ul>
@@ -96,7 +96,15 @@ <h3>2.5. Installation wizard</h3>
9696
<h3>2.6. Sessions and Redis</h3>
9797
<a id="web-install-sessions" class="anchor"></a>
9898
In this beta version, there are known issues with sessions not getting updated fast enough, which can be solved (temporarily) by using a Redis server. Check the command line instructions for more about this. This is a temporary situation that we expect to fix before the stable release.
99-
99+
100+
<h3>2.7. Clean up</h3>h3>
101+
<a id="web-cleanup" class="anchor"></a>
102+
As recommended by the installer's last page, make sure you change permissions on the config/ dir and the .env file, and you delete the public/main/install/ folder.
103+
<pre>
104+
sudo chown -R root: config/ .env
105+
sudo rm -r public/main/install/
106+
</pre>
107+
100108
<h2>3. Command line installation</h2>
101109
<a id="cli-install" class="anchor"></a>
102110

@@ -106,7 +114,7 @@ <h3>3.1. Software stack</h3>
106114
<pre>
107115
sudo -s
108116
apt update && apt -y upgrade
109-
apt -y install apache2 libapache2-mod-php8.3 mariadb-client mariadb-server redis-server php8.3-{bcmath,curl,exif,gd,iconv,intl,mbstring,mysql,opcache,soap,xml,zip,redis}
117+
apt -y install apache2 libapache2-mod-php8.3 mariadb-client mariadb-server redis-server php8.3-{bcmath,curl,exif,gd,iconv,intl,ldap,mbstring,mysql,opcache,soap,xml,zip,redis}
110118
a2enmod rewrite
111119
cd /var/www/
112120
mkdir chamilo
@@ -116,7 +124,7 @@ <h3>3.1. Software stack</h3>
116124
rm chamilo2.0.0-beta.1.tar.gz
117125
cd chamilo
118126
touch .env
119-
chown -R www-data: var .env
127+
chown -R www-data: var/ config/ .env
120128
mysql -u root -e "GRANT ALL PRIVILEGES ON chamilo.* TO chamilo@localhost IDENTIFIED BY '[choose a password here]'";
121129
mysql -u root -e "FLUSH PRIVILEGES;"
122130
mysql_secure_installation
@@ -179,7 +187,7 @@ <h3>3.3. Web server</h3>
179187
systemctl restart apache2</pre>
180188
<h3>3.4. Files permissions</h3>
181189
<a id="cli-install-permissions" class="anchor"></a>
182-
Make sure the following files and folders are writeable by the web server. Set permissions to 0770 for example:
190+
Make sure the following files and folders are writeable by the web server during the installation. Set permissions to 0770 or the owner to www-data, for example:
183191
<ul>
184192
<li>var/</li>
185193
<li>config/</li>
@@ -202,6 +210,14 @@ <h3>3.6. Installation wizard</h3>
202210
You should now be able to direct your browser to your URL (e.g. <em>[http://my.chamilo.local]</em>).<br>
203211
Chamilo will pick it up from there and offer the installation wizard to help guide you through the rest of the process.
204212

213+
<h3>3.7. Clean up</h3>h3>
214+
<a id="cli-cleanup" class="anchor"></a>
215+
As recommended by the installer's last page, make sure you change permissions on the config/ dir and the .env file, and you delete the public/main/install/ folder.
216+
<pre>
217+
sudo chown -R root: config/ .env
218+
sudo rm -r public/main/install/
219+
</pre>
220+
205221
<h2>4. Command line upgrade from 1.11.*</h2>
206222
<a id="cli-upgrade" class="anchor"></a>
207223
<h3>4.1. Database</h3>
@@ -263,7 +279,7 @@ <h4>6.2.1. WampServer</h4>
263279
<a href="https://www.wampserver.com/">Download</a> and install WampServer (accept default options if in doubt).<br>
264280
Restart WampServer to make these changes effective.<br>
265281
Open http://localhost/ in your browser. If the WampServer welcome screen with server configuration info appears, it means WampServer is working.<br>
266-
Click on the WampServer icon in your status bar and go to PHP -&gt; Extensions. Make sure all the following extensions are enabled: php_curl, php_gd, php_intl, php_mbstring, php_mysqli, php_soap, php_xml, php_zip<br>
282+
Click on the WampServer icon in your status bar and go to PHP -&gt; Extensions. Make sure all the following extensions are enabled: php_curl, php_gd, php_intl, php_ldap, php_mbstring, php_mysqli, php_soap, php_xml, php_zip<br>
267283
Edit C:\wamp64\bin\php\php8.3\php.ini, locate ";extension=sodium" and remove the ";" from the beginning of the line.<br>
268284
Also, update the "memory_limit" setting from "128M" to "2048M" and a few other settings as shown below.<br>
269285
<pre>

src/CoreBundle/Controller/Api/DownloadSelectedDocumentsAction.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ function () use ($documents, $zipName): void {
7777
$this->addNodeToZip($zip, $node);
7878
}
7979

80+
if (0 === count($zip->files)) {
81+
$zip->addFile('.empty', '');
82+
}
83+
8084
$zip->finish();
8185
},
8286
Response::HTTP_CREATED
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
<?php
2+
3+
/* For licensing terms, see /license.txt */
4+
5+
declare(strict_types=1);
6+
7+
namespace Chamilo\CoreBundle\Helpers;
8+
9+
use Chamilo\CoreBundle\Entity\ResourceLink;
10+
use Chamilo\CoreBundle\Security\Authorization\Voter\ResourceNodeVoter;
11+
use Laminas\Permissions\Acl\Acl;
12+
use Laminas\Permissions\Acl\Resource\GenericResource;
13+
use Laminas\Permissions\Acl\Role\GenericRole;
14+
use Symfony\Bundle\SecurityBundle\Security;
15+
use Symfony\Component\Security\Acl\Permission\MaskBuilder;
16+
use Symfony\Component\Security\Core\Authentication\Token\NullToken;
17+
use Symfony\Component\Security\Core\User\UserInterface;
18+
19+
readonly class ResourceAclHelper
20+
{
21+
public function __construct(
22+
private Security $security,
23+
) { }
24+
25+
public function isAllowed(
26+
string $attribute,
27+
ResourceLink $resourceLink,
28+
iterable $rights,
29+
bool $allowAnonsToView,
30+
): bool {
31+
// Creating roles
32+
$anon = new GenericRole('IS_AUTHENTICATED_ANONYMOUSLY');
33+
$userRole = new GenericRole('ROLE_USER');
34+
$student = new GenericRole('ROLE_STUDENT');
35+
$teacher = new GenericRole('ROLE_TEACHER');
36+
$studentBoss = new GenericRole('ROLE_STUDENT_BOSS');
37+
38+
$currentStudent = new GenericRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_STUDENT);
39+
$currentTeacher = new GenericRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER);
40+
41+
$currentStudentGroup = new GenericRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_GROUP_STUDENT);
42+
$currentTeacherGroup = new GenericRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_GROUP_TEACHER);
43+
44+
$currentStudentSession = new GenericRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_SESSION_STUDENT);
45+
$currentTeacherSession = new GenericRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_SESSION_TEACHER);
46+
47+
// Setting Simple ACL.
48+
$acl = (new Acl())
49+
->addRole($anon)
50+
->addRole($userRole)
51+
->addRole($student)
52+
->addRole($teacher)
53+
->addRole($studentBoss)
54+
55+
->addRole($currentStudent)
56+
->addRole($currentTeacher, ResourceNodeVoter::ROLE_CURRENT_COURSE_STUDENT)
57+
58+
->addRole($currentStudentSession)
59+
->addRole($currentTeacherSession, ResourceNodeVoter::ROLE_CURRENT_COURSE_SESSION_STUDENT)
60+
61+
->addRole($currentStudentGroup)
62+
->addRole($currentTeacherGroup, ResourceNodeVoter::ROLE_CURRENT_COURSE_GROUP_STUDENT)
63+
;
64+
65+
// Add a security resource.
66+
$acl->addResource(new GenericResource((string) $resourceLink->getId()));
67+
68+
// Check all the right this link has.
69+
// Set rights from the ResourceRight.
70+
foreach ($rights as $right) {
71+
$acl->allow($right->getRole(), null, (string) $right->getMask());
72+
}
73+
74+
// Anons can see.
75+
if ($allowAnonsToView) {
76+
$acl->allow($anon, null, (string) ResourceNodeVoter::getReaderMask());
77+
}
78+
79+
// Asked mask
80+
$mask = new MaskBuilder();
81+
$mask->add($attribute);
82+
83+
$askedMask = (string) $mask->get();
84+
85+
if ($this->security->getToken() instanceof NullToken) {
86+
return (bool) $acl->isAllowed('IS_AUTHENTICATED_ANONYMOUSLY', $resourceLink->getId(), $askedMask);
87+
}
88+
89+
$user = $this->security->getUser();
90+
91+
$roles = $user instanceof UserInterface ? $user->getRoles() : [];
92+
93+
foreach ($roles as $role) {
94+
if ($acl->isAllowed($role, $resourceLink->getId(), $askedMask)) {
95+
return true;
96+
}
97+
}
98+
99+
return false;
100+
}
101+
}

src/CoreBundle/Helpers/ResourceFileHelper.php

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,31 +6,37 @@
66

77
namespace Chamilo\CoreBundle\Helpers;
88

9+
use Chamilo\CoreBundle\Entity\AccessUrl;
910
use Chamilo\CoreBundle\Entity\ResourceFile;
1011
use Chamilo\CoreBundle\Entity\ResourceNode;
1112
use Chamilo\CoreBundle\Settings\SettingsManager;
1213

1314
class ResourceFileHelper
1415
{
16+
private bool $accessUrlSpecificFiles;
17+
private ?AccessUrl $currentAccessUrl;
18+
1519
public function __construct(
16-
private readonly SettingsManager $settingsManager,
17-
private readonly AccessUrlHelper $accessUrlHelper,
18-
) {}
20+
SettingsManager $settingsManager,
21+
AccessUrlHelper $accessUrlHelper,
22+
) {
23+
$this->accessUrlSpecificFiles = $accessUrlHelper->isMultiple()
24+
&& 'true' === $settingsManager->getSetting('document.access_url_specific_files');
25+
26+
$this->currentAccessUrl = $accessUrlHelper->getCurrent();
27+
}
1928

2029
public function resolveResourceFileByAccessUrl(ResourceNode $resourceNode): ?ResourceFile
2130
{
2231
if (!$resourceNode->hasResourceFile()) {
2332
return null;
2433
}
2534

26-
$accessUrlSpecificFiles = 'true' === $this->settingsManager->getSetting('document.access_url_specific_files', true)
27-
&& $this->accessUrlHelper->isMultiple();
28-
2935
$resourceFile = null;
3036
$resourceFiles = $resourceNode->getResourceFiles();
3137

32-
if ($accessUrlSpecificFiles) {
33-
$currentUrl = $this->accessUrlHelper->getCurrent()?->getUrl();
38+
if ($this->accessUrlSpecificFiles) {
39+
$currentUrl = $this->currentAccessUrl?->getUrl();
3440

3541
foreach ($resourceFiles as $file) {
3642
if ($file->getAccessUrl() && $file->getAccessUrl()->getUrl() === $currentUrl) {

src/CoreBundle/Security/Authorization/Voter/ResourceNodeVoter.php

Lines changed: 3 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Chamilo\CoreBundle\Entity\ResourceRight;
1313
use Chamilo\CoreBundle\Entity\Session;
1414
use Chamilo\CoreBundle\Helpers\PageHelper;
15+
use Chamilo\CoreBundle\Helpers\ResourceAclHelper;
1516
use Chamilo\CoreBundle\Settings\SettingsManager;
1617
use Chamilo\CourseBundle\Entity\CDocument;
1718
use Chamilo\CourseBundle\Entity\CGroup;
@@ -54,6 +55,7 @@ public function __construct(
5455
private SettingsManager $settingsManager,
5556
private EntityManagerInterface $entityManager,
5657
private PageHelper $pageHelper,
58+
private readonly ResourceAclHelper $resourceAclHelper,
5759
) {}
5860

5961
public static function getReaderMask(): int
@@ -452,75 +454,7 @@ protected function voteOnAttribute(string $attribute, $subject, TokenInterface $
452454
$rights[] = $resourceRight;
453455
}
454456

455-
// Asked mask
456-
$mask = new MaskBuilder();
457-
$mask->add($attribute);
458-
459-
$askedMask = (string) $mask->get();
460-
461-
// Creating roles
462-
// @todo move this in a service
463-
$anon = new GenericRole('IS_AUTHENTICATED_ANONYMOUSLY');
464-
$userRole = new GenericRole('ROLE_USER');
465-
$student = new GenericRole('ROLE_STUDENT');
466-
$teacher = new GenericRole('ROLE_TEACHER');
467-
$studentBoss = new GenericRole('ROLE_STUDENT_BOSS');
468-
469-
$currentStudent = new GenericRole(self::ROLE_CURRENT_COURSE_STUDENT);
470-
$currentTeacher = new GenericRole(self::ROLE_CURRENT_COURSE_TEACHER);
471-
472-
$currentStudentGroup = new GenericRole(self::ROLE_CURRENT_COURSE_GROUP_STUDENT);
473-
$currentTeacherGroup = new GenericRole(self::ROLE_CURRENT_COURSE_GROUP_TEACHER);
474-
475-
$currentStudentSession = new GenericRole(self::ROLE_CURRENT_COURSE_SESSION_STUDENT);
476-
$currentTeacherSession = new GenericRole(self::ROLE_CURRENT_COURSE_SESSION_TEACHER);
477-
478-
// Setting Simple ACL.
479-
$acl = (new Acl())
480-
->addRole($anon)
481-
->addRole($userRole)
482-
->addRole($student)
483-
->addRole($teacher)
484-
->addRole($studentBoss)
485-
486-
->addRole($currentStudent)
487-
->addRole($currentTeacher, self::ROLE_CURRENT_COURSE_STUDENT)
488-
489-
->addRole($currentStudentSession)
490-
->addRole($currentTeacherSession, self::ROLE_CURRENT_COURSE_SESSION_STUDENT)
491-
492-
->addRole($currentStudentGroup)
493-
->addRole($currentTeacherGroup, self::ROLE_CURRENT_COURSE_GROUP_STUDENT)
494-
;
495-
496-
// Add a security resource.
497-
$linkId = (string) $link->getId();
498-
$acl->addResource(new GenericResource($linkId));
499-
500-
// Check all the right this link has.
501-
// Set rights from the ResourceRight.
502-
foreach ($rights as $right) {
503-
$acl->allow($right->getRole(), null, (string) $right->getMask());
504-
}
505-
506-
// Anons can see.
507-
if ($allowAnonsToView) {
508-
$acl->allow($anon, null, (string) self::getReaderMask());
509-
}
510-
511-
if ($token instanceof NullToken) {
512-
return $acl->isAllowed('IS_AUTHENTICATED_ANONYMOUSLY', $linkId, $askedMask);
513-
}
514-
515-
$roles = $user instanceof UserInterface ? $user->getRoles() : [];
516-
517-
foreach ($roles as $role) {
518-
if ($acl->isAllowed($role, $linkId, $askedMask)) {
519-
return true;
520-
}
521-
}
522-
523-
return false;
457+
return $this->resourceAclHelper->isAllowed($attribute, $link, $rights, $allowAnonsToView);
524458
}
525459

526460
/**

translations/messages.es.po

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23835,7 +23835,7 @@ msgid "Learning path by author"
2383523835
msgstr "Lección por autor"
2383623836

2383723837
msgid "Import assignments from base course"
23838-
msgstr "Importar los tareas del curso base"
23838+
msgstr "Importar las tareas del curso base"
2383923839

2384023840
msgid "Redirect to the platform home page"
2384123841
msgstr "Redirigir a la página de inicio de la plataforma"

0 commit comments

Comments
 (0)