diff --git a/.drone.star b/.drone.star index e8b94a5c0..173846e9a 100644 --- a/.drone.star +++ b/.drone.star @@ -321,7 +321,7 @@ config = { 'federatedServerNeeded': True, 'filterTags': '~@skip&&~@app-required', 'runAllSuites': True, - 'numberOfParts': 29, + 'numberOfParts': 21, 'extraSetup': [ { 'name': 'configure-app', @@ -370,7 +370,7 @@ config = { 'federatedServerNeeded': True, 'filterTags': '~@skip&&~@app-required', 'runAllSuites': True, - 'numberOfParts': 29, + 'numberOfParts': 21, 'cron': 'nightly', 'extraSetup': [ { @@ -560,7 +560,7 @@ config = { 'federatedServerNeeded': True, 'cron': 'nightly', 'runAllSuites': True, - 'numberOfParts': 29, + 'numberOfParts': 21, 'extraApps': { 'encryption': '' }, @@ -739,7 +739,7 @@ config = { 'federatedServerNeeded': True, 'cron': 'nightly', 'runAllSuites': True, - 'numberOfParts': 29, + 'numberOfParts': 21, 'extraApps': { 'encryption': '' }, @@ -927,8 +927,7 @@ config = { } def main(ctx): - - before = beforePipelines() + before = beforePipelines(ctx) coverageTests = coveragePipelines(ctx) if (coverageTests == False): @@ -937,6 +936,13 @@ def main(ctx): dependsOn(before, coverageTests) + nonCoverageTests = nonCoveragePipelines(ctx) + if (nonCoverageTests == False): + print('Errors detected in nonCoveragePipelines. Review messages above.') + return [] + + dependsOn(before, nonCoverageTests) + stages = stagePipelines(ctx) if (stages == False): print('Errors detected. Review messages above.') @@ -951,26 +957,36 @@ def main(ctx): dependsOn(coverageTests, afterCoverageTests) after = afterPipelines(ctx) - dependsOn(afterCoverageTests + stages, after) + dependsOn(afterCoverageTests + nonCoverageTests + stages, after) - return before + coverageTests + afterCoverageTests + stages + after + return before + coverageTests + afterCoverageTests + nonCoverageTests + stages + after -def beforePipelines(): - return codestyle() + jscodestyle() + phpstan() + phan() +def beforePipelines(ctx): + return codestyle(ctx) + jscodestyle(ctx) + phpstan(ctx) + phan(ctx) def coveragePipelines(ctx): - # All pipelines that might have coverage or other test analysis reported - jsPipelines = javascript(ctx) - phpUnitPipelines = phpTests(ctx, 'phpunit') - phpIntegrationPipelines = phpTests(ctx, 'phpintegration') + # All unit test pipelines that have coverage or other test analysis reported + jsPipelines = javascript(ctx, True) + phpUnitPipelines = phpTests(ctx, 'phpunit', True) + phpIntegrationPipelines = phpTests(ctx, 'phpintegration', True) + if (jsPipelines == False) or (phpUnitPipelines == False) or (phpIntegrationPipelines == False): + return False + + return jsPipelines + phpUnitPipelines + phpIntegrationPipelines + +def nonCoveragePipelines(ctx): + # All unit test pipelines that do not have coverage or other test analysis reported + jsPipelines = javascript(ctx, False) + phpUnitPipelines = phpTests(ctx, 'phpunit', False) + phpIntegrationPipelines = phpTests(ctx, 'phpintegration', False) if (jsPipelines == False) or (phpUnitPipelines == False) or (phpIntegrationPipelines == False): return False return jsPipelines + phpUnitPipelines + phpIntegrationPipelines def stagePipelines(ctx): - buildPipelines = build() - ldapIntegrationPipelines = ldapIntegration() + buildPipelines = build(ctx) + ldapIntegrationPipelines = ldapIntegration(ctx) acceptancePipelines = acceptance(ctx) if (buildPipelines == False) or (acceptancePipelines == False) or (ldapIntegrationPipelines == False): return False @@ -987,7 +1003,7 @@ def afterPipelines(ctx): notify() ] -def codestyle(): +def codestyle(ctx): pipelines = [] if 'codestyle' not in config: @@ -1029,7 +1045,7 @@ def codestyle(): 'name': name, 'workspace' : { 'base': '/var/www/owncloud', - 'path': 'server/apps/%s' % config['app'] + 'path': 'server/apps/%s' % ctx.repo.name }, 'steps': [ { @@ -1057,7 +1073,7 @@ def codestyle(): return pipelines -def jscodestyle(): +def jscodestyle(ctx): pipelines = [] if 'jscodestyle' not in config: @@ -1073,12 +1089,12 @@ def jscodestyle(): 'name': 'coding-standard-js', 'workspace' : { 'base': '/var/www/owncloud', - 'path': 'server/apps/%s' % config['app'] + 'path': 'server/apps/%s' % ctx.repo.name }, 'steps': [ { 'name': 'coding-standard-js', - 'image': 'owncloudci/php:7.2', + 'image': 'owncloudci/php:8.0', 'pull': 'always', 'commands': [ 'make test-js-style' @@ -1101,7 +1117,7 @@ def jscodestyle(): return pipelines -def phpstan(): +def phpstan(ctx): pipelines = [] if 'phpstan' not in config: @@ -1145,13 +1161,13 @@ def phpstan(): 'name': name, 'workspace' : { 'base': '/var/www/owncloud', - 'path': 'server/apps/%s' % config['app'] + 'path': 'server/apps/%s' % ctx.repo.name }, 'steps': - installCore('daily-master-qa', 'sqlite', False) + - installApp(phpVersion) + + installCore(ctx, 'daily-master-qa', 'sqlite', False) + + installApp(ctx, phpVersion) + installExtraApps(phpVersion, params['extraApps']) + - setupServerAndApp(phpVersion, params['logLevel']) + + setupServerAndApp(ctx, phpVersion, params['logLevel']) + [ { 'name': 'phpstan', @@ -1178,7 +1194,7 @@ def phpstan(): return pipelines -def phan(): +def phan(ctx): pipelines = [] if 'phan' not in config: @@ -1220,10 +1236,10 @@ def phan(): 'name': name, 'workspace' : { 'base': '/var/www/owncloud', - 'path': 'server/apps/%s' % config['app'] + 'path': 'server/apps/%s' % ctx.repo.name }, 'steps': - installCore('daily-master-qa', 'sqlite', False) + + installCore(ctx, 'daily-master-qa', 'sqlite', False) + [ { 'name': 'phan', @@ -1250,7 +1266,7 @@ def phan(): return pipelines -def build(): +def build(ctx): pipelines = [] if 'build' not in config: @@ -1290,7 +1306,7 @@ def build(): 'name': 'build', 'workspace' : { 'base': '/var/www/owncloud', - 'path': 'server/apps/%s' % config['app'] + 'path': 'server/apps/%s' % ctx.repo.name }, 'steps': [ { @@ -1308,7 +1324,7 @@ def build(): 'settings': { 'checksum': 'sha256', 'file_exists': 'overwrite', - 'files': 'build/dist/%s.tar.gz' % config['app'], + 'files': 'build/dist/%s.tar.gz' % ctx.repo.name, 'prerelease': True, }, 'environment': { @@ -1339,7 +1355,7 @@ def build(): return pipelines -def javascript(ctx): +def javascript(ctx, withCoverage): pipelines = [] if 'javascript' not in config: @@ -1377,23 +1393,31 @@ def javascript(ctx): if params['skip']: return pipelines + # if we only want pipelines with coverage, and this pipeline does not do coverage, then do not include it + if withCoverage and not params['coverage']: + return pipelines + + # if we only want pipelines without coverage, and this pipeline does coverage, then do not include it + if not withCoverage and params['coverage']: + return pipelines + result = { 'kind': 'pipeline', 'type': 'docker', 'name': 'javascript-tests', 'workspace' : { 'base': '/var/www/owncloud', - 'path': 'server/apps/%s' % config['app'] + 'path': 'server/apps/%s' % ctx.repo.name }, 'steps': - installCore('daily-master-qa', 'sqlite', False) + - installApp('7.2') + - setupServerAndApp('7.2', params['logLevel']) + + installCore(ctx, 'daily-master-qa', 'sqlite', False) + + installApp(ctx, '7.4') + + setupServerAndApp(ctx, '7.4', params['logLevel']) + params['extraSetup'] + [ { 'name': 'js-tests', - 'image': 'owncloudci/php:7.2', + 'image': 'owncloudci/php:8.0', 'pull': 'always', 'environment': params['extraEnvironment'], 'commands': params['extraCommandsBeforeTestRun'] + [ @@ -1422,7 +1446,7 @@ def javascript(ctx): }, 'bucket': 'cache', 'source': './coverage/lcov.info', - 'target': '%s/%s' % (ctx.repo.slug, '${DRONE_COMMIT}-${DRONE_BUILD_NUMBER}'), + 'target': '%s/%s' % (ctx.repo.slug, ctx.build.commit + '-${DRONE_BUILD_NUMBER}'), 'path_style': True, 'strip_prefix': './coverage', 'access_key': { @@ -1439,7 +1463,7 @@ def javascript(ctx): return [result] -def phpTests(ctx, testType): +def phpTests(ctx, testType, withCoverage): pipelines = [] if testType not in config: @@ -1492,6 +1516,14 @@ def phpTests(ctx, testType): if params['skip']: continue + # if we only want pipelines with coverage, and this pipeline does not do coverage, then do not include it + if withCoverage and not params['coverage']: + continue + + # if we only want pipelines without coverage, and this pipeline does coverage, then do not include it + if not withCoverage and params['coverage']: + continue + cephS3Params = params['cephS3'] if type(cephS3Params) == "bool": cephS3Needed = cephS3Params @@ -1508,7 +1540,7 @@ def phpTests(ctx, testType): scalityS3Needed = True filesPrimaryS3NeededForScality = scalityS3Params['filesPrimaryS3Needed'] if 'filesPrimaryS3Needed' in scalityS3Params else True - if ((config['app'] != 'files_primary_s3') and (filesPrimaryS3NeededForCeph or filesPrimaryS3NeededForScality)): + if ((ctx.repo.name != 'files_primary_s3') and (filesPrimaryS3NeededForCeph or filesPrimaryS3NeededForScality)): # If we are not already 'files_primary_s3' and we need S3 storage, then install the 'files_primary_s3' app extraAppsDict = { 'files_primary_s3': 'composer install' @@ -1545,13 +1577,13 @@ def phpTests(ctx, testType): 'name': name, 'workspace' : { 'base': '/var/www/owncloud', - 'path': 'server/apps/%s' % config['app'] + 'path': 'server/apps/%s' % ctx.repo.name }, 'steps': - installCore('daily-master-qa', db, False) + - installApp(phpVersion) + + installCore(ctx, 'daily-master-qa', db, False) + + installApp(ctx, phpVersion) + installExtraApps(phpVersion, params['extraApps']) + - setupServerAndApp(phpVersion, params['logLevel']) + + setupServerAndApp(ctx, phpVersion, params['logLevel']) + setupCeph(params['cephS3']) + setupScality(params['scalityS3']) + params['extraSetup'] + @@ -1599,7 +1631,7 @@ def phpTests(ctx, testType): }, 'bucket': 'cache', 'source': 'tests/output/clover-%s.xml' % (name), - 'target': '%s/%s' % (ctx.repo.slug, '${DRONE_COMMIT}-${DRONE_BUILD_NUMBER}'), + 'target': '%s/%s' % (ctx.repo.slug, ctx.build.commit + '-${DRONE_BUILD_NUMBER}'), 'path_style': True, 'strip_prefix': 'tests/output', 'access_key': { @@ -1663,7 +1695,8 @@ def acceptance(ctx): 'pullRequestAndCron': 'nightly', 'skip': False, 'debugSuites': [], - 'skipExceptParts': [] + 'skipExceptParts': [], + 'earlyFail': True, } if 'defaults' in config: @@ -1699,6 +1732,14 @@ def acceptance(ctx): if params['skip']: continue + # switch off earlyFail if the PR title contains full-ci + if ("full-ci" in ctx.build.title.lower()): + params["earlyFail"] = False + + # switch off earlyFail when running cron builds (for example, nightly CI) + if (ctx.build.event == "cron"): + params["earlyFail"] = False + if isAPI or isCLI: params['browsers'] = [''] @@ -1718,7 +1759,7 @@ def acceptance(ctx): scalityS3Needed = True filesPrimaryS3NeededForScality = scalityS3Params['filesPrimaryS3Needed'] if 'filesPrimaryS3Needed' in scalityS3Params else True - if ((config['app'] != 'files_primary_s3') and (filesPrimaryS3NeededForCeph or filesPrimaryS3NeededForScality)): + if ((ctx.repo.name != 'files_primary_s3') and (filesPrimaryS3NeededForCeph or filesPrimaryS3NeededForScality)): # If we are not already 'files_primary_s3' and we need S3 object storage, then install the 'files_primary_s3' app extraAppsDict = { 'files_primary_s3': 'composer install' @@ -1800,15 +1841,15 @@ def acceptance(ctx): 'name': name, 'workspace' : { 'base': '/var/www/owncloud', - 'path': 'testrunner/apps/%s' % config['app'] + 'path': 'testrunner/apps/%s' % ctx.repo.name }, 'steps': - installCore(testConfig['server'], testConfig['database'], testConfig['useBundledApp']) + - installTestrunner('7.4', testConfig['useBundledApp']) + + installCore(ctx, testConfig['server'], testConfig['database'], testConfig['useBundledApp']) + + installTestrunner(ctx, '7.4', testConfig['useBundledApp']) + (installFederated(testConfig['server'], testConfig['phpVersion'], testConfig['logLevel'], testConfig['database'], federationDbSuffix) + owncloudLog('federated') if testConfig['federatedServerNeeded'] else []) + - installApp(testConfig['phpVersion']) + + installApp(ctx, testConfig['phpVersion']) + installExtraApps(testConfig['phpVersion'], testConfig['extraApps']) + - setupServerAndApp(testConfig['phpVersion'], testConfig['logLevel']) + + setupServerAndApp(ctx, testConfig['phpVersion'], testConfig['logLevel'], testConfig['federatedServerNeeded']) + owncloudLog('server') + setupCeph(testConfig['cephS3']) + setupScality(testConfig['scalityS3']) + @@ -1827,7 +1868,7 @@ def acceptance(ctx): 'make %s' % makeParameter ] }), - ] + testConfig['extraTeardown'], + ] + testConfig['extraTeardown'] + buildGithubCommentForBuildStopped(name, params['earlyFail']) + githubComment(params['earlyFail']) + stopBuild(ctx, params['earlyFail']), 'services': databaseService(testConfig['database']) + browserService(testConfig['browser']) + @@ -1849,14 +1890,13 @@ def acceptance(ctx): if (testConfig['cron'] != ''): result['trigger']['cron'] = testConfig['cron'] else: - result['trigger'] = { - 'ref': [ + if ((testConfig['pullRequestAndCron'] != '') and (ctx.build.event != 'pull_request')): + result['trigger']['cron'] = testConfig['pullRequestAndCron'] + else: + result['trigger']['ref'] = [ 'refs/pull/**', 'refs/tags/**' ] - } - for branch in config['branches']: - result['trigger']['ref'].append('refs/heads/%s' % branch) pipelines.append(result) @@ -1866,18 +1906,46 @@ def acceptance(ctx): return pipelines def sonarAnalysis(ctx, phpVersion = '7.4'): + sonar_env = { + "SONAR_TOKEN": { + "from_secret": "sonar_token", + }, + 'SONAR_SCANNER_OPTS': '-Xdebug' + } + + if ctx.build.event == "pull_request": + sonar_env.update({ + "SONAR_PULL_REQUEST_BASE": "%s" % (ctx.build.target), + "SONAR_PULL_REQUEST_BRANCH": "%s" % (ctx.build.source), + "SONAR_PULL_REQUEST_KEY": "%s" % (ctx.build.ref.replace("refs/pull/", "").split("/")[0]), + }) + + repo_slug = ctx.build.source_repo if ctx.build.source_repo else ctx.repo.slug + result = { 'kind': 'pipeline', 'type': 'docker', 'name': 'sonar-analysis', 'workspace' : { 'base': '/var/www/owncloud', - 'path': 'server/apps/%s' % config['app'] + 'path': 'server/apps/%s' % ctx.repo.name }, - 'steps': + 'clone': { + 'disable': True, # Sonarcloud does not apply issues on already merged branch + }, + 'steps': [ + { + "name": "clone", + "image": "owncloudci/alpine:latest", + "commands": [ + "git clone https://github.com/%s.git ." % repo_slug, + "git checkout $DRONE_COMMIT", + ], + }, + ] + cacheRestore() + composerInstall(phpVersion) + - installCore('daily-master-qa', 'sqlite', False) + + installCore(ctx, 'daily-master-qa', 'sqlite', False) + [ { 'name': 'sync-from-cache', @@ -1890,7 +1958,7 @@ def sonarAnalysis(ctx, phpVersion = '7.4'): }, 'commands': [ 'mkdir -p results', - 'mc mirror cache/cache/%s/%s results/' % (ctx.repo.slug, '${DRONE_COMMIT}-${DRONE_BUILD_NUMBER}'), + 'mc mirror cache/cache/%s/%s results/' % (ctx.repo.slug, ctx.build.commit + '-${DRONE_BUILD_NUMBER}'), ] }, { @@ -1902,42 +1970,15 @@ def sonarAnalysis(ctx, phpVersion = '7.4'): ] }, { - 'name': 'sonarcloud-pr', + 'name': 'sonarcloud', 'image': 'sonarsource/sonar-scanner-cli', 'pull': 'always', - 'environment': { - 'SONAR_TOKEN': { - 'from_secret': 'sonar_token' - }, - 'SONAR_PULL_REQUEST_BASE': 'master', - 'SONAR_PULL_REQUEST_BRANCH': '${DRONE_SOURCE_BRANCH}', - 'SONAR_PULL_REQUEST_KEY': '${DRONE_COMMIT_REF}'.replace("refs/pull/", "").split("/")[0], - 'SONAR_SCANNER_OPTS': '-Xdebug' - }, + 'environment': sonar_env, 'when': { - 'event': { - 'include': [ - 'pull_request' - ], - }, - } - }, - { - 'name': 'sonarcloud-master', - 'image': 'sonarsource/sonar-scanner-cli', - 'pull': 'always', - 'environment': { - 'SONAR_TOKEN': { - 'from_secret': 'sonar_token' - }, - 'SONAR_SCANNER_OPTS': '-Xdebug' - }, - 'when': { - 'event': { - 'exclude': [ - 'pull_request' - ], - }, + 'instance': [ + 'drone.owncloud.services', + 'drone.owncloud.com' + ], } }, { @@ -1949,13 +1990,14 @@ def sonarAnalysis(ctx, phpVersion = '7.4'): } }, 'commands': [ - 'mc rm --recursive --force cache/cache/%s/%s' % (ctx.repo.slug, '${DRONE_COMMIT}-${DRONE_BUILD_NUMBER}'), + 'mc rm --recursive --force cache/cache/%s/%s' % (ctx.repo.slug, ctx.build.commit + '-${DRONE_BUILD_NUMBER}'), ] }, ], 'depends_on': [], 'trigger': { 'ref': [ + 'refs/heads/master', 'refs/pull/**', 'refs/tags/**' ] @@ -2262,7 +2304,7 @@ def composerInstall(phpVersion): ] }] -def installCore(version, db, useBundledApp): +def installCore(ctx, version, db, useBundledApp): host = getDbName(db) dbType = host @@ -2295,11 +2337,11 @@ def installCore(version, db, useBundledApp): } if not useBundledApp: - stepDefinition['settings']['exclude'] = 'apps/%s' % config['app'] + stepDefinition['settings']['exclude'] = 'apps/%s' % ctx.repo.name return [stepDefinition] -def installTestrunner(phpVersion, useBundledApp): +def installTestrunner(ctx, phpVersion, useBundledApp): return [{ 'name': 'install-testrunner', 'image': 'owncloudci/php:%s' % phpVersion, @@ -2309,7 +2351,7 @@ def installTestrunner(phpVersion, useBundledApp): 'git clone -b master --depth=1 https://github.com/owncloud/core.git /tmp/testrunner', 'rsync -aIX /tmp/testrunner /var/www/owncloud', ] + ([ - 'cp -r /var/www/owncloud/testrunner/apps/%s /var/www/owncloud/server/apps/' % config['app'] + 'cp -r /var/www/owncloud/testrunner/apps/%s /var/www/owncloud/server/apps/' % ctx.repo.name ] if not useBundledApp else []) }] @@ -2336,33 +2378,34 @@ def installExtraApps(phpVersion, extraApps): 'commands': commandArray }] -def installApp(phpVersion): +def installApp(ctx, phpVersion): if 'appInstallCommand' not in config: return [] return [{ - 'name': 'install-app-%s' % config['app'], + 'name': 'install-app-%s' % ctx.repo.name, 'image': 'owncloudci/php:%s' % phpVersion, 'pull': 'always', 'commands': [ - 'cd /var/www/owncloud/server/apps/%s' % config['app'], + 'cd /var/www/owncloud/server/apps/%s' % ctx.repo.name, config['appInstallCommand'] ] }] -def setupServerAndApp(phpVersion, logLevel): +def setupServerAndApp(ctx, phpVersion, logLevel, federatedServerNeeded = False): return [{ - 'name': 'setup-server-%s' % config['app'], + 'name': 'setup-server-%s' % ctx.repo.name, 'image': 'owncloudci/php:%s' % phpVersion, 'pull': 'always', 'commands': [ 'cd /var/www/owncloud/server', 'php occ a:l', - 'php occ a:e %s' % config['app'], + 'php occ a:e %s' % ctx.repo.name, 'php occ a:e testing', 'php occ a:l', 'php occ config:system:set trusted_domains 1 --value=server', 'php occ log:manage --level %s' % logLevel, + 'php occ config:system:set csrf.disabled --value=true' if federatedServerNeeded else '' ] }] @@ -2553,10 +2596,87 @@ def buildTestConfig(params): configs.append(config) return configs +def stopBuild(ctx, earlyFail): + if (earlyFail): + return [{ + "name": "stop-build", + "image": "drone/cli:alpine", + "pull": "always", + "environment": { + "DRONE_SERVER": "https://drone.owncloud.com", + "DRONE_TOKEN": { + "from_secret": "drone_token", + }, + }, + "commands": [ + "drone build stop owncloud/%s ${DRONE_BUILD_NUMBER}" % ctx.repo.name, + ], + "when": { + "status": [ + "failure", + ], + "event": [ + "pull_request", + ], + }, + }] + + else: + return [] + +def buildGithubCommentForBuildStopped(alternateSuiteName, earlyFail): + if (earlyFail): + return [{ + "name": "build-github-comment-buildStop", + "image": "owncloud/ubuntu:16.04", + "pull": "always", + "commands": [ + 'echo ":boom: Acceptance tests pipeline %s failed. The build has been cancelled.\\n\\n${DRONE_BUILD_LINK}/${DRONE_JOB_NUMBER}${DRONE_STAGE_NUMBER}/1\\n" >> /var/www/owncloud/comments.file' % alternateSuiteName, + ], + "when": { + "status": [ + "failure", + ], + "event": [ + "pull_request", + ], + }, + }] + + else: + return [] + +def githubComment(earlyFail): + if (earlyFail): + return [{ + "name": "github-comment", + "image": "jmccann/drone-github-comment:1", + "pull": "if-not-exists", + "settings": { + "message_file": "/var/www/owncloud/comments.file", + }, + "environment": { + "GITHUB_TOKEN": { + "from_secret": "github_token", + }, + }, + "when": { + "status": [ + "failure", + ], + "event": [ + "pull_request", + ], + }, + }] + + else: + return [] + # This is custom starlark code added just for user_ldap # It is not committed to the starlark "standard" code in other apps because # it is just an unusual way that integration tests have been structured here -def ldapIntegration(): +def ldapIntegration(ctx): pipelines = [] if 'ldapIntegration' not in config: @@ -2615,9 +2735,9 @@ def ldapIntegration(): 'path': 'server/apps/%s' % config['app'] }, 'steps': - installCore(server, db, False) + - installApp(phpVersion) + - setupServerAndApp(phpVersion, params['logLevel']) + + installCore(ctx, server, db, False) + + installApp(ctx, phpVersion) + + setupServerAndApp(ctx, phpVersion, params['logLevel']) + [ ({ 'name': 'ldap-integration-tests', @@ -2629,7 +2749,7 @@ def ldapIntegration(): 'commands': [ 'wait-for-it -t 600 ldap:636', 'php -f ./tests/integration/Lib/%s.php' % test, - ] + ] }), ], 'services': diff --git a/.gitignore b/.gitignore index 95c6abe04..0635e0074 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ /node_modules/ /build/ .php_cs.cache +.php-cs-fixer.cache /tests/output/ # Composer diff --git a/.php_cs.dist b/.php-cs-fixer.dist.php similarity index 100% rename from .php_cs.dist rename to .php-cs-fixer.dist.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 6802b3d20..1b11085ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,8 +3,32 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) -## [Unreleased] -. +## [Unreleased] - XXXX-XX-XX + + +## [0.15.4] - 2021-07-13 + +### Fixed +- user_ldap 0.15.3 double quote in passwords does not work [#662](https://github.com/owncloud/user_ldap/issues/662) +- Fix display errors in combination with other apps [#660](https://github.com/owncloud/user_ldap/issues/660) +- [QA] Frontend breaks with other auser auth apps [#659](https://github.com/owncloud/user_ldap/issues/659) +- [QA] tab break into new line hides content [#656](https://github.com/owncloud/user_ldap/issues/656) +- [QA] Login Attributes: LDAP Filter misagligned output [#653](https://github.com/owncloud/user_ldap/issues/653) + +## [0.15.3] - 2021-06-14 + +### Fixed +- Fix display errors in combination with other apps [#660](https://github.com/owncloud/user_ldap/issues/660) +- Fixed read LDAP attribute value 0 returned as null [#599](https://github.com/owncloud/user_ldap/issues/599) +- Security: filter special characters from password field [#636](https://github.com/owncloud/user_ldap/issues/636) +- LDAP multiple base dns break pagination [#307](https://github.com/owncloud/user_ldap/issues/307) + +### Changed +- Add warning for disabling email login regarding strict login check [#581](https://github.com/owncloud/user_ldap/issues/581) (Requires 10.5.0) +- Facelift [#597](https://github.com/owncloud/user_ldap/issues/597) +- Bump libraries + + ## [0.15.2] - 2020-06-16 @@ -30,6 +54,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) ### Changed - Drop PHP 7.0 - [#474](https://github.com/owncloud/user_ldap/issues/474) +- Requires ownCloud min-version 10.4 ## [0.14.0] - 2019-11-11 @@ -128,7 +153,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) - Add hint for max search term length - [#105](https://github.com/owncloud/user_ldap/issues/105) - Allow proxy to check next server - [#101](https://github.com/owncloud/user_ldap/issues/101) -[Unreleased]: https://github.com/owncloud/user_ldap/compare/v0.15.2...master + +[Unreleased]: https://github.com/owncloud/user_ldap/compare/v0.15.4...master +[0.15.4]: https://github.com/owncloud/user_ldap/compare/v0.15.3...v0.15.4 +[0.15.3]: https://github.com/owncloud/user_ldap/compare/v0.15.2...v0.15.3 [0.15.2]: https://github.com/owncloud/user_ldap/compare/v0.15.1...v0.15.2 [0.15.1]: https://github.com/owncloud/user_ldap/compare/v0.15.0...v0.15.1 [0.15.0]: https://github.com/owncloud/user_ldap/compare/v0.14.0...v0.15.0 diff --git a/Makefile b/Makefile index 23941b3e7..002691517 100644 --- a/Makefile +++ b/Makefile @@ -129,13 +129,13 @@ test-php-phpstan: vendor-bin/phpstan/vendor .PHONY: test-php-style test-php-style: ## Run php-cs-fixer and check owncloud code-style test-php-style: vendor-bin/owncloud-codestyle/vendor vendor-bin/php_codesniffer/vendor - $(PHP_CS_FIXER) fix -v --diff --diff-format udiff --dry-run --allow-risky yes + $(PHP_CS_FIXER) fix -v --diff --dry-run --allow-risky yes $(PHP_CODESNIFFER) --runtime-set ignore_warnings_on_exit --standard=phpcs.xml tests/acceptance .PHONY: test-php-style-fix test-php-style-fix: ## Run php-cs-fixer and fix code-style issues test-php-style-fix: vendor-bin/owncloud-codestyle/vendor - $(PHP_CS_FIXER) fix -v --diff --diff-format udiff --allow-risky yes + $(PHP_CS_FIXER) fix -v --diff --allow-risky yes .PHONY: test-php-unit test-php-unit: ## Run php unit tests diff --git a/appinfo/info.xml b/appinfo/info.xml index b7aaeab21..34397837a 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -14,7 +14,7 @@ More information is available in the [LDAP User and Group Backend documentation] AGPL Jörn Friedrich Dreyer, Tom Needham, Juan Pablo Villafañez Ramos, Dominik Schmidt and Arthur Schiwon - 0.15.2 + 0.15.4 diff --git a/css/settings.css b/css/settings.css index bad218e10..b58057831 100644 --- a/css/settings.css +++ b/css/settings.css @@ -1,14 +1,17 @@ -#ldap section { - margin-bottom: 2rem; - width: 100% !important; +#ldap { + width: calc(100% - 40px); } -@media all and (min-width: 768px) { +@media all and (min-width: 1200px) { #ldap section { - width: 60% !important; + width: 65% !important; } } +#ldap section { + margin-bottom: 2rem; +} + #ldap section h3 { border-bottom: 1px solid #efefef; margin-left: -41px; @@ -75,6 +78,23 @@ #ldap .tablerow .hint { clear: both; font-size: .8em; + position: relative; + padding-left: 1rem; +} + +#ldap .tablerow .hint:before { + background: url('/core/img/actions/info.svg'); + background-size: contain; + background-position: 50% 100%; + background-repeat: no-repeat; + display: inline-block; + height: 1.3em; + width: 1.3em; + margin-right: 0rem; + content: ' '; + position: absolute; + margin-left: -1rem; + top: 3px; } #ldap .tablerow .hint img { @@ -95,7 +115,13 @@ .ldapWizardControls { - text-align: right; + display: flex; + flex-direction: row; + justify-content: end; +} + +.ldapWizardControls > div { + margin-right: 1rem; } .ldapWizardInfo { @@ -215,14 +241,6 @@ select[multiple=multiple] + button { cursor: wait; } -#ldap .ldap_saving { - margin-right: 15px; - color: orange; - font-weight: bold; -} - -#ldap .ldap_saving img { height: 15px; } - #ldap .app-name .ldap_config_state_indicator_container { display: inline-block; margin-left: 2em; @@ -267,17 +285,17 @@ select[multiple=multiple] + button { } #ldap .header { - position: fixed; background: #fff; - width: inherit; top: 5.5em; padding-top: 1.7em; z-index: 1; + width: calc(100% - 40px); } @media all and (min-width: 768px) { #ldap .header { top: 3.5em; + width: calc(750% - 40px); } } @@ -312,14 +330,48 @@ select[multiple=multiple] + button { left: 1.3em; } -#ldap .ui-tabs .ui-tabs-nav li.stateIndicator { +#ldap .ui-tabs .ui-tabs-nav li.stateIndicator, +#ldap .ui-tabs .ui-tabs-nav li.ldap_saving_wrapper { color: #333333; border: none; background: transparent; - padding: 0.7em 1.3em; + padding: 0.2rem 1.3rem; display: none; } +#ldap .ui-tabs .ui-tabs-nav li.ldap_saving_wrapper { + padding: 0.5rem 1.3rem; + display: block; +} + +#ldap .ui-tabs .ui-tabs-nav li.ldap_saving_wrapper .ldap_saving { + margin-right: 15px; + color: orange; + font-weight: bold; +} + +#ldap .ui-tabs .ui-tabs-nav li.ldap_saving_wrapper .ldap_saving .done { + display: none; + color: #128c12; +} + +#ldap .ui-tabs .ui-tabs-nav li.ldap_saving_wrapper .ldap_saving.done img { + display: none; +} + +#ldap .ui-tabs .ui-tabs-nav li.ldap_saving_wrapper .ldap_saving.done .done { + display: inline; +} + +#ldap .ui-tabs .ui-tabs-nav li.ldap_saving_wrapper .ldap_saving.done .working { + display: none; +} + +#ldap .ldap_config_state_indicator_subline { + font-weight: 100; + font-size: 75%; +} + @media all and (min-width: 768px) { #ldap .ui-tabs .ui-tabs-nav li.stateIndicator { display: block; @@ -327,7 +379,7 @@ select[multiple=multiple] + button { } .ui-tabs .ui-tabs-panel { - margin-top: 5.3em; + margin-top: 1rem; } #ldap button { @@ -357,4 +409,4 @@ select[multiple=multiple] + button { #ldap p { margin-bottom: 1em; -} \ No newline at end of file +} diff --git a/js/wizard/configModel.js b/js/wizard/configModel.js index cb2538362..c1ff00bc7 100644 --- a/js/wizard/configModel.js +++ b/js/wizard/configModel.js @@ -626,6 +626,9 @@ OCA = OCA || {}; configPrefix: configID, errorMessage: _.isUndefined(result['message']) ? '' : result['message'] }; + + $('.ldap_config_state_indicator_subline').html('') + model._broadcast('deleteConfiguration', payload); } }; diff --git a/js/wizard/view.js b/js/wizard/view.js index 27d9b8e39..4b0eb2860 100644 --- a/js/wizard/view.js +++ b/js/wizard/view.js @@ -55,6 +55,14 @@ OCA = OCA || {}; }); $('.ldap_action_test_connection').click(this.onTestButtonClick); + + $('#ldap_host').on('input', function () { + $('.ldap_config_state_indicator_subline').html($('#ldap_host').val() + ':' + $('#ldap_port').val()) + }) + + $('#ldap_port').on('input', function () { + $('.ldap_config_state_indicator_subline').html($('#ldap_host').val() + ':' + $('#ldap_port').val()) + }) }, /** @@ -215,6 +223,9 @@ OCA = OCA || {}; view._updateStatusIndicator(view.STATUS_UNTESTED); view.basicStatusCheck(view); view.functionalityCheck(); + if (view['configModel']['configuration']['ldap_host'] !== '') + $('.ldap_config_state_indicator_subline').html(view['configModel']['configuration']['ldap_host'] + ':' + view['configModel']['configuration']['ldap_port']) + }, /** @@ -329,7 +340,7 @@ OCA = OCA || {}; * shows a save spinner */ showSaveSpinner: function() { - this.$saveSpinners.removeClass('hidden'); + this.$saveSpinners.show() $('#ldap *').addClass('save-cursor'); }, @@ -337,8 +348,14 @@ OCA = OCA || {}; * hides the save spinner */ hideSaveSpinner: function() { - this.$saveSpinners.addClass('hidden'); - $('#ldap *').removeClass('save-cursor'); + this.$saveSpinners.addClass('done') + setTimeout(function() { + $('#ldap .ldap_saving').fadeOut(1000, function () { + $('#ldap .ldap_saving').removeClass('done') + }); + $('#ldap *').removeClass('save-cursor'); + + }, 1000) }, /** @@ -468,11 +485,4 @@ OCA = OCA || {}; }; OCA.LDAP.Wizard.WizardView = WizardView; -})(); - -$(document).ready(function () { - $('.ui-tabs .ui-tabs-panel').css('margin-top', $('#ldap .header').outerHeight()) - $(window).on('resize', function(){ - $('.ui-tabs .ui-tabs-panel').css('margin-top', $('#ldap .header').outerHeight()) - }); -}); \ No newline at end of file +})(); \ No newline at end of file diff --git a/lib/Access.php b/lib/Access.php index 4253990e7..0fc8b1a86 100644 --- a/lib/Access.php +++ b/lib/Access.php @@ -172,7 +172,8 @@ public function readAttribute($dn, $attr, $filter = 'objectClass=*') { if (!$this->checkConnection()) { \OC::$server->getLogger()->warning( 'No LDAP Connector assigned, access impossible for readAttribute.', - ['app' => 'user_ldap']); + ['app' => 'user_ldap'] + ); return false; } $cr = $this->connection->getConnectionResource(); @@ -180,7 +181,8 @@ public function readAttribute($dn, $attr, $filter = 'objectClass=*') { //LDAP not available \OC::$server->getLogger()->debug( 'LDAP resource not available.', - ['app' => 'user_ldap']); + ['app' => 'user_ldap'] + ); return false; } //Cancel possibly running Paged Results operation, otherwise we run in @@ -243,7 +245,8 @@ public function readAttribute($dn, $attr, $filter = 'objectClass=*') { \OC::$server->getLogger()->debug( "Requested attribute $attr not found for $dn", - ['app' => 'user_ldap']); + ['app' => 'user_ldap'] + ); return false; } @@ -272,7 +275,8 @@ public function executeRead($cr, $dn, $attributes, $filter, $maxResults) { //do not throw this message on userExists check, irritates \OC::$server->getLogger()->debug( "readAttribute failed for DN $dn", - ['app' => 'user_ldap']); + ['app' => 'user_ldap'] + ); } //in case an error occurs , e.g. object does not exist return false; @@ -280,7 +284,8 @@ public function executeRead($cr, $dn, $attributes, $filter, $maxResults) { if ($attributes[0] === '' && ($filter === 'objectclass=*' || $this->getLDAP()->countEntries($cr, $rr) === 1)) { \OC::$server->getLogger()->debug( "readAttribute: $dn found", - ['app' => 'user_ldap']); + ['app' => 'user_ldap'] + ); return true; } $er = $this->getLDAP()->firstEntry($cr, $rr); @@ -290,7 +295,10 @@ public function executeRead($cr, $dn, $attributes, $filter, $maxResults) { } //LDAP attributes are not case sensitive $result = Util::mb_array_change_key_case( - $this->getLDAP()->getAttributes($cr, $er), MB_CASE_LOWER, 'UTF-8'); + $this->getLDAP()->getAttributes($cr, $er), + MB_CASE_LOWER, + 'UTF-8' + ); if (!\array_key_exists('dn', $result) && \in_array('dn', $attributes, true) @@ -448,11 +456,13 @@ public function username2dn($name) { "DN <$fdn> outside configured base domains:". \print_r($this->connection->ldapBaseUsers, true). " on {$this->connection->ldapHost}", - ['app' => 'user_ldap']); + ['app' => 'user_ldap'] + ); } else { \OC::$server->getLogger()->debug( "No DN found for <$name> on {$this->connection->ldapHost}", - ['app' => 'user_ldap']); + ['app' => 'user_ldap'] + ); } return false; @@ -572,7 +582,8 @@ public function dn2ocname($fdn, $ldapDisplayName = null, $isUser = true) { //If the UUID can't be detected something is foul. \OC::$server->getLogger()->error( "Cannot determine UUID for $fdn. Skipping.", - ['app' => 'user_ldap']); + ['app' => 'user_ldap'] + ); return false; } @@ -581,7 +592,8 @@ public function dn2ocname($fdn, $ldapDisplayName = null, $isUser = true) { if (!isset($ldapDisplayName[0]) && empty($ldapDisplayName[0])) { \OC::$server->getLogger()->error( "No or empty name for $fdn.", - ['app' => 'user_ldap']); + ['app' => 'user_ldap'] + ); return false; } $ldapDisplayName = $ldapDisplayName[0]; @@ -1057,7 +1069,8 @@ private function executeSearch($filter, array $base, &$attr = null, $limit = nul // Return an empty array just like before. \OC::$server->getLogger()->debug( 'Could not search, because resource is missing.', - ['app' => 'user_ldap']); + ['app' => 'user_ldap'] + ); return false; } @@ -1071,10 +1084,12 @@ private function executeSearch($filter, array $base, &$attr = null, $limit = nul \OC::$server->getLogger()->error( 'Error when searching: '.$this->getLDAP()->error($cr). ' code '.$this->getLDAP()->errno($cr), - ['app' => 'user_ldap']); + ['app' => 'user_ldap'] + ); \OC::$server->getLogger()->error( 'Attempt for Paging? '.\print_r($pagedSearchOK, true), - ['app' => 'user_ldap']); + ['app' => 'user_ldap'] + ); return false; } @@ -1109,7 +1124,8 @@ private function processPagedSearchStatus($sr, $filter, $base, $iFoundItems, $li $estimates[$key] = $estimated; \OC::$server->getLogger()->debug( 'Page response cookie '.$this->cookie2str($cookie)." at $range, estimated<$estimated>", - ['app' => 'user_ldap']); + ['app' => 'user_ldap'] + ); $this->setPagedResultCookie($base[$key], $filter, $limit, $offset, $cookie); } } @@ -1128,7 +1144,8 @@ private function processPagedSearchStatus($sr, $filter, $base, $iFoundItems, $li if ($limit !== null) { \OC::$server->getLogger()->info( // TODO level debug? 'Paged search was not available', - ['app' => 'user_ldap']); + ['app' => 'user_ldap'] + ); } } /* ++ Fixing RHDS searches with pages with zero results ++ @@ -1159,7 +1176,8 @@ private function processPagedSearchStatus($sr, $filter, $base, $iFoundItems, $li private function count($filter, array $bases, $attr = null, $limit = null, $offset = null, $skipHandling = false) { \OC::$server->getLogger()->debug( 'Count filter: '.\print_r($filter, true), - ['app' => 'user_ldap']); + ['app' => 'user_ldap'] + ); $limitPerPage = (int)$this->connection->ldapPagingSize; if ($limit !== null && $limit < $limitPerPage && $limit > 0) { @@ -1172,8 +1190,13 @@ private function count($filter, array $bases, $attr = null, $limit = null, $offs $shouldRetryForMissingCookie = true; do { - $search = $this->executeSearch($filter, $bases, $attr, - $limitPerPage, $offset); + $search = $this->executeSearch( + $filter, + $bases, + $attr, + $limitPerPage, + $offset + ); if ($search === false) { if ($counter > 0) { return $counter; @@ -1189,8 +1212,14 @@ private function count($filter, array $bases, $attr = null, $limit = null, $offs $counts = $this->countEntriesInSearchResults($sr); list($hasMorePages, $estimates) = $this->processPagedSearchStatus( - $sr, $filter, $bases, $count, $limitPerPage, - $offset, $pagedSearchOK, $skipHandling + $sr, + $filter, + $bases, + $count, + $limitPerPage, + $offset, + $pagedSearchOK, + $skipHandling ); // according to LDAP documentation, when cookie is missing for @@ -1220,9 +1249,15 @@ private function count($filter, array $bases, $attr = null, $limit = null, $offs // used $this->countEntriesInSearchResults($sr); $this->processPagedSearchStatus( - $retrySr, $filter, $bases, 1, $limitPerPage, - $reOffset, $retryPagedSearchOK, - true); + $retrySr, + $filter, + $bases, + 1, + $limitPerPage, + $reOffset, + $retryPagedSearchOK, + true + ); } // do not continue both retry and original query on error @@ -1311,9 +1346,16 @@ private function search($filter, $bases, $attr = null, $limit = null, $offset = $findings = \array_merge($findings, $this->getLDAP()->getEntries($cr, $res)); } - list($hasMorePages, ) = $this->processPagedSearchStatus($sr, $filter, $bases, $findings['count'], - $limit, $offset, $pagedSearchOK, - false); + list($hasMorePages, ) = $this->processPagedSearchStatus( + $sr, + $filter, + $bases, + $findings['count'], + $limit, + $offset, + $pagedSearchOK, + false + ); // according to LDAP documentation, when cookie is missing for // continued paged search, we should retry search from scratch @@ -1340,9 +1382,16 @@ private function search($filter, $bases, $attr = null, $limit = null, $offset = // i.e. result does not need to be fetched, we just need the cookie // thus pass 1 or any other value as $iFoundItems because it is not // used - $this->processPagedSearchStatus($retrySr, $filter, $bases, 1, $limit, - $reOffset, $retryPagedSearchOK, - true); + $this->processPagedSearchStatus( + $retrySr, + $filter, + $bases, + 1, + $limit, + $reOffset, + $retryPagedSearchOK, + true + ); } // do not continue both retry and original query on error @@ -1491,9 +1540,11 @@ private function combineFilter($filters, $operator) { * @return string the final filter part to use in LDAP searches */ public function getFilterPartForUserSearch($search) { - return $this->getFilterPartForSearch($search, + return $this->getFilterPartForSearch( + $search, $this->connection->ldapAttributesForUserSearch, - $this->connection->ldapUserDisplayName); + $this->connection->ldapUserDisplayName + ); } /** @@ -1502,9 +1553,11 @@ public function getFilterPartForUserSearch($search) { * @return string the final filter part to use in LDAP searches */ public function getFilterPartForGroupSearch($search) { - return $this->getFilterPartForSearch($search, + return $this->getFilterPartForSearch( + $search, $this->connection->ldapAttributesForGroupSearch, - $this->connection->ldapGroupDisplayName); + $this->connection->ldapGroupDisplayName + ); } /** @@ -1551,7 +1604,8 @@ private function getFilterPartForSearch($search, $searchAttributes, $fallbackAtt } catch (\Exception $e) { \OC::$server->getLogger()->info( 'Creating advanced filter for search failed, falling back to simple method.', - ['app' => 'user_ldap']); + ['app' => 'user_ldap'] + ); } } @@ -1723,7 +1777,8 @@ private function detectUuidAttribute($dn, $isUser = true, $force = false) { if (\is_array($value) && isset($value[0]) && !empty($value[0])) { \OC::$server->getLogger()->debug( "Setting $attribute as $uuidAttr", - ['app' => 'user_ldap']); + ['app' => 'user_ldap'] + ); // TODO we should make the autodetection explicit and store it in the configuration after detection // TODO the UserEntry does thet ... but only for users. Get this sorted out in the wizard properly $this->connection->$uuidAttr = $attribute; @@ -1732,7 +1787,8 @@ private function detectUuidAttribute($dn, $isUser = true, $force = false) { } \OC::$server->getLogger()->error( 'Could not autodetect the UUID attribute', - ['app' => 'user_ldap']); + ['app' => 'user_ldap'] + ); return false; } @@ -1758,8 +1814,10 @@ public function getUUID($dn, $isUser = true) { if (!\is_array($uuid) && $uuidOverride !== '' && $this->detectUuidAttribute($dn, $isUser, true)) { - $uuid = $this->readAttribute($dn, - $this->connection->$uuidAttr); + $uuid = $this->readAttribute( + $dn, + $this->connection->$uuidAttr + ); } if (\is_array($uuid) && isset($uuid[0]) && !empty($uuid[0])) { $uuid = $uuid[0]; @@ -1973,7 +2031,8 @@ private function abandonPagedSearch() { if ($this->connection->hasPagedResultSupport) { \OC::$server->getLogger()->debug( 'Abandoning paged search - last cookie: '.$this->cookie2str($this->lastCookie).', cookies: <'.\implode(',', \array_map([$this, 'cookie2str'], $this->cookies)).'>', - ['app' => 'user_ldap']); + ['app' => 'user_ldap'] + ); $cr = $this->connection->getConnectionResource(); $this->getLDAP()->controlPagedResult($cr, 0, false, $this->lastCookie); $this->getPagedSearchResultState(); @@ -2083,13 +2142,15 @@ private function initPagedSearch($filter, $bases, $attr, $limit, $offset) { \OC::$server->getLogger()->debug( "Initializing paged search for Filter $filter base ".\print_r($bases, true) .' attr '.\print_r($attr, true)." at $range", - ['app' => 'user_ldap']); + ['app' => 'user_ldap'] + ); //get the cookie from the search for the previous search, required by LDAP foreach ($bases as $base) { $cookie = $this->getPagedResultCookie($base, $filter, $limit, $offset); \OC::$server->getLogger()->debug( "Cookie for $base at $range is ".$this->cookie2str($cookie), - ['app' => 'user_ldap']); + ['app' => 'user_ldap'] + ); // '0' is valid, because 389ds if (empty($cookie) && $cookie !== '0' && ($offset > 0)) { @@ -2098,7 +2159,8 @@ private function initPagedSearch($filter, $bases, $attr, $limit, $offset) { $this->abandonPagedSearch(); \OC::$server->getLogger()->debug( "Cache not available for continued paged search at $range, aborting.", - ['app' => 'user_ldap']); + ['app' => 'user_ldap'] + ); return false; } if ($cookie !== null) { @@ -2107,22 +2169,28 @@ private function initPagedSearch($filter, $bases, $attr, $limit, $offset) { $this->abandonPagedSearch(); \OC::$server->getLogger()->debug( 'Ready for a paged search with cookie '.$this->cookie2str($cookie)." at $range", - ['app' => 'user_ldap']); + ['app' => 'user_ldap'] + ); } else { \OC::$server->getLogger()->debug( 'Continuing a paged search with cookie '.$this->cookie2str($cookie)." at $range", - ['app' => 'user_ldap']); + ['app' => 'user_ldap'] + ); } $pagedSearchOK = $this->getLDAP()->controlPagedResult( - $this->connection->getConnectionResource(), $limit, - false, $cookie); + $this->connection->getConnectionResource(), + $limit, + false, + $cookie + ); if (!$pagedSearchOK) { return false; } } else { \OC::$server->getLogger()->debug( "No paged search for us at $range", - ['app' => 'user_ldap']); + ['app' => 'user_ldap'] + ); } } } elseif ($this->connection->hasPagedResultSupport && $limit === 0) { @@ -2138,7 +2206,10 @@ private function initPagedSearch($filter, $bases, $attr, $limit, $offset) { $pageSize = 500; } $pagedSearchOK = $this->getLDAP()->controlPagedResult( - $this->connection->getConnectionResource(), $pageSize, false, '' + $this->connection->getConnectionResource(), + $pageSize, + false, + '' ); } diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 80ffbaf3b..103141853 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -55,7 +55,8 @@ public function checkCompatibility() { if ($server->getAppManager()->isEnabledForUser('user_webdavauth')) { $server->getLogger()->warning( 'user_ldap and user_webdavauth are incompatible. You may experience unexpected behaviour', - ['app' => 'user_ldap']); + ['app' => 'user_ldap'] + ); } } diff --git a/lib/Command/CheckUser.php b/lib/Command/CheckUser.php index bbfa2dcd1..c21458dfa 100644 --- a/lib/Command/CheckUser.php +++ b/lib/Command/CheckUser.php @@ -60,16 +60,16 @@ protected function configure() { ->setName('ldap:check-user') ->setDescription('checks whether a user exists on LDAP.') ->addArgument( - 'ocName', - InputArgument::REQUIRED, - 'the user name as used in ownCloud' - ) + 'ocName', + InputArgument::REQUIRED, + 'the user name as used in ownCloud' + ) ->addOption( - 'force', - null, - InputOption::VALUE_NONE, - 'ignores disabled LDAP configuration' - ) + 'force', + null, + InputOption::VALUE_NONE, + 'ignores disabled LDAP configuration' + ) ; } diff --git a/lib/Command/DeleteConfig.php b/lib/Command/DeleteConfig.php index f4ddb9fdb..42a427244 100644 --- a/lib/Command/DeleteConfig.php +++ b/lib/Command/DeleteConfig.php @@ -47,10 +47,10 @@ protected function configure() { ->setName('ldap:delete-config') ->setDescription('deletes an existing LDAP configuration') ->addArgument( - 'configID', - InputArgument::REQUIRED, - 'the configuration ID' - ) + 'configID', + InputArgument::REQUIRED, + 'the configuration ID' + ) ; } diff --git a/lib/Command/Search.php b/lib/Command/Search.php index 1c57ba0c5..25da14706 100644 --- a/lib/Command/Search.php +++ b/lib/Command/Search.php @@ -52,30 +52,30 @@ protected function configure() { ->setName('ldap:search') ->setDescription('executes a user or group search') ->addArgument( - 'search', - InputArgument::REQUIRED, - 'the search string (can be empty)' - ) + 'search', + InputArgument::REQUIRED, + 'the search string (can be empty)' + ) ->addOption( - 'group', - null, - InputOption::VALUE_NONE, - 'searches groups instead of users' - ) + 'group', + null, + InputOption::VALUE_NONE, + 'searches groups instead of users' + ) ->addOption( - 'offset', - null, - InputOption::VALUE_REQUIRED, - 'The offset of the result set. Needs to be a multiple of limit. defaults to 0.', - 0 - ) + 'offset', + null, + InputOption::VALUE_REQUIRED, + 'The offset of the result set. Needs to be a multiple of limit. defaults to 0.', + 0 + ) ->addOption( - 'limit', - null, - InputOption::VALUE_REQUIRED, - 'limit the results. 0 means no limit, defaults to 15', - 15 - ) + 'limit', + null, + InputOption::VALUE_REQUIRED, + 'limit the results. 0 means no limit, defaults to 15', + 15 + ) ; } diff --git a/lib/Command/SetConfig.php b/lib/Command/SetConfig.php index a06dea6ee..5fd0d65e3 100644 --- a/lib/Command/SetConfig.php +++ b/lib/Command/SetConfig.php @@ -50,20 +50,20 @@ protected function configure() { ->setName('ldap:set-config') ->setDescription('modifies an LDAP configuration') ->addArgument( - 'configID', - InputArgument::REQUIRED, - 'the configuration ID' - ) + 'configID', + InputArgument::REQUIRED, + 'the configuration ID' + ) ->addArgument( - 'configKey', - InputArgument::REQUIRED, - 'the configuration key' - ) + 'configKey', + InputArgument::REQUIRED, + 'the configuration key' + ) ->addArgument( - 'configValue', - InputArgument::REQUIRED, - 'the new configuration value' - ) + 'configValue', + InputArgument::REQUIRED, + 'the new configuration value' + ) ; } diff --git a/lib/Command/ShowConfig.php b/lib/Command/ShowConfig.php index 3582414c6..71d919cbf 100644 --- a/lib/Command/ShowConfig.php +++ b/lib/Command/ShowConfig.php @@ -59,16 +59,16 @@ protected function configure() { ->setName('ldap:show-config') ->setDescription('shows the LDAP configuration') ->addArgument( - 'configID', - InputArgument::OPTIONAL, - 'will show the configuration of the specified id' - ) + 'configID', + InputArgument::OPTIONAL, + 'will show the configuration of the specified id' + ) ->addOption( - 'show-password', - null, - InputOption::VALUE_NONE, - 'show ldap bind password' - ) + 'show-password', + null, + InputOption::VALUE_NONE, + 'show ldap bind password' + ) ; } diff --git a/lib/Command/TestConfig.php b/lib/Command/TestConfig.php index e3d4ec3d7..d8e4ca8e2 100644 --- a/lib/Command/TestConfig.php +++ b/lib/Command/TestConfig.php @@ -62,10 +62,10 @@ protected function configure() { ->setName('ldap:test-config') ->setDescription('tests an LDAP configuration') ->addArgument( - 'configID', - InputArgument::REQUIRED, - 'the configuration ID' - ) + 'configID', + InputArgument::REQUIRED, + 'the configuration ID' + ) ; } diff --git a/lib/Configuration.php b/lib/Configuration.php index cc0695225..df68059cf 100644 --- a/lib/Configuration.php +++ b/lib/Configuration.php @@ -187,7 +187,7 @@ public function setConfiguration($config, &$applied = null) { $setMethod = 'setValue'; switch ($key) { case 'ldapAgentPassword': - $val = \filter_var($val, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW); + $val = \filter_var($val, FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_LOW); $setMethod = 'setRawValue'; break; case 'homeFolderNamingRule': @@ -400,9 +400,11 @@ protected function getValue($varName) { if ($defaults === null) { $defaults = $this->getDefaults(); } - return $this->coreConfig->getAppValue('user_ldap', - $this->prefix.$varName, - $defaults[$varName]); + return $this->coreConfig->getAppValue( + 'user_ldap', + $this->prefix.$varName, + $defaults[$varName] + ); } /** @@ -433,9 +435,11 @@ protected function setRawValue($varName, $value) { * @param string $value */ protected function saveValue($varName, $value) { - $this->coreConfig->setAppValue('user_ldap', - $this->prefix.$varName, - $value); + $this->coreConfig->setAppValue( + 'user_ldap', + $this->prefix.$varName, + $value + ); } /** diff --git a/lib/Connection.php b/lib/Connection.php index 4259236a5..dffc94b7a 100644 --- a/lib/Connection.php +++ b/lib/Connection.php @@ -110,9 +110,11 @@ public function __destruct() { * defines behaviour when the instance is cloned */ public function __clone() { - $this->configuration = new Configuration($this->configuration->getCoreConfig(), - $this->configPrefix, - $this->configID !== null); + $this->configuration = new Configuration( + $this->configuration->getCoreConfig(), + $this->configPrefix, + $this->configID !== null + ); $this->ldapConnectionRes = null; } @@ -314,10 +316,12 @@ private function doSoftValidation() { $val = $this->configuration->$keyBase; if (empty($val)) { $obj = \strpos('Users', $keyBase) !== false ? 'Users' : 'Groups'; - Util::writeLog('user_ldap', - 'Base tree for '.$obj. + Util::writeLog( + 'user_ldap', + 'Base tree for '.$obj. ' is empty, using Base DN', - Util::DEBUG); + Util::DEBUG + ); $this->configuration->$keyBase = $this->configuration->ldapBase; } } @@ -330,15 +334,21 @@ private function doSoftValidation() { $this->configuration->$effectiveSetting = $uuidOverride; } else { if ($this->configID !== null && - !\in_array($this->configuration->$effectiveSetting, - \array_merge(['auto'], $this->uuidAttributes), true) + !\in_array( + $this->configuration->$effectiveSetting, + \array_merge(['auto'], $this->uuidAttributes), + true + ) ) { $this->configuration->$effectiveSetting = 'auto'; $this->configuration->saveConfiguration(); - Util::writeLog('user_ldap', - 'Illegal value for the '. + Util::writeLog( + 'user_ldap', + 'Illegal value for the '. $effectiveSetting.', '.'reset to '. - 'autodetect.', Util::INFO); + 'autodetect.', + Util::INFO + ); } } } @@ -362,10 +372,12 @@ private function doSoftValidation() { && \stripos($this->configuration->ldapHost, 'ldaps://') === 0 ) { $this->configuration->ldapTLS = false; - Util::writeLog('user_ldap', - 'LDAPS (already using secure connection) and '. + Util::writeLog( + 'user_ldap', + 'LDAPS (already using secure connection) and '. 'TLS do not work together. Switched off TLS.', - Util::INFO); + Util::INFO + ); } } @@ -403,9 +415,11 @@ private function doCriticalValidation() { break; } $configurationOK = false; - Util::writeLog('user_ldap', - $errorStr.'No '.$subj.' given!', - Util::WARN); + Util::writeLog( + 'user_ldap', + $errorStr.'No '.$subj.' given!', + Util::WARN + ); } } @@ -416,11 +430,13 @@ private function doCriticalValidation() { ($agent === '' && $pwd !== '') || ($agent !== '' && $pwd === '') ) { - Util::writeLog('user_ldap', - $errorStr.'either no password is given for the '. + Util::writeLog( + 'user_ldap', + $errorStr.'either no password is given for the '. 'user agent or a password is given, but not an '. 'LDAP agent.', - Util::WARN); + Util::WARN + ); $configurationOK = false; } @@ -429,18 +445,22 @@ private function doCriticalValidation() { $baseGroups = $this->configuration->ldapBaseGroups; if (empty($base) && empty($baseUsers) && empty($baseGroups)) { - Util::writeLog('user_ldap', - $errorStr.'Not a single Base DN given.', - Util::WARN); + Util::writeLog( + 'user_ldap', + $errorStr.'Not a single Base DN given.', + Util::WARN + ); $configurationOK = false; } if (\mb_strpos($this->configuration->ldapLoginFilter, '%uid', 0, 'UTF-8') === false) { - Util::writeLog('user_ldap', - $errorStr.'login filter does not contain %uid '. + Util::writeLog( + 'user_ldap', + $errorStr.'login filter does not contain %uid '. 'place holder.', - Util::WARN); + Util::WARN + ); $configurationOK = false; } @@ -482,30 +502,38 @@ private function establishConnection() { return false; } if (!$this->ignoreValidation && !$this->configured) { - Util::writeLog('user_ldap', - 'Configuration is invalid, cannot connect', - Util::WARN); + Util::writeLog( + 'user_ldap', + 'Configuration is invalid, cannot connect', + Util::WARN + ); return false; } if (!$this->ldapConnectionRes) { if (!$this->getLDAP()->areLDAPFunctionsAvailable()) { $phpLDAPinstalled = false; - Util::writeLog('user_ldap', - 'function ldap_connect is not available. Make '. + Util::writeLog( + 'user_ldap', + 'function ldap_connect is not available. Make '. 'sure that the PHP ldap module is installed.', - Util::ERROR); + Util::ERROR + ); return false; } if ($this->configuration->turnOffCertCheck) { if (\putenv('LDAPTLS_REQCERT=never')) { - Util::writeLog('user_ldap', + Util::writeLog( + 'user_ldap', 'Turned off SSL certificate validation successfully.', - Util::DEBUG); + Util::DEBUG + ); } else { - Util::writeLog('user_ldap', - 'Could not turn off SSL certificate validation.', - Util::WARN); + Util::writeLog( + 'user_ldap', + 'Could not turn off SSL certificate validation.', + Util::WARN + ); } } @@ -517,18 +545,22 @@ private function establishConnection() { && !$this->getFromCache('overrideMainServer')) ) { $this->doConnect( - $this->configuration->ldapHost, - $this->configuration->ldapPort); + $this->configuration->ldapHost, + $this->configuration->ldapPort + ); if (@$this->ldap->bind( - $this->ldapConnectionRes, - $this->configuration->ldapAgentName, - $this->configuration->ldapAgentPassword) + $this->ldapConnectionRes, + $this->configuration->ldapAgentName, + $this->configuration->ldapAgentPassword + ) ) { return true; } - Util::writeLog('user_ldap', + Util::writeLog( + 'user_ldap', 'Bind failed: ' . $this->getLDAP()->errno($this->ldapConnectionRes) . ': ' . $this->getLDAP()->error($this->ldapConnectionRes), - Util::DEBUG); + Util::DEBUG + ); throw new BindFailedException(); } } catch (ServerNotAvailableException $e) { @@ -547,16 +579,20 @@ private function establishConnection() { } // try the Backup (Replica!) Server - Util::writeLog('user_ldap', + Util::writeLog( + 'user_ldap', 'Trying to connect to backup server '.$this->configuration->ldapBackupHost.':'.$this->configuration->ldapBackupPort, - Util::DEBUG); + Util::DEBUG + ); $this->doConnect( - $this->configuration->ldapBackupHost, - $this->configuration->ldapBackupPort); + $this->configuration->ldapBackupHost, + $this->configuration->ldapBackupPort + ); if (@$this->ldap->bind( - $this->ldapConnectionRes, - $this->configuration->ldapAgentName, - $this->configuration->ldapAgentPassword) + $this->ldapConnectionRes, + $this->configuration->ldapAgentName, + $this->configuration->ldapAgentPassword + ) ) { if (!$this->getFromCache('overrideMainServer')) { //when bind to backup server succeeded and failed to main server, @@ -565,9 +601,11 @@ private function establishConnection() { } return true; } - Util::writeLog('user_ldap', + Util::writeLog( + 'user_ldap', 'Bind to backup server failed: ' . $this->getLDAP()->errno($this->ldapConnectionRes) . ': ' . $this->getLDAP()->error($this->ldapConnectionRes), - Util::DEBUG); + Util::DEBUG + ); throw new BindFailedException(); } return null; diff --git a/lib/Controller/ConfigurationController.php b/lib/Controller/ConfigurationController.php index 3899d90d7..6d08a26d9 100644 --- a/lib/Controller/ConfigurationController.php +++ b/lib/Controller/ConfigurationController.php @@ -63,13 +63,14 @@ class ConfigurationController extends Controller { * @param LDAP $ldapWrapper * @param Helper $helper */ - public function __construct($appName, - IRequest $request, - IConfig $config, - ISession $session, - IL10N $l10n, - LDAP $ldapWrapper, - Helper $helper + public function __construct( + $appName, + IRequest $request, + IConfig $config, + ISession $session, + IL10N $l10n, + LDAP $ldapWrapper, + Helper $helper ) { parent::__construct($appName, $request); $this->config = $config; diff --git a/lib/Controller/MappingController.php b/lib/Controller/MappingController.php index 181aeda20..9e3ac5e0e 100644 --- a/lib/Controller/MappingController.php +++ b/lib/Controller/MappingController.php @@ -49,10 +49,11 @@ class MappingController extends Controller { * @param IL10N $l10n * @param IDBConnection $connection */ - public function __construct($appName, - IRequest $request, - IL10N $l10n, - IDBConnection $connection + public function __construct( + $appName, + IRequest $request, + IL10N $l10n, + IDBConnection $connection ) { parent::__construct($appName, $request); $this->l10n = $l10n; diff --git a/lib/Controller/WizardController.php b/lib/Controller/WizardController.php index c9e100771..e546a3d84 100644 --- a/lib/Controller/WizardController.php +++ b/lib/Controller/WizardController.php @@ -61,12 +61,13 @@ class WizardController extends Controller { * @param IL10N $l10n * @param LDAP $ldapWrapper */ - public function __construct($appName, - IRequest $request, - IConfig $config, - Manager $manager, - IL10N $l10n, - LDAP $ldapWrapper + public function __construct( + $appName, + IRequest $request, + IConfig $config, + Manager $manager, + IL10N $l10n, + LDAP $ldapWrapper ) { parent::__construct($appName, $request); $this->config = $config; diff --git a/lib/Group_LDAP.php b/lib/Group_LDAP.php index 7c4275692..aabf77d3d 100644 --- a/lib/Group_LDAP.php +++ b/lib/Group_LDAP.php @@ -219,8 +219,11 @@ private function _groupMembers($dnGroup, &$seen = null) { return $groupMembers; } $seen[$dnGroup] = 1; - $members = $this->access->readAttribute($dnGroup, $this->access->getConnection()->ldapGroupMemberAssocAttr, - $this->access->getConnection()->ldapGroupFilter); + $members = $this->access->readAttribute( + $dnGroup, + $this->access->getConnection()->ldapGroupMemberAssocAttr, + $this->access->getConnection()->ldapGroupFilter + ); if (\is_array($members)) { foreach ($members as $memberDN) { $allMembers[$memberDN] = 1; @@ -479,7 +482,9 @@ public function getUserGroups($uid) { if (!empty($dynamicGroupMemberURL)) { // look through dynamic groups to add them to the result array if needed $groupsToMatch = $this->access->fetchListOfGroups( - $this->access->getConnection()->ldapGroupFilter, ['dn',$dynamicGroupMemberURL]); + $this->access->getConnection()->ldapGroupFilter, + ['dn',$dynamicGroupMemberURL] + ); foreach ($groupsToMatch as $dynamicGroup) { if (!\array_key_exists($dynamicGroupMemberURL, $dynamicGroup)) { continue; @@ -590,8 +595,10 @@ private function getGroupsByMember($dn, &$seen = null) { $this->access->getConnection()->ldapGroupFilter, $this->access->getConnection()->ldapGroupMemberAssocAttr.'='.$escapedDn ]); - $groups = $this->access->fetchListOfGroups($filter, - [$this->access->getConnection()->ldapGroupDisplayName, 'dn']); + $groups = $this->access->fetchListOfGroups( + $filter, + [$this->access->getConnection()->ldapGroupDisplayName, 'dn'] + ); if (\is_array($groups)) { foreach ($groups as $groupobj) { $groupDN = $groupobj['dn'][0]; @@ -687,9 +694,11 @@ public function usersInGroup($gid, $search = '', $limit = -1, $offset = 0) { $this->access->connection->ldapUserFilter, $this->access->getFilterPartForUserSearch($search)]); } - if (!\is_array($this->access->readAttribute($member, - $this->access->connection->ldapUserDisplayName, - $filter))) { + if (!\is_array($this->access->readAttribute( + $member, + $this->access->connection->ldapUserDisplayName, + $filter + ))) { continue; } // dn2username will also check if the users belong to the allowed base @@ -773,9 +782,11 @@ public function countUsersInGroup($gid, $search = '') { $groupUsers[] = $this->access->dn2username($ldap_users[0]); } else { //we need to apply the search filter now - if (!$this->access->readAttribute($member, + if (!$this->access->readAttribute( + $member, $this->access->getConnection()->ldapUserDisplayName, - $this->access->getFilterPartForUserSearch($search))) { + $this->access->getFilterPartForUserSearch($search) + )) { continue; } // dn2username will also check if the users belong to the allowed base @@ -830,10 +841,12 @@ protected function getGroupsChunk($search = '', $limit = -1, $offset = 0) { $this->access->getFilterPartForGroupSearch($search) ]); \OCP\Util::writeLog('user_ldap', 'getGroups Filter '.$filter, \OCP\Util::DEBUG); - $ldap_groups = $this->access->fetchListOfGroups($filter, - [$this->access->getConnection()->ldapGroupDisplayName, 'dn'], - $limit, - $offset); + $ldap_groups = $this->access->fetchListOfGroups( + $filter, + [$this->access->getConnection()->ldapGroupDisplayName, 'dn'], + $limit, + $offset + ); $ldap_groups = $this->access->ownCloudGroupNames($ldap_groups); $this->access->getConnection()->writeToCache($cacheKey, $ldap_groups); diff --git a/lib/Group_Proxy.php b/lib/Group_Proxy.php index 41b92d8c7..aa1b1891a 100644 --- a/lib/Group_Proxy.php +++ b/lib/Group_Proxy.php @@ -164,7 +164,10 @@ public function usersInGroup($gid, $search = '', $limit = -1, $offset = 0) { */ public function countUsersInGroup($gid, $search = '') { return $this->handleRequest( - $gid, 'countUsersInGroup', [$gid, $search]); + $gid, + 'countUsersInGroup', + [$gid, $search] + ); } /** diff --git a/lib/Helper.php b/lib/Helper.php index ae8fa8339..2f014a70d 100644 --- a/lib/Helper.php +++ b/lib/Helper.php @@ -201,7 +201,9 @@ public function loginName2UserName($param) { $ocConfig = \OC::$server->getConfig(); $userBackend = new User_Proxy( - $configPrefixes, $ldapWrapper, $ocConfig + $configPrefixes, + $ldapWrapper, + $ocConfig ); $uid = $userBackend->loginName2UserName($param['uid']); if ($uid !== false) { diff --git a/lib/ILDAPWrapper.php b/lib/ILDAPWrapper.php index ca16b9c16..eeb2288d6 100644 --- a/lib/ILDAPWrapper.php +++ b/lib/ILDAPWrapper.php @@ -29,12 +29,12 @@ interface ILDAPWrapper { // see http://php.net/manual/en/function.ldap-errno.php#20665 // and https://ldapwiki.com/wiki/LDAP%20Result%20Codes - const LDAP_SUCCESS = 0x00; - const LDAP_OPERATIONS_ERROR = 0x01; - const LDAP_REFERRAL = 0x0a; - const LDAP_NO_SUCH_OBJECT = 0x20; - const LDAP_INAPPROPRIATE_AUTH = 0x30; - const LDAP_INVALID_CREDENTIALS = 0x31; + public const LDAP_SUCCESS = 0x00; + public const LDAP_OPERATIONS_ERROR = 0x01; + public const LDAP_REFERRAL = 0x0a; + public const LDAP_NO_SUCH_OBJECT = 0x20; + public const LDAP_INAPPROPRIATE_AUTH = 0x30; + public const LDAP_INVALID_CREDENTIALS = 0x31; //LDAP functions in use diff --git a/lib/LDAP.php b/lib/LDAP.php index 6b6689981..ca998f682 100644 --- a/lib/LDAP.php +++ b/lib/LDAP.php @@ -69,8 +69,10 @@ public function connect($host, $port) { * @return bool|LDAP */ public function controlPagedResultResponse($link, $result, &$cookie = null, &$estimated = null) { - $this->preFunctionCall('ldap_control_paged_result_response', - [$link, $result, $cookie, $estimated]); + $this->preFunctionCall( + 'ldap_control_paged_result_response', + [$link, $result, $cookie, $estimated] + ); $result = @\ldap_control_paged_result_response($link, $result, $cookie, $estimated); // suppress deprecation for 7.4 $this->postFunctionCall(); @@ -262,7 +264,8 @@ public function isResource($resource) { } private function formatLdapCallArguments($func, $arguments) { - $argumentsLog = \implode(",", + $argumentsLog = \implode( + ",", \array_map( function ($argument) { if (\is_string($argument) || \is_bool($argument) || \is_numeric($argument)) { diff --git a/lib/Mapping/AbstractMapping.php b/lib/Mapping/AbstractMapping.php index 82bad75f5..d9dc8bd1d 100644 --- a/lib/Mapping/AbstractMapping.php +++ b/lib/Mapping/AbstractMapping.php @@ -202,7 +202,8 @@ public function getUUIDByDN($dn) { * @return array */ public function getList($offset = null, $limit = null) { - $query = $this->dbc->prepare(' + $query = $this->dbc->prepare( + ' SELECT `ldap_dn` AS `dn`, `owncloud_name` AS `name`, diff --git a/lib/User/Manager.php b/lib/User/Manager.php index 53ab8919a..ac8d892c4 100644 --- a/lib/User/Manager.php +++ b/lib/User/Manager.php @@ -51,7 +51,7 @@ class Manager { /** * DB config keys for user preferences */ - const USER_PREFKEY_FIRSTLOGIN = 'firstLoginAccomplished'; + public const USER_PREFKEY_FIRSTLOGIN = 'firstLoginAccomplished'; /** @var Access */ protected $access; @@ -93,10 +93,14 @@ class Manager { * @param IDBConnection $db * @throws \Exception when the methods mentioned above do not exist */ - public function __construct(IConfig $ocConfig, - FilesystemHelper $ocFilesystem, ILogger $logger, - IAvatarManager $avatarManager, - IDBConnection $db, IUserManager $userManager) { + public function __construct( + IConfig $ocConfig, + FilesystemHelper $ocFilesystem, + ILogger $logger, + IAvatarManager $avatarManager, + IDBConnection $db, + IUserManager $userManager + ) { $this->ocConfig = $ocConfig; $this->ocFilesystem = $ocFilesystem; $this->logger = $logger; @@ -204,7 +208,8 @@ public function getUserEntryByDn($dn) { $dn, $this->getAttributes(), $this->getConnection()->ldapUserFilter, - 20); // TODO why 20? why is 1 not sufficient? + 20 + ); // TODO why 20? why is 1 not sufficient? if ($result === false || $result['count'] === 0) { // FIXME the ldap error ($result = false) should bubble up ... and not be converted to a DoesNotExistOnLDAPException throw new DoesNotExistOnLDAPException($dn); @@ -445,8 +450,18 @@ private function setOwnCloudAvatar(UserEntry $userEntry, Image $image) { * @param string $uid */ public function markLogin($uid) { - $this->ocConfig->setUserValue( - $uid, 'user_ldap', self::USER_PREFKEY_FIRSTLOGIN, 1); + if ($this->ocConfig->getUserValue( + $uid, + 'user_ldap', + self::USER_PREFKEY_FIRSTLOGIN + ) !== '1') { + $this->ocConfig->setUserValue( + $uid, + 'user_ldap', + self::USER_PREFKEY_FIRSTLOGIN, + '1' + ); + } } /** @@ -489,17 +504,21 @@ public function getUsers($search = '', $limit = 10, $offset = 0) { $this->access->getFilterPartForUserSearch($search) ]); - $this->logger->debug('getUsers: Options: search '.$search + $this->logger->debug( + 'getUsers: Options: search '.$search .' limit '.$limit .' offset ' .$offset .' Filter: '.$filter, - ['app' => self::class]); + ['app' => self::class] + ); //do the search and translate results to owncloud names $ldap_users = $this->fetchListOfUsers( $filter, $this->getAttributes(), - $limit, $offset); + $limit, + $offset + ); $ownCloudUserNames = []; foreach ($ldap_users as $ldapEntry) { try { diff --git a/lib/User/UserEntry.php b/lib/User/UserEntry.php index 5728dead8..5e683a84f 100644 --- a/lib/User/UserEntry.php +++ b/lib/User/UserEntry.php @@ -279,8 +279,10 @@ public function getHome() { //if attribute's value is an absolute path take this, otherwise append it to data dir //check for / at the beginning if ($path[0] !== '/') { - $path = $this->config->getSystemValue('datadirectory', - \OC::$SERVERROOT.'/data') . '/' . $path; + $path = $this->config->getSystemValue( + 'datadirectory', + \OC::$SERVERROOT.'/data' + ) . '/' . $path; } return $path; } diff --git a/lib/User_LDAP.php b/lib/User_LDAP.php index 9beeaecbe..1a794e1bb 100644 --- a/lib/User_LDAP.php +++ b/lib/User_LDAP.php @@ -217,8 +217,10 @@ public function userExists($uid) { * @return bool */ public function deleteUser($uid) { - \OC::$server->getLogger()->info('Cleaning up after user ' . $uid, - ['app' => 'user_ldap']); + \OC::$server->getLogger()->info( + 'Cleaning up after user ' . $uid, + ['app' => 'user_ldap'] + ); $this->userManager->getUserMapper()->unmap($uid); diff --git a/lib/Wizard.php b/lib/Wizard.php index 40ca9c108..c54fa6688 100644 --- a/lib/Wizard.php +++ b/lib/Wizard.php @@ -45,18 +45,18 @@ class Wizard extends LDAPUtility { protected $result; protected $resultCache = []; - const LRESULT_PROCESSED_OK = 2; - const LRESULT_PROCESSED_INVALID = 3; - const LRESULT_PROCESSED_SKIP = 4; + public const LRESULT_PROCESSED_OK = 2; + public const LRESULT_PROCESSED_INVALID = 3; + public const LRESULT_PROCESSED_SKIP = 4; - const LFILTER_LOGIN = 2; - const LFILTER_USER_LIST = 3; - const LFILTER_GROUP_LIST = 4; + public const LFILTER_LOGIN = 2; + public const LFILTER_USER_LIST = 3; + public const LFILTER_GROUP_LIST = 4; - const LFILTER_MODE_ASSISTED = 2; - const LFILTER_MODE_RAW = 1; + public const LFILTER_MODE_ASSISTED = 2; + public const LFILTER_MODE_RAW = 1; - const LDAP_NW_TIMEOUT = 4; + public const LDAP_NW_TIMEOUT = 4; /** * Constructor @@ -367,9 +367,11 @@ private function getUserAttributes() { * @return WizardResult|false the instance's WizardResult instance */ public function determineGroupsForGroups() { - return $this->determineGroups('ldap_groupfilter_groups', - 'ldapGroupFilterGroups', - false); + return $this->determineGroups( + 'ldap_groupfilter_groups', + 'ldapGroupFilterGroups', + false + ); } /** @@ -377,8 +379,10 @@ public function determineGroupsForGroups() { * @return WizardResult|false the instance's WizardResult instance */ public function determineGroupsForUsers() { - return $this->determineGroups('ldap_userfilter_groups', - 'ldapUserFilterGroups'); + return $this->determineGroups( + 'ldap_userfilter_groups', + 'ldapUserFilterGroups' + ); } /** @@ -504,11 +508,13 @@ public function determineGroupObjectClasses() { } $obclasses = ['groupOfNames', 'group', 'posixGroup', 'groupOfUniqueNames', '*']; - $this->determineFeature($obclasses, - 'objectclass', - 'ldap_groupfilter_objectclass', - 'ldapGroupFilterObjectclass', - false); + $this->determineFeature( + $obclasses, + 'objectclass', + 'ldap_groupfilter_objectclass', + 'ldapGroupFilterObjectclass', + false + ); return $this->result; } @@ -535,11 +541,13 @@ public function determineUserObjectClasses() { $filter = $this->configuration->ldapUserFilter; //if filter is empty, it is probably the first time the wizard is called //then, apply suggestions. - $this->determineFeature($obclasses, - 'objectclass', - 'ldap_userfilter_objectclass', - 'ldapUserFilterObjectclass', - empty($filter)); + $this->determineFeature( + $obclasses, + 'objectclass', + 'ldap_userfilter_objectclass', + 'ldapUserFilterObjectclass', + empty($filter) + ); return $this->result; } @@ -559,8 +567,10 @@ public function getGroupFilter() { $displayName = $this->configuration->ldapGroupDisplayName; if ($displayName === '') { $d = $this->configuration->getDefaults(); - $this->applyFind('ldap_group_display_name', - $d['ldap_group_display_name']); + $this->applyFind( + 'ldap_group_display_name', + $d['ldap_group_display_name'] + ); } $filter = $this->composeLdapFilter(self::LFILTER_GROUP_LIST); @@ -1058,9 +1068,11 @@ public function cumulativeSearchOnAttribute($filters, $attr, $dnReadLimit = 3, & continue; } $newItems = []; - $state = $this->getAttributeValuesFromEntry($attributes, - $attr, - $newItems); + $state = $this->getAttributeValuesFromEntry( + $attributes, + $attr, + $newItems + ); $dnReadCount++; $foundItems = \array_merge($foundItems, $newItems); $this->resultCache[$dn][$attr] = $newItems; @@ -1102,8 +1114,12 @@ private function determineFeature($objectclasses, $attr, $dbkey, $confkey, $po = $dig = 3; $availableFeatures = - $this->cumulativeSearchOnAttribute($objectclasses, $attr, - $dig, $maxEntryObjC); + $this->cumulativeSearchOnAttribute( + $objectclasses, + $attr, + $dig, + $maxEntryObjC + ); if (\is_array($availableFeatures) && \count($availableFeatures) > 0) { \natcasesort($availableFeatures); @@ -1181,9 +1197,11 @@ private function getConnection() { $this->getLDAP()->startTls($cr); } - $lo = @$this->getLDAP()->bind($cr, - $this->configuration->ldapAgentName, - $this->configuration->ldapAgentPassword); + $lo = @$this->getLDAP()->bind( + $cr, + $this->configuration->ldapAgentName, + $this->configuration->ldapAgentPassword + ); if ($lo === true) { $this->$cr = $cr; return $cr; diff --git a/templates/part.wizard-groupfilter.php b/templates/part.wizard-groupfilter.php index 5c406450f..1c6a2d344 100644 --- a/templates/part.wizard-groupfilter.php +++ b/templates/part.wizard-groupfilter.php @@ -1,5 +1,5 @@
-
+

t('Groups meeting these criteria are available in %s:', $theme->getName()));?>

@@ -58,5 +58,5 @@

-
+
diff --git a/templates/part.wizard-loginfilter.php b/templates/part.wizard-loginfilter.php index fdf21e392..44ac1c7da 100644 --- a/templates/part.wizard-loginfilter.php +++ b/templates/part.wizard-loginfilter.php @@ -7,14 +7,14 @@
- t('Allows login against the LDAP / AD username, which is either uid or samaccountname and will be detected.'));?>" + t('Allows login against the LDAP / AD username, which is either uid or samaccountname and will be detected.'));?>
- t('Allows login against an email attribute. Mail and mailPrimaryAddress will be allowed. WARNING: Disabling login with email might require enabling strict login checking to be effective, please refer to ownCloud documentation for more details!'));?> + t('Allows login against an email attribute. Mail and mailPrimaryAddress will be allowed. WARNING: Disabling login with email might require enabling strict login checking to be effective, please refer to ownCloud documentation for more details!'));?>
@@ -27,13 +27,13 @@
@@ -44,7 +44,7 @@
- Attempts to receive a DN for the given loginname and the current login filter + Attempts to receive a DN for the given loginname and the current login filter
diff --git a/templates/part.wizard-server.php b/templates/part.wizard-server.php index 808f3e0e9..ef047824f 100644 --- a/templates/part.wizard-server.php +++ b/templates/part.wizard-server.php @@ -56,7 +56,7 @@ class="ldapIconCopy icon-default-style"
- t('You can omit the protocol, except you require SSL. Then start with ldaps://')); ?> + t('You can omit the protocol, except you require SSL. Then start with ldaps://')); ?>
@@ -64,7 +64,7 @@ class="ldapIconCopy icon-default-style"
- t('Enable StartTLS support (also known as LDAP over TLS) for the connection. Note that this is different than LDAPS (LDAP over SSL) which doesn\'t need this checkbox checked. You\'ll need to import the LDAP server\'s certificate in your %s server.', $theme->getName())); ?> + t('Enable StartTLS support (also known as LDAP over TLS) for the connection. Note that this is different than LDAPS (LDAP over SSL) which doesn\'t need this checkbox checked. You\'ll need to import the LDAP server\'s certificate in your %s server.', $theme->getName())); ?>
@@ -72,7 +72,7 @@ class="ldapIconCopy icon-default-style"
- t('The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty.')); ?> + t('The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty.')); ?>
@@ -80,7 +80,7 @@ class="ldapIconCopy icon-default-style"
- t('For anonymous access, leave DN and Password empty.')); ?> + t('For anonymous access, leave DN and Password empty.')); ?>
@@ -89,7 +89,7 @@ class="ldapIconCopy icon-default-style"
- t('You can specify Base DN for users and groups in the Advanced tab')); ?> + t('You can specify Base DN for users and groups in the Advanced tab')); ?>
@@ -105,7 +105,7 @@ class="ldapIconCopy icon-default-style"
- t('Avoids automatic LDAP requests. Better for bigger setups, but requires some LDAP knowledge.')); ?> + t('Avoids automatic LDAP requests. Better for bigger setups, but requires some LDAP knowledge.')); ?>
diff --git a/templates/part.wizard-userfilter.php b/templates/part.wizard-userfilter.php index e39580d24..029c4db41 100644 --- a/templates/part.wizard-userfilter.php +++ b/templates/part.wizard-userfilter.php @@ -7,7 +7,7 @@
- t('The most common object classes for users are organizationalPerson, person, user, and inetOrgPerson. If you are not sure which object class to select, please consult your directory admin.'));?> + t('The most common object classes for users are organizationalPerson, person, user, and inetOrgPerson. If you are not sure which object class to select, please consult your directory admin.'));?>
@@ -45,7 +45,7 @@
- t('The filter specifies which LDAP users shall have access to the %s instance.', $theme->getName()));?> + t('The filter specifies which LDAP users shall have access to the %s instance.', $theme->getName()));?>
diff --git a/templates/part.wizardcontrols.php b/templates/part.wizardcontrols.php index 19ffd2858..537dde186 100644 --- a/templates/part.wizardcontrols.php +++ b/templates/part.wizardcontrols.php @@ -1,5 +1,5 @@
- +
diff --git a/templates/settings.php b/templates/settings.php index b4ba5e7b4..371fba185 100644 --- a/templates/settings.php +++ b/templates/settings.php @@ -52,7 +52,7 @@
-

