From: Ferdinand Thiessen Date: Sun, 29 Oct 2023 17:51:33 +0000 (+0100) Subject: fix(tests): Ensure ldap server can be reached in integration tests on GitHub Actions... X-Git-Tag: v29.0.0beta1~374^2~2 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=52cc18efc0baa916b23350fe5fbb0b0081af5def;p=nextcloud-server.git fix(tests): Ensure ldap server can be reached in integration tests on GitHub Actions and other improvments * Run integration tests for every pull request * Also print docker logs of service containers (ldap, redis) * Ensure consistent `datadir` for test assertions * Test openldap features separatly * Only the LDAP tests rely on `/dev/shm` while `federated.feature` rely on real directory access Signed-off-by: Ferdinand Thiessen --- diff --git a/.github/workflows/integration-sqlite.yml b/.github/workflows/integration-sqlite.yml index 036e8770830..66b654561a1 100644 --- a/.github/workflows/integration-sqlite.yml +++ b/.github/workflows/integration-sqlite.yml @@ -2,10 +2,6 @@ name: Integration sqlite on: pull_request: - paths: - # Only running on PR for this file to save CI time (otherwise pgsql only) - - '.github/workflows/integration-sqlite.yml' - push: branches: - main @@ -63,6 +59,8 @@ jobs: - 'federation_features' - '--tags ~@large files_features' - 'filesdrop_features' + - 'openldap_features' + - 'openldap_numerical_features' - 'ldap_features' - 'remoteapi_features' - 'setup_features' @@ -85,6 +83,8 @@ jobs: - 6379:6379 openldap: image: ghcr.io/nextcloud/continuous-integration-openldap:openldap-7 + ports: + - 389:389 env: SLAPD_DOMAIN: nextcloud.ci SLAPD_ORGANIZATION: Nextcloud @@ -129,15 +129,13 @@ jobs: run: composer i --no-dev - name: Set up Nextcloud - env: - DB_PORT: 4444 run: | mkdir data - ./occ maintenance:install --verbose --database=sqlite --database-name=nextcloud --database-host=127.0.0.1 --database-port=$DB_PORT --database-user=root --database-pass=rootpassword --admin-user admin --admin-pass admin + ./occ maintenance:install --verbose ${{ contains(matrix.test-suite,'ldap') && '--data-dir=/dev/shm/nc_int' || '' }} --database=sqlite --database-name=nextcloud --database-user=root --database-pass=rootpassword --admin-user admin --admin-pass admin ./occ config:system:set hashing_default_password --value=true --type=boolean - name: Configure caching - if: ${{ matrix.test-suite == 'ldap_features' }} + if: ${{ contains(matrix.test-suite,'ldap') }} run: | ./occ config:system:set redis host --value=localhost ./occ config:system:set redis port --value=6379 --type=integer @@ -147,12 +145,16 @@ jobs: - name: Run integration working-directory: build/integration + env: + LDAP_HOST: localhost run: bash run.sh ${{ matrix.test-suite }} no-tail-log - name: Print logs if: always() run: | cat data/nextcloud.log + docker ps -a + docker ps -aq | while read container ; do IMAGE=$(docker inspect --format='{{.Config.Image}}' $container); echo $IMAGE; docker logs $container; echo "\n\n" ; done summary: permissions: diff --git a/build/integration/config/behat.yml b/build/integration/config/behat.yml index 080752a3d6f..8401b841cdd 100644 --- a/build/integration/config/behat.yml +++ b/build/integration/config/behat.yml @@ -192,6 +192,26 @@ default: - admin - admin regular_user_password: 123456 + openldap_numerical: + paths: + - "%paths.base%/../openldap_numerical_features" + contexts: + - LDAPContext: + baseUrl: http://localhost:8080 + admin: + - admin + - admin + regular_user_password: 123456 + openldap: + paths: + - "%paths.base%/../openldap_features" + contexts: + - LDAPContext: + baseUrl: http://localhost:8080 + admin: + - admin + - admin + regular_user_password: 123456 remoteapi: paths: - "%paths.base%/../remoteapi_features" diff --git a/build/integration/features/bootstrap/LDAPContext.php b/build/integration/features/bootstrap/LDAPContext.php index e0315bce84e..fd4a448b5e9 100644 --- a/build/integration/features/bootstrap/LDAPContext.php +++ b/build/integration/features/bootstrap/LDAPContext.php @@ -104,7 +104,7 @@ class LDAPContext implements Context { $this->asAn('admin'); $this->creatingAnLDAPConfigurationAt('/apps/user_ldap/api/v1/config'); $data = new TableNode([ - ['configData[ldapHost]', 'openldap'], + ['configData[ldapHost]', getenv('LDAP_HOST') ?: 'openldap'], ['configData[ldapPort]', '389'], ['configData[ldapBase]', 'dc=nextcloud,dc=ci'], ['configData[ldapAgentName]', 'cn=admin,dc=nextcloud,dc=ci'], @@ -141,6 +141,9 @@ class LDAPContext implements Context { $this->asAn('admin'); $configData = $table->getRows(); foreach ($configData as &$row) { + if (str_contains($row[0], 'Host') && getenv('LDAP_HOST')) { + $row[1] = str_replace('openldap', getenv('LDAP_HOST'), $row[1]); + } $row[0] = 'configData[' . $row[0] . ']'; } $this->settingTheLDAPConfigurationTo(new TableNode($configData)); diff --git a/build/integration/ldap_features/openldap-numerical-id.feature b/build/integration/ldap_features/openldap-numerical-id.feature deleted file mode 100644 index 75eb6827192..00000000000 --- a/build/integration/ldap_features/openldap-numerical-id.feature +++ /dev/null @@ -1,96 +0,0 @@ -Feature: LDAP - Background: - Given using api version "2" - And having a valid LDAP configuration - And modify LDAP configuration - | ldapExpertUsernameAttr | employeeNumber | - | ldapLoginFilter | (&(objectclass=inetorgperson)(employeeNumber=%uid)) | - -# Those tests are dedicated to ensure Nc is working when it is provided with -# users having numerical IDs - -Scenario: Look for a expected LDAP users - Given As an "admin" - And sending "GET" to "/cloud/users" - Then the OCS status code should be "200" - And the "users" result should match - | 92379 | 1 | - | 50194 | 1 | - -Scenario: check default home of an LDAP user - Given As an "admin" - And sending "GET" to "/cloud/users/92379" - Then the OCS status code should be "200" - And the record's fields should match - | storageLocation | /dev/shm/nc_int/92379 | - -Scenario: Test by logging in - Given cookies are reset - And Logging in using web as "92379" - And Sending a "GET" to "/remote.php/webdav/welcome.txt" with requesttoken - Then the HTTP status code should be "200" - -Scenario: Test LDAP group retrieval with numeric group ids and nesting - # Nesting does not play a role here really - Given modify LDAP configuration - | ldapBaseGroups | ou=NumericGroups,dc=nextcloud,dc=ci | - | ldapGroupFilter | (objectclass=groupOfNames) | - | ldapGroupMemberAssocAttr | member | - | ldapNestedGroups | 1 | - | useMemberOfToDetectMembership | 1 | - And As an "admin" - And sending "GET" to "/cloud/groups" - Then the OCS status code should be "200" - And the "groups" result should match - | 2000 | 1 | - | 3000 | 1 | - | 3001 | 1 | - | 3002 | 1 | - -Scenario: Test LDAP group membership with intermediate groups not matching filter, numeric group ids - Given modify LDAP configuration - | ldapBaseGroups | ou=NumericGroups,dc=nextcloud,dc=ci | - | ldapGroupFilter | (&(cn=2000)(objectclass=groupOfNames)) | - | ldapNestedGroups | 1 | - | useMemberOfToDetectMembership | 1 | - | ldapUserFilter | (&(objectclass=inetorgperson)(!(uid=alice))) | - | ldapGroupMemberAssocAttr | member | - And As an "admin" - # for population - And sending "GET" to "/cloud/groups" - And sending "GET" to "/cloud/groups/2000/users" - Then the OCS status code should be "200" - And the "users" result should match - | 92379 | 0 | - | 54172 | 1 | - | 50194 | 1 | - | 59376 | 1 | - | 59463 | 1 | - -Scenario: Test LDAP admin group mapping, empowered user - Given modify LDAP configuration - | ldapBaseGroups | ou=NumericGroups,dc=nextcloud,dc=ci | - | ldapGroupFilter | (objectclass=groupOfNames) | - | ldapGroupMemberAssocAttr | member | - | ldapAdminGroup | 3001 | - | useMemberOfToDetectMembership | 1 | - And cookies are reset - # alice, part of the promoted group - And Logging in using web as "92379" - And sending "GET" to "/cloud/groups" - And sending "GET" to "/cloud/groups/2000/users" - And Sending a "GET" to "/index.php/settings/admin/overview" with requesttoken - Then the HTTP status code should be "200" - -Scenario: Test LDAP admin group mapping, regular user (no access) - Given modify LDAP configuration - | ldapBaseGroups | ou=NumericGroups,dc=nextcloud,dc=ci | - | ldapGroupFilter | (objectclass=groupOfNames) | - | ldapGroupMemberAssocAttr | member | - | ldapAdminGroup | 3001 | - | useMemberOfToDetectMembership | 1 | - And cookies are reset - # gustaf, not part of the promoted group - And Logging in using web as "59376" - And Sending a "GET" to "/index.php/settings/admin/overview" with requesttoken - Then the HTTP status code should be "403" diff --git a/build/integration/ldap_features/openldap-uid-username.feature b/build/integration/ldap_features/openldap-uid-username.feature deleted file mode 100644 index 6793273e8c7..00000000000 --- a/build/integration/ldap_features/openldap-uid-username.feature +++ /dev/null @@ -1,163 +0,0 @@ -Feature: LDAP - Background: - Given using api version "2" - And having a valid LDAP configuration - And modify LDAP configuration - | ldapExpertUsernameAttr | uid | - - Scenario: Look for a expected LDAP users - Given As an "admin" - And sending "GET" to "/cloud/users" - Then the OCS status code should be "200" - And the "users" result should match - | alice | 1 | - | elisa | 1 | - | ghost | 0 | - - Scenario: check default home of an LDAP user - Given As an "admin" - And sending "GET" to "/cloud/users/alice" - Then the OCS status code should be "200" - And the record's fields should match - | storageLocation | /dev/shm/nc_int/alice | - - Scenario: check custom relative home of an LDAP user - Given modify LDAP configuration - | homeFolderNamingRule | sn | - And As an "admin" - And sending "GET" to "/cloud/users/alice" - Then the OCS status code should be "200" - And the record's fields should match - | storageLocation | /dev/shm/nc_int/Alfgeirdottir | - - Scenario: check custom absolute home of an LDAP user - Given modify LDAP configuration - | homeFolderNamingRule | roomNumber | - And As an "admin" - And sending "GET" to "/cloud/users/elisa" - Then the OCS status code should be "200" - And the record's fields should match - | storageLocation | /dev/shm/elisa-data | - - Scenario: Fetch all users, invoking pagination - Given modify LDAP configuration - | ldapBaseUsers | ou=PagingTest,dc=nextcloud,dc=ci | - | ldapPagingSize | 2 | - And As an "admin" - And sending "GET" to "/cloud/users" - Then the OCS status code should be "200" - And the "users" result should match - | ebba | 1 | - | eindis | 1 | - | fjolnir | 1 | - | gunna | 1 | - | juliana | 1 | - | leo | 1 | - | stigur | 1 | - - Scenario: Fetch all users, invoking pagination - Given modify LDAP configuration - | ldapBaseUsers | ou=PagingTest,dc=nextcloud,dc=ci | - | ldapPagingSize | 2 | - And As an "admin" - And sending "GET" to "/cloud/users?limit=10" - Then the OCS status code should be "200" - And the "users" result should match - | ebba | 1 | - | eindis | 1 | - | fjolnir | 1 | - | gunna | 1 | - | juliana | 1 | - | leo | 1 | - | stigur | 1 | - - Scenario: Fetch from second batch of all users, invoking pagination - Given modify LDAP configuration - | ldapBaseUsers | ou=PagingTest,dc=nextcloud,dc=ci | - | ldapPagingSize | 2 | - And As an "admin" - And sending "GET" to "/cloud/users?limit=10&offset=2" - Then the OCS status code should be "200" - And the "users" result should contain "5" of - | ebba | - | eindis | - | fjolnir | - | gunna | - | juliana | - | leo | - | stigur | - - Scenario: Fetch from second batch of all users, invoking pagination with two bases - Given modify LDAP configuration - | ldapBaseUsers | ou=PagingTest,dc=nextcloud,dc=ci;ou=PagingTestSecondBase,dc=nextcloud,dc=ci | - | ldapPagingSize | 2 | - And As an "admin" - And sending "GET" to "/cloud/users?limit=10&offset=2" - Then the OCS status code should be "200" - And the "users" result should contain "5" of - | ebba | - | eindis | - | fjolnir | - | gunna | - | juliana | - | leo | - | stigur | - And the "users" result should contain "3" of - | allisha | - | dogukan | - | lloyd | - | priscilla | - | shannah | - - Scenario: Fetch from second batch of all users, invoking pagination with two bases, third page - Given modify LDAP configuration - | ldapBaseUsers | ou=PagingTest,dc=nextcloud,dc=ci;ou=PagingTestSecondBase,dc=nextcloud,dc=ci | - | ldapPagingSize | 2 | - And As an "admin" - And sending "GET" to "/cloud/users?limit=10&offset=4" - Then the OCS status code should be "200" - And the "users" result should contain "3" of - | ebba | - | eindis | - | fjolnir | - | gunna | - | juliana | - | leo | - | stigur | - And the "users" result should contain "1" of - | allisha | - | dogukan | - | lloyd | - | priscilla | - | shannah | - - Scenario: Deleting an unavailable LDAP user - Given As an "admin" - And sending "GET" to "/cloud/users" - And modify LDAP configuration - | ldapUserFilter | (&(objectclass=inetorgperson)(!(uid=alice))) | - And invoking occ with "ldap:check-user alice" - And the command output contains the text "Clean up the user's remnants by" - And invoking occ with "user:delete alice" - Then the command output contains the text "The specified user was deleted" - - Scenario: Search only with group members - allowed - Given modify LDAP configuration - | ldapGroupFilter | cn=Orcharding | - | ldapGroupMemberAssocAttr | member | - | ldapBaseGroups | ou=OtherGroups,dc=nextcloud,dc=ci | - | ldapAttributesForUserSearch | employeeNumber | - | useMemberOfToDetectMembership | 1 | - And parameter "shareapi_only_share_with_group_members" of app "core" is set to "yes" - And As an "alice" - When getting sharees for - # "5" is part of the employee number of some LDAP records - | search | 5 | - | itemType | file | - Then the OCS status code should be "200" - And the HTTP status code should be "200" - And "exact users" sharees returned is empty - And "users" sharees returned are - | Elisa | 0 | elisa | - And "exact groups" sharees returned is empty - diff --git a/build/integration/openldap_features/openldap-uid-username.feature b/build/integration/openldap_features/openldap-uid-username.feature new file mode 100644 index 00000000000..6793273e8c7 --- /dev/null +++ b/build/integration/openldap_features/openldap-uid-username.feature @@ -0,0 +1,163 @@ +Feature: LDAP + Background: + Given using api version "2" + And having a valid LDAP configuration + And modify LDAP configuration + | ldapExpertUsernameAttr | uid | + + Scenario: Look for a expected LDAP users + Given As an "admin" + And sending "GET" to "/cloud/users" + Then the OCS status code should be "200" + And the "users" result should match + | alice | 1 | + | elisa | 1 | + | ghost | 0 | + + Scenario: check default home of an LDAP user + Given As an "admin" + And sending "GET" to "/cloud/users/alice" + Then the OCS status code should be "200" + And the record's fields should match + | storageLocation | /dev/shm/nc_int/alice | + + Scenario: check custom relative home of an LDAP user + Given modify LDAP configuration + | homeFolderNamingRule | sn | + And As an "admin" + And sending "GET" to "/cloud/users/alice" + Then the OCS status code should be "200" + And the record's fields should match + | storageLocation | /dev/shm/nc_int/Alfgeirdottir | + + Scenario: check custom absolute home of an LDAP user + Given modify LDAP configuration + | homeFolderNamingRule | roomNumber | + And As an "admin" + And sending "GET" to "/cloud/users/elisa" + Then the OCS status code should be "200" + And the record's fields should match + | storageLocation | /dev/shm/elisa-data | + + Scenario: Fetch all users, invoking pagination + Given modify LDAP configuration + | ldapBaseUsers | ou=PagingTest,dc=nextcloud,dc=ci | + | ldapPagingSize | 2 | + And As an "admin" + And sending "GET" to "/cloud/users" + Then the OCS status code should be "200" + And the "users" result should match + | ebba | 1 | + | eindis | 1 | + | fjolnir | 1 | + | gunna | 1 | + | juliana | 1 | + | leo | 1 | + | stigur | 1 | + + Scenario: Fetch all users, invoking pagination + Given modify LDAP configuration + | ldapBaseUsers | ou=PagingTest,dc=nextcloud,dc=ci | + | ldapPagingSize | 2 | + And As an "admin" + And sending "GET" to "/cloud/users?limit=10" + Then the OCS status code should be "200" + And the "users" result should match + | ebba | 1 | + | eindis | 1 | + | fjolnir | 1 | + | gunna | 1 | + | juliana | 1 | + | leo | 1 | + | stigur | 1 | + + Scenario: Fetch from second batch of all users, invoking pagination + Given modify LDAP configuration + | ldapBaseUsers | ou=PagingTest,dc=nextcloud,dc=ci | + | ldapPagingSize | 2 | + And As an "admin" + And sending "GET" to "/cloud/users?limit=10&offset=2" + Then the OCS status code should be "200" + And the "users" result should contain "5" of + | ebba | + | eindis | + | fjolnir | + | gunna | + | juliana | + | leo | + | stigur | + + Scenario: Fetch from second batch of all users, invoking pagination with two bases + Given modify LDAP configuration + | ldapBaseUsers | ou=PagingTest,dc=nextcloud,dc=ci;ou=PagingTestSecondBase,dc=nextcloud,dc=ci | + | ldapPagingSize | 2 | + And As an "admin" + And sending "GET" to "/cloud/users?limit=10&offset=2" + Then the OCS status code should be "200" + And the "users" result should contain "5" of + | ebba | + | eindis | + | fjolnir | + | gunna | + | juliana | + | leo | + | stigur | + And the "users" result should contain "3" of + | allisha | + | dogukan | + | lloyd | + | priscilla | + | shannah | + + Scenario: Fetch from second batch of all users, invoking pagination with two bases, third page + Given modify LDAP configuration + | ldapBaseUsers | ou=PagingTest,dc=nextcloud,dc=ci;ou=PagingTestSecondBase,dc=nextcloud,dc=ci | + | ldapPagingSize | 2 | + And As an "admin" + And sending "GET" to "/cloud/users?limit=10&offset=4" + Then the OCS status code should be "200" + And the "users" result should contain "3" of + | ebba | + | eindis | + | fjolnir | + | gunna | + | juliana | + | leo | + | stigur | + And the "users" result should contain "1" of + | allisha | + | dogukan | + | lloyd | + | priscilla | + | shannah | + + Scenario: Deleting an unavailable LDAP user + Given As an "admin" + And sending "GET" to "/cloud/users" + And modify LDAP configuration + | ldapUserFilter | (&(objectclass=inetorgperson)(!(uid=alice))) | + And invoking occ with "ldap:check-user alice" + And the command output contains the text "Clean up the user's remnants by" + And invoking occ with "user:delete alice" + Then the command output contains the text "The specified user was deleted" + + Scenario: Search only with group members - allowed + Given modify LDAP configuration + | ldapGroupFilter | cn=Orcharding | + | ldapGroupMemberAssocAttr | member | + | ldapBaseGroups | ou=OtherGroups,dc=nextcloud,dc=ci | + | ldapAttributesForUserSearch | employeeNumber | + | useMemberOfToDetectMembership | 1 | + And parameter "shareapi_only_share_with_group_members" of app "core" is set to "yes" + And As an "alice" + When getting sharees for + # "5" is part of the employee number of some LDAP records + | search | 5 | + | itemType | file | + Then the OCS status code should be "200" + And the HTTP status code should be "200" + And "exact users" sharees returned is empty + And "users" sharees returned are + | Elisa | 0 | elisa | + And "exact groups" sharees returned is empty + diff --git a/build/integration/openldap_numerical_features/openldap-numerical-id.feature b/build/integration/openldap_numerical_features/openldap-numerical-id.feature new file mode 100644 index 00000000000..75eb6827192 --- /dev/null +++ b/build/integration/openldap_numerical_features/openldap-numerical-id.feature @@ -0,0 +1,96 @@ +Feature: LDAP + Background: + Given using api version "2" + And having a valid LDAP configuration + And modify LDAP configuration + | ldapExpertUsernameAttr | employeeNumber | + | ldapLoginFilter | (&(objectclass=inetorgperson)(employeeNumber=%uid)) | + +# Those tests are dedicated to ensure Nc is working when it is provided with +# users having numerical IDs + +Scenario: Look for a expected LDAP users + Given As an "admin" + And sending "GET" to "/cloud/users" + Then the OCS status code should be "200" + And the "users" result should match + | 92379 | 1 | + | 50194 | 1 | + +Scenario: check default home of an LDAP user + Given As an "admin" + And sending "GET" to "/cloud/users/92379" + Then the OCS status code should be "200" + And the record's fields should match + | storageLocation | /dev/shm/nc_int/92379 | + +Scenario: Test by logging in + Given cookies are reset + And Logging in using web as "92379" + And Sending a "GET" to "/remote.php/webdav/welcome.txt" with requesttoken + Then the HTTP status code should be "200" + +Scenario: Test LDAP group retrieval with numeric group ids and nesting + # Nesting does not play a role here really + Given modify LDAP configuration + | ldapBaseGroups | ou=NumericGroups,dc=nextcloud,dc=ci | + | ldapGroupFilter | (objectclass=groupOfNames) | + | ldapGroupMemberAssocAttr | member | + | ldapNestedGroups | 1 | + | useMemberOfToDetectMembership | 1 | + And As an "admin" + And sending "GET" to "/cloud/groups" + Then the OCS status code should be "200" + And the "groups" result should match + | 2000 | 1 | + | 3000 | 1 | + | 3001 | 1 | + | 3002 | 1 | + +Scenario: Test LDAP group membership with intermediate groups not matching filter, numeric group ids + Given modify LDAP configuration + | ldapBaseGroups | ou=NumericGroups,dc=nextcloud,dc=ci | + | ldapGroupFilter | (&(cn=2000)(objectclass=groupOfNames)) | + | ldapNestedGroups | 1 | + | useMemberOfToDetectMembership | 1 | + | ldapUserFilter | (&(objectclass=inetorgperson)(!(uid=alice))) | + | ldapGroupMemberAssocAttr | member | + And As an "admin" + # for population + And sending "GET" to "/cloud/groups" + And sending "GET" to "/cloud/groups/2000/users" + Then the OCS status code should be "200" + And the "users" result should match + | 92379 | 0 | + | 54172 | 1 | + | 50194 | 1 | + | 59376 | 1 | + | 59463 | 1 | + +Scenario: Test LDAP admin group mapping, empowered user + Given modify LDAP configuration + | ldapBaseGroups | ou=NumericGroups,dc=nextcloud,dc=ci | + | ldapGroupFilter | (objectclass=groupOfNames) | + | ldapGroupMemberAssocAttr | member | + | ldapAdminGroup | 3001 | + | useMemberOfToDetectMembership | 1 | + And cookies are reset + # alice, part of the promoted group + And Logging in using web as "92379" + And sending "GET" to "/cloud/groups" + And sending "GET" to "/cloud/groups/2000/users" + And Sending a "GET" to "/index.php/settings/admin/overview" with requesttoken + Then the HTTP status code should be "200" + +Scenario: Test LDAP admin group mapping, regular user (no access) + Given modify LDAP configuration + | ldapBaseGroups | ou=NumericGroups,dc=nextcloud,dc=ci | + | ldapGroupFilter | (objectclass=groupOfNames) | + | ldapGroupMemberAssocAttr | member | + | ldapAdminGroup | 3001 | + | useMemberOfToDetectMembership | 1 | + And cookies are reset + # gustaf, not part of the promoted group + And Logging in using web as "59376" + And Sending a "GET" to "/index.php/settings/admin/overview" with requesttoken + Then the HTTP status code should be "403"