diff --git a/appinfo/routes.php b/appinfo/routes.php index 10cb35c8e5..e53f9c6389 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -117,6 +117,14 @@ 'apiVersion' => 'v2(\.1)?' ] ], + [ + 'name' => 'api#ownerTransfer', + 'url' => '/api/{apiVersion}/form/transfer', + 'verb' => 'POST', + 'requirements' => [ + 'apiVersion' => 'v2(\.1)?' + ] + ], [ 'name' => 'api#deleteForm', 'url' => '/api/{apiVersion}/form/{id}', @@ -141,7 +149,6 @@ 'apiVersion' => 'v2(\.1)?' ] ], - // Questions [ 'name' => 'api#newQuestion', diff --git a/lib/Controller/ApiController.php b/lib/Controller/ApiController.php index 673b2a0a51..e3e4b5d9eb 100644 --- a/lib/Controller/ApiController.php +++ b/lib/Controller/ApiController.php @@ -405,6 +405,44 @@ public function updateForm(int $id, array $keyValuePairs): DataResponse { return new DataResponse($form->getId()); } + /** + * @NoAdminRequired + * + * Transfer ownership of a form to another user + * + * @param int $formId id of the form to update + * @param string $uid id of the new owner + * @return DataResponse + * @throws OCSBadRequestException + * @throws OCSForbiddenException + */ + public function ownerTransfer(int $formId, string $uid): DataResponse { + $this->logger->debug('Updating owner: formId: {formId}, userId: {uid}', [ + 'formId' => $formId, + 'uid' => $uid + ]); + + try { + $form = $this->formMapper->findById($formId); + } catch (IMapperException $e) { + $this->logger->debug('Could not find form'); + throw new OCSBadRequestException('Could not find form'); + } + + if ($form->getOwnerId() !== $this->currentUser->getUID()) { + $this->logger->debug('This form is not owned by the current user'); + throw new OCSForbiddenException(); + } + + // update form owner + $form->setOwnerId($uid); + + // Update changed Columns in Db. + $this->formMapper->update($form); + + return new DataResponse($form->getOwnerId()); + } + /** * @CORS * @NoAdminRequired diff --git a/lib/Db/ShareMapper.php b/lib/Db/ShareMapper.php index 8ac36f5b64..3733d03d16 100644 --- a/lib/Db/ShareMapper.php +++ b/lib/Db/ShareMapper.php @@ -103,7 +103,28 @@ public function findPublicShareByHash(string $hash): Share { return $this->findEntity($qb); } + /** + * Find Share by formId and user id + * @param int $formId + * @param string $uid + * @return Share + * @throws MultipleObjectsReturnedException if more than one result + * @throws DoesNotExistException if not found + */ + public function findPublicShareByFormIdAndUid(int $formId, string $uid): Share { + $qb = $this->db->getQueryBuilder(); + $qb->select('*') + ->from($this->getTableName()) + ->where( + $qb->expr()->eq('form_id', $qb->createNamedParameter($formId, IQueryBuilder::PARAM_INT)) + ) + ->andWhere( + $qb->expr()->eq('share_with', $qb->createNamedParameter($uid, IQueryBuilder::PARAM_STR)) + ); + + return $this->findEntity($qb); + } /** * Delete a share * @param int $id of the share. diff --git a/src/components/SidebarTabs/SettingsSidebarTab.vue b/src/components/SidebarTabs/SettingsSidebarTab.vue index e3a6f95bab..27859d7d0f 100644 --- a/src/components/SidebarTabs/SettingsSidebarTab.vue +++ b/src/components/SidebarTabs/SettingsSidebarTab.vue @@ -59,6 +59,7 @@ {{ t('forms', 'Show expiration date on form') }} + @@ -67,11 +68,13 @@ import moment from '@nextcloud/moment' import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js' import NcDatetimePicker from '@nextcloud/vue/dist/Components/NcDatetimePicker.js' import ShareTypes from '../../mixins/ShareTypes.js' +import TransferOwnership from './TransferOwnership.vue' export default { components: { NcCheckboxRadioSwitch, NcDatetimePicker, + TransferOwnership, }, mixins: [ShareTypes], diff --git a/src/components/SidebarTabs/TransferOwnership.vue b/src/components/SidebarTabs/TransferOwnership.vue new file mode 100644 index 0000000000..fd30e12c81 --- /dev/null +++ b/src/components/SidebarTabs/TransferOwnership.vue @@ -0,0 +1,169 @@ + + + + + + {{ t('forms', 'Transfer ownership') }} + + + + + {{ t('forms', 'Transfer ') }} {{ form.title }} + + + + {{ t('forms', 'Account to transfer to') }} + + + + {{ transferData.displayName }} + + X + + + + + + {{ t('forms', 'Type ') }} {{ confirmationString }} {{ t('forms', ' to confirm') }} + + + + + {{ t('forms', 'I understand, transfer this form') }} + + + + + + + + +
+ {{ t('forms', 'Account to transfer to') }} +
{{ transferData.displayName }}
+ {{ t('forms', 'Type ') }} {{ confirmationString }} {{ t('forms', ' to confirm') }} +