t('LDAP')); ?>

+

t('LDAP')); ?>

t('Backup (Replica) Host')); ?>
- t('Give an optional backup host. It must be a replica of the main LDAP/AD server.')); ?> + t('Give an optional backup host. It must be a replica of the main LDAP/AD server.')); ?>
@@ -103,25 +108,25 @@
- t('Only connect to the replica server.')); ?> + t('Only connect to the replica server.')); ?>
- t('Not recommended, use it for testing only! If connection only works with this option, import the LDAP server\'s SSL certificate in your %s server.', $theme->getName())); ?> + t('Not recommended, use it for testing only! If connection only works with this option, import the LDAP server\'s SSL certificate in your %s server.', $theme->getName())); ?>
- t('in seconds. A change empties the cache.')); ?> + t('in seconds. A change empties the cache.')); ?>
- t('timeout for all the ldap network operations, in seconds.')); ?> + t('timeout for all the ldap network operations, in seconds.')); ?>
@@ -134,28 +139,28 @@
- t('The LDAP attribute to use to generate the user\'s display name.')); ?> + t('The LDAP attribute to use to generate the user\'s display name.')); ?>
- t('Optional. An LDAP attribute to be added to the display name in brackets. Results in e.g. »John Doe (john.doe@example.org)«.')); ?> + t('Optional. An LDAP attribute to be added to the display name in brackets. Results in e.g. »John Doe (john.doe@example.org)«.')); ?>
- t('Base User Tree')); ?> + t('Base User Tree')); ?>
- t('User Search Attributes')); ?> + t('User Search Attributes')); ?>
@@ -166,21 +171,21 @@
- t('The LDAP attribute to use to generate the groups\'s display name.')); ?> + t('The LDAP attribute to use to generate the groups\'s display name.')); ?>
- t('Base Group Tree')); ?> + t('Base Group Tree')); ?>
- t('Group Search Attributes')); ?> + t('Group Search Attributes')); ?>
@@ -200,19 +205,19 @@
- t('The LDAP attribute that on group objects contains an LDAP search URL that determines what objects belong to the group. (An empty setting disables dynamic group membership functionality.)')); ?> + t('The LDAP attribute that on group objects contains an LDAP search URL that determines what objects belong to the group. (An empty setting disables dynamic group membership functionality.)')); ?>
- t('When switched on, groups that contain groups are supported. (Only works if the group member attribute contains DNs.)')); ?> + t('When switched on, groups that contain groups are supported. (Only works if the group member attribute contains DNs.)')); ?>
- t('Chunksize used for paged LDAP searches that may return bulky results like user or group enumeration. (Setting it 0 disables paged LDAP searches in those situations.)')); ?> + t('Chunksize used for paged LDAP searches that may return bulky results like user or group enumeration. (Setting it 0 disables paged LDAP searches in those situations.)')); ?>
@@ -225,28 +230,28 @@
- t('Leave empty for user\'s default quota. Otherwise, specify an LDAP/AD attribute.')); ?> + t('Leave empty for user\'s default quota. Otherwise, specify an LDAP/AD attribute.')); ?>
- t('Override default quota for LDAP users who do not have a quota set in the Quota Field.')); ?> + t('Override default quota for LDAP users who do not have a quota set in the Quota Field.')); ?>
- t('Set the user\'s email from their LDAP attribute. Leave it empty for default behaviour.')); ?> + t('Set the user\'s email from their LDAP attribute. Leave it empty for default behaviour.')); ?>
- t('Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute.')); ?> + t('Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute.')); ?>
@@ -257,7 +262,7 @@

