Skip to content

Commit dde4a72

Browse files
nickvergessenbackportbot[bot]
authored andcommitted
feat(tests): Add integration test for file system tags cache bug
Signed-off-by: Joas Schilling <[email protected]>
1 parent 62154a1 commit dde4a72

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
@@ -26,5 +26,7 @@
2626
return [
2727
'ocs' => [
2828
['name' => 'Endpoint#reset', 'url' => '', 'verb' => 'DELETE'],
29+
['name' => 'Endpoint#prepare', 'url' => '', 'verb' => 'POST'],
30+
['name' => 'Endpoint#tagFile', 'url' => '/tag-file', 'verb' => 'POST'],
2931
],
3032
];

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

+41
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,22 @@
2727

2828
use OCP\AppFramework\Http\DataResponse;
2929
use OCP\AppFramework\OCSController;
30+
use OCP\Files\IRootFolder;
3031
use OCP\IDBConnection;
3132
use OCP\IRequest;
33+
use OCP\SystemTag\ISystemTagManager;
34+
use OCP\SystemTag\ISystemTagObjectMapper;
35+
use OCP\SystemTag\TagNotFoundException;
3236

3337
class EndpointController extends OCSController {
3438
public function __construct(
3539
string $appName,
3640
IRequest $request,
3741
protected IDBConnection $db,
42+
protected ISystemTagManager $systemTagManager,
43+
protected ISystemTagObjectMapper $systemTagObjectMapper,
44+
protected IRootFolder $rootFolder,
45+
protected string $userId,
3846
) {
3947
parent::__construct($appName, $request);
4048
}
@@ -49,6 +57,39 @@ public function reset(): DataResponse {
4957
$query->delete('flow_operations')->executeStatement();
5058
$query->delete('flow_operations_scope')->executeStatement();
5159

60+
61+
try {
62+
$tag = $this->systemTagManager->getTag('files_accesscontrol_intergrationtest', true, true);
63+
$this->systemTagManager->deleteTags([$tag->getId()]);
64+
} catch (TagNotFoundException) {
65+
}
66+
67+
return new DataResponse();
68+
}
69+
70+
/**
71+
* @return DataResponse
72+
*/
73+
public function prepare(): DataResponse {
74+
try {
75+
$tag = $this->systemTagManager->getTag('files_accesscontrol_intergrationtest', true, true);
76+
} catch (TagNotFoundException) {
77+
$tag = $this->systemTagManager->createTag('files_accesscontrol_intergrationtest', true, true);
78+
}
79+
return new DataResponse(['tagId' => $tag->getId()]);
80+
}
81+
82+
/**
83+
* @NoAdminRequired
84+
* @return DataResponse
85+
*/
86+
public function tagFile(string $path): DataResponse {
87+
$tag = $this->systemTagManager->getTag('files_accesscontrol_intergrationtest', true, true);
88+
89+
$userFolder = $this->rootFolder->getUserFolder($this->userId);
90+
$node = $userFolder->get($path);
91+
$this->systemTagObjectMapper->assignTags((string)$node->getId(), 'files', [$tag->getId()]);
92+
5293
return new DataResponse();
5394
}
5495
}

tests/Integration/features/bootstrap/FeatureContext.php

+56-16
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ class FeatureContext implements Context {
5656
/** @var string */
5757
protected $baseUrl;
5858

59+
protected string $tagId = '';
60+
protected array $createdUsers = [];
61+
5962
/**
6063
* FeatureContext constructor.
6164
*/
@@ -69,29 +72,45 @@ public function __construct() {
6972
* @AfterScenario
7073
*/
7174
public function cleanUpBetweenTests() {
72-
// TODO: Remove all created tags?
7375
$this->setCurrentUser('admin');
7476
$this->sendingTo('DELETE', '/apps/files_accesscontrol_testing');
7577
$this->assertStatusCode($this->response, 200);
78+
}
7679

77-
try {
78-
$this->userDeletesFile('test1', 'folder', '/subdir');
79-
} catch (\Exception $e) {
80-
}
81-
try {
82-
$this->userDeletesFile('test1', 'file', '/foobar.txt');
83-
} catch (\Exception $e) {
84-
}
85-
try {
86-
$this->userDeletesFile('test1', 'file', '/definitely.notexe');
87-
} catch (\Exception $e) {
88-
}
89-
try {
90-
$this->emptyTrashbin('test1');
91-
} catch (\Exception $e) {
80+
/**
81+
* @AfterScenario
82+
*/
83+
public function tearDown() {
84+
foreach ($this->createdUsers as $user) {
85+
$this->deleteUser($user);
9286
}
9387
}
9488

89+
/**
90+
* @Given /^Ensure tag exists$/
91+
*/
92+
public function createTag() {
93+
$this->setCurrentUser('admin');
94+
$this->sendingTo('POST', '/apps/files_accesscontrol_testing');
95+
$this->assertStatusCode($this->response, 200);
96+
97+
$ocsData = json_decode($this->response->getBody()->getContents(), true, flags: JSON_THROW_ON_ERROR);
98+
$data = $ocsData['ocs']['data'];
99+
$this->tagId = $data['tagId'];
100+
}
101+
102+
/**
103+
* @Given /^user "([^"]*)" tags file "([^"]*)"$/
104+
*/
105+
public function tagFile(string $user, string $path) {
106+
// TODO: Remove all created tags?
107+
$this->setCurrentUser($user);
108+
$this->sendingToWith('POST', '/apps/files_accesscontrol_testing/tag-file', [
109+
'path' => $path,
110+
]);
111+
$this->assertStatusCode($this->response, 200);
112+
}
113+
95114
/**
96115
* @Given /^user "([^"]*)" creates (global|user) flow with (\d+)$/
97116
*/
@@ -103,6 +122,7 @@ public function createFlow(string $user, string $scope, int $statusCode, TableNo
103122
$checks = [];
104123
foreach ($formData as $key => $value) {
105124
if (strpos($key, 'checks-') === 0) {
125+
$value = str_replace('{{{FILES_ACCESSCONTROL_INTEGRATIONTEST_TAGID}}}', $this->tagId, $value);
106126
$checks[] = json_decode($value, true);
107127
unset($formData[$key]);
108128
}
@@ -209,6 +229,26 @@ private function createUser(string $user): void {
209229
];
210230
$client->get($userProvisioningUrl . '/' . $user, $options2);
211231

232+
$this->createdUsers[] = $user;
233+
$this->currentUser = $previous_user;
234+
}
235+
236+
private function deleteUser(string $user): void {
237+
$previous_user = $this->currentUser;
238+
$this->currentUser = 'admin';
239+
240+
$userProvisioningUrl = $this->baseUrl . 'ocs/v2.php/cloud/users/' . $user;
241+
$client = new Client();
242+
$options = [
243+
'auth' => ['admin', 'admin'],
244+
'headers' => [
245+
'OCS-APIREQUEST' => 'true',
246+
],
247+
];
248+
$client->delete($userProvisioningUrl, $options);
249+
250+
unset($this->createdUsers[$user]);
251+
212252
$this->currentUser = $previous_user;
213253
}
214254

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)