From 76ed36f766d4dd443c4bffb94591b639de7ff8f6 Mon Sep 17 00:00:00 2001 From: Vladimir D Date: Mon, 11 Dec 2023 14:34:51 +0400 Subject: [PATCH] LDAP auth implemented --- CloudronManifest.json | 4 +++- POSTINSTALL.md | 6 +++++- start.sh | 13 +++++++++++++ test/test.js | 40 ++++++++++++++++++++++++++++++++-------- 4 files changed, 53 insertions(+), 10 deletions(-) diff --git a/CloudronManifest.json b/CloudronManifest.json index 8675217..428aa74 100644 --- a/CloudronManifest.json +++ b/CloudronManifest.json @@ -10,7 +10,8 @@ "healthCheckPath": "/healthcheck", "httpPort": 8000, "addons": { - "localstorage": {} + "localstorage": {}, + "ldap": {} }, "tcpPorts": { "SYNC_PORT": { @@ -36,5 +37,6 @@ "https://screenshots.cloudron.io/net.syncthing.cloudronapp2/2.png", "https://screenshots.cloudron.io/net.syncthing.cloudronapp2/3.png" ], + "optionalSso": true, "postInstallMessage": "file://POSTINSTALL.md" } diff --git a/POSTINSTALL.md b/POSTINSTALL.md index 8033fc6..527098c 100644 --- a/POSTINSTALL.md +++ b/POSTINSTALL.md @@ -1,7 +1,11 @@ + +All Cloudron users are admins and can manage synchronising files. + + This app is pre-setup with an admin account. The initial credentials are: **Username**: admin
**Password**: changeme
Please change the admin password immediately. - +
diff --git a/start.sh b/start.sh index 7494c3d..a6aab99 100755 --- a/start.sh +++ b/start.sh @@ -17,8 +17,21 @@ if [[ ! -f /app/data/config/config.xml ]]; then --update "//configuration/options/defaultFolderPath" -v '/app/data/folders' \ --update "//configuration/options/urAccepted" -v '-1' \ /app/data/config/config.xml + fi +if [[ -n ${CLOUDRON_LDAP_HOST:-} ]]; then + xmlstarlet ed --inplace \ + --subnode "//configuration/gui" -t elem -n "authMode" -v "ldap" \ + --subnode "//configuration/ldap" -t elem -n "address" -v "${CLOUDRON_LDAP_HOST:-}:${CLOUDRON_LDAP_PORT}" \ + --subnode "//configuration/ldap" -t elem -n "bindDN" -v "${CLOUDRON_LDAP_BIND_DN:-}" \ + --subnode "//configuration/ldap" -t elem -n "insecureSkipVerify" -v "true" \ + --subnode "//configuration/ldap" -t elem -n "searchBaseDN" -v "${CLOUDRON_LDAP_USERS_BASE_DN:-}" \ + --subnode "//configuration/ldap" -t elem -n "searchFilter" -v "(&(objectclass=user)(|(username=%s)(mail=%s)))" \ + /app/data/config/config.xml +fi + + # Set the listenAddress and the gui enabled to make sure user doesnt lock themselves out by accident. sed -e "s,.*,tcp://:${SYNC_PORT}," -i /app/data/config/config.xml sed -e 's,,,' -i /app/data/config/config.xml diff --git a/test/test.js b/test/test.js index f3632e2..0ac5564 100644 --- a/test/test.js +++ b/test/test.js @@ -19,6 +19,11 @@ const execSync = require('child_process').execSync, { Builder, By, until } = require('selenium-webdriver'), { Options } = require('selenium-webdriver/chrome'); +if (!process.env.USERNAME || !process.env.PASSWORD) { + console.log('USERNAME and PASSWORD env vars need to be set'); + process.exit(1); +} + describe('Application life cycle test', function () { this.timeout(0); @@ -29,7 +34,9 @@ describe('Application life cycle test', function () { const EXEC_ARGS = { cwd: path.resolve(__dirname, '..'), stdio: 'inherit' }; let browser, app; - const username = 'admin', password = 'changeme'; + const adminUsername = 'admin', adminPassword = 'changeme'; + let username = process.env.USERNAME; + let password = process.env.PASSWORD; before(function () { browser = new Builder().forBrowser('chrome').setChromeOptions(new Options().windowSize({ width: 1280, height: 1024 })).build(); @@ -50,7 +57,7 @@ describe('Application life cycle test', function () { await browser.wait(until.elementIsVisible(browser.findElement(elem)), TEST_TIMEOUT); } - async function login() { + async function login(username, password) { await browser.manage().deleteAllCookies(); await browser.get('https://' + app.fqdn); await waitForElement(By.id('user')); @@ -86,10 +93,25 @@ describe('Application life cycle test', function () { xit('build app', function () { execSync('cloudron build', EXEC_ARGS); }); - it('install app', function () { execSync('cloudron install --port-bindings SYNC_PORT=' + SYNC_PORT + ' --location ' + LOCATION, EXEC_ARGS); }); + // NO SSO + it('install app (NO SSO)', function () { execSync('cloudron install --no-sso --port-bindings SYNC_PORT=' + SYNC_PORT + ' --location ' + LOCATION, EXEC_ARGS); }); it('can get app information', getAppInfo); - it('can login', login); + it('can admin login', login.bind(null, adminUsername, adminPassword)); + it('can load page', loadPage); + it('can add folder', addFolder); + it('can check folder', checkFolder); + + it('uninstall app', async function () { + await browser.get('about:blank'); + execSync('cloudron uninstall --app ' + app.id, EXEC_ARGS); + }); + + // SSO + it('install app (SSO)', function () { execSync('cloudron install --port-bindings SYNC_PORT=' + SYNC_PORT + ' --location ' + LOCATION, EXEC_ARGS); }); + it('can get app information', getAppInfo); + + it('can login', login.bind(null, username, password)); it('can load page', loadPage); it('can add folder', addFolder); @@ -100,7 +122,7 @@ describe('Application life cycle test', function () { await timers.setTimeout(5000); }); - it('can login', login); + it('can login', login.bind(null, username, password)); it('can load page', loadPage); it('can check folder', checkFolder); @@ -111,7 +133,7 @@ describe('Application life cycle test', function () { }); it('can get app information', getAppInfo); - it('can login', login); + it('can login', login.bind(null, username, password)); it('can load page', loadPage); it('can check folder', checkFolder); @@ -126,7 +148,8 @@ describe('Application life cycle test', function () { await timers.setTimeout(30000); }); it('can get app information', getAppInfo); - it('can login', login); + // next release it should be replaced with LDAP login + it('can admin login', login.bind(null, adminUsername, adminPassword)); it('can load page', loadPage); it('can add folder', addFolder); it('can update', async function () { @@ -134,7 +157,8 @@ describe('Application life cycle test', function () { execSync('cloudron update --app ' + LOCATION, EXEC_ARGS); await timers.setTimeout(30000); }); - it('can login', login); + // next release it should be replaced with LDAP login + it('can admin login', login.bind(null, adminUsername, adminPassword)); it('can check folder', checkFolder); it('uninstall app', async function () {