t('Internal Username')); ?>

-

t('By default the internal username will be created from the UUID attribute. It makes sure that the username is unique and characters do not need to be converted. The internal username has the restriction that only these characters are allowed: [ a-zA-Z0-9+_.@- ]. Other characters are replaced with their ASCII correspondence or simply omitted. On collisions a number will be added/increased. The internal username is used to identify a user internally. It is also the default name for the user home folder. It is also a part of remote URLs, for instance for all *DAV services. With this setting, the default behavior can be overridden. To achieve a similar behavior as before ownCloud 5 enter the user display name attribute in the following field. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users.')); ?>

+

t('By default the internal username will be created from the UUID attribute. It makes sure that the username is unique and characters do not need to be converted. The internal username has the restriction that only these characters are allowed: [ a-zA-Z0-9+_.@- ]. Other characters are replaced with their ASCII correspondence or simply omitted. On collisions a number will be added/increased. The internal username is used to identify a user internally. It is also the default name for the user home folder. It is also a part of remote URLs, for instance for all *DAV services. With this setting, the default behavior can be overridden. To do so, enter the user display name attribute in the following field. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users.')); ?>

diff --git a/tests/acceptance/features/bootstrap/UserLdapGeneralContext.php b/tests/acceptance/features/bootstrap/UserLdapGeneralContext.php index 6b6573503..1fa58f6c3 100644 --- a/tests/acceptance/features/bootstrap/UserLdapGeneralContext.php +++ b/tests/acceptance/features/bootstrap/UserLdapGeneralContext.php @@ -73,7 +73,9 @@ public function createNewLdapConfig($configId) { * @throws Exception */ public function ldapConfigHasKeySetTo( - $configId, $configKey, $configValue + $configId, + $configKey, + $configValue ) { $oldConfig = $this->featureContext->getOldLdapConfig(); if (!isset($oldConfig[$configId][$configKey])) { @@ -117,7 +119,9 @@ public function ldapConfigHasKeySetTo( public function ldapConfigHasTheseSettings($configId, TableNode $table) { foreach ($table as $line) { $this->ldapConfigHasKeySetTo( - $configId, $line['key'], $line['value'] + $configId, + $line['key'], + $line['value'] ); } } @@ -164,7 +168,10 @@ public function theAdminListsTheEnabledBackendsUsingTheOccCommand() { * @throws LdapException */ public function setTheLdapAttributeOfTheEntryTo( - $attribute, $entry, $value, $append=false + $attribute, + $entry, + $value, + $append=false ) { $ldap = $this->featureContext->getLdap(); $ldapEntry = $ldap->getEntry($entry . "," . $this->featureContext->getLdapBaseDN()); @@ -187,12 +194,16 @@ public function theLdapAttributeOfTheEntryToTable($attribute, $entry, $table) { foreach ($table as $row) { if ($first) { $this->setTheLdapAttributeOfTheEntryTo( - $attribute, $entry, $row + $attribute, + $entry, + $row ); $first = false; } else { $this->addValueToLdapAttributeOfTheEntry( - $attribute, $entry, $row + $attribute, + $entry, + $row ); } } @@ -209,12 +220,16 @@ public function theLdapAttributeOfTheEntryToTable($attribute, $entry, $table) { * @throws LdapException */ public function theLdapAttributeOfTheEntryToContentOfFile( - $attribute, $entry, $filename + $attribute, + $entry, + $filename ) { $value = \file_get_contents(\getenv("FILES_FOR_UPLOAD") . $filename); $this->setTheLdapAttributeOfTheEntryTo( - $attribute, $entry, $value + $attribute, + $entry, + $value ); } @@ -258,7 +273,8 @@ public function deleteTheLdapEntry($entry) { public function deleteValueFromLdapAttribute($value, $attribute, $entry) { $ldap = $this->featureContext->getLdap(); $ldap->deleteAttributes( - $entry . "," . $this->featureContext->getLdapBaseDN(), [$attribute => [$value]] + $entry . "," . $this->featureContext->getLdapBaseDN(), + [$attribute => [$value]] ); } @@ -291,7 +307,10 @@ public function theAdminImportsThisLdifData(PyStringNode $ldifData) { public function createLDAPUsers($amount, $prefix, $ou) { $ldap = $this->featureContext->getLdap(); $uidNumberSearch = $ldap->searchEntries( - 'objectClass=posixAccount', null, 0, ['uidNumber'] + 'objectClass=posixAccount', + null, + 0, + ['uidNumber'] ); $maxUidNumber = 0; foreach ($uidNumberSearch as $searchResult) { @@ -328,7 +347,11 @@ public function createLDAPUsers($amount, $prefix, $ou) { $ldap->add($newDN, $entry); $this->featureContext->addUserToCreatedUsersList( - $uid, $uid, $uid, null, false + $uid, + $uid, + $uid, + null, + false ); if ($ouExists) { diff --git a/tests/acceptance/features/bootstrap/UserLdapUsersContext.php b/tests/acceptance/features/bootstrap/UserLdapUsersContext.php index 21b9eef75..567307758 100644 --- a/tests/acceptance/features/bootstrap/UserLdapUsersContext.php +++ b/tests/acceptance/features/bootstrap/UserLdapUsersContext.php @@ -85,7 +85,9 @@ public function addUserToLdapGroup($user, $group, $ou = null) { } $this->userLdapGeneralContext->addValueToLdapAttributeOfTheEntry( - $user, "memberUid", "cn=$group,ou=$ou" + $user, + "memberUid", + "cn=$group,ou=$ou" ); $this->featureContext->theLdapUsersHaveBeenReSynced(); // To sync new ldap groups @@ -108,7 +110,9 @@ public function removeUserFromLdapGroup($user, $group, $ou = null) { $ou = $this->featureContext->getLdapGroupsOU(); } $this->userLdapGeneralContext->deleteValueFromLdapAttribute( - $user, "memberUid", "cn=$group,ou=$ou" + $user, + "memberUid", + "cn=$group,ou=$ou" ); } diff --git a/tests/acceptance/features/bootstrap/bootstrap.php b/tests/acceptance/features/bootstrap/bootstrap.php index fd82a9bb6..cf7a56c3c 100644 --- a/tests/acceptance/features/bootstrap/bootstrap.php +++ b/tests/acceptance/features/bootstrap/bootstrap.php @@ -24,21 +24,31 @@ $classLoader = new \Composer\Autoload\ClassLoader(); $classLoader->addPsr4( - "", __DIR__ . "/../../../../../../tests/acceptance/features/bootstrap", true + "", + __DIR__ . "/../../../../../../tests/acceptance/features/bootstrap", + true ); $classLoader->addPsr4("Page\\", __DIR__ . "/../lib", true); $classLoader->addPsr4( - "Page\\", __DIR__ . "/../../../../../../tests/acceptance/features/lib", true + "Page\\", + __DIR__ . "/../../../../../../tests/acceptance/features/lib", + true ); $classLoader->addPsr4( - "TestHelpers\\", __DIR__ . "/../../../../../../tests/TestHelpers", true + "TestHelpers\\", + __DIR__ . "/../../../../../../tests/TestHelpers", + true ); // Some tests require User management app $classLoader->addPsr4( - "", __DIR__ . "/../../../../../../apps/user_management/tests/acceptance/features/bootstrap", true + "", + __DIR__ . "/../../../../../../apps/user_management/tests/acceptance/features/bootstrap", + true ); $classLoader->addPsr4( - "Page\\", __DIR__ . "/../../../../../../apps/user_management/tests/acceptance/features/lib", true + "Page\\", + __DIR__ . "/../../../../../../apps/user_management/tests/acceptance/features/lib", + true ); $classLoader->register(); diff --git a/tests/acceptance/features/webUIProvisioning/users.feature b/tests/acceptance/features/webUIProvisioning/users.feature index f217d86b3..bcb603596 100644 --- a/tests/acceptance/features/webUIProvisioning/users.feature +++ b/tests/acceptance/features/webUIProvisioning/users.feature @@ -32,7 +32,7 @@ Feature: add users When the administrator changes the display name of user "new-user" to "New User" using the webUI And the administrator logs out of the webUI And user "new-user" logs in using the webUI - Then "New User" should be shown as the name of the current user on the WebUI + Then "New User" should be shown as the name of the current user on the webUI And user "new-user" should exist And the user attributes returned by the API should include | displayname | New User | @@ -68,7 +68,7 @@ Feature: add users And the administrator changes the display name of user "Alice" to "New User" using the webUI And the administrator logs out of the webUI And user "Alice" logs in using the webUI - Then "ldap user" should be shown as the name of the current user on the WebUI + Then "ldap user" should be shown as the name of the current user on the webUI And user "Alice" should exist And the user attributes returned by the API should include | displayname | ldap user | diff --git a/tests/acceptance/features/webUIUserLDAP/avatar.feature b/tests/acceptance/features/webUIUserLDAP/avatar.feature index 3d9a6c9de..ffae74907 100644 --- a/tests/acceptance/features/webUIUserLDAP/avatar.feature +++ b/tests/acceptance/features/webUIUserLDAP/avatar.feature @@ -12,12 +12,12 @@ Feature: providing an avatar by LDAP Scenario: upload an avatar to the LDAP server When the administrator sets the ldap attribute "jpegPhoto" of the entry "uid=Alice,ou=TestUsers" to the content of the file "testavatar.jpg" And user "Alice" has logged in using the webUI - Then the display name should not be visible on the WebUI - And an avatar should be shown for the current user on the WebUI + Then the display name should not be visible on the webUI + And an avatar should be shown for the current user on the webUI Scenario: set the avatar on the LDAP server to an invalid string When the administrator sets the ldap attribute "jpegPhoto" of the entry "uid=Alice,ou=TestUsers" to "0" And user "Alice" has logged in using the webUI - Then the display name should be visible on the WebUI - And "Alice Hansen" should be shown as the name of the current user on the WebUI - And no avatar should be shown for the current user on the WebUI + Then the display name should be visible on the webUI + And "Alice Hansen" should be shown as the name of the current user on the webUI + And no avatar should be shown for the current user on the webUI diff --git a/tests/acceptance/features/webUIUserLDAP/changingDisplayName.feature b/tests/acceptance/features/webUIUserLDAP/changingDisplayName.feature index e1b312398..715bda8f9 100644 --- a/tests/acceptance/features/webUIUserLDAP/changingDisplayName.feature +++ b/tests/acceptance/features/webUIUserLDAP/changingDisplayName.feature @@ -11,7 +11,7 @@ Feature: changing display name Scenario Outline: change display name on the LDAP server Given the administrator sets the ldap attribute "displayname" of the entry "uid=Alice,ou=TestUsers" to "" When user "Alice" logs in using the webUI - Then "" should be shown as the name of the current user on the WebUI + Then "" should be shown as the name of the current user on the webUI Examples: | new-displayname | | 999 | @@ -22,12 +22,12 @@ Feature: changing display name Scenario: change display name on the LDAP server Given the administrator sets the ldap attribute "displayname" of the entry "uid=Alice,ou=TestUsers" to "0" When user "Alice" logs in using the webUI - Then "0" should be shown as the name of the current user on the WebUI + Then "0" should be shown as the name of the current user on the webUI Scenario: delete display name on the LDAP server Given user "Brian" has been created with default attributes and without skeleton files And the administrator sets the ldap attribute "displayname" of the entry "uid=Alice,ou=TestUsers" to "" When user "Alice" logs in using the webUI - Then "Alice" should be shown as the name of the current user on the WebUI + Then "Alice" should be shown as the name of the current user on the webUI When the user re-logs in as "Brian" using the webUI - Then "Brian Murphy" should be shown as the name of the current user on the WebUI + Then "Brian Murphy" should be shown as the name of the current user on the webUI diff --git a/tests/integration/ExceptionOnLostConnection.php b/tests/integration/ExceptionOnLostConnection.php index 9b8dba296..d82d603e0 100644 --- a/tests/integration/ExceptionOnLostConnection.php +++ b/tests/integration/ExceptionOnLostConnection.php @@ -169,7 +169,10 @@ private function setProxyState($isEnabled) { $ch = $this->getCurl(); \curl_setopt($ch, CURLOPT_POST, true); \curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); - \curl_setopt($ch, CURLOPT_HTTPHEADER, [ + \curl_setopt( + $ch, + CURLOPT_HTTPHEADER, + [ 'Content-Type: application/json', 'Content-Length: ' . \strlen($postData)] ); diff --git a/tests/unit/CommandTest.php b/tests/unit/CommandTest.php index dc7a5bb93..e1ffeb437 100644 --- a/tests/unit/CommandTest.php +++ b/tests/unit/CommandTest.php @@ -57,7 +57,9 @@ protected function setUp(): void { * @param array $expectedNotToBeContained */ public function testShowConfigAsTable( - $input, $expectedToBeContained, $expectedNotToBeContained + $input, + $expectedToBeContained, + $expectedNotToBeContained ) { $this->commandTester->execute($input); $output = $this->commandTester->getDisplay(); diff --git a/tests/unit/Controller/ConfigurationControllerTest.php b/tests/unit/Controller/ConfigurationControllerTest.php index f1467f071..2f5cbec96 100644 --- a/tests/unit/Controller/ConfigurationControllerTest.php +++ b/tests/unit/Controller/ConfigurationControllerTest.php @@ -159,7 +159,8 @@ public function testCreateWithCopy() { return $expectedValue === $value; }; return true; - })); + }) + ); $result = $this->controller->create('src'); diff --git a/tests/unit/User/ManagerTest.php b/tests/unit/User/ManagerTest.php index 00e196fc9..d461e4ed9 100644 --- a/tests/unit/User/ManagerTest.php +++ b/tests/unit/User/ManagerTest.php @@ -114,8 +114,12 @@ protected function setUp(): void { ->willReturn($this->connection); $this->manager = new Manager( - $this->config, $filesystem, $logger, $avatarManager, - $dbConn, $userMgr + $this->config, + $filesystem, + $logger, + $avatarManager, + $dbConn, + $userMgr ); $this->manager->setLdapAccess($this->access); } diff --git a/tests/unit/User/UserEntryTest.php b/tests/unit/User/UserEntryTest.php index 4ca71f7c6..9c9d2361d 100644 --- a/tests/unit/User/UserEntryTest.php +++ b/tests/unit/User/UserEntryTest.php @@ -56,7 +56,10 @@ public function testInvalidNew() { } public function testGetDN() { - $userEntry = new UserEntry($this->config, $this->logger, $this->connection, + $userEntry = new UserEntry( + $this->config, + $this->logger, + $this->connection, [ 'dn' => [0 => 'cn=foo,dc=foobar,dc=bar'] ] @@ -69,7 +72,10 @@ public function testGetUserName() { ->method('__get') ->with($this->equalTo('ldapUserName')) ->will($this->returnValue('uid')); - $userEntry = new UserEntry($this->config, $this->logger, $this->connection, + $userEntry = new UserEntry( + $this->config, + $this->logger, + $this->connection, [ 'dn' => [0 => 'cn=foo,dc=foobar,dc=bar'], 'uid' => [0 => 'foo'] @@ -83,7 +89,10 @@ public function testGetUserIdIsConfigured() { ->method('__get') ->with($this->equalTo('ldapExpertUsernameAttr')) ->will($this->returnValue('mail')); - $userEntry = new UserEntry($this->config, $this->logger, $this->connection, + $userEntry = new UserEntry( + $this->config, + $this->logger, + $this->connection, [ 'dn' => [0 => 'cn=foo,dc=foobar,dc=bar'], 'mail' => [0 => 'a@b.c'] @@ -111,7 +120,10 @@ public function testGetUserIdFallbackOnUUID($uuidAttr, $uuidValue, $expected) { $uuidAttr, $uuidAttr ); - $userEntry = new UserEntry($this->config, $this->logger, $this->connection, + $userEntry = new UserEntry( + $this->config, + $this->logger, + $this->connection, [ 'dn' => [0 => 'cn=foo,dc=foobar,dc=bar'], $uuidAttr => [0 => $uuidValue] @@ -129,7 +141,10 @@ public function testGetUserIdUndetermined() { ->method('__get') ->with($this->equalTo('ldapExpertUsernameAttr')) ->will($this->returnValue('mail')); - $userEntry = new UserEntry($this->config, $this->logger, $this->connection, + $userEntry = new UserEntry( + $this->config, + $this->logger, + $this->connection, [ 'dn' => [0 => 'cn=foo,dc=foobar,dc=bar'] ] @@ -165,7 +180,10 @@ public function testGetUUIDIsConfigured($uuidAttr, $uuidValue, $expected) { ->method('__get') ->with($this->equalTo('ldapExpertUUIDUserAttr')) ->will($this->returnValue($uuidAttr)); - $userEntry = new UserEntry($this->config, $this->logger, $this->connection, + $userEntry = new UserEntry( + $this->config, + $this->logger, + $this->connection, [ 'dn' => [0 => 'cn=foo,dc=foobar,dc=bar'], $uuidAttr => [0 => $uuidValue] @@ -191,7 +209,10 @@ public function testGetUUIDIsAuto($uuidAttr, $uuidValue, $expected) { 'auto', 'auto' ); - $userEntry = new UserEntry($this->config, $this->logger, $this->connection, + $userEntry = new UserEntry( + $this->config, + $this->logger, + $this->connection, [ 'dn' => [0 => 'cn=foo,dc=foobar,dc=bar'], $uuidAttr => [0 => $uuidValue] @@ -209,7 +230,10 @@ public function testGetUUIDUndetermined() { ->method('__get') ->with($this->equalTo('ldapExpertUUIDUserAttr')) ->will($this->returnValue('auto')); - $userEntry = new UserEntry($this->config, $this->logger, $this->connection, + $userEntry = new UserEntry( + $this->config, + $this->logger, + $this->connection, [ 'dn' => [0 => 'cn=foo,dc=foobar,dc=bar'], ] @@ -226,7 +250,10 @@ public function testGetUUIDInvalidBinaryUUID() { ->method('__get') ->with($this->equalTo('ldapExpertUUIDUserAttr')) ->will($this->returnValue('objectguid')); - $userEntry = new UserEntry($this->config, $this->logger, $this->connection, + $userEntry = new UserEntry( + $this->config, + $this->logger, + $this->connection, [ 'dn' => [0 => 'cn=foo,dc=foobar,dc=bar'], 'objectguid' => [0 => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"], @@ -246,7 +273,10 @@ public function testGetDisplayName() { 'displayname', '' ); - $userEntry = new UserEntry($this->config, $this->logger, $this->connection, + $userEntry = new UserEntry( + $this->config, + $this->logger, + $this->connection, [ 'dn' => [0 => 'cn=foo,dc=foobar,dc=bar'], 'displayname' => [0 => 'Foo'], @@ -266,7 +296,10 @@ public function testGetDisplayNameWithSecondDisplayName() { 'displayname', 'mail' ); - $userEntry = new UserEntry($this->config, $this->logger, $this->connection, + $userEntry = new UserEntry( + $this->config, + $this->logger, + $this->connection, [ 'dn' => [0 => 'cn=foo,dc=foobar,dc=bar'], 'displayname' => [0 => 'Foo'], @@ -289,7 +322,10 @@ public function testGetDisplayNameFallback() { 'mail', 'uid' ); - $userEntry = new UserEntry($this->config, $this->logger, $this->connection, + $userEntry = new UserEntry( + $this->config, + $this->logger, + $this->connection, [ 'dn' => [0 => 'cn=foo,dc=foobar,dc=bar'], 'uid' => [0 => 'foo'], @@ -303,7 +339,10 @@ public function testGetQuota() { ->method('__get') ->with($this->equalTo('ldapQuotaAttribute')) ->will($this->returnValue('quota')); - $userEntry = new UserEntry($this->config, $this->logger, $this->connection, + $userEntry = new UserEntry( + $this->config, + $this->logger, + $this->connection, [ 'dn' => [0 => 'cn=foo,dc=foobar,dc=bar'], 'quota' => [0 => '5 GB'] @@ -325,7 +364,10 @@ public function testGetQuotaInvalid() { '1 GB', '1 GB' ); - $userEntry = new UserEntry($this->config, $this->logger, $this->connection, + $userEntry = new UserEntry( + $this->config, + $this->logger, + $this->connection, [ 'dn' => [0 => 'cn=foo,dc=foobar,dc=bar'], 'quota' => [0 => 'invalid'] @@ -347,7 +389,10 @@ public function testGetQuotaDefault() { '2 GB', '2 GB' ); - $userEntry = new UserEntry($this->config, $this->logger, $this->connection, + $userEntry = new UserEntry( + $this->config, + $this->logger, + $this->connection, [ 'dn' => [0 => 'cn=foo,dc=foobar,dc=bar'], ] @@ -368,7 +413,10 @@ public function testGetQuotaDefaultInvalid() { 'invalid', 'invalid' ); - $userEntry = new UserEntry($this->config, $this->logger, $this->connection, + $userEntry = new UserEntry( + $this->config, + $this->logger, + $this->connection, [ 'dn' => [0 => 'cn=foo,dc=foobar,dc=bar'], 'quota' => [0 => 'invalid'] @@ -388,7 +436,10 @@ public function testGetQuotaDefaultFallback() { null, null ); - $userEntry = new UserEntry($this->config, $this->logger, $this->connection, + $userEntry = new UserEntry( + $this->config, + $this->logger, + $this->connection, [ 'dn' => [0 => 'cn=foo,dc=foobar,dc=bar'], ] @@ -401,7 +452,10 @@ public function testGetEmailAddress() { ->method('__get') ->with($this->equalTo('ldapEmailAttribute')) ->will($this->returnValue('mail')); - $userEntry = new UserEntry($this->config, $this->logger, $this->connection, + $userEntry = new UserEntry( + $this->config, + $this->logger, + $this->connection, [ 'dn' => [0 => 'cn=foo,dc=foobar,dc=bar'], 'mail' => [0 => 'a@b.c'] @@ -415,7 +469,10 @@ public function testGetEmailAddressUnset() { ->method('__get') ->with($this->equalTo('ldapEmailAttribute')) ->will($this->returnValue('mail')); - $userEntry = new UserEntry($this->config, $this->logger, $this->connection, + $userEntry = new UserEntry( + $this->config, + $this->logger, + $this->connection, [ 'dn' => [0 => 'cn=foo,dc=foobar,dc=bar'] ] @@ -428,7 +485,10 @@ public function testGetHomeAttributeWithAbsolutePath() { ->method('__get') ->with($this->equalTo('homeFolderNamingRule')) ->will($this->returnValue('attr:home')); - $userEntry = new UserEntry($this->config, $this->logger, $this->connection, + $userEntry = new UserEntry( + $this->config, + $this->logger, + $this->connection, [ 'dn' => [0 => 'cn=foo,dc=foobar,dc=bar'], 'home' => [0 => '/absolute/path/to/home'] @@ -445,7 +505,10 @@ public function testGetHomeAttributeWithRelativePath() { ->method('__get') ->with($this->equalTo('homeFolderNamingRule')) ->will($this->returnValue('attr:home')); - $userEntry = new UserEntry($this->config, $this->logger, $this->connection, + $userEntry = new UserEntry( + $this->config, + $this->logger, + $this->connection, [ 'dn' => [0 => 'cn=foo,dc=foobar,dc=bar'], 'home' => [0 => 'f/o/o'] @@ -459,7 +522,10 @@ public function testGetHomeUnset() { ->method('__get') ->with($this->equalTo('homeFolderNamingRule')) ->will($this->returnValue('attr:home')); - $userEntry = new UserEntry($this->config, $this->logger, $this->connection, + $userEntry = new UserEntry( + $this->config, + $this->logger, + $this->connection, [ 'dn' => [0 => 'cn=foo,dc=foobar,dc=bar'], ] @@ -485,7 +551,10 @@ public function testGetHomeUnsetButRequired() { 'attr:home', 'mail' ); - $userEntry = new UserEntry($this->config, $this->logger, $this->connection, + $userEntry = new UserEntry( + $this->config, + $this->logger, + $this->connection, [ 'dn' => [0 => 'cn=foo,dc=foobar,dc=bar'], 'mail' => [0 => 'a@b.c'] @@ -495,7 +564,10 @@ public function testGetHomeUnsetButRequired() { } public function testGetAvatarImageInJpegPhoto() { - $userEntry = new UserEntry($this->config, $this->logger, $this->connection, + $userEntry = new UserEntry( + $this->config, + $this->logger, + $this->connection, [ 'dn' => [0 => 'cn=foo,dc=foobar,dc=bar'], 'jpegphoto' => [0 => 'binarydata'] @@ -505,7 +577,10 @@ public function testGetAvatarImageInJpegPhoto() { } public function testGetAvatarImageInThumbnailPhoto() { - $userEntry = new UserEntry($this->config, $this->logger, $this->connection, + $userEntry = new UserEntry( + $this->config, + $this->logger, + $this->connection, [ 'dn' => [0 => 'cn=foo,dc=foobar,dc=bar'], 'thumbnailphoto' => [0 => 'binarydata'] @@ -519,7 +594,10 @@ public function testGetSearchTerms() { ->method('__get') ->with($this->equalTo('ldapAttributesForUserSearch')) ->will($this->returnValue(['mail', 'uid', 'firstname'])); - $userEntry = new UserEntry($this->config, $this->logger, $this->connection, + $userEntry = new UserEntry( + $this->config, + $this->logger, + $this->connection, [ 'dn' => [0 => 'cn=foo,dc=foobar,dc=bar'], 'mail' => [0 => 'a@b.c', 1 => 'alt@b.c'], // all mails should be found @@ -535,7 +613,10 @@ public function testGetSearchTermsUnconfigured() { ->method('__get') ->with($this->equalTo('ldapAttributesForUserSearch')) ->will($this->returnValue([])); - $userEntry = new UserEntry($this->config, $this->logger, $this->connection, + $userEntry = new UserEntry( + $this->config, + $this->logger, + $this->connection, [ 'dn' => [0 => 'cn=foo,dc=foobar,dc=bar'], ] diff --git a/tests/unit/WizardTest.php b/tests/unit/WizardTest.php index 98b7b94b0..82cb65359 100644 --- a/tests/unit/WizardTest.php +++ b/tests/unit/WizardTest.php @@ -291,8 +291,10 @@ public function testDetectEmailAttributeOverrideSet() { })); $result = $this->wizard->detectEmailAttribute()->getResultArray(); - $this->assertSame('mailPrimaryAddress', - $result['changes']['ldap_email_attr']); + $this->assertSame( + 'mailPrimaryAddress', + $result['changes']['ldap_email_attr'] + ); } public function testDetectEmailAttributeFind() { @@ -330,8 +332,10 @@ public function testDetectEmailAttributeFind() { $this->wizard = new Wizard($this->ldap, $this->configuration, $this->access, $this->l10n); $result = $this->wizard->detectEmailAttribute()->getResultArray(); - $this->assertSame('mailPrimaryAddress', - $result['changes']['ldap_email_attr']); + $this->assertSame( + 'mailPrimaryAddress', + $result['changes']['ldap_email_attr'] + ); } public function testDetectEmailAttributeFindNothing() { diff --git a/vendor-bin/owncloud-codestyle/composer.json b/vendor-bin/owncloud-codestyle/composer.json index d82e81c02..7326e6cfa 100644 --- a/vendor-bin/owncloud-codestyle/composer.json +++ b/vendor-bin/owncloud-codestyle/composer.json @@ -1,5 +1,5 @@ { "require": { - "owncloud/coding-standard": "^2.0" + "owncloud/coding-standard": "^3.0" } -} \ No newline at end of file +}