protected function body() { $inputs = array('name' => array('isNotEmpty'), 'description' => 'isNotEmpty'); if (!$this->isInputValid($inputs)) { return false; } $name = $this->getParams('name'); $description = $this->getParams('description'); $id = $this->getParams('id'); $isIdSet = $id !== null && $id !== ''; $user = User::instance(); $userId = $user->getId(); if (!$isIdSet) { if (!$this->userHasPrivileges(User::lecturesAdd)) { return false; } $lecture = new \Lecture(); $lecture->setName($name); $lecture->setDescription($description); $lecture->setOwner(User::instance()->getEntity()); Repositories::persistAndFlush($lecture); } else { if ($isIdSet) { $lecture = Repositories::findEntity(Repositories::Lecture, $id); if (!$user->hasPrivileges(User::lecturesManageAll) && (!$user->hasPrivileges(User::lecturesManageOwn) || $lecture->getOwner()->getId() != $userId)) { return $this->death(StringID::InsufficientPrivileges); } $lecture->setDescription($description); Repositories::persistAndFlush($lecture); } } return true; }
protected function body() { if (!$this->userHasPrivileges(User::groupsJoinPrivate, User::groupsJoinPublic, User::groupsRequest)) { return false; } if (!$this->isInputValid(array('id' => 'isIndex'))) { return false; } $groupId = $this->getParams('id'); /** * @var $group \Group */ $group = Repositories::findEntity(Repositories::Group, $groupId); // Calculate privileges of the user $user = User::instance(); $canJoinPrivate = User::instance()->hasPrivileges(User::groupsJoinPrivate); $groupIsPrivate = $group->getType() == \Group::TYPE_PRIVATE; $hasSufficientPrivileges = $groupIsPrivate && ($canJoinPrivate || $user->hasPrivileges(User::groupsRequest)) || !$groupIsPrivate && $user->hasPrivileges(User::groupsJoinPublic); if (!$hasSufficientPrivileges) { return $this->death(StringID::InsufficientPrivileges); } $status = $canJoinPrivate || !$groupIsPrivate ? \Subscription::STATUS_SUBSCRIBED : \Subscription::STATUS_REQUESTED; // Put into database $subscription = new \Subscription(); $subscription->setGroup($group); $subscription->setUser(User::instance()->getEntity()); $subscription->setStatus($status); Repositories::persistAndFlush($subscription); return true; }
protected function body() { if (!$this->isInputValid(array('id' => 'isIndex'))) { return false; } $id = $this->getParams('id'); /** * @var $question \Question */ $question = Repositories::findEntity(Repositories::Question, $id); if (!$this->authorizedToManageLecture($question->getLecture())) { return $this->death(StringID::InsufficientPrivileges); } // What if some tests refer to this question? Then the deletion should not be permitted. /** * @var $xtests \Xtest[] */ $xtests = Repositories::getRepository(Repositories::Xtest)->findAll(); foreach ($xtests as $xtest) { $templateArray = explode(',', $xtest->getTemplate()); if (in_array($question->getId(), $templateArray)) { return $this->death(StringID::CannotDeleteQuestionThatsPartOfATest); } } Repositories::remove($question); return true; }
/** * Deletes the usertype specified by ID. * @return bool Was it successful? */ protected function body() { if (!$this->userHasPrivileges(User::usersPrivPresets)) { return false; } if (!$this->isInputSet('id')) { return false; } $id = $this->getParams('id'); if ($id == Repositories::StudentUserType) { return $this->death(StringID::CannotRemoveBasicStudentType); } /** * @var $deletedType \UserType */ $deletedType = Repositories::findEntity(Repositories::UserType, $id); $users = Repositories::getRepository(Repositories::User)->findBy(['type' => $id]); /** @var \UserType $studentType */ $studentType = Repositories::findEntity(Repositories::UserType, Repositories::StudentUserType); foreach ($users as $user) { /** @var $user \User */ $user->setType($studentType); Repositories::persist($user); } Repositories::remove($deletedType); Repositories::flushAll(); return true; }
protected function body() { if (!$this->isInputValid(['resetLink' => 'isNotEmpty', 'pass' => 'isNotEmpty'])) { return false; } $resetLink = $this->getParams('resetLink'); if (strlen($resetLink) < 1) { // We double-check here. This should not be necessary because the isInputValid function takes care of this. // However, if there is a bug in isInputValid that causes the check to be skipped, // this will allow the user to change the password of the first user with no resetLink active. // This could plausibly be the administrator. return $this->death(StringID::HackerError); } $encryptionType = Security::HASHTYPE_PHPASS; $newPassword = $this->getParams('pass'); $newPasswordHash = Security::hash($newPassword, $encryptionType); $usersWithThisResetLink = Repositories::getRepository(Repositories::User)->findBy(['resetLink' => $resetLink]); if (count($usersWithThisResetLink) !== 1) { return $this->death(StringID::ResetLinkDoesNotExist); } /** * @var $user \User */ $user = $usersWithThisResetLink[0]; if ($user->getResetLinkExpiry() < new \DateTime()) { return $this->death(StringID::ResetLinkExpired); } $user->setResetLink(''); $user->setPass($newPasswordHash); Repositories::persistAndFlush($user); return true; }
protected function body() { if (!$this->isInputSet(array('email'))) { return false; } $email = $this->getParams('email'); $users = Repositories::getRepository(Repositories::User)->findBy(['email' => $email]); foreach ($users as $user) { /** * @var $user \User */ // Generate reset link. $resetLink = StringUtils::randomString(60); $now = new \DateTime(); $expiryDate = $now->add(new \DateInterval('P1D')); // Add in in the database (replacing any older reset links in the process) $user->setResetLink($resetLink); $user->setResetLinkExpiry($expiryDate); Repositories::persistAndFlush($user); // Send the e-mail $body = "A Password Reset Link was requested for your e-mail address on XMLCheck.\n\nYour name: " . $user->getRealName() . "\nYour login: "******"\n\nClick this link to reset your password: \n\n" . Config::get('roots', 'http') . "#resetPassword#" . $resetLink . "\n\nThe link will be valid for the next 24 hours, until " . $expiryDate->format("Y-m-d H:i:s") . "."; if (!Core::sendEmail($user->getEmail(), "[XMLCheck] Password Reset Link for '" . $user->getRealName() . "'", $body)) { return $this->death(StringID::MailError); } } $this->addOutput('count', count($users)); return true; }
protected function body() { if (!$this->userHasPrivileges(User::submissionsCorrect)) { return false; } $canViewAuthors = User::instance()->hasPrivileges(User::submissionsViewAuthors); $rated = $this->getParams('rated') ? true : false; $all = $this->getParams('all') ? true : false; $absolutelyAll = $this->getParams('absolutelyAll') ? true : false; $userId = User::instance()->getId(); if ($absolutelyAll) { if (!$this->userHasPrivileges(User::lecturesManageAll, User::groupsManageAll, User::otherAdministration)) { return false; } } /** * @var $submissions \Submission[] */ // group is a DQL reserved word, so we must use _group if ($absolutelyAll) { $submissions = Repositories::makeDqlQuery("SELECT submission, user, assignment, problem, _group FROM \\Submission submission JOIN submission.assignment assignment JOIN assignment.problem problem JOIN submission.user user JOIN assignment.group _group WHERE submission.status <> 'deleted'")->getResult(); } else { $submissions = Repositories::makeDqlQuery("SELECT submission, user, assignment, problem, _group FROM \\Submission submission JOIN submission.assignment assignment JOIN assignment.problem problem JOIN submission.user user JOIN assignment.group _group WHERE _group.owner = :submissionCorrector AND (submission.status = 'graded' OR submission.status = 'latest' OR submission.status = 'handsoff') AND _group.deleted = 0")->setParameter('submissionCorrector', $userId)->getResult(); } foreach ($submissions as $submission) { if (!$all && !$absolutelyAll) { if ($rated && $submission->getStatus() !== \Submission::STATUS_GRADED) { continue; } if (!$rated && $submission->getStatus() === \Submission::STATUS_GRADED) { continue; } } $descriptionForTeacher = $submission->getInfo(); if ($submission->getSimilarityStatus() == \Submission::SIMILARITY_STATUS_GUILTY) { $descriptionForTeacher = Language::get(StringID::ThisSubmissionIsPlagiarism) . "\n======\n" . $descriptionForTeacher; } if ($submission->getSimilarityStatus() == \Submission::SIMILARITY_STATUS_INNOCENT) { $descriptionForTeacher = $descriptionForTeacher . "\n======\n" . Language::get(StringID::ThisSubmissionIsInnocent); } if ($submission->getSimilarityStatus() == \Submission::SIMILARITY_STATUS_NEW) { $descriptionForTeacher = $descriptionForTeacher . "\n======\n" . Language::get(StringID::ThisHasYetToBeCheckedForPlagiarism); } if ($submission->getStatus() == \Submission::STATUS_REQUESTING_GRADING) { $descriptionForTeacher = Language::get(StringID::GradingRequested) . " " . $descriptionForTeacher; } $row = [$submission->getId(), $submission->getAssignment()->getProblem()->getName(), $submission->getAssignment()->getGroup()->getName(), $submission->getDate()->format("Y-m-d H:i:s"), $submission->getSuccess(), $descriptionForTeacher, $submission->getRating(), $submission->getExplanation(), $submission->getAssignment()->getReward(), $submission->getAssignment()->getDeadline()->format("Y-m-d H:i:s"), $canViewAuthors ? $submission->getUser()->getId() : 0, $canViewAuthors ? $submission->getUser()->getRealName() : Language::get(StringID::NotAuthorizedForName), $submission->getOutputfile() != '', $submission->getAssignment()->getId()]; if ($absolutelyAll) { $row[] = $canViewAuthors ? $submission->getUser()->getEmail() : Language::get(StringID::NotAuthorizedForName); $row[] = $submission->getStatus(); } $this->addRowToOutput($row); } return true; }
protected function body() { if (!$this->userHasPrivileges(User::pluginsAdd)) { return false; } $inputs = array('name' => array('isName', 'isNotEmpty')); if (!$this->isInputValid($inputs)) { return false; } $name = $this->getParams('name'); $existingPluginsWithSameName = Repositories::getRepository(Repositories::Plugin)->findBy(['name' => $name]); if (count($existingPluginsWithSameName) > 0) { return $this->death(StringID::PluginNameAlreadyExists); } $pluginFile = $this->getUploadedFile('plugin'); if (!$pluginFile) { return false; } $pluginFolder = Config::get('paths', 'plugins') . $name; if (file_exists($pluginFolder)) { return $this->death(StringID::PluginFolderAlreadyExists); } if (!Filesystem::createDir($pluginFolder)) { return $this->death(StringID::FileSystemError); } if (!Compression::unzip($pluginFile, $pluginFolder)) { $this->death(StringID::UnzipUnsuccessful); goto cleanup_error; } $manifestFile = $pluginFolder . DIRECTORY_SEPARATOR . 'manifest.xml'; $manifest = null; if (!($manifest = $this->parsePluginManifest($manifestFile))) { $this->death(StringID::BadlyFormedPlugin); goto cleanup_error; } if (!file_exists($pluginFolder . DIRECTORY_SEPARATOR . $manifest['mainFile'])) { $this->death(StringID::BadlyFormedPlugin); goto cleanup_error; } $plugin = new \Plugin(); $plugin->setIdentifier($manifest['identifier']); $plugin->setDescription($manifest['description']); $plugin->setConfig($manifest['arguments']); $plugin->setMainfile($name . '/' . $manifest['mainFile']); $plugin->setName($name); $plugin->setType($manifest['type']); Repositories::persistAndFlush($plugin); Filesystem::removeFile($pluginFile); return true; cleanup_error: Filesystem::removeDir($pluginFolder); Filesystem::removeFile($pluginFile); return false; }
protected function body() { $inputs = array('lecture' => 'isIndex', 'name' => array('isName', 'isNotEmpty'), 'type' => array('isEnum' => array('text', 'code', 'image'))); if (!$this->isInputValid($inputs)) { return false; } $lectureId = $this->getParams('lecture'); /** @var \Lecture $lecture */ $lecture = Repositories::findEntity(Repositories::Lecture, $lectureId); $name = $this->getParams('name'); $type = $this->getParams('type'); $id = $this->getParams('id'); $isIdSet = $id !== null && $id !== ''; $originalName = $this->getUploadedFileName('file'); if (!$originalName) { return false; } $extensionStart = strrpos($originalName, '.'); $extension = $extensionStart === false ? '' : substr($originalName, strrpos($originalName, '.')); $attachmentFolder = Config::get('paths', 'attachments'); $filename = $id . '_' . $name . $extension; if (!$this->checkTestGenerationPrivileges($lecture)) { return $this->death(StringID::InsufficientPrivileges); } /** * @var $attachment \Attachment */ $attachment = null; if (!$this->saveUploadedFile('file', $attachmentFolder . $filename)) { return $this->death(StringID::InsufficientPrivileges); } /** @var \Attachment[] $attachmentsWithThisName */ $attachmentsWithThisName = Repositories::getRepository(Repositories::Attachment)->findBy(['lecture' => $lectureId, 'name' => $name]); if ($isIdSet) { $attachment = Repositories::findEntity(Repositories::Attachment, $id); if (count($attachmentsWithThisName) > 0) { if ($attachmentsWithThisName[0]->getId() !== $attachment->getId()) { return $this->death(StringID::AttachmentExists); } } } else { if (count($attachmentsWithThisName) > 0) { return $this->death(StringID::AttachmentExists); } $attachment = new \Attachment(); } $attachment->setType($type); $attachment->setLecture($lecture); $attachment->setName($name); $attachment->setFile($filename); Repositories::persistAndFlush($attachment); return true; }
protected function body() { $plugins = Repositories::getRepository(Repositories::Plugin)->findAll(); $errors = []; foreach ($plugins as $plugin) { /** @var $plugin \Plugin */ $dbPhpFile = $plugin->getMainfile(); $dbDescription = $plugin->getDescription(); $dbIdentifier = $plugin->getIdentifier(); $pluginDirectory = $this->getMainDirectory($dbPhpFile); if ($pluginDirectory === false) { $errors[] = $plugin->getName() . ": " . Language::get(StringID::ReloadManifests_InvalidFolder); continue; } $manifestFile = Filesystem::combinePaths(Config::get('paths', 'plugins'), $pluginDirectory, "manifest.xml"); $xml = new \DOMDocument(); $success = $xml->load(realpath($manifestFile)); if ($success === false) { $errors[] = $plugin->getName() . ": " . Language::get(StringID::ReloadManifests_MalformedXmlOrFileMissing); continue; } $fileDescription = $xml->getElementsByTagName('description')->item(0); $fileArguments = $xml->getElementsByTagName('argument'); $fileIdentifier = $xml->getElementsByTagName('identifier')->item(0); $fileArgumentsArray = []; for ($i = 0; $i < $fileArguments->length; $i++) { $fileArgumentsArray[] = trim($fileArguments->item($i)->nodeValue); } $fileArgumentsString = implode(';', $fileArgumentsArray); if ($dbDescription !== trim($fileDescription->nodeValue)) { $errors[] = $plugin->getName() . ": " . Language::get(StringID::ReloadManifests_DescriptionMismatch); $plugin->setDescription(trim($fileDescription->nodeValue)); Repositories::persist($plugin); } if ($dbIdentifier !== trim($fileIdentifier->nodeValue)) { $errors[] = $plugin->getName() . ": " . Language::get(StringID::ReloadManifests_IdentifierMismatch); $plugin->setIdentifier(trim($fileIdentifier->nodeValue)); Repositories::persist($plugin); } if ($plugin->getConfig() !== $fileArgumentsString) { $errors[] = $plugin->getName() . ": " . Language::get(StringID::ReloadManifests_ArgumentsMismatch); $plugin->setConfig($fileArgumentsString); Repositories::persist($plugin); } } Repositories::flushAll(); if (count($errors) === 0) { $this->addOutput("text", Language::get(StringID::ReloadManifests_DatabaseCorrespondsToManifests)); } else { $this->addOutput("text", implode('<br>', $errors)); } return true; }
protected function body() { $inputs = array('lecture' => 'isIndex', 'text' => 'isNotEmpty', 'type' => array('isEnum' => array('text', 'choice', 'multi'))); if (!$this->isInputValid($inputs)) { return false; } $lectureId = $this->getParams('lecture'); $text = $this->getParams('text'); $type = $this->getParams('type'); $id = $this->getParams('id'); $isIdSet = $id !== null && $id !== ''; $options = $this->getParams('options') . ''; $attachments = $this->getParams('attachments') . ''; if (!$this->checkTestGenerationPrivileges($lectureId)) { return $this->death(StringID::InsufficientPrivileges); } $visibleAttachments = CommonQueries::GetAttachmentsVisibleToActiveUser(); $attTmp = $attachments ? explode(';', $attachments) : array(); foreach ($visibleAttachments as $va) { $aId = $va->getId(); $index = array_search($aId, $attTmp); if ($index !== false) { array_splice($attTmp, $index, 1); if ($va->getLecture()->getId() != $lectureId) { return $this->death(StringID::AttachmentBelongsToAnotherLecture); } } } if (count($attTmp)) { return $this->stop(ErrorCause::invalidInput('Following attachment IDs are invalid or inaccessible: ' . implode(', ', $attTmp) . '.', 'attachments')); } /** @var \Question $question */ $question = null; if (!$isIdSet) { $question = new \Question(); } else { $question = Repositories::findEntity(Repositories::Question, $id); if ($question->getLecture()->getId() != $lectureId) { // This must be a weak comparison, because lectureId comes from user and is text. return $this->death(StringID::HackerError); } } $question->setAttachments($attachments); /** @var \Lecture $lecture */ $lecture = Repositories::findEntity(Repositories::Lecture, $lectureId); $question->setLecture($lecture); $question->setOptions($options); $question->setText($text); $question->setType($type); Repositories::persistAndFlush($question); return true; }
protected function body() { $questions = $this->getParams('questions'); if ($questions === null || $questions === '') { return $this->death(StringID::ChooseAtLeastOneQuestion); // Put this in front to have a more specific, comprehensible error message } $inputs = array('description' => 'isNotEmpty', 'count' => 'isNonNegativeInt', 'questions' => 'isNotEmpty'); if (!$this->isInputValid($inputs)) { return false; } $description = $this->getParams('description'); $count = $this->getParams('count'); $questions = $this->getParams('questions'); $questionsArray = explode(',', $questions); $visibleQuestions = CommonQueries::GetQuestionsVisibleToActiveUser(); /** * @var $lecture \Lecture */ $lecture = null; foreach ($visibleQuestions as $vq) { $qId = $vq->getId(); $index = array_search($qId, $questionsArray); if ($index !== false) { array_splice($questionsArray, $index, 1); if ($lecture === null) { $lecture = $vq->getLecture(); } elseif ($lecture->getId() !== $vq->getLecture()->getId()) { return $this->death(StringID::TestCannotContainQuestionsOfDifferentLectures); } } } if (count($questionsArray)) { return $this->stop(ErrorCause::invalidInput('Following question IDs are invalid or inaccessible: ' . implode(', ', $questionsArray) . '.', 'questions')); } if ($lecture === null) { return $this->death(StringID::ChooseAtLeastOneQuestion); } if (!$this->checkTestGenerationPrivileges($lecture->getId())) { return $this->death(StringID::InsufficientPrivileges); } $randomized = $this->generateTest($questions, $count); $xtest = new \Xtest(); $xtest->setDescription($description); $xtest->setCount($count); $xtest->setLecture($lecture); $xtest->setTemplate($questions); $xtest->setGenerated(implode(',', $randomized)); Repositories::persistAndFlush($xtest); return true; }
protected final function body() { if (!$this->isInputValid(array('id' => 'isIndex'))) { return false; } $id = $this->getParams('id'); /** @var \XTest $test */ $test = Repositories::findEntity(Repositories::Xtest, $id); $description = $test->getDescription(); $questions = $test->getGenerated(); $lecture = $test->getLecture(); $user = User::instance(); if (!$user->hasPrivileges(User::lecturesManageAll) && (!$user->hasPrivileges(User::lecturesManageOwn) || $lecture->getOwner()->getId() != $user->getId())) { return $this->death(StringID::InsufficientPrivileges); } if (!$questions) { return $this->stop('the test has not been generated yet', 'cannot create test'); } $questions = explode(',', $questions); $selectedQuestions = array(); $attachmentIds = array(); foreach ($questions as $questionId) { /** @var \Question $qData */ $qData = Repositories::findEntity(Repositories::Question, $questionId); $options = $qData->getOptions(); $options = $options ? explode($options[0], substr($options, 1)) : array(); $qAtt = $qData->getAttachments(); $qAtt = $qAtt ? explode(';', $qAtt) : array(); array_push($selectedQuestions, array('text' => $qData->getText(), 'type' => $qData->getType(), 'options' => $options, 'attachments' => $qAtt)); $attachmentIds = array_merge($attachmentIds, $qAtt); } $attachmentIds = array_unique($attachmentIds); $reverseIndex = array_flip($attachmentIds); foreach ($selectedQuestions as &$selQ) { $translated = array(); foreach ($selQ['attachments'] as $selA) { array_push($translated, $reverseIndex[$selA] + 1); } $selQ['attachments'] = $translated; } $attachments = array(); $folder = Config::get('paths', 'attachments'); foreach ($attachmentIds as $attachmentId) { /** @var \Attachment $aData */ $aData = Repositories::findEntity(Repositories::Attachment, $attachmentId); array_push($attachments, array('id' => $aData->getId(), 'type' => $aData->getType(), 'file' => $folder . $aData->getFile())); } $this->setContentType('text/html'); $this->generateTestHtml($description, $selectedQuestions, $attachments); return true; }
protected function body() { if (!$this->isInputValid(array('id' => 'isIndex'))) { return false; } $id = $this->getParams('id'); /** * @var $subscription \Subscription */ $subscription = Repositories::findEntity(Repositories::Subscription, $id); if ($subscription->getUser()->getId() !== User::instance()->getId()) { return $this->death(StringID::InsufficientPrivileges); } Repositories::remove($subscription); return true; }
protected function body() { if (!$this->isInputValid(array('id' => 'isIndex'))) { return false; } /** * @var $group \Group */ $group = Repositories::findEntity(Repositories::Group, $this->getParams('id')); $user = User::instance(); if (!$user->hasPrivileges(User::groupsManageAll) && (!$user->hasPrivileges(User::groupsManageOwn) || $user->getId() != $group->getOwner()->getId())) { return $this->death(StringID::InsufficientPrivileges); } RemovalManager::hideGroupAndItsAssignments($group); return true; }
protected function body() { if (!$this->isInputSet('id')) { return false; } $id = $this->getParams('id'); /** * @var $subscription \Subscription */ $subscription = Repositories::findEntity(Repositories::Subscription, $id); if (User::instance()->getId() !== $subscription->getGroup()->getOwner()->getId()) { return $this->death(StringID::InsufficientPrivileges); } $this->handleRequest($subscription); return true; }
protected function body() { if (!$this->isInputValid(array('id' => 'isIndex'))) { return false; } $id = $this->getParams('id'); /** * @var $xtest \Xtest */ $xtest = Repositories::findEntity(Repositories::Xtest, $id); if (!$this->checkTestGenerationPrivileges($xtest->getLecture()->getId())) { return $this->death(StringID::InsufficientPrivileges); } Repositories::remove($xtest); return true; }
protected function body() { if (!$this->isInputValid(array('id' => 'isIndex'))) { return false; } /** * @var $lecture \Lecture */ $lecture = Repositories::findEntity(Repositories::Lecture, $this->getParams('id')); $user = User::instance(); if (!$user->hasPrivileges(User::lecturesManageAll) && (!$user->hasPrivileges(User::lecturesManageOwn) || $user->getId() != $lecture->getId())) { return $this->death(StringID::InsufficientPrivileges); } RemovalManager::hideLectureItsProblemsGroupsQuestionsAttachmentsAndXtests($lecture); return true; }
protected function body() { if (!$this->userHasPrivileges(User::usersRemove)) { return false; } if (!$this->isInputSet('id')) { return false; } $id = $this->getParams('id'); if ($id == User::instance()->getId()) { return $this->death(StringID::YouCannotRemoveYourself); } /** @var \User $user */ $user = Repositories::findEntity(Repositories::User, $id); RemovalManager::hideUserAndAllHeOwns($user); return true; }
protected function body() { if (!$this->isInputValid(array('id' => 'isIndex'))) { return false; } /** * @var $assignment \Assignment */ $assignment = Repositories::findEntity(Repositories::Assignment, $this->getParams('id')); $user = User::instance(); if (!$user->hasPrivileges(User::groupsManageAll) && (!$user->hasPrivileges(User::groupsManageOwn) || $user->getId() != $assignment->getGroup()->getOwner()->getId())) { return $this->death(StringID::InsufficientPrivileges); } $assignment->setDeleted(true); Repositories::persistAndFlush($assignment); return true; }
/** * Gets submission with supplied ID if it's accessible to user [stopping]. * @param int $id submission ID * @return \Submission submission or false in case of failure */ protected final function findAccessibleSubmissionById($id) { /** * @var $submission \Submission */ $submission = Repositories::findEntity(Repositories::Submission, $id); $userId = User::instance()->getId(); $authorId = $submission->getUser()->getId(); $ownerId = $submission->getAssignment()->getGroup()->getOwner()->getId(); if ($authorId !== $userId && $ownerId !== $userId) { if (User::instance()->hasPrivileges(User::groupsManageAll, User::lecturesManageAll, User::otherAdministration)) { return $submission; } return $this->death(StringID::InsufficientPrivileges); } return $submission; }
protected function body() { if (!$this->isInputValid(array('id' => 'isIndex'))) { return false; } $id = $this->getParams('id'); /** * @var $submission \Submission */ $submission = Repositories::findEntity(Repositories::Submission, $id); $userId = User::instance()->getId(); if ($submission->getUser()->getId() != $userId) { return $this->death(StringID::HackerError); } // First, if you handed something off previously, it is no longer handed off /** * @var $yourSubmissions \Submission[] */ $yourSubmissions = Repositories::getRepository(Repositories::Submission)->findBy(['user' => $userId, 'assignment' => $submission->getAssignment()->getId()]); foreach ($yourSubmissions as $previouslyHandedOffSubmission) { if ($previouslyHandedOffSubmission->getStatus() == \Submission::STATUS_REQUESTING_GRADING || $previouslyHandedOffSubmission->getStatus() == \Submission::STATUS_LATEST) { $previouslyHandedOffSubmission->setStatus(\Submission::STATUS_NORMAL); Repositories::persistAndFlush($previouslyHandedOffSubmission); } } // Next, hand off the submission $submission->setStatus(\Submission::STATUS_REQUESTING_GRADING); Repositories::persistAndFlush($submission); $emailText = file_get_contents(Config::get("paths", "newSubmissionEmail")); $emailText = str_replace("%{RealName}", User::instance()->getRealName(), $emailText); $emailText = str_replace("%{Email}", User::instance()->getEmail(), $emailText); $emailText = str_replace("%{Link}", Config::getHttpRoot() . "#correctionAll#submission#" . $submission->getId(), $emailText); $lines = explode("\n", $emailText); $subject = $lines[0]; // The first line is subject. $text = preg_replace('/^.*\\n/', '', $emailText); // Everything except the first line. $to = $submission->getAssignment()->getGroup()->getOwner(); if ($to->getSendEmailOnNewSubmission()) { if (!Core::sendEmail($to->getEmail(), $subject, $text)) { return $this->death(StringID::MailError); } } return true; }
protected function body() { if (!$this->isInputValid(array('id' => 'isIndex'))) { return false; } $id = $this->getParams('id'); /** * @var $problem \Problem */ $problem = Repositories::findEntity(Repositories::Problem, $id); $lecture = $problem->getLecture(); $user = User::instance(); if (!$user->hasPrivileges(User::lecturesManageAll) && (!$user->hasPrivileges(User::lecturesManageOwn) || $user->getId() != $lecture->getOwner())) { return $this->death(StringID::InsufficientPrivileges); } RemovalManager::hideProblemAndItsAssignments($problem); return true; }
protected function body() { if (!$this->userHasPrivileges(User::otherAdministration, User::groupsManageAll, User::lecturesManageAll)) { return false; } $newId = $this->getParams('newId'); if (!$newId) { return true; } $canViewAuthors = User::instance()->hasPrivileges(User::submissionsViewAuthors); /** @var \Similarity[] $similarities */ $similarities = Repositories::getRepository(Repositories::Similarity)->findBy(['newSubmission' => $newId]); foreach ($similarities as $similarity) { $row = [$similarity->getId(), $similarity->getOldSubmission()->getId(), $similarity->getSuspicious() ? "yes" : false, $similarity->getScore(), $similarity->getDetails(), $canViewAuthors ? $similarity->getOldSubmission()->getUser()->getRealName() : Language::get(StringID::NotAuthorizedForName), $similarity->getOldSubmission()->getDate()->format("Y-m-d H:i:s"), $similarity->getOldSubmission()->getStatus()]; $this->addRowToOutput($row); } return true; }
protected function body() { if (!$this->isInputSet(array('code'))) { return false; } $code = $this->getParams('code'); /** * @var $users \User[] */ $users = Repositories::getRepository(Repositories::User)->findBy(['activationCode' => $code]); if (count($users) === 1) { $users[0]->setActivationCode(''); Repositories::persistAndFlush($users[0]); return true; } else { return $this->death(StringID::InvalidActivationCode); } }
protected function body() { if (!$this->userHasPrivileges()) { return; } $query = "SELECT a, p, l, z, g FROM Assignment a JOIN a.problem p LEFT JOIN p.plugin z JOIN p.lecture l JOIN a.group g WITH g.id IN (SELECT IDENTITY(k.group) FROM \\Subscription k WHERE k.user = :id AND a.deleted = false)"; /** * @var $assignments \Assignment[] */ $userId = User::instance()->getId(); $assignments = Repositories::getEntityManager()->createQuery($query)->setParameter('id', $userId)->getResult(); foreach ($assignments as $assignment) { $submissionGraded = count(Repositories::getRepository(Repositories::Submission)->findBy(['assignment' => $assignment->getId(), 'user' => $userId, 'status' => \Submission::STATUS_GRADED])) > 0; $submissionExists = count(Repositories::getRepository(Repositories::Submission)->findBy(['assignment' => $assignment->getId(), 'user' => $userId])) > 0; $row = [$assignment->getId(), $assignment->getProblem()->getName(), $assignment->getProblem()->getDescription(), $assignment->getProblem()->getPlugin() ? $assignment->getProblem()->getPlugin()->getDescription() : Language::get(StringID::NoPluginUsed), $assignment->getDeadline()->format("Y-m-d H:i:s"), $assignment->getReward(), $assignment->getProblem()->getLecture()->getName(), $assignment->getProblem()->getLecture()->getDescription(), $assignment->getGroup()->getName(), $assignment->getGroup()->getDescription(), $submissionExists, $submissionGraded]; $this->addRowToOutput($row); } }
protected function body() { if (!$this->isInputValid(array('id' => 'isIndex'))) { return false; } $id = $this->getParams('id'); /** * @var $attachment \Attachment */ $attachment = Repositories::findEntity(Repositories::Attachment, $id); if (!$this->authorizedToManageLecture($attachment->getLecture())) { return false; } $folder = Config::get('paths', 'attachments'); $file = $attachment->getFile(); RemovalManager::deleteAttachmentById($id); Filesystem::removeFile($folder . $file); return true; }
protected function body() { if (!$this->isInputValid(array('id' => 'isIndex'))) { return false; } $id = $this->getParams('id'); /** * @var $attachment \Attachment */ $attachment = Repositories::findEntity(Repositories::Attachment, $id); $file = $attachment->getFile(); $lecture = $attachment->getLecture(); if (!$this->authorizedToManageLecture($lecture)) { return $this->death(StringID::InsufficientPrivileges); } $this->doNotAttach(); $this->setOutput(Config::get('paths', 'attachments') . $file); return true; }
/** * Runs this script. * @return bool Is it successful? */ protected function body() { if (!$this->isInputSet(array('id'))) { return false; } $id = $this->getParams('id'); /** * @var $submission \Submission */ $submission = Repositories::findEntity(Repositories::Submission, $id); if ($submission->getUser()->getId() !== User::instance()->getId()) { return $this->death(StringID::InsufficientPrivileges); } if ($submission->getStatus() === \Submission::STATUS_GRADED) { return $this->death(StringID::CannotDeleteGradedSubmissions); } if ($submission->getStatus() === \Submission::STATUS_REQUESTING_GRADING) { return $this->death(StringID::CannotDeleteHandsoffSubmissions); } $status = $submission->getStatus(); $submission->setStatus(\Submission::STATUS_DELETED); Repositories::persist($submission); // Make something else latest if ($status === \Submission::STATUS_LATEST) { $latestSubmission = null; /** * @var $submissions \Submission[] * @var $latestSubmission \Submission */ $submissions = Repositories::getRepository(Repositories::Submission)->findBy(['status' => \Submission::STATUS_NORMAL, 'assignment' => $submission->getAssignment()->getId(), 'user' => User::instance()->getId()]); foreach ($submissions as $olderSolution) { if ($latestSubmission === null || $olderSolution->getDate() > $latestSubmission->getDate()) { $latestSubmission = $olderSolution; } } if ($latestSubmission !== null) { $latestSubmission->setStatus(\Submission::STATUS_LATEST); Repositories::persist($latestSubmission); } } Repositories::flushAll(); return true; }
protected function body() { if (!$this->userHasPrivileges(User::pluginsRemove)) { return false; } if (!$this->isInputValid(array('id' => 'isIndex'))) { return false; } $id = $this->getParams('id'); /** * @var $plugin \Plugin */ $plugin = Repositories::findEntity(Repositories::Plugin, $id); $pluginFolder = Filesystem::combinePaths(Config::get('paths', 'plugins'), $plugin->getName()); if (!Filesystem::removeDir($pluginFolder)) { return $this->death(StringID::FileSystemError); } RemovalManager::deletePluginById($id); return true; }