Skip to content

Commit

Permalink
Merge pull request #1174 from nextcloud/backport/1160/stable0.7
Browse files Browse the repository at this point in the history
[stable0.7] fix: only add resource if user can manage resource
  • Loading branch information
enjeck committed Jul 4, 2024
2 parents 19354ed + 090c32e commit 2e14106
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 5 deletions.
4 changes: 3 additions & 1 deletion lib/Controller/ContextController.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ public function create(string $name, string $iconName, string $description = '',
* @param ?string $description provide this parameter to set a new description
* @param ?array{id: int, type: int, permissions: int, order: int} $nodes provide this parameter to set a new list of nodes.
*
* @return DataResponse<Http::STATUS_OK, TablesContext, array{}>|DataResponse<Http::STATUS_INTERNAL_SERVER_ERROR|Http::STATUS_NOT_FOUND, array{message: string}, array{}>
* @return DataResponse<Http::STATUS_OK, TablesContext, array{}>|DataResponse<Http::STATUS_INTERNAL_SERVER_ERROR|Http::STATUS_NOT_FOUND|Http::STATUS_FORBIDDEN, array{message: string}, array{}>
*
* 200: returning the full context information
* 403: No permissions
Expand All @@ -148,6 +148,8 @@ public function update(int $contextId, ?string $name, ?string $iconName, ?string
)->jsonSerialize());
} catch (Exception|MultipleObjectsReturnedException $e) {
return $this->handleError($e);
} catch (PermissionError $e) {
return $this->handlePermissionError($e);
} catch (DoesNotExistException $e) {
return $this->handleNotFoundError(new NotFoundError($e->getMessage(), $e->getCode(), $e));
}
Expand Down
8 changes: 7 additions & 1 deletion lib/Service/ContextService.php
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ public function create(string $name, string $iconName, string $description, arra
* @psalm-param list<array{id: int, type: int, permissions?: int, order?: int}> $nodes
* @throws Exception
* @throws DoesNotExistException
* @throws MultipleObjectsReturnedException
* @throws PermissionError|MultipleObjectsReturnedException
*/
public function update(int $contextId, string $userId, ?string $name, ?string $iconName, ?string $description, ?array $nodes): Context {
$context = $this->contextMapper->findById($contextId, $userId);
Expand Down Expand Up @@ -207,6 +207,12 @@ public function update(int $contextId, string $userId, ?string $name, ?string $i
unset($nodesBeingRemoved);

foreach ($nodesBeingAdded as $node) {
$nodeType = (int)($node['type']);
$nodeId = (int)($node['id']);
if (!$this->permissionsService->canManageNodeById($nodeType, $nodeId, $userId)) {
throw new PermissionError(sprintf('Owner cannot manage node %d (type %d)', $nodeId, $nodeType));
}

/** @var ContextNodeRelation $addedNode */
/** @var PageContent $updatedContent */
[$addedNode, $updatedContent] = $this->addNodeToContextAndStartpage(
Expand Down
38 changes: 38 additions & 0 deletions openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -8728,6 +8728,44 @@
}
}
}
},
"403": {
"description": "No permissions",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {
"type": "object",
"required": [
"message"
],
"properties": {
"message": {
"type": "string"
}
}
}
}
}
}
}
}
}
}
}
},
Expand Down
10 changes: 8 additions & 2 deletions src/shared/components/ncContextResource/ResourceForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { NcSelect } from '@nextcloud/vue'
import { mapState } from 'vuex'
import { NODE_TYPE_TABLE, NODE_TYPE_VIEW } from '../../../shared/constants.js'
import SearchAndSelectOption from '../../../views/partials/SearchAndSelectOption.vue'
import permissionsMixin from '../../../shared/components/ncTable/mixins/permissionsMixin.js'
export default {
name: 'ResourceForm',
Expand All @@ -42,6 +43,8 @@ export default {
SearchAndSelectOption,
},
mixins: [permissionsMixin],
props: {
resources: {
type: Array,
Expand Down Expand Up @@ -97,12 +100,15 @@ export default {
async getSuggestions(searchTerm) {
this.loading = true
let filteredTables = this.tables.filter((table) => table.title.toLowerCase().includes(searchTerm.toLowerCase())
let filteredTables = this.tables.filter((table) => this.canManageTable(table))
filteredTables = filteredTables.filter((table) => table.title.toLowerCase().includes(searchTerm.toLowerCase())
&& !this.resources.find(t => t.nodeType === NODE_TYPE_TABLE && parseInt(t.id) === parseInt(table.id)))
filteredTables = filteredTables.map(table => {
return this.formatElementData(table, NODE_TYPE_TABLE, 'table-')
})
let filteredViews = this.views.filter((view) => view.title.toLowerCase().includes(searchTerm.toLowerCase())
let filteredViews = this.views.filter((view) => this.canManageElement(view))
filteredViews = filteredViews.filter((view) => view.title.toLowerCase().includes(searchTerm.toLowerCase())
&& !this.resources.find(v => v.nodeType === NODE_TYPE_VIEW && parseInt(v.id) === parseInt(view.id)))
filteredViews = filteredViews.map(view => {
return this.formatElementData(view, NODE_TYPE_VIEW, 'view-')
Expand Down
13 changes: 13 additions & 0 deletions src/types/openapi/openapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3228,6 +3228,19 @@ export type operations = {
};
};
};
/** @description No permissions */
403: {
content: {
"application/json": {
ocs: {
meta: components["schemas"]["OCSMeta"];
data: {
message: string;
};
};
};
};
};
/** @description Not found */
404: {
content: {
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/features/APIv2.feature
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ Feature: APIv2
| alias | type | permissions |
| t1 | table | read,create,update |
| t2 | table | read |
Then the reported status is "200"
Then the reported status is "403"
When user "participant1-v2" fetches Context "c1"
Then the fetched Context "c1" has following data:
| field | value |
Expand Down

0 comments on commit 2e14106

Please sign in to comment.