Tidy up the auth plugin API mechanism to hide implementation details

The caller doesn't care which plugin is being used, so this commit
consolidates implementation details within auth.js

The motivation for this work is to prepare for extending the auth API
(to allow "advanced" LDAP to query user entry ontological state at start
up), by tidying up rather than duplicating the existing mechanism.
This commit is contained in:
Jonathan Sambrook 2020-04-22 14:33:35 +01:00
parent be78a5809a
commit a0d10989ad
4 changed files with 48 additions and 16 deletions

44
src/plugins/auth.js Normal file
View file

@ -0,0 +1,44 @@
"use strict";
const log = require("../log");
const colors = require("chalk");
// The order defines priority: the first available plugin is used.
// Always keep 'local' auth plugin at the end of the list; it should always be enabled.
const plugins = [require("./auth/ldap"), require("./auth/local")];
function unimplemented(funcName) {
log.debug(
`Auth module ${colors.bold(
module.exports.moduleName
)} doesn't implement function ${colors.bold(funcName)}`
);
}
// Default API implementations
module.exports = {
moduleName: "<module with no name>",
// Must override: implements authentication mechanism
auth: () => unimplemented("auth"),
};
// local auth should always be enabled, but check here to verify
let somethingEnabled = false;
// Override default API stubs with exports from first enabled plugin found
for (const plugin of plugins) {
if (plugin.isEnabled()) {
somethingEnabled = true;
for (const name in plugin) {
module.exports[name] = plugin[name];
}
break;
}
}
if (!somethingEnabled) {
log.error("None of the auth plugins is enabled");
}

View file

@ -144,6 +144,7 @@ function isLdapEnabled() {
}
module.exports = {
moduleName: "ldap",
auth: ldapAuth,
isEnabled: isLdapEnabled,
};

View file

@ -46,6 +46,7 @@ function localAuth(manager, client, user, password, callback) {
}
module.exports = {
moduleName: "local",
auth: localAuth,
isEnabled: () => true,
};

View file

@ -17,16 +17,13 @@ const net = require("net");
const Identification = require("./identification");
const changelog = require("./plugins/changelog");
const inputs = require("./plugins/inputs");
const Auth = require("./plugins/auth");
const themes = require("./plugins/packages/themes");
themes.loadLocalThemes();
const packages = require("./plugins/packages/index");
// The order defined the priority: the first available plugin is used
// ALways keep local auth in the end, which should always be enabled.
const authPlugins = [require("./plugins/auth/ldap"), require("./plugins/auth/local")];
// A random number that will force clients to reload the page if it differs
const serverHash = Math.floor(Date.now() * Math.random());
@ -854,18 +851,7 @@ function performAuthentication(data) {
}
// Perform password checking
let auth = () => {
log.error("None of the auth plugins is enabled");
};
for (let i = 0; i < authPlugins.length; ++i) {
if (authPlugins[i].isEnabled()) {
auth = authPlugins[i].auth;
break;
}
}
auth(manager, client, data.user, data.password, authCallback);
Auth.auth(manager, client, data.user, data.password, authCallback);
}
function reverseDnsLookup(ip, callback) {