From 1b8b911b638efdc673e0bbb48c3f50bebb1eea70 Mon Sep 17 00:00:00 2001 From: Viktor Scharf Date: Fri, 12 Jul 2024 14:41:16 +0200 Subject: [PATCH] list Invitation --- docs/ocis/development/testing.md | 4 +- tests/TestHelpers/OcmHelper.php | 26 ++- tests/acceptance/config/behat.yml | 1 + ...ected-failures-localAPI-on-OCIS-storage.md | 3 + .../features/apiOcm/acceptInvitation.feature | 99 ++++++----- .../features/apiOcm/createInvitation.feature | 168 ++++++++++++++++++ .../acceptance/features/apiOcm/share.feature | 4 +- .../features/bootstrap/OcmContext.php | 64 ++++++- 8 files changed, 316 insertions(+), 53 deletions(-) create mode 100755 tests/acceptance/features/apiOcm/createInvitation.feature diff --git a/docs/ocis/development/testing.md b/docs/ocis/development/testing.md index b252bba26f..933c6969fe 100644 --- a/docs/ocis/development/testing.md +++ b/docs/ocis/development/testing.md @@ -561,7 +561,7 @@ OCM_OCM_INVITE_MANAGER_INSECURE=true \ OCM_OCM_SHARE_PROVIDER_INSECURE=true \ OCM_OCM_STORAGE_PROVIDER_INSECURE=true \ OCM_OCM_PROVIDER_AUTHORIZER_PROVIDERS_FILE="${workspaceFolder}/tests/config/drone/providers.json" \ -OCIS_ADD_RUN_SERVICES="ocm" +OCIS_ADD_RUN_SERVICES="ocm" \ ocis/bin/ocis server ``` @@ -587,7 +587,7 @@ To enable ocm in the web interface, you need to set the following envs: `FRONTEND_OCS_INCLUDE_OCM_SHAREES=true` \ `FRONTEND_OCS_LIST_OCM_SHARES=true` \ `FRONTEND_ENABLE_FEDERATED_SHARING_INCOMING=true` \ -`FRONTEND_ENABLE_FEDERATED_SHARING_OUTGOING=true` +`FRONTEND_ENABLE_FEDERATED_SHARING_OUTGOING=true` \ and put `ocm` to apps https://github.com/owncloud/ocis/blob/master/services/web/pkg/config/defaults/defaultconfig.go#L101 {{< /hint>}} diff --git a/tests/TestHelpers/OcmHelper.php b/tests/TestHelpers/OcmHelper.php index d06fa8a66c..045372b398 100644 --- a/tests/TestHelpers/OcmHelper.php +++ b/tests/TestHelpers/OcmHelper.php @@ -9,7 +9,6 @@ namespace TestHelpers; use GuzzleHttp\Exception\GuzzleException; -use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; /** @@ -132,4 +131,29 @@ class OcmHelper { self::getRequestHeaders() ); } + + /** + * @param string $baseUrl + * @param string $xRequestId + * @param string $user + * @param string $password + * + * @return ResponseInterface + * @throws GuzzleException + */ + public static function listInvite( + string $baseUrl, + string $xRequestId, + string $user, + string $password + ): ResponseInterface { + $url = self::getFullUrl($baseUrl, 'list-invite'); + return HttpRequestHelper::get( + $url, + $xRequestId, + $user, + $password, + self::getRequestHeaders() + ); + } } diff --git a/tests/acceptance/config/behat.yml b/tests/acceptance/config/behat.yml index cb965fe6ca..3a831670d5 100644 --- a/tests/acceptance/config/behat.yml +++ b/tests/acceptance/config/behat.yml @@ -389,6 +389,7 @@ default: - OcmContext: - SharingNgContext: - SpacesContext: + - OcisConfigContext: cliCommands: paths: diff --git a/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md b/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md index 38a031f2ec..5623d3e42e 100644 --- a/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md +++ b/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md @@ -312,5 +312,8 @@ The expected failures in this file are from features in the owncloud/ocis repo. - [apiOcm/share.feature:12](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiOcm/share.feature#L12) - [apiOcm/share.feature:91](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiOcm/share.feature#L91) +### [OCM. user cannot see invite description and inviteUser email](https://github.com/owncloud/ocis/issues/9591) + +- [apiOcm/createInvitation.feature:63](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiOcm/createInvitation.feature#L63) - Note: always have an empty line at the end of this file. The bash script that processes this file requires that the last line has a newline on the end. diff --git a/tests/acceptance/features/apiOcm/acceptInvitation.feature b/tests/acceptance/features/apiOcm/acceptInvitation.feature index 8cece5525c..315f23dd09 100755 --- a/tests/acceptance/features/apiOcm/acceptInvitation.feature +++ b/tests/acceptance/features/apiOcm/acceptInvitation.feature @@ -14,28 +14,7 @@ Feature: accepting invitation Scenario: user accepts invitation Given using server "LOCAL" - When "Alice" creates the federation share invitation - Then the HTTP status code should be "200" - And the JSON data of the response should match - """ - { - "type": "object", - "required": [ - "expiration", - "token" - ], - "properties": { - "expiration": { - "type": "integer", - "pattern": "^[0-9]{10}$" - }, - "token": { - "type": "string", - "pattern": "^%fed_invitation_token_pattern%$" - } - } - } - """ + And "Alice" has created the federation share invitation When using server "REMOTE" And "Brian" accepts the last federation share invitation Then the HTTP status code should be "200" @@ -43,28 +22,7 @@ Feature: accepting invitation Scenario: user accepts invitation sent with email and description Given using server "LOCAL" - When "Alice" creates the federation share invitation with email "alice@example.com" and description "a share invitation from Alice" - Then the HTTP status code should be "200" - And the JSON data of the response should match - """ - { - "type": "object", - "required": [ - "expiration", - "token" - ], - "properties": { - "expiration": { - "type": "integer", - "pattern": "^[0-9]{10}$" - }, - "token": { - "type": "string", - "pattern": "^%fed_invitation_token_pattern%$" - } - } - } - """ + And "Alice" has created the federation share invitation with email "brian@example.com" and description "a share invitation from Alice" When using server "REMOTE" And "Brian" accepts the last federation share invitation Then the HTTP status code should be "200" @@ -135,3 +93,56 @@ Feature: accepting invitation } } """ + + @env-config + Scenario: user cannot accept expired invitation tokens + Given using server "LOCAL" + And the config "OCM_OCM_INVITE_MANAGER_TOKEN_EXPIRATION" has been set to "1s" + And "Alice" has created the federation share invitation + When using server "REMOTE" + And the user waits "2" seconds for the token to expire + And "Brian" tries to accept the last federation share invitation + Then the HTTP status code should be "400" + And the JSON data of the response should match + """ + { + "type": "object", + "required": [ + "code", + "message" + ], + "properties": { + "code": { + "const": "INVALID_PARAMETER" + }, + "message": { + "const": "token has expired" + } + } + } + """ + + + Scenario: user cannot accept invalid invitation token + Given using server "LOCAL" + And "Alice" tries to accept the invitation with invalid token + Then the HTTP status code should be "404" + And the JSON data of the response should match + """ + { + "type": "object", + "required": [ + "code", + "message" + ], + "properties": { + "code": { + "const": "RESOURCE_NOT_FOUND" + }, + "message": { + "const": "token not found" + } + } + } + """ + diff --git a/tests/acceptance/features/apiOcm/createInvitation.feature b/tests/acceptance/features/apiOcm/createInvitation.feature new file mode 100755 index 0000000000..f2689d5702 --- /dev/null +++ b/tests/acceptance/features/apiOcm/createInvitation.feature @@ -0,0 +1,168 @@ +@ocm +Feature: create invitation + As a user + I can create an invitations and send it to the person I want to share with + + Background: + Given user "Alice" has been created with default attributes and without skeleton files + + + Scenario: user creates invitation + Given using server "LOCAL" + When "Alice" creates the federation share invitation + Then the HTTP status code should be "200" + And the JSON data of the response should match + """ + { + "type": "object", + "required": [ + "expiration", + "token" + ], + "properties": { + "expiration": { + "type": "integer", + "pattern": "^[0-9]{10}$" + }, + "token": { + "type": "string", + "pattern": "^%fed_invitation_token_pattern%$" + } + } + } + """ + When "Alice" lists the created invitations + Then the HTTP status code should be "200" + And the JSON data of the response should match + """ + { + "type": "array", + "minItems": 1, + "maxItems": 1, + "items": { + "type": "object", + "required": [ + "expiration", + "token" + ], + "properties": { + "expiration": { + "type": "integer", + "pattern": "^[0-9]{10}$" + }, + "token": { + "type": "string", + "pattern": "^%fed_invitation_token_pattern%$" + } + } + } + } + """ + + @issue-9591 + Scenario: user creates invitation with email and description + Given using server "LOCAL" + When "Alice" creates the federation share invitation with email "brian@example.com" and description "a share invitation from Alice" + Then the HTTP status code should be "200" + And the JSON data of the response should match + """ + { + "type": "object", + "required": [ + "expiration", + "token", + "description", + "recipient" + ], + "properties": { + "expiration": { + "type": "integer", + "pattern": "^[0-9]{10}$" + }, + "token": { + "type": "string", + "pattern": "^%fed_invitation_token_pattern%$" + }, + "description": { + "type": "string", + "const": "a share invitation from Alice" + }, + "recipient": { + "type": "string", + "const": "brian@example.com" + } + } + } + """ + And the HTTP status code should be "200" + And the JSON data of the response should match + """ + { + "type": "array", + "minItems": 1, + "maxItems": 1, + "items": { + "type": "object", + "required": [ + "expiration", + "token" + ], + "properties": { + "expiration": { + "type": "integer", + "pattern": "^[0-9]{10}$" + }, + "token": { + "type": "string", + "pattern": "^%fed_invitation_token_pattern%$" + }, + "description": { + "type": "string", + "const": "a share invitation from Alice" + }, + "recipient": { + "type": "string", + "const": "brian@example.com" + } + } + } + } + """ + + @env-config + Scenario: user cannot see expired invitation tokens + Given using server "LOCAL" + And the config "OCM_OCM_INVITE_MANAGER_TOKEN_EXPIRATION" has been set to "1s" + When "Alice" creates the federation share invitation + Then the HTTP status code should be "200" + And the JSON data of the response should match + """ + { + "type": "object", + "required": [ + "expiration", + "token" + ], + "properties": { + "expiration": { + "type": "integer", + "pattern": "^[0-9]{10}$" + }, + "token": { + "type": "string", + "pattern": "^%fed_invitation_token_pattern%$" + } + } + } + """ + And the user waits "2" seconds for the token to expire + When "Alice" lists the created invitations + Then the HTTP status code should be "200" + And the JSON data of the response should match + """ + { + "type": "array", + "minItems": 0, + "maxItems": 0 + } + """ \ No newline at end of file diff --git a/tests/acceptance/features/apiOcm/share.feature b/tests/acceptance/features/apiOcm/share.feature index 560bcb74a9..028f133ff6 100755 --- a/tests/acceptance/features/apiOcm/share.feature +++ b/tests/acceptance/features/apiOcm/share.feature @@ -8,7 +8,7 @@ Feature: an user shares resources usin ScienceMesh application And using server "REMOTE" And user "Brian" has been created with default attributes and without skeleton files - + @issue-9534 Scenario: users shares folder to federation users after receiver accepted invitation Given using server "LOCAL" And "Alice" has created the federation share invitation @@ -87,7 +87,7 @@ Feature: an user shares resources usin ScienceMesh application } """ - + @issue-9534 Scenario: users shares folder to federation users after accepting invitation Given using server "LOCAL" And "Alice" has created the federation share invitation diff --git a/tests/acceptance/features/bootstrap/OcmContext.php b/tests/acceptance/features/bootstrap/OcmContext.php index b38ffba1af..7447d7ab24 100644 --- a/tests/acceptance/features/bootstrap/OcmContext.php +++ b/tests/acceptance/features/bootstrap/OcmContext.php @@ -25,6 +25,7 @@ use GuzzleHttp\Exception\GuzzleException; use Psr\Http\Message\ResponseInterface; use TestHelpers\OcisHelper; use TestHelpers\OcmHelper; +use TestHelpers\WebDavHelper; /** * Acceptance test steps related to testing federation share(ocm) features @@ -122,31 +123,35 @@ class OcmContext implements Context { /** * @Given :user has created the federation share invitation + * @Given :user has created the federation share invitation with email :email and description :description * * @param string $user + * @param string $email + * @param string $description * * @return void * @throws GuzzleException */ - public function userHasCreatedTheFederationShareInvitation(string $user): void { - $response = $this->createInvitation($user); + public function userHasCreatedTheFederationShareInvitation(string $user, $email = null, $description = null): void { + $response = $this->createInvitation($user, $email, $description); $this->featureContext->theHTTPStatusCodeShouldBe(200, '', $response); } /** * @param string $user + * @param string $token * * @return ResponseInterface * @throws GuzzleException */ - public function acceptInvitation(string $user): ResponseInterface { + public function acceptInvitation(string $user, string $token = null): ResponseInterface { $providerDomain = ($this->featureContext->getCurrentServer() === "LOCAL") ? $this->getFedOcisDomain() : $this->getOcisDomain(); return OcmHelper::acceptInvitation( $this->featureContext->getBaseUrl(), $this->featureContext->getStepLineRef(), $user, $this->featureContext->getPasswordForUser($user), - $this->invitationToken, + $token ? $token : $this->invitationToken, $providerDomain ); } @@ -164,6 +169,18 @@ class OcmContext implements Context { $this->featureContext->setResponse($this->acceptInvitation($user)); } + /** + * @When :user tries to accept the invitation with invalid token + * + * @param string $user + * + * @return void + * @throws GuzzleException + */ + public function userTriesToAcceptInvitationWithInvalidToken(string $user): void { + $this->featureContext->setResponse($this->acceptInvitation($user, WebDavHelper::generateUUIDv4())); + } + /** * @Given :user has accepted invitation * @@ -203,4 +220,43 @@ class OcmContext implements Context { public function userFindsAcceptedUsers(string $user): void { $this->featureContext->setResponse($this->findAcceptedUsers($user)); } + + /** + * @param string $user + * + * @return ResponseInterface + * @throws GuzzleException + */ + public function listInvitations(string $user): ResponseInterface { + return OcmHelper::listInvite( + $this->featureContext->getBaseUrl(), + $this->featureContext->getStepLineRef(), + $user, + $this->featureContext->getPasswordForUser($user) + ); + } + + /** + * @When :user lists the created invitations + * + * @param string $user + * + * @return void + * @throws GuzzleException + */ + public function userListsCreatedInvitations(string $user): void { + $this->featureContext->setResponse($this->listInvitations($user)); + } + + /** + * @When the user waits :number seconds for the token to expire + * + * @param int $number + * + * @return void + * @throws GuzzleException + */ + public function theUserWaitsForTokenToExpire(int $number): void { + \sleep($number); + } }