auth provider refactor

This commit is contained in:
Jan Prochazka
2024-07-26 09:15:22 +02:00
parent c3c9ad1aed
commit dd964273cd
6 changed files with 76 additions and 29 deletions

View File

@@ -2,10 +2,15 @@ const crypto = require('crypto');
const tokenSecret = crypto.randomUUID(); const tokenSecret = crypto.randomUUID();
export function getTokenLifetime() { function getTokenLifetime() {
return process.env.TOKEN_LIFETIME || '1d'; return process.env.TOKEN_LIFETIME || '1d';
} }
export function getTokenSecret() { function getTokenSecret() {
return tokenSecret; return tokenSecret;
} }
module.exports = {
getTokenLifetime,
getTokenSecret,
};

View File

@@ -61,10 +61,19 @@ class AuthProviderBase {
return {}; return {};
} }
getCurrentLogin(req) {} getCurrentLogin(req) {
const { user } = (req && req.auth) || {};
return user;
}
getCurrentPermissions(req) { getCurrentPermissions(req) {
return process.env.PERMISSIONS; const login = this.getCurrentLogin(req);
const permissions = process.env[`LOGIN_PERMISSIONS_${login}`];
return permissions || process.env.PERMISSIONS;
}
isLoginForm() {
return false;
} }
} }
@@ -123,6 +132,11 @@ class OAuthProvider extends AuthProviderBase {
return { error: 'Token not found' }; return { error: 'Token not found' };
} }
getCurrentLogin(req) {
const { login } = (req && req.user) || {};
return login;
}
} }
class ADProvider extends AuthProviderBase { class ADProvider extends AuthProviderBase {
@@ -156,6 +170,10 @@ class ADProvider extends AuthProviderBase {
shouldAuthorizeApi() { shouldAuthorizeApi() {
return true; return true;
} }
isLoginForm() {
return true;
}
} }
class LoginsProvider extends AuthProviderBase { class LoginsProvider extends AuthProviderBase {
@@ -183,9 +201,21 @@ class LoginsProvider extends AuthProviderBase {
shouldAuthorizeApi() { shouldAuthorizeApi() {
return !process.env.BASIC_AUTH; return !process.env.BASIC_AUTH;
} }
getCurrentPermissions(req) {
const logins = getEnvLogins();
const loginName =
req && req.user && req.user.login ? req.user.login : req && req.auth && req.auth.user ? req.auth.user : null;
const login = logins && loginName ? logins.find(x => x.login == loginName) : null;
return login ? login.permissions : process.env.PERMISSIONS;
}
isLoginForm() {
return !process.env.BASIC_AUTH;
}
} }
export function detectEnvAuthProvider() { function detectEnvAuthProvider() {
if (process.env.AUTH_PROVIDER) { if (process.env.AUTH_PROVIDER) {
return process.env.AUTH_PROVIDER; return process.env.AUTH_PROVIDER;
} }
@@ -201,7 +231,7 @@ export function detectEnvAuthProvider() {
return 'none'; return 'none';
} }
export function createAuthProvider() { function createAuthProvider() {
const authProvider = detectEnvAuthProvider(); const authProvider = detectEnvAuthProvider();
switch (authProvider) { switch (authProvider) {
case 'oauth': case 'oauth':
@@ -214,3 +244,8 @@ export function createAuthProvider() {
return new AuthProviderBase(); return new AuthProviderBase();
} }
} }
module.exports = {
detectEnvAuthProvider,
createAuthProvider,
};

View File

@@ -1,7 +1,6 @@
const axios = require('axios'); const axios = require('axios');
const jwt = require('jsonwebtoken'); const jwt = require('jsonwebtoken');
const getExpressPath = require('../utility/getExpressPath'); const getExpressPath = require('../utility/getExpressPath');
const { getLogins } = require('../utility/hasPermission');
const { getLogger } = require('dbgate-tools'); const { getLogger } = require('dbgate-tools');
const AD = require('activedirectory2').promiseWrapper; const AD = require('activedirectory2').promiseWrapper;
const crypto = require('crypto'); const crypto = require('crypto');

View File

@@ -3,7 +3,7 @@ const os = require('os');
const path = require('path'); const path = require('path');
const axios = require('axios'); const axios = require('axios');
const { datadir, getLogsFilePath } = require('../utility/directories'); const { datadir, getLogsFilePath } = require('../utility/directories');
const { hasPermission, getLogins } = require('../utility/hasPermission'); const { hasPermission } = require('../utility/hasPermission');
const socket = require('../utility/socket'); const socket = require('../utility/socket');
const _ = require('lodash'); const _ = require('lodash');
const AsyncLock = require('async-lock'); const AsyncLock = require('async-lock');
@@ -11,6 +11,7 @@ const AsyncLock = require('async-lock');
const currentVersion = require('../currentVersion'); const currentVersion = require('../currentVersion');
const platformInfo = require('../utility/platformInfo'); const platformInfo = require('../utility/platformInfo');
const connections = require('../controllers/connections'); const connections = require('../controllers/connections');
const { createAuthProvider } = require('../auth/authProvider');
const lock = new AsyncLock(); const lock = new AsyncLock();
@@ -27,11 +28,10 @@ module.exports = {
get_meta: true, get_meta: true,
async get(_params, req) { async get(_params, req) {
const logins = getLogins(); const authProvider = createAuthProvider();
const loginName = const login = authProvider.getCurrentLogin(req);
req && req.user && req.user.login ? req.user.login : req && req.auth && req.auth.user ? req.auth.user : null; const permissions = authProvider.getCurrentPermissions(req);
const login = logins && loginName ? logins.find(x => x.login == loginName) : null; const isLoginForm = authProvider.isLoginForm();
const permissions = login ? login.permissions : process.env.PERMISSIONS;
return { return {
runAsPortal: !!connections.portalConnections, runAsPortal: !!connections.portalConnections,
@@ -47,7 +47,7 @@ module.exports = {
oauthClient: process.env.OAUTH_CLIENT_ID, oauthClient: process.env.OAUTH_CLIENT_ID,
oauthScope: process.env.OAUTH_SCOPE, oauthScope: process.env.OAUTH_SCOPE,
oauthLogout: process.env.OAUTH_LOGOUT, oauthLogout: process.env.OAUTH_LOGOUT,
isLoginForm: !!process.env.AD_URL || (!!logins && !process.env.BASIC_AUTH), isLoginForm,
storageDatabase: process.env.STORAGE_DATABASE, storageDatabase: process.env.STORAGE_DATABASE,
logsFilePath: getLogsFilePath(), logsFilePath: getLogsFilePath(),
connectionsFilePath: path.join(datadir(), 'connections.jsonl'), connectionsFilePath: path.join(datadir(), 'connections.jsonl'),

View File

@@ -32,7 +32,6 @@ const onFinished = require('on-finished');
const { rundir } = require('./utility/directories'); const { rundir } = require('./utility/directories');
const platformInfo = require('./utility/platformInfo'); const platformInfo = require('./utility/platformInfo');
const getExpressPath = require('./utility/getExpressPath'); const getExpressPath = require('./utility/getExpressPath');
const { getLogins } = require('./utility/hasPermission');
const _ = require('lodash'); const _ = require('lodash');
const { getLogger } = require('dbgate-tools'); const { getLogger } = require('dbgate-tools');
const { createAuthProvider } = require('./auth/authProvider'); const { createAuthProvider } = require('./auth/authProvider');

View File

@@ -1,27 +1,37 @@
const { compilePermissions, testPermission } = require('dbgate-tools'); const { compilePermissions, testPermission } = require('dbgate-tools');
const _ = require('lodash'); const _ = require('lodash');
const { createAuthProvider } = require('../auth/authProvider');
const userPermissions = {}; const cachedPermissions = {};
function hasPermission(tested, req) { function hasPermission(tested, req) {
if (!req) { if (!req) {
// request object not available, allow all // request object not available, allow all
return true; return true;
} }
const { user } = (req && req.auth) || {};
const { login } = (process.env.OAUTH_PERMISSIONS && req && req.user) || {};
const key = user || login || '';
const logins = getLogins();
if (!userPermissions[key]) { const permissions = createAuthProvider().getCurrentPermissions(req);
if (logins) {
const login = logins.find(x => x.login == user); if (!cachedPermissions[permissions]) {
userPermissions[key] = compilePermissions(login ? login.permissions : null); cachedPermissions[permissions] = compilePermissions(permissions);
} else {
userPermissions[key] = compilePermissions(process.env.PERMISSIONS);
} }
}
return testPermission(tested, userPermissions[key]); return testPermission(tested, cachedPermissions[permissions]);
// const { user } = (req && req.auth) || {};
// const { login } = (process.env.OAUTH_PERMISSIONS && req && req.user) || {};
// const key = user || login || '';
// const logins = getLogins();
// if (!userPermissions[key]) {
// if (logins) {
// const login = logins.find(x => x.login == user);
// userPermissions[key] = compilePermissions(login ? login.permissions : null);
// } else {
// userPermissions[key] = compilePermissions(process.env.PERMISSIONS);
// }
// }
// return testPermission(tested, userPermissions[key]);
} }
// let loginsCache = null; // let loginsCache = null;
@@ -86,7 +96,6 @@ function testConnectionPermission(connection, req) {
module.exports = { module.exports = {
hasPermission, hasPermission,
getLogins,
connectionHasPermission, connectionHasPermission,
testConnectionPermission, testConnectionPermission,
}; };