Merge pull request #260 from nextcloud/fix/only_own_forms

Fix/only own forms
This commit is contained in:
Jonas 2020-04-09 12:51:00 +02:00 коммит произвёл GitHub
Родитель 52b692451f 0fe295f11e
Коммит 46791f1f5c
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
6 изменённых файлов: 40 добавлений и 268 удалений

Просмотреть файл

@ -42,8 +42,8 @@ return [
['name' => 'api#get_options', 'url' => '/get/options/{formId}', 'verb' => 'GET'], ['name' => 'api#get_options', 'url' => '/get/options/{formId}', 'verb' => 'GET'],
['name' => 'api#get_shares', 'url' => '/get/shares/{formId}', 'verb' => 'GET'], ['name' => 'api#get_shares', 'url' => '/get/shares/{formId}', 'verb' => 'GET'],
['name' => 'api#get_form', 'url' => '/get/form/{formId}', 'verb' => 'GET'], ['name' => 'api#get_form', 'url' => '/get/form/{formId}', 'verb' => 'GET'],
['name' => 'api#get_forms', 'url' => '/get/forms', 'verb' => 'GET'],
['name' => 'api#getForms', 'url' => 'api/v1/forms', 'verb' => 'GET'],
['name' => 'api#newForm', 'url' => 'api/v1/form', 'verb' => 'POST'], ['name' => 'api#newForm', 'url' => 'api/v1/form', 'verb' => 'POST'],
['name' => 'api#deleteForm', 'url' => 'api/v1/form/{id}', 'verb' => 'DELETE'], ['name' => 'api#deleteForm', 'url' => 'api/v1/form/{id}', 'verb' => 'DELETE'],
['name' => 'api#updateQuestion', 'url' => 'api/v1/question/update/', 'verb' => 'POST'], ['name' => 'api#updateQuestion', 'url' => 'api/v1/question/update/', 'verb' => 'POST'],

Просмотреть файл

@ -28,6 +28,7 @@
namespace OCA\Forms\Controller; namespace OCA\Forms\Controller;
use OCA\Forms\AppInfo\Application;
use OCP\AppFramework\Controller; use OCP\AppFramework\Controller;
use OCP\AppFramework\Http; use OCP\AppFramework\Http;
use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\Http\DataResponse;
@ -53,8 +54,6 @@ use OCA\Forms\Db\QuestionMapper;
use OCA\Forms\Db\Option; use OCA\Forms\Db\Option;
use OCA\Forms\Db\OptionMapper; use OCA\Forms\Db\OptionMapper;
use OCP\Util;
class ApiController extends Controller { class ApiController extends Controller {
private $groupManager; private $groupManager;
@ -71,21 +70,7 @@ class ApiController extends Controller {
/** @var string */ /** @var string */
private $userId; private $userId;
/**
* PageController constructor.
* @param string $appName
* @param IGroupManager $groupManager
* @param IRequest $request
* @param IUserManager $userManager
* @param string $userId
* @param FormMapper $formMapper
* @param SubmissionMapper $submissionMapper
* @param AnswerMapper $answerMapper
* @param QuestionMapper $questionMapper
* @param OptionMapper $optionMapper
*/
public function __construct( public function __construct(
$appName,
IGroupManager $groupManager, IGroupManager $groupManager,
IRequest $request, IRequest $request,
IUserManager $userManager, IUserManager $userManager,
@ -97,7 +82,7 @@ class ApiController extends Controller {
OptionMapper $optionMapper, OptionMapper $optionMapper,
ILogger $logger ILogger $logger
) { ) {
parent::__construct($appName, $request); parent::__construct(Application::APP_ID, $request);
$this->userId = $userId; $this->userId = $userId;
$this->groupManager = $groupManager; $this->groupManager = $groupManager;
$this->userManager = $userManager; $this->userManager = $userManager;
@ -339,31 +324,23 @@ class ApiController extends Controller {
} }
/** /**
* Get all forms
* @NoAdminRequired * @NoAdminRequired
* @return DataResponse
*/ */
public function getForms() { public function getForms() {
if (!\OC::$server->getUserSession()->getUser() instanceof IUser) { $forms = $this->formMapper->findAllByOwnerId($this->userId);
return new DataResponse(null, Http::STATUS_UNAUTHORIZED);
$result = [];
foreach ($forms as $form) {
$result[] = [
'id' => $form->getId(),
'form' => $form->read(),
'mode' => 'edit',
'shares' => $this->getShares($form->getId()),
'questions' => $this->getQuestions($form->getId())
];
} }
try { return new DataResponse($result);
$forms = $this->formMapper->findAll();
} catch (DoesNotExistException $e) {
return new DataResponse($e, Http::STATUS_NOT_FOUND);
}
$formsList = array();
foreach ($forms as $formElement) {
$form = $this->getFullForm($formElement->id);
//if ($form['grantedAs'] !== 'none') {
$formsList[] = $form;
//}
}
return new DataResponse($formsList, Http::STATUS_OK);
} }
/** /**

Просмотреть файл

@ -4,7 +4,7 @@
* *
* @author Vinzenz Rosenkranz <vinzenz.rosenkranz@gmail.com> * @author Vinzenz Rosenkranz <vinzenz.rosenkranz@gmail.com>
* @author René Gieling <github@dartcafe.de> * @author René Gieling <github@dartcafe.de>
* *
* @license GNU AGPL version 3 or any later version * @license GNU AGPL version 3 or any later version
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -32,6 +32,7 @@ class FormMapper extends QBMapper {
/** /**
* FormMapper constructor. * FormMapper constructor.
*
* @param IDBConnection $db * @param IDBConnection $db
*/ */
public function __construct(IDBConnection $db) { public function __construct(IDBConnection $db) {
@ -40,15 +41,15 @@ class FormMapper extends QBMapper {
/** /**
* @param Integer $id * @param Integer $id
* @throws \OCP\AppFramework\Db\DoesNotExistException if not found
* @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException if more than one result
* @return Form * @return Form
* @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException if more than one result
* @throws \OCP\AppFramework\Db\DoesNotExistException if not found
*/ */
public function find(int $id): Form { public function find(int $id): Form {
$qb = $this->db->getQueryBuilder(); $qb = $this->db->getQueryBuilder();
$qb->select('*') $qb->select('*')
->from($this->tableName) ->from($this->getTableName())
->where( ->where(
$qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)) $qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT))
); );
@ -58,15 +59,15 @@ class FormMapper extends QBMapper {
/** /**
* @param String $hash * @param String $hash
* @throws \OCP\AppFramework\Db\DoesNotExistException if not found
* @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException if more than one result
* @return Form * @return Form
* @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException if more than one result
* @throws \OCP\AppFramework\Db\DoesNotExistException if not found
*/ */
public function findByHash(string $hash): Form { public function findByHash(string $hash): Form {
$qb = $this->db->getQueryBuilder(); $qb = $this->db->getQueryBuilder();
$qb->select('*') $qb->select('*')
->from($this->tableName) ->from($this->getTableName())
->where( ->where(
$qb->expr()->eq('hash', $qb->createNamedParameter($hash, IQueryBuilder::PARAM_STR)) $qb->expr()->eq('hash', $qb->createNamedParameter($hash, IQueryBuilder::PARAM_STR))
); );
@ -75,14 +76,28 @@ class FormMapper extends QBMapper {
} }
/** /**
* @throws \OCP\AppFramework\Db\DoesNotExistException if not found
* @return Form[] * @return Form[]
*/ */
public function findAll(): array { public function findAll(): array {
$qb = $this->db->getQueryBuilder(); $qb = $this->db->getQueryBuilder();
$qb->select('*') $qb->select('*')
->from($this->tableName); ->from($this->getTableName());
return $this->findEntities($qb);
}
/**
* @return Form[]
*/
public function findAllByOwnerId(string $ownerId): array {
$qb = $this->db->getQueryBuilder();
$qb->select('*')
->from($this->getTableName())
->where(
$qb->expr()->eq('owner_id', $qb->createNamedParameter($ownerId))
);
return $this->findEntities($qb); return $this->findEntities($qb);
} }

Просмотреть файл

@ -122,7 +122,7 @@ export default {
async loadForms() { async loadForms() {
this.loading = true this.loading = true
try { try {
const response = await axios.get(generateUrl('apps/forms/get/forms')) const response = await axios.get(generateUrl('apps/forms/api/v1/forms'))
this.forms = response.data this.forms = response.data
} catch (error) { } catch (error) {
showError(t('forms', 'An error occurred while loading the forms list')) showError(t('forms', 'An error occurred while loading the forms list'))

Просмотреть файл

@ -1,53 +0,0 @@
/**
* @copyright Copyright (c) 2019 John Molakvoæ <skjnldsv@protonmail.com>
*
* @author John Molakvoæ <skjnldsv@protonmail.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import axios from '@nextcloud/axios'
/**
* Get the forms list
*
* @returns {Array}
*/
const getForms = async function() {
try {
const response = await axios.get(OC.generateUrl('apps/forms/get/forms'))
return response.data
} catch (error) {
console.error(error)
throw Error(t('forms', 'Unable to fetch the forms list'))
}
}
/**
* Delete a form
*
* @param {int} id the form id to delete
*/
const deleteForm = async function(id) {
try {
axios.delete(OC.generateUrl('apps/forms/forms/{id}', { id }))
} catch (error) {
console.error(error)
throw Error(t('forms', 'Unable to delete the form'))
}
}
export { deleteForm, getForms }

Просмотреть файл

@ -1,167 +0,0 @@
<!--
- @copyright Copyright (c) 2018 René Gieling <github@dartcafe.de>
-
- @author René Gieling <github@dartcafe.de>
- @author Natalie Gilbert
-
- @license GNU AGPL version 3 or any later version
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
- published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-->
<template>
<AppContent>
<div v-if="noForms" class="">
<div class="icon-forms" />
<h2> {{ t('No existing forms.') }} </h2>
<router-link :to="{ name: 'create'}" class="button new">
<span>{{ t('forms', 'Click here to add a form') }}</span>
</router-link>
</div>
<transition-group
v-if="!noForms"
name="list"
tag="div"
class="table">
<FormListItem
key="0"
:header="true" />
<li
is="form-list-item"
v-for="(form, index) in forms"
:key="form.id"
:form="form"
@deleteForm="removeForm(index, form.form)"
@viewResults="viewFormResults(index, form.form, 'results')" />
</transition-group>
<LoadingOverlay v-if="loading" />
<modal-dialog />
</AppContent>
</template>
<script>
import { showError } from '@nextcloud/dialogs'
import axios from '@nextcloud/axios'
import AppContent from '@nextcloud/vue/dist/Components/AppContent'
import FormListItem from '../components/formListItem'
import ViewsMixin from '../mixins/ViewsMixin'
export default {
name: 'List',
components: {
AppContent,
FormListItem,
},
mixins: [ViewsMixin],
data() {
return {
loading: true,
forms: [],
}
},
computed: {
noForms() {
return this.forms && this.forms.length > 0
},
},
beforeMount() {
this.loadForms()
},
methods: {
/**
* Initial forms load
*/
async loadForms() {
this.loading = true
try {
const response = await axios.get(OC.generateUrl('apps/forms/get/forms'))
this.forms = response.data
} catch (error) {
showError(t('forms', 'An error occurred while loading the forms list'))
console.error(error)
} finally {
this.loading = false
}
},
/**
* Open the help page
*/
helpPage() {
window.open('https://github.com/nextcloud/forms/blob/master/Forms_Support.md')
},
viewFormResults(index, form, name) {
this.$router.push({
name: name,
params: {
hash: form.id,
},
})
},
removeForm(index, form) {
const params = {
title: t('forms', 'Delete form'),
text: t('forms', 'Do you want to delete "%n"?', 1, form.title),
buttonHideText: t('forms', 'No, keep form.'),
buttonConfirmText: t('forms', 'Yes, delete form.'),
onConfirm: () => {
// this.deleteForm(index, form)
axios.delete(OC.generateUrl('apps/forms/forms/{id}', { id: form.id }))
.then((response) => {
this.forms.splice(index, 1)
OC.Notification.showTemporary(t('forms', 'Form "%n" deleted', 1, form.title))
}, (error) => {
OC.Notification.showTemporary(t('forms', 'Error while deleting Form "%n"', 1, form.title))
/* eslint-disable-next-line no-console */
console.log(error.response)
}
)
},
}
this.$modal.show(params)
},
},
}
</script>
<style lang="scss">
.table {
width: 100%;
margin-top: 45px;
display: flex;
flex-direction: column;
flex-grow: 1;
flex-wrap: nowrap;
}
#emptycontent {
.icon-forms {
background-color: black;
-webkit-mask: url('./img/app.svg') no-repeat 50% 50%;
mask: url('./img/app.svg') no-repeat 50% 50%;
}
}
</style>