mirror of
https://git.cloudron.io/cloudron/peertube-app.git
synced 2024-11-25 02:51:16 +00:00
OIDC auth implemented, tests updated
This commit is contained in:
parent
56009a97dd
commit
4fcf9b1684
3 changed files with 82 additions and 23 deletions
|
@ -24,7 +24,7 @@
|
||||||
"postgresql": {},
|
"postgresql": {},
|
||||||
"redis": {},
|
"redis": {},
|
||||||
"sendmail": { "supportsDisplayName": false },
|
"sendmail": { "supportsDisplayName": false },
|
||||||
"ldap": {}
|
"oidc": { "loginRedirectUri": "/plugins/auth-openid-connect/router/code-cb" }
|
||||||
},
|
},
|
||||||
"memoryLimit": 1073741824,
|
"memoryLimit": 1073741824,
|
||||||
"forumUrl": "https://forum.cloudron.io/category/91/peertube",
|
"forumUrl": "https://forum.cloudron.io/category/91/peertube",
|
||||||
|
|
50
start.sh
50
start.sh
|
@ -7,11 +7,45 @@ mkdir -p /app/data/storage /run/peertube/cache /run/peertube/npm /tmp/peertube
|
||||||
# do not rely on WORKDIR
|
# do not rely on WORKDIR
|
||||||
cd /app/code/server
|
cd /app/code/server
|
||||||
|
|
||||||
update_ldap() {
|
migrate_ldap_to_oidc() {
|
||||||
echo "==> Updating Ldap credentials"
|
if [[ -n "${CLOUDRON_OIDC_ISSUER:-}" ]]; then
|
||||||
|
OIDC_PLUIGIN_INSTALLED=$(PGPASSWORD=${CLOUDRON_POSTGRESQL_PASSWORD} psql -h ${CLOUDRON_POSTGRESQL_HOST} -p ${CLOUDRON_POSTGRESQL_PORT} -U ${CLOUDRON_POSTGRESQL_USERNAME} -d ${CLOUDRON_POSTGRESQL_DATABASE} -AXqtc "SELECT count(*) FROM \"plugin\" WHERE name='auth-openid-connect'")
|
||||||
|
if [ ${OIDC_PLUIGIN_INSTALLED} -eq 0 ]; then
|
||||||
|
install_oidc
|
||||||
|
fi
|
||||||
|
|
||||||
|
USERS_TO_MIGRATE=$(PGPASSWORD=${CLOUDRON_POSTGRESQL_PASSWORD} psql -h ${CLOUDRON_POSTGRESQL_HOST} -p ${CLOUDRON_POSTGRESQL_PORT} -U ${CLOUDRON_POSTGRESQL_USERNAME} -d ${CLOUDRON_POSTGRESQL_DATABASE} -AXqtc "SELECT count(*) FROM \"user\" u WHERE \"pluginAuth\"='peertube-plugin-auth-ldap'")
|
||||||
|
echo "==> Migrating users to OIDC";
|
||||||
|
echo " Users to migrate: ${USERS_TO_MIGRATE}"
|
||||||
|
if [ ${USERS_TO_MIGRATE} -gt 0 ]; then
|
||||||
|
PGPASSWORD=${CLOUDRON_POSTGRESQL_PASSWORD} psql -h ${CLOUDRON_POSTGRESQL_HOST} -p ${CLOUDRON_POSTGRESQL_PORT} -U ${CLOUDRON_POSTGRESQL_USERNAME} -d ${CLOUDRON_POSTGRESQL_DATABASE} -c "UPDATE \"user\" SET \"pluginAuth\"='peertube-plugin-auth-openid-connect' WHERE \"pluginAuth\"='peertube-plugin-auth-ldap'"
|
||||||
|
fi
|
||||||
|
|
||||||
|
LDAP_PLUGIN_INSTALLED=$(PGPASSWORD=${CLOUDRON_POSTGRESQL_PASSWORD} psql -h ${CLOUDRON_POSTGRESQL_HOST} -p ${CLOUDRON_POSTGRESQL_PORT} -U ${CLOUDRON_POSTGRESQL_USERNAME} -d ${CLOUDRON_POSTGRESQL_DATABASE} -AXqtc "SELECT count(*) FROM \"plugin\" WHERE name='auth-ldap'")
|
||||||
|
if [ ${LDAP_PLUGIN_INSTALLED} -gt 0 ]; then
|
||||||
|
echo "==> Uninstalling LDAP plugin"
|
||||||
|
gosu cloudron:cloudron npm run plugin:uninstall -- -n peertube-plugin-auth-ldap
|
||||||
|
|
||||||
|
echo "==> Deleting LDAP settings"
|
||||||
|
PGPASSWORD=${CLOUDRON_POSTGRESQL_PASSWORD} psql -h ${CLOUDRON_POSTGRESQL_HOST} -p ${CLOUDRON_POSTGRESQL_PORT} -U ${CLOUDRON_POSTGRESQL_USERNAME} -d ${CLOUDRON_POSTGRESQL_DATABASE} -c "DELETE FROM \"plugin\" WHERE name='auth-ldap'"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
install_oidc() {
|
||||||
|
# https://docs.joinpeertube.org/maintain-tools?id=cli-wrapper . Note that we have to restart peertube when installed this way
|
||||||
|
if [[ -n "${CLOUDRON_OIDC_ISSUER:-}" ]]; then
|
||||||
|
echo "==> Installing OIDC plugin"
|
||||||
|
gosu cloudron:cloudron npm run plugin:install -- -n peertube-plugin-auth-openid-connect -v 0.1.1
|
||||||
|
update_oidc
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
update_oidc() {
|
||||||
|
echo "==> Updating OIDC config"
|
||||||
|
|
||||||
PGPASSWORD=${CLOUDRON_POSTGRESQL_PASSWORD} psql -h ${CLOUDRON_POSTGRESQL_HOST} -p ${CLOUDRON_POSTGRESQL_PORT} -U ${CLOUDRON_POSTGRESQL_USERNAME} -d ${CLOUDRON_POSTGRESQL_DATABASE} \
|
PGPASSWORD=${CLOUDRON_POSTGRESQL_PASSWORD} psql -h ${CLOUDRON_POSTGRESQL_HOST} -p ${CLOUDRON_POSTGRESQL_PORT} -U ${CLOUDRON_POSTGRESQL_USERNAME} -d ${CLOUDRON_POSTGRESQL_DATABASE} \
|
||||||
-c "UPDATE plugin SET settings='{\"url\": \"${CLOUDRON_LDAP_URL}\", \"weight\": 100, \"insecure-tls\": false, \"bind-dn\": \"${CLOUDRON_LDAP_BIND_DN}\", \"bind-credentials\": \"${CLOUDRON_LDAP_BIND_PASSWORD}\", \"search-base\": \"${CLOUDRON_LDAP_USERS_BASE_DN}\", \"mail-property\": \"mail\", \"search-filter\": \"(|(mail={{username}})(username={{username}}))\", \"username-property\": \"username\"}' WHERE name='auth-ldap'"
|
-c "UPDATE plugin SET settings='{\"scope\": \"openid email profile\", \"client-id\": \"${CLOUDRON_OIDC_CLIENT_ID}\", \"discover-url\": \"${CLOUDRON_OIDC_DISCOVERY_URL}\", \"client-secret\": \"${CLOUDRON_OIDC_CLIENT_SECRET}\", \"mail-property\": \"email\", \"auth-display-name\": \"Cloudron\", \"username-property\": \"preferred_username\", \"signature-algorithm\": \"RS256\", \"display-name-property\": \"name\"}' WHERE name='auth-openid-connect'"
|
||||||
}
|
}
|
||||||
|
|
||||||
first_time_setup() {
|
first_time_setup() {
|
||||||
|
@ -31,12 +65,7 @@ first_time_setup() {
|
||||||
echo "changeme" | gosu cloudron:cloudron npm run reset-password -- -u root
|
echo "changeme" | gosu cloudron:cloudron npm run reset-password -- -u root
|
||||||
sleep 5 # the above command seems to spawn a separate process to change password in background
|
sleep 5 # the above command seems to spawn a separate process to change password in background
|
||||||
|
|
||||||
# https://docs.joinpeertube.org/maintain-tools?id=cli-wrapper . Note that we have to restart peertube when installed this way
|
install_oidc
|
||||||
if [[ -n "${CLOUDRON_LDAP_SERVER:-}" ]]; then
|
|
||||||
echo "==> Installing LDAP plugin"
|
|
||||||
gosu cloudron:cloudron npm run plugin:install -- -n peertube-plugin-auth-ldap -v 0.0.10
|
|
||||||
update_ldap
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "==> First time setup complete"
|
echo "==> First time setup complete"
|
||||||
}
|
}
|
||||||
|
@ -109,8 +138,9 @@ if [[ ! -f "/app/data/production.yaml" ]]; then
|
||||||
first_time_setup
|
first_time_setup
|
||||||
else
|
else
|
||||||
update_config
|
update_config
|
||||||
|
migrate_ldap_to_oidc
|
||||||
|
|
||||||
[[ -n "${CLOUDRON_LDAP_SERVER:-}" ]] && update_ldap
|
[[ -n "${CLOUDRON_OIDC_ISSUER:-}" ]] && update_oidc
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "==> Configuring nginx"
|
echo "==> Configuring nginx"
|
||||||
|
|
45
test/test.js
45
test/test.js
|
@ -38,6 +38,7 @@ describe('Application life cycle test', function () {
|
||||||
let username = process.env.USERNAME;
|
let username = process.env.USERNAME;
|
||||||
let password = process.env.PASSWORD;
|
let password = process.env.PASSWORD;
|
||||||
let email = process.env.EMAIL;
|
let email = process.env.EMAIL;
|
||||||
|
let athenticated_by_oidc = false;
|
||||||
|
|
||||||
before(function () {
|
before(function () {
|
||||||
browser = new Builder().forBrowser('chrome').setChromeOptions(new Options().windowSize({ width: 1280, height: 1024 })).build();
|
browser = new Builder().forBrowser('chrome').setChromeOptions(new Options().windowSize({ width: 1280, height: 1024 })).build();
|
||||||
|
@ -78,6 +79,29 @@ describe('Application life cycle test', function () {
|
||||||
await waitForElement(By.xpath('//a[contains(@href, "/my-library")]'));
|
await waitForElement(By.xpath('//a[contains(@href, "/my-library")]'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function loginOIDC(username, password) {
|
||||||
|
browser.manage().deleteAllCookies();
|
||||||
|
await browser.get(`https://${app.fqdn}/login`);
|
||||||
|
await browser.sleep(2000);
|
||||||
|
|
||||||
|
await browser.wait(until.elementLocated(By.xpath('//a[contains(., "Cloudron")]')), TEST_TIMEOUT);
|
||||||
|
await browser.findElement(By.xpath('//a[contains(., "Cloudron")]')).click();
|
||||||
|
await browser.sleep(2000);
|
||||||
|
|
||||||
|
if (!athenticated_by_oidc) {
|
||||||
|
await waitForElement(By.xpath('//input[@name="username"]'));
|
||||||
|
await browser.findElement(By.xpath('//input[@name="username"]')).sendKeys(username);
|
||||||
|
await browser.findElement(By.xpath('//input[@name="password"]')).sendKeys(password);
|
||||||
|
await browser.sleep(2000);
|
||||||
|
await browser.findElement(By.xpath('//button[@type="submit" and contains(text(), "Sign in")]')).click();
|
||||||
|
await browser.sleep(2000);
|
||||||
|
|
||||||
|
athenticated_by_oidc = true;
|
||||||
|
}
|
||||||
|
await browser.sleep(20000);
|
||||||
|
await waitForElement(By.xpath('//a[contains(@href, "/my-library")]'));
|
||||||
|
}
|
||||||
|
|
||||||
async function closeAccountSetupDialog() {
|
async function closeAccountSetupDialog() {
|
||||||
await browser.get('https://' + app.fqdn);
|
await browser.get('https://' + app.fqdn);
|
||||||
|
|
||||||
|
@ -99,8 +123,12 @@ describe('Application life cycle test', function () {
|
||||||
async function completeSetup() {
|
async function completeSetup() {
|
||||||
let button;
|
let button;
|
||||||
|
|
||||||
|
// await browser.executeScript('localStorage.clear();');
|
||||||
await browser.get(`https://${app.fqdn}`);
|
await browser.get(`https://${app.fqdn}`);
|
||||||
await waitForElement(By.xpath('//a[contains(text(), "Configure my instance")]'));
|
await browser.sleep(2000);
|
||||||
|
|
||||||
|
if (await browser.findElements(By.xpath('//a[contains(text(), "Configure my instance")]')).then(found => !!found.length)) {
|
||||||
|
// await waitForElement(By.xpath('//a[contains(text(), "Configure my instance")]'));
|
||||||
await browser.findElement(By.xpath('//a[contains(text(), "Configure my instance")]')).click(); // this opens a new window
|
await browser.findElement(By.xpath('//a[contains(text(), "Configure my instance")]')).click(); // this opens a new window
|
||||||
|
|
||||||
let say_cmd = await getOS() == "Darwin" ? "say" : "spd-say";
|
let say_cmd = await getOS() == "Darwin" ? "say" : "spd-say";
|
||||||
|
@ -108,6 +136,7 @@ describe('Application life cycle test', function () {
|
||||||
|
|
||||||
await rl.question('Is tab closed? ');
|
await rl.question('Is tab closed? ');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function uploadVideo() {
|
async function uploadVideo() {
|
||||||
browser.get('https://' + app.fqdn + '/videos/upload');
|
browser.get('https://' + app.fqdn + '/videos/upload');
|
||||||
|
@ -129,19 +158,19 @@ describe('Application life cycle test', function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
xit('build app', function () { execSync('cloudron build', EXEC_ARGS); });
|
xit('build app', function () { execSync('cloudron build', EXEC_ARGS); });
|
||||||
xit('install app', async function () {
|
it('install app', async function () {
|
||||||
execSync('cloudron install --location ' + LOCATION, EXEC_ARGS);
|
execSync('cloudron install --location ' + LOCATION, EXEC_ARGS);
|
||||||
await sleep(40000); // takes a bit to create root user in background
|
await sleep(40000); // takes a bit to create root user in background
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can get app information', getAppInfo);
|
it('can get app information', getAppInfo);
|
||||||
it('can root login', login.bind(null, 'root', 'changeme'));
|
it('can root login', login.bind(null, 'root', 'changeme'));
|
||||||
xit('can complete setup', completeSetup);
|
it('can complete setup', completeSetup);
|
||||||
it('can upload video', uploadVideo);
|
it('can upload video', uploadVideo);
|
||||||
it('video exists', videoExists);
|
it('video exists', videoExists);
|
||||||
it('logout', logout);
|
it('logout', logout);
|
||||||
|
|
||||||
it('can login', login.bind(null, username, password));
|
it('can OIDC login', loginOIDC.bind(null, username, password));
|
||||||
it('can close account setup dialog', closeAccountSetupDialog);
|
it('can close account setup dialog', closeAccountSetupDialog);
|
||||||
it('logout', logout);
|
it('logout', logout);
|
||||||
|
|
||||||
|
@ -159,7 +188,7 @@ describe('Application life cycle test', function () {
|
||||||
it('video exists', videoExists);
|
it('video exists', videoExists);
|
||||||
it('logout', logout);
|
it('logout', logout);
|
||||||
|
|
||||||
it('can login', login.bind(null, username, password));
|
it('can OIDC login', loginOIDC.bind(null, username, password));
|
||||||
it('logout', logout);
|
it('logout', logout);
|
||||||
|
|
||||||
it('can restart app', function () {
|
it('can restart app', function () {
|
||||||
|
@ -169,7 +198,7 @@ describe('Application life cycle test', function () {
|
||||||
it('video exists', videoExists);
|
it('video exists', videoExists);
|
||||||
it('logout', logout);
|
it('logout', logout);
|
||||||
|
|
||||||
it('can login', login.bind(null, username, password));
|
it('can OIDC login', loginOIDC.bind(null, username, password));
|
||||||
it('logout', logout);
|
it('logout', logout);
|
||||||
|
|
||||||
// this is not supported for federation
|
// this is not supported for federation
|
||||||
|
@ -180,7 +209,7 @@ describe('Application life cycle test', function () {
|
||||||
it('video exists', videoExists);
|
it('video exists', videoExists);
|
||||||
it('logout', logout);
|
it('logout', logout);
|
||||||
|
|
||||||
it('can login', login.bind(null, username, password));
|
it('can OIDC login', loginOIDC.bind(null, username, password));
|
||||||
it('logout', logout);
|
it('logout', logout);
|
||||||
|
|
||||||
it('uninstall app', async function () {
|
it('uninstall app', async function () {
|
||||||
|
@ -222,7 +251,7 @@ describe('Application life cycle test', function () {
|
||||||
it('video exists', videoExists);
|
it('video exists', videoExists);
|
||||||
it('logout', logout);
|
it('logout', logout);
|
||||||
|
|
||||||
it('can login', login.bind(null, username, password));
|
it('can OIDC login', loginOIDC.bind(null, username, password));
|
||||||
it('can close account setup dialog', closeAccountSetupDialog);
|
it('can close account setup dialog', closeAccountSetupDialog);
|
||||||
it('logout', logout);
|
it('logout', logout);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue