From 002b6723bb141534d933a19a956eb2f0df5fea11 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Mon, 27 Apr 2020 10:13:59 +0200 Subject: [PATCH] Add ldap auth plugin --- .gitignore | 1 + peertube-plugin-auth-ldap/README.md | 3 + .../client/common-client-plugin.js | 46 +++++ peertube-plugin-auth-ldap/main.js | 157 ++++++++++++++++++ peertube-plugin-auth-ldap/package-lock.json | 151 +++++++++++++++++ peertube-plugin-auth-ldap/package.json | 24 +++ 6 files changed, 382 insertions(+) create mode 100644 .gitignore create mode 100644 peertube-plugin-auth-ldap/README.md create mode 100644 peertube-plugin-auth-ldap/client/common-client-plugin.js create mode 100644 peertube-plugin-auth-ldap/main.js create mode 100644 peertube-plugin-auth-ldap/package-lock.json create mode 100644 peertube-plugin-auth-ldap/package.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c2658d7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/peertube-plugin-auth-ldap/README.md b/peertube-plugin-auth-ldap/README.md new file mode 100644 index 0000000..436534a --- /dev/null +++ b/peertube-plugin-auth-ldap/README.md @@ -0,0 +1,3 @@ +# LDAP auth plugin for PeerTube + +Add LDAP support to login form in PeerTube. \ No newline at end of file diff --git a/peertube-plugin-auth-ldap/client/common-client-plugin.js b/peertube-plugin-auth-ldap/client/common-client-plugin.js new file mode 100644 index 0000000..c126219 --- /dev/null +++ b/peertube-plugin-auth-ldap/client/common-client-plugin.js @@ -0,0 +1,46 @@ +function register ({ registerHook, peertubeHelpers }) { + initMatomo(registerHook, peertubeHelpers) + .catch(err => console.error('Cannot initialize Matomo', err)) +} + +export { + register +} + +function initMatomo (registerHook, peertubeHelpers) { + return peertubeHelpers.getSettings() + .then(s => { + if (!s || !s['site-id'] || !s['url']) { + console.error('Matomo settings are not set.') + return + } + + const matomoUrl = s['url'] + const siteId = s['site-id'] + + window._paq = window._paq || []; + window._paq.push(['trackPageView']); + window._paq.push(['enableLinkTracking']); + (function() { + var u = matomoUrl + '/'; + window._paq.push(['setTrackerUrl', u+'matomo.php']); + window._paq.push(['setSiteId', siteId]); + var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; + g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s); + })(); + + window._paq.push(['setDocumentTitle', window.document.title]); + window._paq.push(['setCustomUrl', '/' + window.location.hash.substr(1)]); + window._paq.push(['trackPageView']); + + registerHook({ + target: 'action:router.navigation-end', + handler: function (params) { + window._paq.push(['setDocumentTitle', window.document.title]); + window._paq.push(['setCustomUrl', params.path]); + window._paq.push(['trackPageView']); + } + }) + }) + +} diff --git a/peertube-plugin-auth-ldap/main.js b/peertube-plugin-auth-ldap/main.js new file mode 100644 index 0000000..0b6fc7c --- /dev/null +++ b/peertube-plugin-auth-ldap/main.js @@ -0,0 +1,157 @@ +const LdapAuth = require('ldapauth-fork') + +async function register ({ + registerIdAndPassAuth, + registerSetting, + settingsManager, + peertubeHelpers +}) { + registerSetting({ + name: 'url', + label: 'URL', + type: 'input', + private: true + }) + + registerSetting({ + name: 'insecure-tls', + label: 'Insecure TLS', + type: 'input-checkbox', + private: true, + default: false + }) + + registerSetting({ + name: 'bind-dn', + label: 'Bind DN', + type: 'input', + private: true + }) + + registerSetting({ + name: 'bind-credentials', + label: 'Bind Password', + type: 'input', + private: true + }) + + registerSetting({ + name: 'search-base', + label: 'Search base', + type: 'input', + private: true + }) + + registerSetting({ + name: 'search-filter', + label: 'Search filter', + type: 'input', + private: true, + default: '(|(mail={{username}})(uid={{username}}))' + }) + + registerSetting({ + name: 'mail-property', + label: 'Mail property', + type: 'input', + private: true, + default: 'mail' + }) + + registerSetting({ + name: 'username-property', + label: 'Username property', + type: 'input', + private: true, + default: 'uid' + }) + + registerIdAndPassAuth({ + authName: 'ldap', + getWeight: () => 100, + login: options => login(peertubeHelpers, settingsManager, options) + }) +} + +async function unregister () { + return +} + +module.exports = { + register, + unregister +} + +// ############################################################################ + +async function login (peertubeHelpers, settingsManager, options) { + const logger = peertubeHelpers.logger + + const settings = await settingsManager.getSettings([ + 'url', + 'insecure-tls', + 'bind-dn', + 'bind-credentials', + 'search-base', + 'search-filter', + 'mail-property', + 'username-property', + ]) + + if (!settings['url']) { + logger.info('Do not login user %s because admin did not configure LDAP.', options.id) + return null + } + + const ldapClient = new LdapAuth({ + url: settings['url'], + bindDN: settings['bind-dn'], + bindCredentials: settings['bind-credentials'], + searchBase: settings['search-base'], + searchFilter: settings['search-filter'], + reconnect: true, + tlsOptions: { + rejectUnauthorized: settings['insecure-tls'] !== true + } + }) + + return new Promise(res => { + function onError (err) { + logger.warn('Cannot login %s in LDAP plugin.', options.id, { err }) + return res(null) + } + + ldapClient.on('error', onError) + + ldapClient.authenticate(options.id, options.password, function (err, user) { + ldapClient.close(function () { + // We don't care about the closing + }) + + if (err) return onError(err) + + if (!user) { + logger.warn('Cannot find user %s in LDAP plugin.', options.id) + return res(null) + } + + const mailProperty = settings['mail-property'] + const usernameProperty = settings['username-property'] + + if (!user[mailProperty]) { + logger.warn('Cannot find mail property in LDAP plugin.', { mailProperty, user }) + return res(null) + } + + if (!user[usernameProperty]) { + logger.warn('Cannot find username property in LDAP plugin.', { usernameProperty, user }) + return res(null) + } + + return res({ + username: user[usernameProperty], + email: user[mailProperty] + }) + }) + }) +} \ No newline at end of file diff --git a/peertube-plugin-auth-ldap/package-lock.json b/peertube-plugin-auth-ldap/package-lock.json new file mode 100644 index 0000000..5adbac7 --- /dev/null +++ b/peertube-plugin-auth-ldap/package-lock.json @@ -0,0 +1,151 @@ +{ + "name": "peertube-plugin-auth-ldap", + "version": "0.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@types/ldapjs": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/ldapjs/-/ldapjs-1.0.7.tgz", + "integrity": "sha512-Cacc0pQ6fw8+J5Qwebbj2+YpYANOl09WEDjJsNyPHpNSza318mUIuAhgXDfC8kXDViymlEQIvgbvuPKovRIVEQ==", + "requires": { + "@types/node": "*" + } + }, + "@types/node": { + "version": "13.13.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.2.tgz", + "integrity": "sha512-LB2R1Oyhpg8gu4SON/mfforE525+Hi/M1ineICEDftqNVTyFg1aRIeGuTvXAoWHc4nbrFncWtJgMmoyRvuGh7A==" + }, + "abstract-logging": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/abstract-logging/-/abstract-logging-1.0.0.tgz", + "integrity": "sha1-i33q/TEFWbwo93ck3RuzAXcnjBs=" + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "backoff": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/backoff/-/backoff-2.5.0.tgz", + "integrity": "sha1-9hbtqdPktmuMp/ynn2lXIsX44m8=", + "requires": { + "precond": "0.2" + } + }, + "bcryptjs": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", + "integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "extsprintf": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.0.tgz", + "integrity": "sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=" + }, + "ldap-filter": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/ldap-filter/-/ldap-filter-0.3.3.tgz", + "integrity": "sha1-KxTGiiqdQQTb28kQocqF/Riel5c=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "ldapauth-fork": { + "version": "5.0.0-rc.6", + "resolved": "https://registry.npmjs.org/ldapauth-fork/-/ldapauth-fork-5.0.0-rc.6.tgz", + "integrity": "sha512-0OfaaSq1ufXlMwcy1oTPVRsN7GYi2tYI1WH2mxL4aN+sJhPVf+JSzmuFDLqFPoAcZyY2slllWLdL+8WnZxg31g==", + "requires": { + "@types/ldapjs": "^1.0.4", + "@types/node": "*", + "bcryptjs": "^2.4.0", + "ldapjs": "^2.0.0-pre.5", + "lru-cache": "^5.1.1" + } + }, + "ldapjs": { + "version": "2.0.0-pre.5", + "resolved": "https://registry.npmjs.org/ldapjs/-/ldapjs-2.0.0-pre.5.tgz", + "integrity": "sha512-nmcSqdUjS7dzloToGCrSX3/TCdKJqLKUD+mMeo2K+NAkRkyn2iDZJRVusUFwFykXcaAr8hPX2qOKzc9PeTA4MQ==", + "requires": { + "abstract-logging": "^1.0.0", + "asn1": "^0.2.4", + "assert-plus": "^1.0.0", + "backoff": "^2.5.0", + "ldap-filter": "^0.3.3", + "once": "^1.4.0", + "vasync": "^2.2.0", + "verror": "^1.8.1" + } + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "requires": { + "yallist": "^3.0.2" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "precond": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/precond/-/precond-0.2.3.tgz", + "integrity": "sha1-qpWRvKokkj8eD0hJ0kD0fvwQdaw=" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "vasync": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/vasync/-/vasync-2.2.0.tgz", + "integrity": "sha1-z951GGChWCLbOxMrxZsRakra8Bs=", + "requires": { + "verror": "1.10.0" + } + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + } + } +} diff --git a/peertube-plugin-auth-ldap/package.json b/peertube-plugin-auth-ldap/package.json new file mode 100644 index 0000000..7be3567 --- /dev/null +++ b/peertube-plugin-auth-ldap/package.json @@ -0,0 +1,24 @@ +{ + "name": "peertube-plugin-auth-ldap", + "version": "0.0.1", + "description": "Add LDAP support to login form in PeerTube.", + "engine": { + "peertube": ">=2.2.0" + }, + "keywords": [ + "peertube", + "plugin", + "auth" + ], + "homepage": "https://framagit.org/framasoft/peertube/official-plugins/tree/master/peertube-plugin-auth-ldap", + "author": "Chocobozzz", + "bugs": "https://framagit.org/framasoft/peertube/official-plugins/issues", + "library": "./main.js", + "staticDirs": {}, + "css": [], + "clientScripts": [], + "translations": {}, + "dependencies": { + "ldapauth-fork": "^5.0.0-rc.6" + } +}