Fix 5404 update document without relation permission - #5887
Conversation
…0.39.0 Make 1.4.x compatible with latest db release 0.39.0
This commit removes check pemission from update document in appwrite as permission is being checked by Utopia already. This commits also improves the test case to have 3 levels of depth with relationships
stnguyen90
left a comment
There was a problem hiding this comment.
I left a comment. Also, I tried to update a document in the console but go an error:
The appwrite logs has:
appwrite | [Error] Timestamp: 2023-08-01T22:20:36+00:00
appwrite | [Error] Method: PATCH
appwrite | [Error] URL: /v1/databases/:databaseId/collections/:collectionId/documents/:documentId
appwrite | [Error] Type: PDOException
appwrite | [Error] Message: Unknown column 'databaseId' in 'field list'
appwrite | [Error] File: @swoole-src/library/core/Database/PDOStatementProxy.php
appwrite | [Error] Line: 64
Are these problems just my instance?
Hmm, not really sure. This branch now requires more updates in Utopia. Could be because of that, let's wait till we have the changes merged in Utopia. |
| "utopia-php/cli": "0.15.*", | ||
| "utopia-php/config": "0.2.*", | ||
| "utopia-php/database": "0.38.*", | ||
| "utopia-php/database": "0.41.*", |
There was a problem hiding this comment.
I have 3 collections with a two-way one-to-one relationship between them like level1 => level2 => level3 and I experienced 2 problems:
First problem
With update access to level1 but read-only access to level2, I can update a document in level1 to point to a document in level2, but when I switch it to point to another document:
{
"level2": "level2other"
}I get an error:
{
"message": "Document with the requested ID already exists.",
"code": 409,
"type": "document_already_exists",
"version": "dev",
"file": "/usr/src/code/app/controllers/api/databases.php",
"line": 3286,
"trace": [
{
"file": "/usr/src/code/vendor/utopia-php/framework/src/App.php",
"line": 593,
"function": "{closure}",
"args": [
"one-to-one",
"level1",
"level1a",
{
"$internalId": "1",
"$id": "level1a",
"$createdAt": "2023-08-10T23:15:31.935+00:00",
"$updatedAt": "2023-08-11T00:19:12.395+00:00",
"$permissions": [],
"$collection": "level1",
"level2": "level2a"
},
[],
null,
{},
{},
{},
"default"
]
},
{
"file": "/usr/src/code/vendor/utopia-php/framework/src/App.php",
"line": 770,
"function": "execute",
"class": "Utopia\\App",
"type": "->",
"args": [
{},
{}
]
},
{
"file": "/usr/src/code/app/http.php",
"line": 248,
"function": "run",
"class": "Utopia\\App",
"type": "->",
"args": [
{},
{}
]
}
]
}Second problem
With update access to level1 and level2 but read-only access to level3, I can't set level3 on level2:
{
"level2": {
"$id": "level2b",
"level3": "level3a"
}
}results in:
{
"$id": "level1a",
"$createdAt": "2023-08-10T23:15:31.935+00:00",
"$updatedAt": "2023-08-11T00:25:44.052+00:00",
"$permissions": [],
"level2": {
"_createdAt": null,
"$id": "level2b",
"$updatedAt": "2023-08-11T00:16:59.164+00:00",
"$permissions": [],
"level3": null,
"$databaseId": "one-to-one",
"$collectionId": "level2"
},
"$databaseId": "one-to-one",
"$collectionId": "level1"
}
There was a problem hiding this comment.
Also, when I sent a request like:
{
"level2": {
"$id": "level2b",
"level3": "level3a"
}
}my level2 document ended up with a _createdAt attribute:
{
"level2": {
"_createdAt": null,
"$id": "level2a",
"$updatedAt": "2023-08-10T23:15:53.689+00:00",
"$permissions": [],
"level3": null,
"$databaseId": "one-to-one",
"$collectionId": "level2"
}
}There was a problem hiding this comment.
With two way relationship you need permission for both collection because when you are linking to a new document, you are updating both documents.
With one way you can link to a new document of related collection by only having the permission of the parent collection.
|
@stnguyen90 Please re-review with the latest DB updates |
Hold off on that.. looks like there are some issues |
f7f3ff2 to
971ebbc
Compare
adbfa30 to
8e1ef81
Compare
| 'name' => ID::custom('collection2'), | ||
| 'documentSecurity' => false, | ||
| 'permissions' => [ | ||
| Permission::read(Role::user($userId)), |
There was a problem hiding this comment.
Is there any test where a document in collection1 is updated to link to a different collection2 document? When I tried:
{
"data": {
"level2": "level2b"
}
}I got an error:
{
"message": "The current user is not authorized to perform the requested action.",
"code": 401,
"type": "user_unauthorized",
"version": "dev",
"file": "/usr/src/code/app/controllers/api/databases.php",
"line": 3333,
"trace": [
{
"file": "/usr/src/code/vendor/utopia-php/framework/src/App.php",
"line": 593,
"function": "{closure}",
"args": [
"one-to-one",
"level1",
"level1a",
{
"$internalId": "1",
"$id": "level1a",
"$createdAt": "2023-08-15T00:50:55.532+00:00",
"$updatedAt": "2023-08-15T01:04:34.280+00:00",
"$permissions": [],
"$collection": "database_1_collection_1",
"level2": "level2b"
},
[],
null,
{},
{},
{},
"default"
]
},
{
"file": "/usr/src/code/vendor/utopia-php/framework/src/App.php",
"line": 770,
"function": "execute",
"class": "Utopia\\App",
"type": "->",
"args": [
{},
{}
]
},
{
"file": "/usr/src/code/app/http.php",
"line": 248,
"function": "run",
"class": "Utopia\\App",
"type": "->",
"args": [
{},
{}
]
}
]
}Interestingly, when I updated like:
{
"data": {
"level2": {
"$id": "level2b"
}
}
}it screwed up the document such that $createdAt and $updatedAt" disappeared and _createdAt and _updatedAt were added.
{
"$id": "level1a",
"$createdAt": "2023-08-15T00:50:55.532+00:00",
"$updatedAt": "2023-08-15T01:07:00.060+00:00",
"$permissions": [],
"level2": {
"_createdAt": null,
"_updatedAt": null,
"text": null,
"$id": "level2b",
"$permissions": [],
"level3": null,
"$databaseId": "one-to-one",
"$collectionId": "level2"
},
"$databaseId": "one-to-one",
"$collectionId": "level1"
}There was a problem hiding this comment.
In the test case, there is now the ability to link to a different document without update permission in the child level. If you are performing a two-way link, it is necessary to have update permission in both collections, as updating is required in both documents. For a one-way link, update permission is only required in the parent level.
Additionally, when running something like this, ensure that you have create permission in the level2 collection if the document does not already exist. If the document already exists and it is a one-way link, you should be able to link it with update permission in level1. This has been included in the test case. If it is a two-way link, permission is required in both levels only during linking documents. If you are updating attribute of a level/collection in two way relationship type, you don't need permission for both levels but only the level you're updating.
{
"data": {
"level2": {
"$id": "level2b"
}
}
}
There was a problem hiding this comment.
Regarding the null values for _createdAt and _updatedAt, I have confirmed that this issue is already present in version 1.4.x. It is not directly related to the permission bug, and we have not made any changes to it.
There was a problem hiding this comment.
If you are performing a two-way link, it is necessary to have update permission in both collections
Good point! I'll make sure to test accordingly.
Regarding the null values for _createdAt and _updatedAt, I have confirmed that this issue is already present in version 1.4.x. It is not directly related to the permission bug, and we have not made any changes to it.
Do we have an issue or something to track this so that we can make a fix?
There was a problem hiding this comment.
Do we have an issue or something to track this so that we can make a fix?
We don't have an issue open for this. Let me create an issue for that.
| "utopia-php/cli": "0.15.*", | ||
| "utopia-php/config": "0.2.*", | ||
| "utopia-php/database": "0.38.*", | ||
| "utopia-php/database": "0.41.*", |
There was a problem hiding this comment.
With two way relationship you need permission for both collection because when you are linking to a new document, you are updating both documents.
With one way you can link to a new document of related collection by only having the permission of the parent collection.
| 'name' => ID::custom('collection2'), | ||
| 'documentSecurity' => false, | ||
| 'permissions' => [ | ||
| Permission::read(Role::user($userId)), |
There was a problem hiding this comment.
In the test case, there is now the ability to link to a different document without update permission in the child level. If you are performing a two-way link, it is necessary to have update permission in both collections, as updating is required in both documents. For a one-way link, update permission is only required in the parent level.
Additionally, when running something like this, ensure that you have create permission in the level2 collection if the document does not already exist. If the document already exists and it is a one-way link, you should be able to link it with update permission in level1. This has been included in the test case. If it is a two-way link, permission is required in both levels only during linking documents. If you are updating attribute of a level/collection in two way relationship type, you don't need permission for both levels but only the level you're updating.
{
"data": {
"level2": {
"$id": "level2b"
}
}
}
| 'name' => ID::custom('collection2'), | ||
| 'documentSecurity' => false, | ||
| 'permissions' => [ | ||
| Permission::read(Role::user($userId)), |
There was a problem hiding this comment.
Regarding the null values for _createdAt and _updatedAt, I have confirmed that this issue is already present in version 1.4.x. It is not directly related to the permission bug, and we have not made any changes to it.
…-5404-update-document-without-relation-permission


What does this PR do?
Update of document with relations without permissions of relation collection
Fixes: #5404
Test Plan
Added E2E test case
Related PRs and Issues
Checklist