Skip to content

Commit 5812ee2

Browse files
committed
feat(tests): Add integration test for file system tags cache bug
Signed-off-by: Joas Schilling <[email protected]>
1 parent 10b54a7 commit 5812ee2

File tree

4 files changed

+156
-19
lines changed

4 files changed

+156
-19
lines changed

tests/Integration/app/appinfo/routes.php

+2
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,7 @@
99
return [
1010
'ocs' => [
1111
['name' => 'Endpoint#reset', 'url' => '', 'verb' => 'DELETE'],
12+
['name' => 'Endpoint#prepare', 'url' => '', 'verb' => 'POST'],
13+
['name' => 'Endpoint#tagFile', 'url' => '/tag-file', 'verb' => 'POST'],
1214
],
1315
];

tests/Integration/app/lib/Controller/EndpointController.php

+41
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,22 @@
1010

1111
use OCP\AppFramework\Http\DataResponse;
1212
use OCP\AppFramework\OCSController;
13+
use OCP\Files\IRootFolder;
1314
use OCP\IDBConnection;
1415
use OCP\IRequest;
16+
use OCP\SystemTag\ISystemTagManager;
17+
use OCP\SystemTag\ISystemTagObjectMapper;
18+
use OCP\SystemTag\TagNotFoundException;
1519

1620
class EndpointController extends OCSController {
1721
public function __construct(
1822
string $appName,
1923
IRequest $request,
2024
protected IDBConnection $db,
25+
protected ISystemTagManager $systemTagManager,
26+
protected ISystemTagObjectMapper $systemTagObjectMapper,
27+
protected IRootFolder $rootFolder,
28+
protected string $userId,
2129
) {
2230
parent::__construct($appName, $request);
2331
}
@@ -32,6 +40,39 @@ public function reset(): DataResponse {
3240
$query->delete('flow_operations')->executeStatement();
3341
$query->delete('flow_operations_scope')->executeStatement();
3442

43+
44+
try {
45+
$tag = $this->systemTagManager->getTag('files_accesscontrol_intergrationtest', true, true);
46+
$this->systemTagManager->deleteTags([$tag->getId()]);
47+
} catch (TagNotFoundException) {
48+
}
49+
50+
return new DataResponse();
51+
}
52+
53+
/**
54+
* @return DataResponse
55+
*/
56+
public function prepare(): DataResponse {
57+
try {
58+
$tag = $this->systemTagManager->getTag('files_accesscontrol_intergrationtest', true, true);
59+
} catch (TagNotFoundException) {
60+
$tag = $this->systemTagManager->createTag('files_accesscontrol_intergrationtest', true, true);
61+
}
62+
return new DataResponse(['tagId' => $tag->getId()]);
63+
}
64+
65+
/**
66+
* @NoAdminRequired
67+
* @return DataResponse
68+
*/
69+
public function tagFile(string $path): DataResponse {
70+
$tag = $this->systemTagManager->getTag('files_accesscontrol_intergrationtest', true, true);
71+
72+
$userFolder = $this->rootFolder->getUserFolder($this->userId);
73+
$node = $userFolder->get($path);
74+
$this->systemTagObjectMapper->assignTags((string)$node->getId(), 'files', [$tag->getId()]);
75+
3576
return new DataResponse();
3677
}
3778
}

tests/Integration/features/bootstrap/FeatureContext.php

