зеркало из https://github.com/nextcloud/spreed.git
Fix issues mentioned in the polls review
* Question is limited to 32k chars (not multibyte save, so an emoji is 3-4 chars) * Json encoded options array is limited to 60k chars (not multibyte save, so an emoji is 3-4 chars) * Options on creation are now validated to be strings * Options array on creating needs to be at least 2 strings long * Options on voting are now validated to be integers * System messages `poll_voted` do not contain the actor anymore to be okay with the hidden result mode Signed-off-by: Joas Schilling <coding@schilljs.com>
This commit is contained in:
Родитель
c36cab3f55
Коммит
35fc94d947
|
@ -386,7 +386,7 @@ See [OCP\RichObjectStrings\Definitions](https://github.com/nextcloud/server/blob
|
|||
* `reaction_deleted` - Reaction deleted by author (replacement of `reaction` after the action has been performed)
|
||||
* `reaction_revoked` - {actor} deleted a reaction (the action that will replace `reaction` with a `reaction_deleted` message)
|
||||
* Creating a poll is an `object_shared` with a poll object
|
||||
* `poll_voted` - {actor} voted on the poll {poll}
|
||||
* `poll_voted` - Someone voted on the poll {poll}
|
||||
* `poll_closed` - {actor} closed the poll {poll}
|
||||
* `message_expiration_enabled` - {actor} set the message expiration to 3 hours
|
||||
* `message_expiration_disabled` - {actor} disabled message expiration
|
||||
|
|
32
docs/poll.md
32
docs/poll.md
|
@ -18,7 +18,7 @@ Base endpoint is: `/ocs/v2.php/apps/spreed/api/v1`
|
|||
* Response:
|
||||
- Status code:
|
||||
+ `201 Created`
|
||||
+ `400 Bad Request` When the question or the options were too long
|
||||
+ `400 Bad Request` When the question or the options were too long or invalid (not strings)
|
||||
+ `403 Forbidden` When the conversation is read-only
|
||||
+ `403 Forbidden` When the actor does not have chat permissions
|
||||
+ `404 Not Found` When the conversation could not be found for the participant
|
||||
|
@ -94,21 +94,21 @@ Base endpoint is: `/ocs/v2.php/apps/spreed/api/v1`
|
|||
It is therefor recommended to use `format=json` or send the `Content-Type: application/json` header,
|
||||
to receive a JSON response.
|
||||
|
||||
| field | type | Description |
|
||||
|--------------------|----------|-----------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `id` | int | ID of the poll |
|
||||
| `question` | string | The question of the poll |
|
||||
| `options` | string[] | The options participants can vote for |
|
||||
| `votes` | int[] | Map with `'option-' + optionId` => number of votes (only available for when the actor voted on public poll or the poll is closed) |
|
||||
| `actorType` | string | Actor type of the poll author (see [Constants - Attendee types](constants.md#attendee-types)) |
|
||||
| `actorId` | string | Actor ID identifying the poll author |
|
||||
| `actorDisplayName` | string | Display name of the poll author |
|
||||
| `status` | int | Status of the poll (see [Constants - Poll status](constants.md#poll-status)) |
|
||||
| `resultMode` | int | Result mode of the poll (see [Constants - Poll mode](constants.md#poll-mode)) |
|
||||
| `maxVotes` | int | Maximum amount of options a user can vote for, `0` means unlimited |
|
||||
| `votedSelf` | int[] | Array of option ids the participant voted for |
|
||||
| `numVoters` | int | The number of unique voters that (only available for when the actor voted on public poll or the poll is closed) |
|
||||
| `details` | array[] | Detailed list who voted for which option (only available for public closed polls), see [Details](#details) below |
|
||||
| field | type | Description |
|
||||
|--------------------|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `id` | int | ID of the poll |
|
||||
| `question` | string | The question of the poll |
|
||||
| `options` | string[] | The options participants can vote for |
|
||||
| `votes` | int[] | Map with `'option-' + optionId` => number of votes (only available for when the actor voted on public poll or the poll is closed) |
|
||||
| `actorType` | string | Actor type of the poll author (see [Constants - Attendee types](constants.md#attendee-types)) |
|
||||
| `actorId` | string | Actor ID identifying the poll author |
|
||||
| `actorDisplayName` | string | Display name of the poll author |
|
||||
| `status` | int | Status of the poll (see [Constants - Poll status](constants.md#poll-status)) |
|
||||
| `resultMode` | int | Result mode of the poll (see [Constants - Poll mode](constants.md#poll-mode)) |
|
||||
| `maxVotes` | int | Maximum amount of options a user can vote for, `0` means unlimited |
|
||||
| `votedSelf` | int[] | Array of option ids the participant voted for |
|
||||
| `numVoters` | int | The number of unique voters that voted (only available when the actor voted on public poll or the poll is closed unless for the creator and moderators) |
|
||||
| `details` | array[] | Detailed list who voted for which option (only available for public closed polls), see [Details](#details) below |
|
||||
|
||||
### Details
|
||||
|
||||
|
|
|
@ -497,10 +497,8 @@ class SystemMessage {
|
|||
}
|
||||
} elseif ($message === 'poll_voted') {
|
||||
$parsedParameters['poll'] = $parameters['poll'];
|
||||
$parsedMessage = $this->l->t('{actor} voted on the poll {poll}');
|
||||
if ($currentUserIsActor) {
|
||||
$parsedMessage = $this->l->t('You voted on the poll {poll}');
|
||||
}
|
||||
$parsedMessage = $this->l->t('Someone voted on the poll {poll}');
|
||||
unset($parsedParameters['actor']);
|
||||
} else {
|
||||
throw new \OutOfBoundsException('Unknown subject');
|
||||
}
|
||||
|
|
|
@ -50,13 +50,37 @@ class PollService {
|
|||
}
|
||||
|
||||
public function createPoll(int $roomId, string $actorType, string $actorId, string $displayName, string $question, array $options, int $resultMode, int $maxVotes): Poll {
|
||||
if (strlen($question) > 32_000) {
|
||||
throw new \UnexpectedValueException();
|
||||
}
|
||||
|
||||
try {
|
||||
$jsonOptions = json_encode($options, JSON_THROW_ON_ERROR, 1);
|
||||
} catch (\Exception $e) {
|
||||
throw new \RuntimeException();
|
||||
}
|
||||
|
||||
foreach ($options as $option) {
|
||||
if (!is_string($option)) {
|
||||
throw new \RuntimeException();
|
||||
}
|
||||
}
|
||||
|
||||
if (count($options) < 2) {
|
||||
throw new \RuntimeException();
|
||||
}
|
||||
|
||||
if (strlen($jsonOptions) > 60_000) {
|
||||
throw new \UnexpectedValueException();
|
||||
}
|
||||
|
||||
$poll = new Poll();
|
||||
$poll->setRoomId($roomId);
|
||||
$poll->setActorType($actorType);
|
||||
$poll->setActorId($actorId);
|
||||
$poll->setDisplayName($displayName);
|
||||
$poll->setQuestion($question);
|
||||
$poll->setOptions(json_encode($options));
|
||||
$poll->setOptions($jsonOptions);
|
||||
$poll->setVotes(json_encode([]));
|
||||
$poll->setResultMode($resultMode);
|
||||
$poll->setMaxVotes($maxVotes);
|
||||
|
@ -139,6 +163,12 @@ class PollService {
|
|||
}
|
||||
|
||||
if (!empty($optionIds)) {
|
||||
foreach ($optionIds as $optionId) {
|
||||
if (!is_numeric($optionId)) {
|
||||
throw new \RangeException();
|
||||
}
|
||||
}
|
||||
|
||||
$maxOptionId = max(array_keys(json_decode($poll->getOptions(), true, 512, JSON_THROW_ON_ERROR)));
|
||||
$maxVotedId = max($optionIds);
|
||||
$minVotedId = min($optionIds);
|
||||
|
|
Загрузка…
Ссылка в новой задаче