Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[stable29] feat(tests): Add integration test for file system tags #622

Merged
merged 1 commit into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions tests/Integration/app/appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,7 @@
return [
'ocs' => [
['name' => 'Endpoint#reset', 'url' => '', 'verb' => 'DELETE'],
['name' => 'Endpoint#prepare', 'url' => '', 'verb' => 'POST'],
['name' => 'Endpoint#tagFile', 'url' => '/tag-file', 'verb' => 'POST'],
],
];
41 changes: 41 additions & 0 deletions tests/Integration/app/lib/Controller/EndpointController.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,22 @@

use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCSController;
use OCP\Files\IRootFolder;
use OCP\IDBConnection;
use OCP\IRequest;
use OCP\SystemTag\ISystemTagManager;
use OCP\SystemTag\ISystemTagObjectMapper;
use OCP\SystemTag\TagNotFoundException;

class EndpointController extends OCSController {
public function __construct(
string $appName,
IRequest $request,
protected IDBConnection $db,
protected ISystemTagManager $systemTagManager,
protected ISystemTagObjectMapper $systemTagObjectMapper,
protected IRootFolder $rootFolder,
protected string $userId,
) {
parent::__construct($appName, $request);
}
Expand All @@ -49,6 +57,39 @@ public function reset(): DataResponse {
$query->delete('flow_operations')->executeStatement();
$query->delete('flow_operations_scope')->executeStatement();


try {
$tag = $this->systemTagManager->getTag('files_accesscontrol_intergrationtest', true, true);
$this->systemTagManager->deleteTags([$tag->getId()]);
} catch (TagNotFoundException) {
}

return new DataResponse();
}

/**
* @return DataResponse
*/
public function prepare(): DataResponse {
try {
$tag = $this->systemTagManager->getTag('files_accesscontrol_intergrationtest', true, true);
} catch (TagNotFoundException) {
$tag = $this->systemTagManager->createTag('files_accesscontrol_intergrationtest', true, true);
}
return new DataResponse(['tagId' => $tag->getId()]);
}

/**
* @NoAdminRequired
* @return DataResponse
*/
public function tagFile(string $path): DataResponse {
$tag = $this->systemTagManager->getTag('files_accesscontrol_intergrationtest', true, true);

$userFolder = $this->rootFolder->getUserFolder($this->userId);
$node = $userFolder->get($path);
$this->systemTagObjectMapper->assignTags((string)$node->getId(), 'files', [$tag->getId()]);

return new DataResponse();
}
}
72 changes: 56 additions & 16 deletions tests/Integration/features/bootstrap/FeatureContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ class FeatureContext implements Context {
/** @var string */
protected $baseUrl;

protected string $tagId = '';
protected array $createdUsers = [];

/**
* FeatureContext constructor.
*/
Expand All @@ -69,29 +72,45 @@ public function __construct() {
* @AfterScenario
*/
public function cleanUpBetweenTests() {
// TODO: Remove all created tags?
$this->setCurrentUser('admin');
$this->sendingTo('DELETE', '/apps/files_accesscontrol_testing');
$this->assertStatusCode($this->response, 200);
}

try {
$this->userDeletesFile('test1', 'folder', '/subdir');
} catch (\Exception $e) {
}
try {
$this->userDeletesFile('test1', 'file', '/foobar.txt');
} catch (\Exception $e) {
}
try {
$this->userDeletesFile('test1', 'file', '/definitely.notexe');
} catch (\Exception $e) {
}
try {
$this->emptyTrashbin('test1');
} catch (\Exception $e) {
/**
* @AfterScenario
*/
public function tearDown() {
foreach ($this->createdUsers as $user) {
$this->deleteUser($user);
}
}

/**
* @Given /^Ensure tag exists$/
*/
public function createTag() {
$this->setCurrentUser('admin');
$this->sendingTo('POST', '/apps/files_accesscontrol_testing');
$this->assertStatusCode($this->response, 200);

$ocsData = json_decode($this->response->getBody()->getContents(), true, flags: JSON_THROW_ON_ERROR);
$data = $ocsData['ocs']['data'];
$this->tagId = $data['tagId'];
}

/**
* @Given /^user "([^"]*)" tags file "([^"]*)"$/
*/
public function tagFile(string $user, string $path) {
// TODO: Remove all created tags?
$this->setCurrentUser($user);
$this->sendingToWith('POST', '/apps/files_accesscontrol_testing/tag-file', [
'path' => $path,
]);
$this->assertStatusCode($this->response, 200);
}

/**
* @Given /^user "([^"]*)" creates (global|user) flow with (\d+)$/
*/
Expand All @@ -103,6 +122,7 @@ public function createFlow(string $user, string $scope, int $statusCode, TableNo
$checks = [];
foreach ($formData as $key => $value) {
if (strpos($key, 'checks-') === 0) {
$value = str_replace('{{{FILES_ACCESSCONTROL_INTEGRATIONTEST_TAGID}}}', $this->tagId, $value);
$checks[] = json_decode($value, true);
unset($formData[$key]);
}
Expand Down Expand Up @@ -209,6 +229,26 @@ private function createUser(string $user): void {
];
$client->get($userProvisioningUrl . '/' . $user, $options2);

$this->createdUsers[] = $user;
$this->currentUser = $previous_user;
}

private function deleteUser(string $user): void {
$previous_user = $this->currentUser;
$this->currentUser = 'admin';

$userProvisioningUrl = $this->baseUrl . 'ocs/v2.php/cloud/users/' . $user;
$client = new Client();
$options = [
'auth' => ['admin', 'admin'],
'headers' => [
'OCS-APIREQUEST' => 'true',
],
];
$client->delete($userProvisioningUrl, $options);

unset($this->createdUsers[$user]);

$this->currentUser = $previous_user;
}

Expand Down
60 changes: 57 additions & 3 deletions tests/Integration/features/sharing-user.feature
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ Feature: Sharing user
When User "test2" deletes file "/subdir/foobar.txt"
Then The webdav response should have a status code "403"

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

Scenario: Share a file that is allowed by mimetype exludes
Scenario: Share a file that is allowed by mimetype excludes
Given User "test1" uploads file "data/nextcloud.pdf" to "/nextcloud2.pdf"
And The webdav response should have a status code "201"
And user "test1" shares file "/nextcloud2.pdf" with user "test2"
Expand All @@ -117,4 +117,58 @@ Feature: Sharing user
| checks-0 | {"class":"OCA\\WorkflowEngine\\Check\\FileMimeType", "operator": "!is", "value": "httpd/directory"} |
| checks-1 | {"class":"OCA\\WorkflowEngine\\Check\\FileMimeType", "operator": "!is", "value": "application/pdf"} |
And Downloading file "/nextcloud2.pdf" as "test2"
And The webdav response should have a status code "200"
And The webdav response should have a status code "200"

Scenario: Jailed storage cache bug blocking first
Given Ensure tag exists
Given User "test1" uploads file "data/textfile.txt" to "/nextcloud2.txt"
And The webdav response should have a status code "201"
Given User "test1" uploads file "data/textfile.txt" to "/nextcloud3.txt"
And The webdav response should have a status code "201"
And user "test1" shares file "/nextcloud2.txt" with user "test2"
And Downloading file "/nextcloud2.txt" as "test2"
And The webdav response should have a status code "200"
And user "test1" shares file "/nextcloud3.txt" with user "test2"
And Downloading file "/nextcloud3.txt" as "test2"
And The webdav response should have a status code "200"
And user "test1" tags file "/nextcloud2.txt"
When user "admin" creates global flow with 200
| name | Admin flow |
| class | OCA\FilesAccessControl\Operation |
| entity | OCA\WorkflowEngine\Entity\File |
| events | [] |
| operation | deny |
| checks-0 | {"class":"OCA\\WorkflowEngine\\Check\\FileSystemTags", "operator": "is", "value": "{{{FILES_ACCESSCONTROL_INTEGRATIONTEST_TAGID}}}"} |
Then Downloading file "/nextcloud2.txt" as "test2"
And The webdav response should have a status code "404"
And Downloading file "/nextcloud3.txt" as "test2"
And The webdav response should have a status code "200"
And user "test2" should see following elements
| /nextcloud3.txt |

Scenario: Jailed storage cache bug blocking last
Given Ensure tag exists
Given User "test1" uploads file "data/textfile.txt" to "/nextcloud2.txt"
And The webdav response should have a status code "201"
Given User "test1" uploads file "data/textfile.txt" to "/nextcloud3.txt"
And The webdav response should have a status code "201"
And user "test1" shares file "/nextcloud2.txt" with user "test2"
And Downloading file "/nextcloud2.txt" as "test2"
And The webdav response should have a status code "200"
And user "test1" shares file "/nextcloud3.txt" with user "test2"
And Downloading file "/nextcloud3.txt" as "test2"
And The webdav response should have a status code "200"
And user "test1" tags file "/nextcloud3.txt"
When user "admin" creates global flow with 200
| name | Admin flow |
| class | OCA\FilesAccessControl\Operation |
| entity | OCA\WorkflowEngine\Entity\File |
| events | [] |
| operation | deny |
| checks-0 | {"class":"OCA\\WorkflowEngine\\Check\\FileSystemTags", "operator": "is", "value": "{{{FILES_ACCESSCONTROL_INTEGRATIONTEST_TAGID}}}"} |
Then Downloading file "/nextcloud2.txt" as "test2"
And The webdav response should have a status code "200"
And Downloading file "/nextcloud3.txt" as "test2"
And The webdav response should have a status code "404"
And user "test2" should see following elements
| /nextcloud2.txt |
Loading