+56-16
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ class FeatureContext implements Context {
4242
/** @var string */
4343
protected $baseUrl;
4444

45+
protected string $tagId = '';
46+
protected array $createdUsers = [];
47+
4548
/**
4649
* FeatureContext constructor.
4750
*/
@@ -55,29 +58,45 @@ public function __construct() {
5558
* @AfterScenario
5659
*/
5760
public function cleanUpBetweenTests() {
58-
// TODO: Remove all created tags?
5961
$this->setCurrentUser('admin');
6062
$this->sendingTo('DELETE', '/apps/files_accesscontrol_testing');
6163
$this->assertStatusCode($this->response, 200);
64+
}
6265

63-
try {
64-
$this->userDeletesFile('test1', 'folder', '/subdir');
65-
} catch (\Exception $e) {
66-
}
67-
try {
68-
$this->userDeletesFile('test1', 'file', '/foobar.txt');
69-
} catch (\Exception $e) {
70-
}
71-
try {
72-
$this->userDeletesFile('test1', 'file', '/definitely.notexe');
73-
} catch (\Exception $e) {
74-
}
75-
try {
76-
$this->emptyTrashbin('test1');
77-
} catch (\Exception $e) {
66+
/**
67+
* @AfterScenario
68+
*/
69+
public function tearDown() {
70+
foreach ($this->createdUsers as $user) {
71+
$this->deleteUser($user);
7872
}
7973
}
8074

75+
/**
76+
* @Given /^Ensure tag exists$/
77+
*/
78+
public function createTag() {
79+
$this->setCurrentUser('admin');
80+
$this->sendingTo('POST', '/apps/files_accesscontrol_testing');
81+
$this->assertStatusCode($this->response, 200);
82+
83+
$ocsData = json_decode($this->response->getBody()->getContents(), true, flags: JSON_THROW_ON_ERROR);
84+
$data = $ocsData['ocs']['data'];
85+
$this->tagId = $data['tagId'];
86+
}
87+
88+
/**
89+
* @Given /^user "([^"]*)" tags file "([^"]*)"$/
90+
*/
91+
public function tagFile(string $user, string $path) {
92+
// TODO: Remove all created tags?
93+
$this->setCurrentUser($user);
94+
$this->sendingToWith('POST', '/apps/files_accesscontrol_testing/tag-file', [
95+
'path' => $path,
96+
]);
97+
$this->assertStatusCode($this->response, 200);
98+
}
99+
81100
/**
82101
* @Given /^user "([^"]*)" creates (global|user) flow with (\d+)$/
83102
*/
@@ -89,6 +108,7 @@ public function createFlow(string $user, string $scope, int $statusCode, TableNo
89108
$checks = [];
90109
foreach ($formData as $key => $value) {
91110
if (strpos($key, 'checks-') === 0) {
111+
$value = str_replace('{{{FILES_ACCESSCONTROL_INTEGRATIONTEST_TAGID}}}', $this->tagId, $value);
92112
$checks[] = json_decode($value, true);
93113
unset($formData[$key]);
94114
}
@@ -195,6 +215,26 @@ private function createUser(string $user): void {
195215
];
196216
$client->get($userProvisioningUrl . '/' . $user, $options2);
197217

218+
$this->createdUsers[] = $user;
219+
$this->currentUser = $previous_user;
220+
}
221+
222+
private function deleteUser(string $user): void {
223+
$previous_user = $this->currentUser;
224+
$this->currentUser = 'admin';
225+
226+
$userProvisioningUrl = $this->baseUrl . 'ocs/v2.php/cloud/users/' . $user;
227+
$client = new Client();
228+
$options = [
229+
'auth' => ['admin', 'admin'],
230+
'headers' => [
231+
'OCS-APIREQUEST' => 'true',
232+
],
233+
];
234+
$client->delete($userProvisioningUrl, $options);
235+
236+
unset($this->createdUsers[$user]);
237+
198238
$this->currentUser = $previous_user;
199239
}
200240

tests/Integration/features/sharing-user.feature

+57-3
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ Feature: Sharing user
8484
When User "test2" deletes file "/subdir/foobar.txt"
8585
Then The webdav response should have a status code "403"
8686

87-
Scenario: Upload and share a file that is allowed by mimetype exludes
87+
Scenario: Upload and share a file that is allowed by mimetype excludes
8888
And user "admin" creates global flow with 200
8989
| name | Admin flow |
9090
| class | OCA\FilesAccessControl\Operation |
@@ -102,7 +102,7 @@ Feature: Sharing user
102102
And Downloading file "/nextcloud.pdf" as "test2"
103103
And The webdav response should have a status code "200"
104104

105-
Scenario: Share a file that is allowed by mimetype exludes
105+
Scenario: Share a file that is allowed by mimetype excludes
106106
Given User "test1" uploads file "data/nextcloud.pdf" to "/nextcloud2.pdf"
107107
And The webdav response should have a status code "201"
108108
And user "test1" shares file "/nextcloud2.pdf" with user "test2"
@@ -117,4 +117,58 @@ Feature: Sharing user
117117
| checks-0 | {"class":"OCA\\WorkflowEngine\\Check\\FileMimeType", "operator": "!is", "value": "httpd/directory"} |
118118
| checks-1 | {"class":"OCA\\WorkflowEngine\\Check\\FileMimeType", "operator": "!is", "value": "application/pdf"} |
119119
And Downloading file "/nextcloud2.pdf" as "test2"
120-
And The webdav response should have a status code "200"
120+
And The webdav response should have a status code "200"
121+
122+
Scenario: Jailed storage cache bug blocking first
123+
Given Ensure tag exists
124+
Given User "test1" uploads file "data/textfile.txt" to "/nextcloud2.txt"
125+
And The webdav response should have a status code "201"
126+
Given User "test1" uploads file "data/textfile.txt" to "/nextcloud3.txt"
127+
And The webdav response should have a status code "201"
128+
And user "test1" shares file "/nextcloud2.txt" with user "test2"
129+
And Downloading file "/nextcloud2.txt" as "test2"
130+
And The webdav response should have a status code "200"
131+
And user "test1" shares file "/nextcloud3.txt" with user "test2"
132+
And Downloading file "/nextcloud3.txt" as "test2"
133+
And The webdav response should have a status code "200"
134+
And user "test1" tags file "/nextcloud2.txt"
135+
When user "admin" creates global flow with 200
136+
| name | Admin flow |
137+
| class | OCA\FilesAccessControl\Operation |
138+
| entity | OCA\WorkflowEngine\Entity\File |
139+
| events | [] |
140+
| operation | deny |
141+
| checks-0 | {"class":"OCA\\WorkflowEngine\\Check\\FileSystemTags", "operator": "is", "value": "{{{FILES_ACCESSCONTROL_INTEGRATIONTEST_TAGID}}}"} |
142+
Then Downloading file "/nextcloud2.txt" as "test2"
143+
And The webdav response should have a status code "404"
144+
And Downloading file "/nextcloud3.txt" as "test2"
145+
And The webdav response should have a status code "200"
146+
And user "test2" should see following elements
147+
| /nextcloud3.txt |
148+
149+
Scenario: Jailed storage cache bug blocking last
150+
Given Ensure tag exists
151+
Given User "test1" uploads file "data/textfile.txt" to "/nextcloud2.txt"
152+
And The webdav response should have a status code "201"
153+
Given User "test1" uploads file "data/textfile.txt" to "/nextcloud3.txt"
154+
And The webdav response should have a status code "201"
155+
And user "test1" shares file "/nextcloud2.txt" with user "test2"
156+
And Downloading file "/nextcloud2.txt" as "test2"
157+
And The webdav response should have a status code "200"
158+
And user "test1" shares file "/nextcloud3.txt" with user "test2"
159+
And Downloading file "/nextcloud3.txt" as "test2"
160+
And The webdav response should have a status code "200"
161+
And user "test1" tags file "/nextcloud3.txt"
162+
When user "admin" creates global flow with 200
163+
| name | Admin flow |
164+
| class | OCA\FilesAccessControl\Operation |
165+
| entity | OCA\WorkflowEngine\Entity\File |
166+
| events | [] |
167+
| operation | deny |
168+
| checks-0 | {"class":"OCA\\WorkflowEngine\\Check\\FileSystemTags", "operator": "is", "value": "{{{FILES_ACCESSCONTROL_INTEGRATIONTEST_TAGID}}}"} |
169+
Then Downloading file "/nextcloud2.txt" as "test2"
170+
And The webdav response should have a status code "200"
171+
And Downloading file "/nextcloud3.txt" as "test2"
172+
And The webdav response should have a status code "404"
173+
And user "test2" should see following elements
174+
| /nextcloud2.txt |

0 commit comments

Comments
 (0)