From 03c5927fa48eb86f44042a12c4d8cfb9eb7e41f3 Mon Sep 17 00:00:00 2001 From: Jan-Hendrik Willms <tleilax+studip@gmail.com> Date: Thu, 29 Aug 2024 14:38:15 +0000 Subject: [PATCH] use csrf protection correctly, fixes #4545 Closes #4545 Merge request studip/studip!3341 --- app/controllers/admin/login_style.php | 7 +- app/controllers/admin/user.php | 2 +- app/controllers/contact.php | 4 +- app/controllers/course/timesrooms.php | 6 +- app/controllers/course/wiki.php | 9 +- app/controllers/materialien/files.php | 31 +-- app/controllers/questionnaire.php | 5 +- app/controllers/settings/deputies.php | 2 +- app/controllers/shared/contacts.php | 4 +- .../studiengaenge/studiengaenge.php | 50 ++-- app/views/materialien/files/index.php | 236 +++++++++--------- app/views/materialien/files/range.php | 206 +++++++-------- app/views/shared/contacts/index.php | 171 +++++++------ lib/classes/forms/Form.php | 5 +- 14 files changed, 364 insertions(+), 374 deletions(-) diff --git a/app/controllers/admin/login_style.php b/app/controllers/admin/login_style.php index 35cd7d820ff..6f721aaf741 100644 --- a/app/controllers/admin/login_style.php +++ b/app/controllers/admin/login_style.php @@ -64,7 +64,8 @@ class Admin_LoginStyleController extends AuthenticatedController */ public function add_pic_action() { - CSRFProtection::verifyRequest(); + CSRFProtection::verifyUnsafeRequest(); + $success = 0; foreach ($_FILES['pictures']['name'] as $index => $filename) { if ($_FILES['pictures']['error'][$index] !== UPLOAD_ERR_OK) { @@ -174,7 +175,7 @@ class Admin_LoginStyleController extends AuthenticatedController public function store_faq_action(LoginFaq $entry = null) { - CSRFProtection::verifyRequest(); + CSRFProtection::verifyUnsafeRequest(); $entry->setData([ 'title' => Request::i18n('title'), @@ -190,7 +191,7 @@ class Admin_LoginStyleController extends AuthenticatedController public function delete_faq_action(LoginFaq $entry) { - CSRFProtection::verifyRequest(); + CSRFProtection::verifyUnsafeRequest(); if ($entry->delete()) { PageLayout::postSuccess(_('Der Hinweistext wurde gelöscht.')); diff --git a/app/controllers/admin/user.php b/app/controllers/admin/user.php index a9a04cfd354..49b5f61408c 100644 --- a/app/controllers/admin/user.php +++ b/app/controllers/admin/user.php @@ -1093,7 +1093,7 @@ class Admin_UserController extends AuthenticatedController */ public function store_user_institute_action($user_id, $institute_id) { - CSRFProtection::verifyRequest(); + CSRFProtection::verifyUnsafeRequest(); $inst_membership = InstituteMember::findOneBySQL('user_id = ? AND institut_id = ?', [$user_id, $institute_id]); diff --git a/app/controllers/contact.php b/app/controllers/contact.php index 2148777c360..7820ce6cc50 100644 --- a/app/controllers/contact.php +++ b/app/controllers/contact.php @@ -166,7 +166,7 @@ class ContactController extends AuthenticatedController $this->group->owner_id = User::findCurrent()->id; } if (Request::submitted('store')) { - CSRFProtection::verifyRequest(); + CSRFProtection::verifyUnsafeRequest(); $this->group->name = Request::get('name'); $this->group->store(); $this->redirect('contact/index/' . $this->group->id); @@ -175,7 +175,7 @@ class ContactController extends AuthenticatedController public function deleteGroup_action() { - CSRFProtection::verifyRequest(); + CSRFProtection::verifyUnsafeRequest(); $this->group->delete(); $this->redirect('contact/index'); } diff --git a/app/controllers/course/timesrooms.php b/app/controllers/course/timesrooms.php index 9b124697cf6..4d4dbff1c5d 100644 --- a/app/controllers/course/timesrooms.php +++ b/app/controllers/course/timesrooms.php @@ -1239,7 +1239,8 @@ class Course_TimesroomsController extends AuthenticatedController */ public function saveCycle_action() { - CSRFProtection::verifyRequest(); + CSRFProtection::verifyUnsafeRequest(); + $start = strtotime(Request::get('start_time')); $end = strtotime(Request::get('end_time')); @@ -1390,7 +1391,8 @@ class Course_TimesroomsController extends AuthenticatedController */ public function deleteCycle_action($cycle_id) { - CSRFProtection::verifyRequest(); + CSRFProtection::verifyUnsafeRequest(); + $cycle = SeminarCycleDate::find($cycle_id); if ($cycle === null) { $message = sprintf(_('Es gibt keinen regelmäßigen Eintrag "%s".'), $cycle_id); diff --git a/app/controllers/course/wiki.php b/app/controllers/course/wiki.php index ac997e8e828..970ea4695df 100644 --- a/app/controllers/course/wiki.php +++ b/app/controllers/course/wiki.php @@ -299,9 +299,12 @@ class Course_WikiController extends AuthenticatedController public function delete_action(WikiPage $page) { - if (!Request::isPost() || !$page->isEditable() || !CSRFProtection::verifyRequest()) { + CSRFProtection::verifyUnsafeRequest(); + + if (!$page->isEditable()) { throw new AccessDeniedException(); } + $name = $page->name; $page->delete(); PageLayout::postSuccess(sprintf(_('Die Seite %s wurde gelöscht.'), htmlReady($name))); @@ -310,7 +313,9 @@ class Course_WikiController extends AuthenticatedController public function deleteversion_action(WikiPage $page) { - if (!Request::isPost() || !$page->isEditable() || !CSRFProtection::verifyRequest()) { + CSRFProtection::verifyUnsafeRequest(); + + if (!$page->isEditable()) { throw new AccessDeniedException(); } diff --git a/app/controllers/materialien/files.php b/app/controllers/materialien/files.php index 804668ef603..acdc14cdda4 100644 --- a/app/controllers/materialien/files.php +++ b/app/controllers/materialien/files.php @@ -435,7 +435,7 @@ class Materialien_FilesController extends MVVController public function delete_range_action($mvvfile_id, $range_id) { - CSRFProtection::verifyRequest(); + CSRFProtection::verifyUnsafeRequest(); if ($mvvfile_range = MvvFileRange::find([$mvvfile_id, $range_id])) { $vacant = $mvvfile_range->position; @@ -460,36 +460,9 @@ class Materialien_FilesController extends MVVController } } - public function delete_fileref_action($mvvfile_id, $fileref_id) - { - CSRFProtection::verifyRequest(); - - if ($mvv_file = MvvFile::find($mvvfile_id)) { - $vacant = $mvv_file->position; - $range_id = $mvv_file->range_id; - if ($mvv_file->delete()) { - foreach (MvvFile::findBySQL('range_id = ? ORDER BY position ASC',[$range_id]) as $other_file) { - if ($other_file->position > $vacant) { - $tmp = $other_file->position; - $other_file->position = $vacant; - $other_file->store(); - $vacant = $tmp; - } - } - PageLayout::postSuccess(_('Das Dokument wurde gelöscht.')); - } - } - $this->range_id = $range_id; - if (Request::isXhr()) { - $this->response->add_header('X-Dialog-Execute', 'STUDIP.MVV.Document.reload_documenttable("' . $range_id . '")'); - $this->response->add_header('X-Dialog-Close', 1); - $this->render_nothing(); - } - } - public function delete_all_dokument_action($mvvfile_id) { - CSRFProtection::verifyRequest(); + CSRFProtection::verifyUnsafeRequest(); MvvFile::deleteBySQL('mvvfile_id =?', [$mvvfile_id]); MvvFileRange::deleteBySQL('mvvfile_id =?', [$mvvfile_id]); diff --git a/app/controllers/questionnaire.php b/app/controllers/questionnaire.php index 07e28a1399c..d81b6cda508 100644 --- a/app/controllers/questionnaire.php +++ b/app/controllers/questionnaire.php @@ -381,9 +381,12 @@ class QuestionnaireController extends AuthenticatedController public function reset_action(Questionnaire $questionnaire) { - if (!Request::isPost() || !$questionnaire->isEditable() || !CSRFProtection::verifyRequest()) { + CSRFProtection::verifyUnsafeRequest(); + + if (!$questionnaire->isEditable()) { throw new AccessDeniedException(); } + foreach ($questionnaire->anonymousanswers as $anonymous) { $anonymous->delete(); } diff --git a/app/controllers/settings/deputies.php b/app/controllers/settings/deputies.php index 3476692cfbb..8ce4555e7d7 100644 --- a/app/controllers/settings/deputies.php +++ b/app/controllers/settings/deputies.php @@ -101,7 +101,7 @@ class Settings_DeputiesController extends Settings_SettingsController public function add_member_action() { - CSRFProtection::verifyRequest(); + CSRFProtection::verifyUnsafeRequest(); $mp = MultiPersonSearch::load('settings_add_deputy'); $msg = [ diff --git a/app/controllers/shared/contacts.php b/app/controllers/shared/contacts.php index 62dd7a88816..963e60bcb5e 100644 --- a/app/controllers/shared/contacts.php +++ b/app/controllers/shared/contacts.php @@ -641,7 +641,7 @@ class Shared_ContactsController extends MVVController public function delete_all_ranges_action($contact_id = null) { - CSRFProtection::verifyRequest(); + CSRFProtection::verifyUnsafeRequest(); $contact = MvvContact::find($contact_id); if (!($contact && MvvPerm::get($contact)->haveFieldPerm('ranges', MvvPerm::PERM_CREATE))) { @@ -662,7 +662,7 @@ class Shared_ContactsController extends MVVController public function delete_extern_contact_action($user_id = null) { - CSRFProtection::verifyRequest(); + CSRFProtection::verifyUnsafeRequest(); if ($mvv_ext_contact = MvvExternContact::find($user_id)) { $mvv_ext_contact->delete(); diff --git a/app/controllers/studiengaenge/studiengaenge.php b/app/controllers/studiengaenge/studiengaenge.php index d053f482915..5134ceb68c6 100644 --- a/app/controllers/studiengaenge/studiengaenge.php +++ b/app/controllers/studiengaenge/studiengaenge.php @@ -288,17 +288,13 @@ class Studiengaenge_StudiengaengeController extends MVVController $studiengang = Studiengang::find($studiengang_id); if (!$studiengang) { PageLayout::postError(_('Unbekannter Studiengang')); - } else { - if (Request::isPost()) { - if (Request::submitted('delete')) { - CSRFProtection::verifyRequest(); - PageLayout::postSuccess(sprintf( - _('Studiengang "%s" gelöscht!'), - htmlReady($studiengang->name) - )); - $studiengang->delete(); - } - } + } else if (Request::submitted('delete')) { + CSRFProtection::verifyUnsafeRequest(); + PageLayout::postSuccess(sprintf( + _('Studiengang "%s" gelöscht!'), + htmlReady($studiengang->name) + )); + $studiengang->delete(); } $this->redirect($this->action_url('index')); } @@ -538,23 +534,21 @@ class Studiengaenge_StudiengaengeController extends MVVController if ($this->stg_stgteil->isNew()) { PageLayout::postError(_('Unbekannter Studiengangteil')); } else { - if (Request::isPost()) { - CSRFProtection::verifyRequest(); - if (!MvvPerm::haveFieldPermStudiengangteile($studiengang, MvvPerm::PERM_CREATE)) { - throw new Trails_Exception(403); - } - $stgteil_name = $this->stg_stgteil->stgteil_name; - $stgbez_name = $this->stg_stgteil->stgbez_name; - if ($this->stg_stgteil->delete()) { - PageLayout::postSuccess(sprintf( - _('Die Zuordnung des Studiengangteils "%s" als "%s" zum Studiengang "%s" wurde gelöscht.'), - htmlReady($stgteil_name), - htmlReady($stgbez_name), - htmlReady($studiengang->name) - )); - } else { - PageLayout::postError(_('Der Studiengangteil konnte nicht gelöscht werden.')); - } + CSRFProtection::verifyUnsafeRequest(); + if (!MvvPerm::haveFieldPermStudiengangteile($studiengang, MvvPerm::PERM_CREATE)) { + throw new Trails_Exception(403); + } + $stgteil_name = $this->stg_stgteil->stgteil_name; + $stgbez_name = $this->stg_stgteil->stgbez_name; + if ($this->stg_stgteil->delete()) { + PageLayout::postSuccess(sprintf( + _('Die Zuordnung des Studiengangteils "%s" als "%s" zum Studiengang "%s" wurde gelöscht.'), + htmlReady($stgteil_name), + htmlReady($stgbez_name), + htmlReady($studiengang->name) + )); + } else { + PageLayout::postError(_('Der Studiengangteil konnte nicht gelöscht werden.')); } } $this->redirect( diff --git a/app/views/materialien/files/index.php b/app/views/materialien/files/index.php index 538d97a38c0..d1eb03c5828 100644 --- a/app/views/materialien/files/index.php +++ b/app/views/materialien/files/index.php @@ -1,123 +1,127 @@ -<table id="mvv_files" class="default collapsable"> - <caption> - <?= _('Verlinkte Dokumente') ?> - <span class="actions"><? printf(ngettext('%s Dokument', '%s Dokumente', $count), $count) ?></span> - </caption> - <thead> - <tr class="sortable"> - <?= $controller->renderSortLink('materialien/files/', _('Name'), 'mvv_files_filerefs.name') ?> - <?= $controller->renderSortLink('materialien/files/', _('Dateiname'), 'file_refs.name') ?> - <?= $controller->renderSortLInk('materialien/files/', _('Sichtbarkeit'), 'extern_visible') ?> - <?= $controller->renderSortLInk('materialien/files/', _('Sprache'), 'file_language') ?> - <?= $controller->renderSortLink('materialien/files/', _('Art der Datei'), 'type') ?> - <?= $controller->renderSortLink('materialien/files/', _('Datum'), 'mkdate') ?> - <th><?= _('Dateityp') ?></th> - <?= $controller->renderSortLInk('materialien/files/', _('Kategorie'), 'category') ?> - <?= $controller->renderSortLink('materialien/files/', _('Zuordnungen'), 'count_relations') ?> - <th class="actions" style="width: 5%"><?= _('Aktionen') ?></th> - </tr> - </thead> -<? foreach ($dokumente as $mvv_file) : ?> - <tbody class="<?= (in_array($range_id, $mvv_file->getRangesArray()) && ($fileref_id && in_array($fileref_id, $mvv_file->getFileRefsArray())) ? 'not-collapsed' : 'collapsed') ?>"> - <tr class="header-row"> - <td class="toggle-indicator"> - <a class="mvv-load-in-new-row" - href="<?= $controller->link_for('materialien/files/details', $mvv_file->mvvfile_id) ?>"> - <?= htmlReady($mvv_file->getDisplayName()) ?> - </a> - </td> - <td class="dont-hide"> - <? if ($mvv_file->getFiletypes()[0] === 'Link'): ?> - <a href="<?= htmlReady($mvv_file->file_refs[0]->file_ref->file->metadata['url']); ?>" target="_blank"> - <?= Icon::create('link-extern')->asImg(['class' => 'text-bottom']) ?> +<form method="post"> + <?= CSRFProtection::tokenTag() ?> + <table id="mvv_files" class="default collapsable"> + <caption> + <?= _('Verlinkte Dokumente') ?> + <span class="actions"><? printf(ngettext('%s Dokument', '%s Dokumente', $count), $count) ?></span> + </caption> + <thead> + <tr class="sortable"> + <?= $controller->renderSortLink('materialien/files/', _('Name'), 'mvv_files_filerefs.name') ?> + <?= $controller->renderSortLink('materialien/files/', _('Dateiname'), 'file_refs.name') ?> + <?= $controller->renderSortLInk('materialien/files/', _('Sichtbarkeit'), 'extern_visible') ?> + <?= $controller->renderSortLInk('materialien/files/', _('Sprache'), 'file_language') ?> + <?= $controller->renderSortLink('materialien/files/', _('Art der Datei'), 'type') ?> + <?= $controller->renderSortLink('materialien/files/', _('Datum'), 'mkdate') ?> + <th><?= _('Dateityp') ?></th> + <?= $controller->renderSortLInk('materialien/files/', _('Kategorie'), 'category') ?> + <?= $controller->renderSortLink('materialien/files/', _('Zuordnungen'), 'count_relations') ?> + <th class="actions" style="width: 5%"><?= _('Aktionen') ?></th> + </tr> + </thead> + <? foreach ($dokumente as $mvv_file) : ?> + <tbody class="<?= (in_array($range_id, $mvv_file->getRangesArray()) && ($fileref_id && in_array($fileref_id, $mvv_file->getFileRefsArray())) ? 'not-collapsed' : 'collapsed') ?>"> + <tr class="header-row"> + <td class="toggle-indicator"> + <a class="mvv-load-in-new-row" + href="<?= $controller->link_for('materialien/files/details', $mvv_file->mvvfile_id) ?>"> + <?= htmlReady($mvv_file->getDisplayName()) ?> + </a> + </td> + <td class="dont-hide"> + <? if ($mvv_file->getFiletypes()[0] === 'Link'): ?> + <a href="<?= htmlReady($mvv_file->file_refs[0]->file_ref->file->metadata['url']); ?>" target="_blank"> + <?= Icon::create('link-extern')->asImg(['class' => 'text-bottom']) ?> + <?= htmlReady($mvv_file->getFilenames()[0]); ?> + </a> + <? else: ?> <?= htmlReady($mvv_file->getFilenames()[0]); ?> - </a> - <? else: ?> - <?= htmlReady($mvv_file->getFilenames()[0]); ?> - <? endif; ?> - </td> - <td class="dont-hide" style="text-align: center;"> - <?= Icon::create( - $mvv_file->extern_visible?'visibility-visible':'visibility-invisible', - Icon::ROLE_INFO - )->asImg([ - 'class' => 'text-bottom', - 'title' => $mvv_file->extern_visible?_('sichtbar'):_('unsichtbar') - ]) ?> - </td> - <td class="dont-hide"> - <? foreach ($mvv_file->file_refs as $fileref) : ?> - <?= Assets::img(MVV::getContentLanguageImagePath($fileref->file_language), ['size' => '24']) ?> - <? endforeach; ?> - </td> - <td class="dont-hide"><?= htmlReady($GLOBALS['MVV_DOCUMENTS']['TYPE']['values'][$mvv_file->type]['name']) ?></td> - <td class="dont-hide"><?= strftime('%x', $mvv_file->mkdate) ?></td> - <td class="dont-hide"><?= htmlReady($mvv_file->getFiletypes()[0]) ?></td> - <td class="dont-hide"><?= htmlReady($GLOBALS['MVV_DOCUMENTS']['CATEGORY']['values'][$mvv_file->category]['name']) ?></td> - <td class="dont-hide" style="text-align: center;"><?= htmlReady($mvv_file->count_relations) ?></td> - <td class="dont-hide actions"> - <? - $actions = ActionMenu::get()->setContext($mvv_file->getFilenames()[0]); - $actions->addLink( - $controller->url_for('materialien/files/add_dokument', 'index', $mvv_file->getRangeType()?:0, 0, $mvv_file->mvvfile_id), - _('Dokument bearbeiten'), - Icon::create('edit'), - ['data-dialog' => 'size=auto'] - ); - $actions->addLink( - $controller->url_for('materialien/files/add_ranges_to_file',$mvv_file->mvvfile_id), - _('Dokument zuordnen'), - Icon::create('add'), - ['data-dialog' => 'size=auto'] - ); - foreach ($mvv_file->file_refs as $fileref) { + <? endif; ?> + </td> + <td class="dont-hide" style="text-align: center;"> + <?= Icon::create( + $mvv_file->extern_visible?'visibility-visible':'visibility-invisible', + Icon::ROLE_INFO + )->asImg([ + 'class' => 'text-bottom', + 'title' => $mvv_file->extern_visible?_('sichtbar'):_('unsichtbar') + ]) ?> + </td> + <td class="dont-hide"> + <? foreach ($mvv_file->file_refs as $fileref) : ?> + <?= Assets::img(MVV::getContentLanguageImagePath($fileref->file_language), ['size' => '24']) ?> + <? endforeach; ?> + </td> + <td class="dont-hide"><?= htmlReady($GLOBALS['MVV_DOCUMENTS']['TYPE']['values'][$mvv_file->type]['name']) ?></td> + <td class="dont-hide"><?= strftime('%x', $mvv_file->mkdate) ?></td> + <td class="dont-hide"><?= htmlReady($mvv_file->getFiletypes()[0]) ?></td> + <td class="dont-hide"><?= htmlReady($GLOBALS['MVV_DOCUMENTS']['CATEGORY']['values'][$mvv_file->category]['name']) ?></td> + <td class="dont-hide" style="text-align: center;"><?= htmlReady($mvv_file->count_relations) ?></td> + <td class="dont-hide actions"> + <? + $actions = ActionMenu::get()->setContext($mvv_file->getFilenames()[0]); $actions->addLink( - $fileref->file_ref->getDownloadURL('force_download'), - _('Datei herunterladen') . ' (' . $fileref->file_language . ')', - Icon::create('download'), - ['target' => '_blank'] + $controller->url_for('materialien/files/add_dokument', 'index', $mvv_file->getRangeType()?:0, 0, $mvv_file->mvvfile_id), + _('Dokument bearbeiten'), + Icon::create('edit'), + ['data-dialog' => 'size=auto'] ); - } - $actions->addLink( - $controller->url_for("materialien/files/delete_all_dokument/{$mvv_file->mvvfile_id}"), - _('Dokument löschen'), - Icon::create('trash'), - [ - 'data-confirm' => _('Wollen Sie das Dokument wirklich entfernen?'), - 'data-dialog' => 'size=auto' - ] - ); - echo $actions->render(); - ?> - </td> - </tr> - <? if (in_array($range_id, $mvv_file->getRangesArray()) && ($fileref_id && in_array($fileref_id, $mvv_file->getFileRefsArray()))) : ?> - <tr class="loaded-details nohover"> - <?= $this->render_partial('materialien/files/details', compact('mvv_file')) ?> - </tr> - <? endif; ?> - </tbody> -<? endforeach; ?> -<? if ($count > MVVController::$items_per_page) : ?> - <tfoot> - <tr> - <td colspan="10" style="text-align: right"> - <? - $pagination = $GLOBALS['template_factory']->open('shared/pagechooser'); - $pagination->clear_attributes(); - $pagination->set_attribute('perPage', MVVController::$items_per_page); - $pagination->set_attribute('num_postings', $count); - $pagination->set_attribute('page', $page); - // ARGH! - $page_link = explode('?', $controller->action_url('index'))[0] . '?page_files=%s'; - $pagination->set_attribute('pagelink', $page_link); - echo $pagination->render("shared/pagechooser"); + $actions->addLink( + $controller->url_for('materialien/files/add_ranges_to_file',$mvv_file->mvvfile_id), + _('Dokument zuordnen'), + Icon::create('add'), + ['data-dialog' => 'size=auto'] + ); + foreach ($mvv_file->file_refs as $fileref) { + $actions->addLink( + $fileref->file_ref->getDownloadURL('force_download'), + _('Datei herunterladen') . ' (' . $fileref->file_language . ')', + Icon::create('download'), + ['target' => '_blank'] + ); + } + $actions->addButton( + 'delete', + _('Dokument löschen'), + Icon::create('trash'), + [ + 'data-confirm' => _('Wollen Sie das Dokument wirklich entfernen?'), + 'data-dialog' => 'size=auto', + 'formaction' => $controller->url_for("materialien/files/delete_all_dokument/{$mvv_file->mvvfile_id}"), + ] + ); + echo $actions->render(); ?> - </td> - </tr> - </tfoot> -<? endif; ?> -</table> + </td> + </tr> + <? if (in_array($range_id, $mvv_file->getRangesArray()) && ($fileref_id && in_array($fileref_id, $mvv_file->getFileRefsArray()))) : ?> + <tr class="loaded-details nohover"> + <?= $this->render_partial('materialien/files/details', compact('mvv_file')) ?> + </tr> + <? endif; ?> + </tbody> + <? endforeach; ?> + <? if ($count > MVVController::$items_per_page) : ?> + <tfoot> + <tr> + <td colspan="10" style="text-align: right"> + <? + $pagination = $GLOBALS['template_factory']->open('shared/pagechooser'); + $pagination->clear_attributes(); + $pagination->set_attribute('perPage', MVVController::$items_per_page); + $pagination->set_attribute('num_postings', $count); + $pagination->set_attribute('page', $page); + // ARGH! + $page_link = explode('?', $controller->action_url('index'))[0] . '?page_files=%s'; + $pagination->set_attribute('pagelink', $page_link); + echo $pagination->render("shared/pagechooser"); + ?> + </td> + </tr> + </tfoot> + <? endif; ?> + </table> +</form> <script type="text/javascript"> jQuery(function ($) { $(document).on('dialog-close', function(event) { diff --git a/app/views/materialien/files/range.php b/app/views/materialien/files/range.php index bbf24755dd7..0bdbc15a200 100644 --- a/app/views/materialien/files/range.php +++ b/app/views/materialien/files/range.php @@ -5,109 +5,113 @@ <? endforeach ?> <? endif; ?> </div> -<table id="mvv_files" class="default sortable-table" data-sortlist="[[0, 0]]"> - <caption> - <span class="actions"> - <a href="<?= $controller->url_for('materialien/files/add_dokument', 'range', $range_type, $range_id);?>" data-dialog=""> - <?= Icon::create('upload', Icon::ROLE_CLICKABLE, ['title' => _('neues Dokument hinzufügen')]); ?> - </a> - <a href="<?= $controller->url_for('materialien/files/add_files_to_range',$range_type, $range_id);?>" data-dialog=""> - <?= Icon::create('add', Icon::ROLE_CLICKABLE, ['title' => _('vorhandenes Dokument hinzufügen')]); ?> - </a> - <a href="<?= $controller->url_for('materialien/files/sort', $range_type, $range_id);?>" data-dialog="size=auto"> - <?= Icon::create('arr_2up', Icon::ROLE_CLICKABLE, ['title' => _('Reihenfolge der Dokumente ändern')]); ?> - </a> - </span> - </caption> - <thead> - <tr class="sortable"> - <th data-sorter="digit"><?= _('Pos.') ?></th> - <th data-sorter="text"><?= _('Name') ?></th> - <th data-sorter="text"><?= _('Dateiname') ?></th> - <th data-sorter="digit"><?= _('Sichtbarkeit') ?></th> - <th><?= _('Sprache') ?></th> - <th data-sorter="text"><?= _('Art der Datei') ?></th> - <th data-sorter="digit"><?= _('Datum') ?></th> - <th data-sorter="text"><?= _('Dateityp') ?></th> - <th data-sorter="text"><?= _('Kategorie') ?></th> - <th data-sorter="digit"><?= _('Zuordnungen') ?></th> - <th data-sorter="false" style="text-align: right;"><?= _('Aktionen') ?></th> - </tr> - </thead> -<? if($dokumente): ?> - <tbody> - <? foreach($dokumente as $mvv_file): ?> - <tr> - <td><?= htmlReady($mvv_file->getPositionInRange($range_id)); ?></td> - <td><?= htmlReady($mvv_file->getDisplayName()) ?></td> - <td data-sort-value="<?= htmlReady($mvv_file->getFilenames()[0]); ?>"> - <? if($mvv_file->getFiletypes()[0] == 'Link'): ?> - <a href="<?= htmlReady($mvv_file->getFilenames()[0]); ?>" target="_blank"> - <?= Icon::create('link-extern', Icon::ROLE_CLICKABLE, ['class' => 'text-bottom']); ?> +<form method="post"> + <?= CSRFProtection::tokenTag() ?> + <table id="mvv_files" class="default sortable-table" data-sortlist="[[0, 0]]"> + <caption> + <span class="actions"> + <a href="<?= $controller->url_for('materialien/files/add_dokument', 'range', $range_type, $range_id);?>" data-dialog=""> + <?= Icon::create('upload', Icon::ROLE_CLICKABLE, ['title' => _('neues Dokument hinzufügen')]); ?> + </a> + <a href="<?= $controller->url_for('materialien/files/add_files_to_range',$range_type, $range_id);?>" data-dialog=""> + <?= Icon::create('add', Icon::ROLE_CLICKABLE, ['title' => _('vorhandenes Dokument hinzufügen')]); ?> + </a> + <a href="<?= $controller->url_for('materialien/files/sort', $range_type, $range_id);?>" data-dialog="size=auto"> + <?= Icon::create('arr_2up', Icon::ROLE_CLICKABLE, ['title' => _('Reihenfolge der Dokumente ändern')]); ?> + </a> + </span> + </caption> + <thead> + <tr class="sortable"> + <th data-sorter="digit"><?= _('Pos.') ?></th> + <th data-sorter="text"><?= _('Name') ?></th> + <th data-sorter="text"><?= _('Dateiname') ?></th> + <th data-sorter="digit"><?= _('Sichtbarkeit') ?></th> + <th><?= _('Sprache') ?></th> + <th data-sorter="text"><?= _('Art der Datei') ?></th> + <th data-sorter="digit"><?= _('Datum') ?></th> + <th data-sorter="text"><?= _('Dateityp') ?></th> + <th data-sorter="text"><?= _('Kategorie') ?></th> + <th data-sorter="digit"><?= _('Zuordnungen') ?></th> + <th data-sorter="false" style="text-align: right;"><?= _('Aktionen') ?></th> + </tr> + </thead> + <? if($dokumente): ?> + <tbody> + <? foreach($dokumente as $mvv_file): ?> + <tr> + <td><?= htmlReady($mvv_file->getPositionInRange($range_id)); ?></td> + <td><?= htmlReady($mvv_file->getDisplayName()) ?></td> + <td data-sort-value="<?= htmlReady($mvv_file->getFilenames()[0]); ?>"> + <? if($mvv_file->getFiletypes()[0] == 'Link'): ?> + <a href="<?= htmlReady($mvv_file->getFilenames()[0]); ?>" target="_blank"> + <?= Icon::create('link-extern', Icon::ROLE_CLICKABLE, ['class' => 'text-bottom']); ?> + <?= htmlReady($mvv_file->getFilenames()[0]); ?> + </a> + <? else: ?> <?= htmlReady($mvv_file->getFilenames()[0]); ?> - </a> - <? else: ?> - <?= htmlReady($mvv_file->getFilenames()[0]); ?> - <? endif; ?> - </td> - <td style="text-align: center;" data-sort-value="<?= $mvv_file->extern_visible?'1':'0' ?>"> - <?= Icon::create( - $mvv_file->extern_visible?'visibility-visible':'visibility-invisible', - Icon::ROLE_INFO, + <? endif; ?> + </td> + <td style="text-align: center;" data-sort-value="<?= $mvv_file->extern_visible?'1':'0' ?>"> + <?= Icon::create( + $mvv_file->extern_visible?'visibility-visible':'visibility-invisible', + Icon::ROLE_INFO, + [ + 'class' => 'text-bottom', + 'title' => $mvv_file->extern_visible?_('sichtbar'):_('unsichtbar') + ] + ); + ?> + </td> + <td> + <? foreach ($mvv_file->file_refs as $fileref) : ?> + <?= Assets::img(MVV::getContentLanguageImagePath($fileref->file_language), ['size' => 24]) ?> + <? endforeach; ?> + </td> + <td><?= htmlReady($GLOBALS['MVV_DOCUMENTS']['TYPE']['values'][$mvv_file->type]['name']); ?></td> + <td data-sort-value="<?= htmlReady($mvv_file->mkdate); ?>"><?= htmlReady(date('d.m.Y', $mvv_file->mkdate)); ?></td> + <td style="text-align: center;"><?= htmlReady($mvv_file->getFiletypes()[0]); ?></td> + <td><?= htmlReady($GLOBALS['MVV_DOCUMENTS']['CATEGORY']['values'][$mvv_file->category]['name']); ?></td> + <td style="text-align: center;"><?= htmlReady($mvv_file->count_relations); ?></td> + <td class="actions"> + <? + $actions = ActionMenu::get()->setContext($mvv_file->getDisplayName()); + $actions->addLink( + $controller->url_for('materialien/files/details',$mvv_file->mvvfile_id), + _('Details'), + Icon::create('info-circle'), + ['data-dialog' => 'size=auto'] + ); + $actions->addLink( + $controller->url_for('materialien/files/add_dokument','range', $range_type, $range_id, $mvv_file->mvvfile_id), + _('Dokument bearbeiten'), + Icon::create('edit'), + ['data-dialog' => ''] + ); + foreach ($mvv_file->file_refs as $fileref) { + $actions->addLink( + $fileref->file_ref->getDownloadURL('force_download'), + _('Datei herunterladen') . ' (' . $fileref->file_language . ')', + Icon::create('download', 'clickable', ['size' => 20]), + ['target' => '_blank'] + ); + } + $actions->addButton( + 'delete', + _('Dokument-Zuordnung löschen'), + Icon::create('trash'), [ - 'class' => 'text-bottom', - 'title' => $mvv_file->extern_visible?_('sichtbar'):_('unsichtbar') + 'data-confirm' => _('Wollen Sie die Zuordnung des Dokuments wirklich entfernen?'), + 'data-dialog' => 'size=auto', + 'formaction' => $controller->url_for('materialien/files/delete_range', $mvv_file->mvvfile_id, $range_id), ] ); + echo $actions; ?> - </td> - <td> - <? foreach ($mvv_file->file_refs as $fileref) : ?> - <?= Assets::img(MVV::getContentLanguageImagePath($fileref->file_language), ['size' => 24]) ?> - <? endforeach; ?> - </td> - <td><?= htmlReady($GLOBALS['MVV_DOCUMENTS']['TYPE']['values'][$mvv_file->type]['name']); ?></td> - <td data-sort-value="<?= htmlReady($mvv_file->mkdate); ?>"><?= htmlReady(date('d.m.Y', $mvv_file->mkdate)); ?></td> - <td style="text-align: center;"><?= htmlReady($mvv_file->getFiletypes()[0]); ?></td> - <td><?= htmlReady($GLOBALS['MVV_DOCUMENTS']['CATEGORY']['values'][$mvv_file->category]['name']); ?></td> - <td style="text-align: center;"><?= htmlReady($mvv_file->count_relations); ?></td> - <td class="actions"> - <? - $actions = ActionMenu::get()->setContext($mvv_file->getDisplayName()); - $actions->addLink( - $controller->url_for('materialien/files/details',$mvv_file->mvvfile_id), - _('Details'), - Icon::create('info-circle'), - ['data-dialog' => 'size=auto'] - ); - $actions->addLink( - $controller->url_for('materialien/files/add_dokument','range', $range_type, $range_id, $mvv_file->mvvfile_id), - _('Dokument bearbeiten'), - Icon::create('edit'), - ['data-dialog' => ''] - ); - foreach ($mvv_file->file_refs as $fileref) { - $actions->addLink( - $fileref->file_ref->getDownloadURL('force_download'), - _('Datei herunterladen') . ' (' . $fileref->file_language . ')', - Icon::create('download', 'clickable', ['size' => 20]), - ['target' => '_blank'] - ); - } - $actions->addLink( - $controller->url_for('materialien/files/delete_range', $mvv_file->mvvfile_id, $range_id), - _('Dokument-Zuordnung löschen'), - Icon::create('trash'), - [ - 'data-confirm' => _('Wollen Sie die Zuordnung des Dokuments wirklich entfernen?'), - 'data-dialog' => 'size=auto' - ] - ); - echo $actions; - ?> - </td> - </tr> - <? endforeach; ?> - </tbody> -<? endif; ?> -</table> + </td> + </tr> + <? endforeach; ?> + </tbody> + <? endif; ?> + </table> +</form> diff --git a/app/views/shared/contacts/index.php b/app/views/shared/contacts/index.php index 297de31b7bd..496aeaadf71 100644 --- a/app/views/shared/contacts/index.php +++ b/app/views/shared/contacts/index.php @@ -5,93 +5,98 @@ <? endforeach ?> <? endif; ?> </div> -<table id="mvv_contacts" class="default collapsable"> - <caption> - <span class="actions"><? printf('%s Ansprechpartner', $count) ?></span> - </caption> - <thead> - <tr> - <?= $controller->renderSortLink('shared/contacts/', _('Name/Institution'), 'name', ['style' => 'width: 40%;']) ?> - <?= $controller->renderSortLink('shared/contacts/', _('Alternative Kontaktmail'), 'alt_mail', ['style' => 'width: 20%;']) ?> - <?= $controller->renderSortLink('shared/contacts/', _('Status'), 'contact_status', ['style' => 'width: 15%;']) ?> - <?= $controller->renderSortLink('shared/contacts/', _('Zuordnungen'), 'count_relations', ['style' => 'width: 20%;']) ?> - <th style="width: 5%; text-align: right;"><?= _('Aktionen') ?></th> - </tr> - </thead> -<? if ($contacts) : ?> - <? foreach ($contacts as $mvv_contact) : ?> - <? $perm = new MvvPerm($mvv_contact) ?> - <tbody class="<?= ($contact_id == $mvv_contact->contact_id ? 'not-collapsed' : 'collapsed') ?>"> - <tr class="header-row"> - <td class="toggle-indicator"> - <a class="mvv-load-in-new-row" - href="<?= $controller->url_for('shared/contacts/details/index', $mvv_contact->contact_id) ?>"><?= htmlReady($mvv_contact->getContactName()) ?></a> - </td> - <td class="dont-hide"><?= htmlReady($mvv_contact->alt_mail); ?></td> - <td class="dont-hide"><?= htmlReady($GLOBALS['MVV_CONTACTS']['STATUS']['values'][$mvv_contact->contact_status]['name'] ?? '') ?></td> - <td class="dont-hide"><?= htmlReady($mvv_contact->count_relations); ?></td> - <td class="dont-hide actions"> - <? - $actions = ActionMenu::get()->setContext($mvv_contact->getContactName()); - if ($perm->haveFieldPerm('ranges', MvvPerm::PERM_CREATE)) { - $actions->addLink( - $controller->url_for('shared/contacts/add_ranges_to_contact', $mvv_contact->contact_id), - _('Ansprechpartner zuordnen'), - Icon::create('person'), - ['data-dialog' => 'size=auto'] - ); - $actions->addLink( - $controller->url_for('shared/contacts/delete_all_ranges', $mvv_contact->contact_id), - _('Alle Zuordnungen löschen'), - Icon::create('trash'), - [ - 'data-confirm' => _('Wollen Sie wirklich alle Zuordnungen entfernen?'), - 'data-dialog' => 'size=auto' - ] - ); - } - if ($mvv_contact->contact_status === 'extern' && $perm->havePerm(MvvPerm::PERM_CREATE)) { - $actions->addLink( - $controller->url_for('shared/contacts/delete_extern_contact', $mvv_contact->contact_id), - _('Externe Person löschen'), - Icon::create('trash'), - [ - 'data-confirm' => _('Wollen Sie die externe Person wirklich löschen?'), - 'data-dialog' => 'size=auto' - ] - ); - } - echo $actions; - ?> - </td> - </tr> - <? if ($contact_id == $mvv_contact->contact_id) : ?> - <tr class="loaded-details nohover"> - <?= $this->render_partial('shared/contacts/details', compact('mvv_contact')) ?> - </tr> - <? endif; ?> - </tbody> - <? endforeach; ?> - <? if ($count > MVVController::$items_per_page) : ?> - <tfoot> +<form method="post"> + <?= CSRFProtection::tokenTag() ?> + <table id="mvv_contacts" class="default collapsable"> + <caption> + <span class="actions"><? printf('%s Ansprechpartner', $count) ?></span> + </caption> + <thead> <tr> - <td colspan="10" style="text-align: right"> - <? - $pagination = $GLOBALS['template_factory']->open('shared/pagechooser'); - $pagination->clear_attributes(); - $pagination->set_attribute('perPage', MVVController::$items_per_page); - $pagination->set_attribute('num_postings', $count); - $pagination->set_attribute('page', $page); - $page_link = explode('?', $controller->action_url('index'))[0] . '?page_contacts=%s'; - $pagination->set_attribute('pagelink', $page_link); - echo $pagination->render('shared/pagechooser'); - ?> + <?= $controller->renderSortLink('shared/contacts/', _('Name/Institution'), 'name', ['style' => 'width: 40%;']) ?> + <?= $controller->renderSortLink('shared/contacts/', _('Alternative Kontaktmail'), 'alt_mail', ['style' => 'width: 20%;']) ?> + <?= $controller->renderSortLink('shared/contacts/', _('Status'), 'contact_status', ['style' => 'width: 15%;']) ?> + <?= $controller->renderSortLink('shared/contacts/', _('Zuordnungen'), 'count_relations', ['style' => 'width: 20%;']) ?> + <th style="width: 5%; text-align: right;"><?= _('Aktionen') ?></th> + </tr> + </thead> + <? if ($contacts) : ?> + <? foreach ($contacts as $mvv_contact) : ?> + <? $perm = new MvvPerm($mvv_contact) ?> + <tbody class="<?= ($contact_id == $mvv_contact->contact_id ? 'not-collapsed' : 'collapsed') ?>"> + <tr class="header-row"> + <td class="toggle-indicator"> + <a class="mvv-load-in-new-row" + href="<?= $controller->url_for('shared/contacts/details/index', $mvv_contact->contact_id) ?>"><?= htmlReady($mvv_contact->getContactName()) ?></a> + </td> + <td class="dont-hide"><?= htmlReady($mvv_contact->alt_mail); ?></td> + <td class="dont-hide"><?= htmlReady($GLOBALS['MVV_CONTACTS']['STATUS']['values'][$mvv_contact->contact_status]['name'] ?? '') ?></td> + <td class="dont-hide"><?= htmlReady($mvv_contact->count_relations); ?></td> + <td class="dont-hide actions"> + <? + $actions = ActionMenu::get()->setContext($mvv_contact->getContactName()); + if ($perm->haveFieldPerm('ranges', MvvPerm::PERM_CREATE)) { + $actions->addLink( + $controller->url_for('shared/contacts/add_ranges_to_contact', $mvv_contact->contact_id), + _('Ansprechpartner zuordnen'), + Icon::create('person'), + ['data-dialog' => 'size=auto'] + ); + $actions->addButton( + 'delete_all_ranges', + _('Alle Zuordnungen löschen'), + Icon::create('trash'), + [ + 'data-confirm' => _('Wollen Sie wirklich alle Zuordnungen entfernen?'), + 'data-dialog' => 'size=auto', + 'formaction' => $controller->url_for('shared/contacts/delete_all_ranges', $mvv_contact->contact_id), + ] + ); + } + if ($mvv_contact->contact_status === 'extern' && $perm->havePerm(MvvPerm::PERM_CREATE)) { + $actions->addButton( + 'delete_extern_contact', + _('Externe Person löschen'), + Icon::create('trash'), + [ + 'data-confirm' => _('Wollen Sie die externe Person wirklich löschen?'), + 'data-dialog' => 'size=auto', + 'formaction' => $controller->url_for('shared/contacts/delete_extern_contact', $mvv_contact->contact_id), + ] + ); + } + echo $actions; + ?> </td> </tr> - </tfoot> + <? if ($contact_id == $mvv_contact->contact_id) : ?> + <tr class="loaded-details nohover"> + <?= $this->render_partial('shared/contacts/details', compact('mvv_contact')) ?> + </tr> + <? endif; ?> + </tbody> + <? endforeach; ?> + <? if ($count > MVVController::$items_per_page) : ?> + <tfoot> + <tr> + <td colspan="10" style="text-align: right"> + <? + $pagination = $GLOBALS['template_factory']->open('shared/pagechooser'); + $pagination->clear_attributes(); + $pagination->set_attribute('perPage', MVVController::$items_per_page); + $pagination->set_attribute('num_postings', $count); + $pagination->set_attribute('page', $page); + $page_link = explode('?', $controller->action_url('index'))[0] . '?page_contacts=%s'; + $pagination->set_attribute('pagelink', $page_link); + echo $pagination->render('shared/pagechooser'); + ?> + </td> + </tr> + </tfoot> + <? endif; ?> <? endif; ?> -<? endif; ?> -</table> + </table> +</form> <script type="text/javascript"> jQuery(function ($) { $(document).on('dialog-close', function(event) { diff --git a/lib/classes/forms/Form.php b/lib/classes/forms/Form.php index fa0422e1a92..fbedc1fb676 100644 --- a/lib/classes/forms/Form.php +++ b/lib/classes/forms/Form.php @@ -388,9 +388,8 @@ class Form extends Part */ public function store() { - if (!\CSRFProtection::verifyRequest()) { - throw new \AccessDeniedException(); - } + \CSRFProtection::verifyUnsafeRequest(); + \NotificationCenter::postNotification('FormWillStore', $this); $stored = 0; -- GitLab