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 0000000000000000000000000000000000000000..83377ce5a2d75e2d1c1d6ff1391615baa58332a7 --- /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 9771c32faf02a42692dd6bafd62f54347c7b6ee1..523a1a165b7d22b25280e3403c833183e9ce5dda 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 c22803b3bfcdc8521f9c1b5628d0ce79f11bf8db..8894f2b95a6684fc90127ca9b9d5ff09a434b828 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 fe14b9fd83e78a45b33765ccdb05bac696499f37..239dfb99e290e861697004a5828c6aebde7d5044 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()