diff --git a/CHANGELOG.md b/CHANGELOG.md
index 084163922..dd597ac2c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,9 +10,8 @@ All notable changes to this project will be documented in this file.
- Reveal hidden voters if hidden in case of performance concerns
- Support better readability of vote page
- Added revoking of shares
- - Shares can now be revoked which works as a read only share mechanism. Revoked shares can still enter the poll, but all interaction (voting and commenting) is disabled.
- - Deletion of unsent shares have no more a redo timer
- - Deletion of revoked shares deletes the users votes as well
+ - Shares can now be locked which works as a read only share mechanism. Locked shares can still enter the poll, but every interaction (voting and commenting) is disabled.
+ - Deletion of locked shares deletes the users votes as well
### Changes
- Improved username check for public polls with a large number of groups in the backend
## [5.3.2] - 2023-09-11
diff --git a/appinfo/info.xml b/appinfo/info.xml
index f3c47ab04..81060de48 100644
--- a/appinfo/info.xml
+++ b/appinfo/info.xml
@@ -4,7 +4,7 @@
Polls
A polls app, similar to Doodle/Dudle with the possibility to restrict access.
A polls app, similar to Doodle/Dudle with the possibility to restrict access (members, certain groups/users, hidden and public).
- 5.4.0-beta5
+ 5.4.0-beta6
agpl
Vinzenz Rosenkranz
René Gieling
diff --git a/appinfo/routes.php b/appinfo/routes.php
index 86e393ad3..648996c17 100644
--- a/appinfo/routes.php
+++ b/appinfo/routes.php
@@ -98,8 +98,8 @@
['name' => 'share#admin_to_user', 'url' => '/share/{token}/user', 'verb' => 'PUT'],
['name' => 'share#set_label', 'url' => '/share/{token}/setlabel', 'verb' => 'PUT'],
['name' => 'share#set_public_poll_email', 'url' => '/share/{token}/publicpollemail/{value}', 'verb' => 'PUT'],
- ['name' => 'share#revoke', 'url' => '/share/{token}/revoke', 'verb' => 'PUT'],
- ['name' => 'share#re_revoke', 'url' => '/share/{token}/rerevoke', 'verb' => 'PUT'],
+ ['name' => 'share#lock', 'url' => '/share/{token}/lock', 'verb' => 'PUT'],
+ ['name' => 'share#unlock', 'url' => '/share/{token}/unlock', 'verb' => 'PUT'],
['name' => 'settings#getAppSettings', 'url' => '/settings/app', 'verb' => 'GET'],
['name' => 'settings#writeAppSettings', 'url' => '/settings/app', 'verb' => 'POST'],
diff --git a/lib/Controller/ShareController.php b/lib/Controller/ShareController.php
index ff12770b3..157182ce9 100644
--- a/lib/Controller/ShareController.php
+++ b/lib/Controller/ShareController.php
@@ -118,8 +118,8 @@ public function delete(string $token): JSONResponse {
* @NoAdminRequired
*/
- public function revoke(string $token): JSONResponse {
- return $this->responseDeleteTolerant(fn () => ['share' => $this->shareService->revoke(token: $token)]);
+ public function lock(string $token): JSONResponse {
+ return $this->responseDeleteTolerant(fn () => ['share' => $this->shareService->lock(token: $token)]);
}
/**
@@ -127,8 +127,8 @@ public function revoke(string $token): JSONResponse {
* @NoAdminRequired
*/
- public function reRevoke(string $token): JSONResponse {
- return $this->responseDeleteTolerant(fn () => ['share' => $this->shareService->reRevoke(token: $token)]);
+ public function unlock(string $token): JSONResponse {
+ return $this->responseDeleteTolerant(fn () => ['share' => $this->shareService->unlock(token: $token)]);
}
/**
diff --git a/lib/Db/Share.php b/lib/Db/Share.php
index 89195fe03..8fb45633f 100644
--- a/lib/Db/Share.php
+++ b/lib/Db/Share.php
@@ -47,8 +47,8 @@
* @method void setInvitationSent(integer $value)
* @method int getReminderSent()
* @method void setReminderSent(integer $value)
- * @method int getRevoked()
- * @method void setRevoked(integer $value)
+ * @method int getLocked()
+ * @method void setLocked(integer $value)
* @method string getDisplayName()
* @method void setDisplayName(string $value)
* @method string getMiscSettings()
@@ -123,7 +123,7 @@ class Share extends Entity implements JsonSerializable {
protected ?string $emailAddress = null;
protected int $invitationSent = 0;
protected int $reminderSent = 0;
- protected int $revoked = 0;
+ protected int $locked = 0;
protected ?string $displayName = null;
protected ?string $miscSettings = '';
protected int $voted = 0;
@@ -131,7 +131,7 @@ class Share extends Entity implements JsonSerializable {
public function __construct() {
$this->addType('pollId', 'int');
$this->addType('invitationSent', 'int');
- $this->addType('Revoked', 'int');
+ $this->addType('Locked', 'int');
$this->addType('reminderSent', 'int');
$this->urlGenerator = Container::queryClass(IURLGenerator::class);
$this->appSettings = new AppSettings;
@@ -150,7 +150,7 @@ public function jsonSerialize(): array {
'emailAddress' => $this->getEmailAddress(),
'invitationSent' => $this->getInvitationSent(),
'reminderSent' => $this->getReminderSent(),
- 'revoked' => $this->getRevoked(),
+ 'locked' => $this->getLocked(),
'displayName' => $this->getDisplayName(),
'isNoUser' => !(in_array($this->getType(), [self::TYPE_USER, self::TYPE_ADMIN], true)),
'URL' => $this->getURL(),
diff --git a/lib/Event/ShareEvent.php b/lib/Event/ShareEvent.php
index bc1f71ef9..ba891a3a0 100644
--- a/lib/Event/ShareEvent.php
+++ b/lib/Event/ShareEvent.php
@@ -35,7 +35,7 @@ abstract class ShareEvent extends BaseEvent {
public const CHANGE_REG_CONSTR = 'share_change_reg_const';
public const REGISTRATION = 'share_registration';
public const DELETE = 'share_delete';
- public const REVOKED = 'share_revoked';
+ public const LOCKED = 'share_locked';
private Share $share;
// protected UserBase $sharee = null;
diff --git a/lib/Event/ShareRevokedEvent.php b/lib/Event/ShareLockedEvent.php
similarity index 92%
rename from lib/Event/ShareRevokedEvent.php
rename to lib/Event/ShareLockedEvent.php
index 465dc52e6..f204d2c46 100644
--- a/lib/Event/ShareRevokedEvent.php
+++ b/lib/Event/ShareLockedEvent.php
@@ -25,9 +25,9 @@
use OCA\Polls\Db\Share;
-class ShareRevokedEvent extends ShareEvent {
+class ShareLockedEvent extends ShareEvent {
public function __construct(Share $share) {
parent::__construct($share);
- $this->eventId = self::REVOKED;
+ $this->eventId = self::LOCKED;
}
}
diff --git a/lib/Migration/TableSchema.php b/lib/Migration/TableSchema.php
index 7de5fb0fa..d86944b95 100644
--- a/lib/Migration/TableSchema.php
+++ b/lib/Migration/TableSchema.php
@@ -143,6 +143,7 @@ abstract class TableSchema {
Share::TABLE => [
'user', // dropped in 1.01
'user_email', // dropped in 1.06 and migrated to email_address
+ 'revoked', // introduced in 5.4.0-beta3 and replaced with column 'locked' in 5.4.0-beta5, no migration
],
Log::TABLE => [
'message', // dropped in 1.07, orphaned
@@ -218,7 +219,7 @@ abstract class TableSchema {
'display_name' => ['type' => Types::STRING, 'options' => ['notnull' => false, 'default' => null, 'length' => 256]],
'email_address' => ['type' => Types::STRING, 'options' => ['notnull' => false, 'default' => null, 'length' => 256]],
'invitation_sent' => ['type' => Types::BIGINT, 'options' => ['notnull' => true, 'default' => 0, 'length' => 20]],
- 'revoked' => ['type' => Types::BIGINT, 'options' => ['notnull' => true, 'default' => 0, 'length' => 20]],
+ 'locked' => ['type' => Types::BIGINT, 'options' => ['notnull' => true, 'default' => 0, 'length' => 20]],
'reminder_sent' => ['type' => Types::BIGINT, 'options' => ['notnull' => true, 'default' => 0, 'length' => 20]],
'misc_settings' => ['type' => Types::TEXT, 'options' => ['notnull' => false, 'default' => null, 'length' => 65535]],
],
diff --git a/lib/Migration/Version050400Date20231011211202.php b/lib/Migration/Version050400Date20231011211203.php
similarity index 98%
rename from lib/Migration/Version050400Date20231011211202.php
rename to lib/Migration/Version050400Date20231011211203.php
index 594983734..e5cfe04e2 100644
--- a/lib/Migration/Version050400Date20231011211202.php
+++ b/lib/Migration/Version050400Date20231011211203.php
@@ -36,7 +36,7 @@
* Changed class naming: Version[jjmmpp]Date[YYYYMMDDHHMMSS]
* Version: jj = major version, mm = minor, pp = patch
*/
-class Version050400Date20231011211202 extends SimpleMigrationStep {
+class Version050400Date20231011211203 extends SimpleMigrationStep {
private ISchemaWrapper $schema;
public function __construct(
diff --git a/lib/Model/Acl.php b/lib/Model/Acl.php
index 2dd8a78fd..b5593c661 100644
--- a/lib/Model/Acl.php
+++ b/lib/Model/Acl.php
@@ -369,7 +369,7 @@ private function getIsDelegatedAdmin(): bool {
}
if ($this->loadShare()) { // load share, if not loaded
- return $this->share->getType() === Share::TYPE_ADMIN && !$this->share->getRevoked();
+ return $this->share->getType() === Share::TYPE_ADMIN && !$this->share->getLocked();
};
return false;
}
@@ -480,7 +480,7 @@ private function getAllowAddOptions(): bool {
return false; // Request for option proposals is expired, deny
}
- if ($this->share?->getRevoked()) {
+ if ($this->share?->getLocked()) {
return false; // Request for option proposals is expired, deny
}
@@ -499,7 +499,7 @@ private function getAllowComment(): bool {
return false; // public shares are not allowed to comment
}
- if ($this->share?->getRevoked()) {
+ if ($this->share?->getLocked()) {
return false; // public shares are not allowed to comment
}
@@ -518,7 +518,7 @@ private function getAllowVote(): bool {
return false; // public shares are not allowed to vote
}
- if ($this->share?->getRevoked()) {
+ if ($this->share?->getLocked()) {
return false; // public shares are not allowed to vote
}
diff --git a/lib/Service/ShareService.php b/lib/Service/ShareService.php
index d5a14418b..2b27acbf4 100644
--- a/lib/Service/ShareService.php
+++ b/lib/Service/ShareService.php
@@ -31,8 +31,8 @@
use OCA\Polls\Event\ShareChangedRegistrationConstraintEvent;
use OCA\Polls\Event\ShareCreateEvent;
use OCA\Polls\Event\ShareDeletedEvent;
+use OCA\Polls\Event\ShareLockedEvent;
use OCA\Polls\Event\ShareRegistrationEvent;
-use OCA\Polls\Event\ShareRevokedEvent;
use OCA\Polls\Event\ShareTypeChangedEvent;
use OCA\Polls\Exceptions\ForbiddenException;
use OCA\Polls\Exceptions\InvalidShareTypeException;
@@ -327,31 +327,31 @@ public function delete(Share $share = null, string $token = null): string {
}
/**
- * Revoke share
+ * Lock share
*/
- public function revoke(Share $share = null, string $token = null): string {
+ public function lock(Share $share = null, string $token = null): string {
if ($token) {
$share = $this->shareMapper->findByToken($token);
}
$this->acl->setPollId($share->getPollId(), Acl::PERMISSION_POLL_EDIT);
- $share->setRevoked(time());
+ $share->setLocked(time());
$this->shareMapper->update($share);
- $this->eventDispatcher->dispatchTyped(new ShareRevokedEvent($share));
+ $this->eventDispatcher->dispatchTyped(new ShareLockedEvent($share));
return $share->getToken();
}
/**
- * Re-revoke share
+ * Unlock share
*/
- public function reRevoke(Share $share = null, string $token = null): string {
+ public function unlock(Share $share = null, string $token = null): string {
if ($token) {
$share = $this->shareMapper->findByToken($token);
}
$this->acl->setPollId($share->getPollId(), Acl::PERMISSION_POLL_EDIT);
- $share->setRevoked(0);
+ $share->setLocked(0);
$this->shareMapper->update($share);
$this->eventDispatcher->dispatchTyped(new ShareCreateEvent($share));
diff --git a/src/js/Api/modules/shares.js b/src/js/Api/modules/shares.js
index b45c1015d..d5cd08f96 100644
--- a/src/js/Api/modules/shares.js
+++ b/src/js/Api/modules/shares.js
@@ -95,19 +95,19 @@ const shares = {
})
},
- revokeShare(shareToken) {
+ lockShare(shareToken) {
return httpInstance.request({
method: 'PUT',
- url: `share/${shareToken}/revoke`,
- cancelToken: cancelTokenHandlerObject[this.revokeShare.name].handleRequestCancellation().token,
+ url: `share/${shareToken}/lock`,
+ cancelToken: cancelTokenHandlerObject[this.lockShare.name].handleRequestCancellation().token,
})
},
- reRevokeShare(shareToken) {
+ unlockShare(shareToken) {
return httpInstance.request({
method: 'PUT',
- url: `share/${shareToken}/rerevoke`,
- cancelToken: cancelTokenHandlerObject[this.reRevokeShare.name].handleRequestCancellation().token,
+ url: `share/${shareToken}/unlock`,
+ cancelToken: cancelTokenHandlerObject[this.unlockShare.name].handleRequestCancellation().token,
})
},
diff --git a/src/js/components/Actions/modules/ActionDelete.vue b/src/js/components/Actions/modules/ActionDelete.vue
index bf6c914ff..375151899 100644
--- a/src/js/components/Actions/modules/ActionDelete.vue
+++ b/src/js/components/Actions/modules/ActionDelete.vue
@@ -29,7 +29,7 @@
-
import { NcButton } from '@nextcloud/vue'
import DeleteIcon from 'vue-material-design-icons/Delete.vue'
-import RevokeIcon from 'vue-material-design-icons/Close.vue'
+import LockIcon from 'vue-material-design-icons/Lock.vue'
import UndoIcon from 'vue-material-design-icons/ArrowULeftTop.vue'
export default {
name: 'ActionDelete',
components: {
DeleteIcon,
- RevokeIcon,
+ LockIcon,
UndoIcon,
NcButton,
},
@@ -69,7 +69,7 @@ export default {
type: Number,
default: 20,
},
- revoke: {
+ lock: {
type: Boolean,
default: false,
},
diff --git a/src/js/components/Shares/ShareItem.vue b/src/js/components/Shares/ShareItem.vue
index 904ce5e9e..05e53cb46 100644
--- a/src/js/components/Shares/ShareItem.vue
+++ b/src/js/components/Shares/ShareItem.vue
@@ -24,7 +24,6 @@
@@ -38,7 +37,7 @@
-
+
{{ t('polls', 'Do not ask for an email address') }}
-
-
-
-
+
-
+
+
- {{ t('polls', 'Re-Revoke share') }}
+ {{ share.locked ? t('polls', 'Unlock share') : t('polls', 'Lock share') }}
-
@@ -143,7 +138,8 @@ import EditIcon from 'vue-material-design-icons/Pencil.vue'
import WithdrawAdminIcon from 'vue-material-design-icons/ShieldCrownOutline.vue'
import ClippyIcon from 'vue-material-design-icons/ClipboardArrowLeftOutline.vue'
import QrIcon from 'vue-material-design-icons/Qrcode.vue'
-import ReRevokeIcon from 'vue-material-design-icons/Recycle.vue'
+import LockIcon from 'vue-material-design-icons/Lock.vue'
+import UnlockIcon from 'vue-material-design-icons/LockOpenVariant.vue'
export default {
name: 'ShareItem',
@@ -164,7 +160,8 @@ export default {
NcActionRadio,
ActionDelete,
ResolveGroupIcon,
- ReRevokeIcon,
+ LockIcon,
+ UnlockIcon,
},
props: {
@@ -183,15 +180,12 @@ export default {
this.$store.commit('shares/setShareProperty', { id: this.share.id, displayName: value })
},
},
+
deleteButtonCaption() {
- if (this.share.voted && this.share.revoked) {
+ if (this.share.voted && this.share.locked) {
return t('polls', 'Delete share and remove user from poll')
}
- if (this.share.voted && !this.share.revoked) {
- return t('polls', 'Revoke share')
- }
-
return t('polls', 'Delete share')
},
@@ -200,23 +194,35 @@ export default {
methods: {
...mapActions({
deleteShare: 'shares/delete',
- revokeShare: 'shares/revoke',
- reRevokeShare: 'shares/reRevoke',
+ lockShare: 'shares/lock',
+ unlockShare: 'shares/unlock',
switchAdmin: 'shares/switchAdmin',
setPublicPollEmail: 'shares/setPublicPollEmail',
setLabel: 'shares/writeLabel',
deleteUser: 'votes/deleteUser',
}),
+ async switchLocked(share) {
+ try {
+ if (share.locked) {
+ this.unlockShare({ share })
+ showSuccess(t('polls', 'Share for user {displayName} unlocked', { displayName: share.displayName }))
+ } else {
+ this.lockShare({ share })
+ showSuccess(t('polls', 'Share for user {displayName} locked', { displayName: share.displayName }))
+ }
+ } catch (e) {
+ showError(t('polls', 'Error deleting or revoking share for user {displayName}', { displayName: share.displayName }))
+ console.error('Error deleting or revoking share', { share }, e.response)
+ }
+ },
+
async clickDeleted(share) {
try {
- if (share.voted && share.revoked) {
+ if (share.voted && share.locked) {
this.deleteShare({ share })
this.deleteUser({ userId: share.userId })
showSuccess(t('polls', 'Deleted share and votes for {displayName}', { displayName: share.displayName }))
- } else if (share.voted && !share.revoked) {
- this.revokeShare({ share })
- showSuccess(t('polls', 'Share for user {displayName} revoked', { displayName: share.displayName }))
} else {
this.deleteShare({ share })
showSuccess(t('polls', 'Deleted share for user {displayName}', { displayName: share.displayName }))
diff --git a/src/js/components/Shares/SharesListRevoked.vue b/src/js/components/Shares/SharesListLocked.vue
similarity index 83%
rename from src/js/components/Shares/SharesListRevoked.vue
rename to src/js/components/Shares/SharesListLocked.vue
index bc89f86b0..32fc2e0db 100644
--- a/src/js/components/Shares/SharesListRevoked.vue
+++ b/src/js/components/Shares/SharesListLocked.vue
@@ -21,12 +21,12 @@
-->
-
+
-
+
-
@@ -36,14 +36,14 @@