From 642a2172a6a965cae5e6bf481382d70e6a4b7e67 Mon Sep 17 00:00:00 2001 From: Moritz Strohm Date: Wed, 28 Aug 2024 16:00:20 +0000 Subject: Prevent root folder uploads by students in courses, re #3745 Merge request studip/studip!2608 --- ...folder_upload_by_students_in_courses_config.php | 34 ++++++++++++++ lib/filesystem/RootFolder.php | 53 ++++++++++++++++++---- templates/filesystem/root_folder/edit.php | 32 +++++++++---- tests/jsonapi/FileRefsCreateTest.php | 2 + 4 files changed, 104 insertions(+), 17 deletions(-) create mode 100644 db/migrations/5.9.1_add_prevent_root_folder_upload_by_students_in_courses_config.php 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 @@ +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 @@ - - + +PREVENT_ROOT_FOLDER_UPLOADS_BY_STUDENTS_IN_COURSES) : ?> + + + + + + 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() -- cgit v1.0