aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMoritz Strohm <strohm@data-quest.de>2024-08-28 16:00:20 +0000
committerMoritz Strohm <strohm@data-quest.de>2024-08-28 16:00:20 +0000
commit642a2172a6a965cae5e6bf481382d70e6a4b7e67 (patch)
tree9f69d46b4f18653a3ae190fea59cfcdbd0654b54
parentd380495e4f39bd86d8ca9df18656bb919aa237d0 (diff)
Prevent root folder uploads by students in courses, re #3745
Merge request studip/studip!2608
-rw-r--r--db/migrations/5.9.1_add_prevent_root_folder_upload_by_students_in_courses_config.php34
-rw-r--r--lib/filesystem/RootFolder.php53
-rw-r--r--templates/filesystem/root_folder/edit.php32
-rw-r--r--tests/jsonapi/FileRefsCreateTest.php2
4 files changed, 104 insertions, 17 deletions
diff --git a/db/migrations/5.9.1_add_prevent_root_folder_upload_by_students_in_courses_config.php b/db/migrations/5.9.1_add_prevent_root_folder_upload_by_students_in_courses_config.php
new file mode 100644
index 0000000..83377ce
--- /dev/null
+++ b/db/migrations/5.9.1_add_prevent_root_folder_upload_by_students_in_courses_config.php
@@ -0,0 +1,34 @@
+<?php
+
+
+class AddPreventRootFolderUploadByStudentsInCoursesConfig extends Migration
+{
+ public function description()
+ {
+ return 'Adds the PREVENT_ROOT_FOLDER_UPLOADS_BY_STUDENTS_IN_COURSES configuration.';
+ }
+
+ protected function up()
+ {
+ DBManager::get()->exec(
+ "INSERT IGNORE INTO `config`
+ (`field`, `value`, `type`, `range`, `section`,
+ `mkdate`, `chdate`,
+ `description`)
+ VALUES
+ ('PREVENT_ROOT_FOLDER_UPLOADS_BY_STUDENTS_IN_COURSES', '0', 'boolean', 'global', 'files',
+ UNIX_TIMESTAMP(), UNIX_TIMESTAMP(),
+ 'Studierende können im Dateibereich einer Veranstaltung auf der Ebene des Hauptordners keine Dateien hochladen.')"
+ );
+ }
+
+ protected function down()
+ {
+ DBManager::get()->exec(
+ "DELETE `config`, `config_values`
+ FROM `config`
+ LEFT JOIN `config_values` USING (`field`)
+ WHERE `field` = 'PREVENT_ROOT_FOLDER_UPLOADS_BY_STUDENTS_IN_COURSES'"
+ );
+ }
+}
diff --git a/lib/filesystem/RootFolder.php b/lib/filesystem/RootFolder.php
index 9771c32..523a1a1 100644
--- a/lib/filesystem/RootFolder.php
+++ b/lib/filesystem/RootFolder.php
@@ -47,15 +47,45 @@ class RootFolder extends StandardFolder
*/
public function isWritable($user_id)
{
- return ($this->range_type === 'user' && $this->range_id === $user_id)
+ if (
+ ($this->range_type === 'user' && $this->range_id === $user_id)
|| $this->isEditable($user_id)
- || (
- Seminar_Perm::get()->have_studip_perm('autor', $this->range_id, $user_id)
- && (
- !$this->folderdata['data_content']
- || !$this->folderdata['data_content']['locked']
- )
- );
+ ) {
+ return true;
+ }
+
+ if (!Seminar_Perm::get()->have_studip_perm('autor', $this->range_id, $user_id)) {
+ return false;
+ }
+
+ //The user has autor permissions. This is a special case since the upload to the root folder
+ //may be denied globally and allowed locally, or it may be allowed globally and denied locally.
+ //Also, this only affects courses, not study groups or root folders in other range types (institutes etc.).
+ if ($this->range_type !== 'course') {
+ //Upload allowed.
+ return true;
+ }
+
+ //The root folder belongs to a course object.
+ $course = Course::find($this->range_id);
+ $locked_status = null;
+ if (isset($this->folderdata['data_content']['locked'])) {
+ $locked_status = $this->folderdata['data_content']['locked'] === 1;
+ }
+ if ($course->isStudygroup()) {
+ //Study groups are not affected by the global PREVENT_ROOT_FOLDER_UPLOADS_BY_STUDENTS_IN_COURSES config.
+ return !$locked_status;
+ }
+ //At this point, only the settings for real courses are left to be checked:
+ if ($locked_status !== null) {
+ //The locked status for the folder is set. Uploading to the folder is allowed
+ //when the locked status is not '1'.
+ return !$locked_status;
+ }
+
+ // The locked status for the folder is not set. Therefore, the global configuration
+ // is relevant for checking if upload is allowed:
+ return !Config::get()->PREVENT_ROOT_FOLDER_UPLOADS_BY_STUDENTS_IN_COURSES;
}
/**
@@ -101,8 +131,13 @@ class RootFolder extends StandardFolder
*/
public function setDataFromEditTemplate($request)
{
+ $locked_status = null;
+ if (isset($request['locked'])) {
+ //The locked status is defined in one way or another.
+ $locked_status = $request['locked'] ? 1 : 0;
+ }
$this->folderdata['data_content'] = [
- 'locked' => $request['locked'] ? 1 : 0
+ 'locked' => $locked_status
];
return $this;
}
diff --git a/templates/filesystem/root_folder/edit.php b/templates/filesystem/root_folder/edit.php
index c22803b..8894f2b 100644
--- a/templates/filesystem/root_folder/edit.php
+++ b/templates/filesystem/root_folder/edit.php
@@ -1,8 +1,24 @@
-<label>
- <input type="checkbox"
- name="locked"
- <?= $folder->data_content && $folder->data_content['locked'] ? 'checked' : '' ?>
- value="1">
- <?= _('Upload für Studierende sperren') ?>
-</label>
-<?= _('Uploads sind weiterhin in entsprechenden Unterordnern möglich') ?>
+<?php
+/**
+ * @var $folder RootFolder
+ */
+?>
+<? if (Config::get()->PREVENT_ROOT_FOLDER_UPLOADS_BY_STUDENTS_IN_COURSES) : ?>
+ <label>
+ <input type="checkbox"
+ name="locked"
+ <?= $folder->data_content && $folder->data_content['locked'] === 0 ? 'checked' : '' ?>
+ value="0">
+ <?= _('Studierenden das Hochladen von Dateien in den Hauptordner erlauben.') ?>
+ </label>
+ <?= _('Studierenden ist es standardmäßig verboten, Dateien in den Hauptordner einer Veranstaltung hochzuladen.') ?>
+<? else: ?>
+ <label>
+ <input type="checkbox"
+ name="locked"
+ <?= $folder->data_content && $folder->data_content['locked'] ? 'checked' : '' ?>
+ value="1">
+ <?= _('Studierenden das Hochladen von Dateien in den Hauptordner verbieten.') ?>
+ </label>
+ <?= _('Studierenden ist es weiterhin möglich, Dateien in Unterordnern hochzuladen.') ?>
+<? endif ?>
diff --git a/tests/jsonapi/FileRefsCreateTest.php b/tests/jsonapi/FileRefsCreateTest.php
index fe14b9f..239dfb9 100644
--- a/tests/jsonapi/FileRefsCreateTest.php
+++ b/tests/jsonapi/FileRefsCreateTest.php
@@ -21,6 +21,8 @@ class FileRefsCreateTest extends \Codeception\Test\Unit
protected function _before()
{
\DBManager::getInstance()->setConnection('studip', $this->getModule('\\Helper\\StudipDb')->dbh);
+ $GLOBALS['SEM_TYPE'] = SemType::getTypes();
+ $GLOBALS['SEM_CLASS'] = SemClass::getClasses();
}
protected function _after()