add getUserObjFromUsername util function,

update all backends to use userObj,
add user backend manager wrapper which calls all linked backends dealing with user data,
list backend handlers for each realm
This commit is contained in:
Arthur Lu 2024-06-03 18:09:28 +00:00
parent bb7404a82d
commit b12f38e608
13 changed files with 211 additions and 109 deletions

View File

@ -30,10 +30,14 @@
} }
}, },
"handlers": { "handlers": {
"pve": "pve", "instance": {
"db": "localdb",
"auth": {
"pve": "pve" "pve": "pve"
},
"users": {
"pve": [
"localdb",
"pve"
]
} }
}, },
"application": { "application": {

View File

@ -2,7 +2,7 @@ import path from "path";
import url from "url"; import url from "url";
export default async () => { export default async () => {
const backends = {}; global.backends = {};
for (const name in global.config.backends) { for (const name in global.config.backends) {
// get files and config // get files and config
const target = global.config.backends[name].import; const target = global.config.backends[name].import;
@ -14,17 +14,11 @@ export default async () => {
const importPath = `./${path.relative(thisPath, targetPath)}`; const importPath = `./${path.relative(thisPath, targetPath)}`;
// import and add to list of imported handlers // import and add to list of imported handlers
const Backend = (await import(importPath)).default; const Backend = (await import(importPath)).default;
backends[name] = new Backend(config); global.backends[name] = new Backend(config);
console.log(`backends: initialized backend ${name} from ${importPath}`); console.log(`backends: initialized backend ${name} from ${importPath}`);
} }
// assign backends to handlers by type global.pve = global.backends[global.config.handlers.instance.pve];
const handlers = global.config.handlers; global.userManager = new USER_BACKEND_MANAGER(global.config.handlers.users);
global.pve = backends[handlers.pve];
global.db = backends[handlers.db];
global.auth = handlers.auth;
Object.keys(global.auth).forEach((e) => {
global.auth[e] = backends[global.auth[e]];
});
}; };
/** /**
@ -34,10 +28,11 @@ export default async () => {
class BACKEND { class BACKEND {
/** /**
* Opens a session with the backend and creates session tokens if needed * Opens a session with the backend and creates session tokens if needed
* @param {{username: string, password: string}} credentials object containing username and password fields * @param {{id: string, realm: string}} user object containing username and password fields
* @param {string} password
* @returns {{ok: boolean, status: number, cookies: {name: string, value: string}[]}} response like object with list of session token objects with token name and value * @returns {{ok: boolean, status: number, cookies: {name: string, value: string}[]}} response like object with list of session token objects with token name and value
*/ */
openSession (credentials) { openSession (user, password) {
return { return {
ok: true, ok: true,
status: 200, status: 200,
@ -70,12 +65,14 @@ class USER_BACKEND extends BACKEND {
* @param {Object} params authentication params, usually req.cookies * @param {Object} params authentication params, usually req.cookies
*/ */
addUser (user, attributes, params = null) {} addUser (user, attributes, params = null) {}
/** /**
* Get user from backend * Get user from backend
* @param {{id: string, realm: string}} user * @param {{id: string, realm: string}} user
* @param {Object} params authentication params, usually req.cookies * @param {Object} params authentication params, usually req.cookies
*/ */
getUser (user, params = null) {} getUser (user, params = null) {}
/** /**
* Modify user in backend * Modify user in backend
* @param {{id: string, realm: string}} user * @param {{id: string, realm: string}} user
@ -83,6 +80,7 @@ class USER_BACKEND extends BACKEND {
* @param {Object} params authentication params, usually req.cookies * @param {Object} params authentication params, usually req.cookies
*/ */
setUser (user, attributes, params = null) {} setUser (user, attributes, params = null) {}
/** /**
* Delete user from backend * Delete user from backend
* @param {{id: string, realm: string}} user * @param {{id: string, realm: string}} user
@ -97,12 +95,14 @@ class USER_BACKEND extends BACKEND {
* @param {Object} params authentication params, usually req.cookies * @param {Object} params authentication params, usually req.cookies
*/ */
addGroup (group, attributes, params = null) {} addGroup (group, attributes, params = null) {}
/** /**
* Get group from backend * Get group from backend
* @param {{id: string}} group * @param {{id: string}} group
* @param {Object} params authentication params, usually req.cookies * @param {Object} params authentication params, usually req.cookies
*/ */
getGroup (group, params = null) {} getGroup (group, params = null) {}
/** /**
* Modify group in backend * Modify group in backend
* @param {{id: string}} group * @param {{id: string}} group
@ -110,6 +110,7 @@ class USER_BACKEND extends BACKEND {
* @param {Object} params authentication params, usually req.cookies * @param {Object} params authentication params, usually req.cookies
*/ */
setGroup (group, attributes, params = null) {} setGroup (group, attributes, params = null) {}
/** /**
* Delete group from backend * Delete group from backend
* @param {{id: string}} group * @param {{id: string}} group
@ -124,6 +125,7 @@ class USER_BACKEND extends BACKEND {
* @param {Object} params authentication params, usually req.cookies * @param {Object} params authentication params, usually req.cookies
*/ */
addUserToGroup (user, group, params = null) {} addUserToGroup (user, group, params = null) {}
/** /**
* Remove user from group * Remove user from group
* @param {{id: string, realm: string}} user * @param {{id: string, realm: string}} user
@ -147,3 +149,122 @@ export class DB_BACKEND extends USER_BACKEND {}
* Interface for user auth backends. * Interface for user auth backends.
*/ */
export class AUTH_BACKEND extends USER_BACKEND {} export class AUTH_BACKEND extends USER_BACKEND {}
/**
* Interface combining all user backends into a single interface
* Calling methods will also call sub handler methods
* Also handles refreshing proxmox handler
*/
class USER_BACKEND_MANAGER extends USER_BACKEND {
#config = null;
constructor (config) {
super();
this.#config = config;
}
getBackendsByUser (user) {
return this.#config[user.realm];
}
/**
* Add user to backend
* @param {{id: string, realm: string}} user
* @param {Object} attributes user attributes
* @param {Object} params authentication params, usually req.cookies
*/
addUser (user, attributes, params = null) {}
/**
* Get user from backend
* @param {{id: string, realm: string}} user
* @param {Object} params authentication params, usually req.cookies
*/
async getUser (user, params = null) {
let userData = {};
for (const backend of this.#config[user.realm]) {
let backendData = await global.backends[backend].getUser(user, params)
if (backendData) {
userData = { ...backendData, ...userData };
}
}
return userData;
}
/**
* Modify user in backend
* @param {{id: string, realm: string}} user
* @param {Object} attributes new user attributes to modify
* @param {Object} params authentication params, usually req.cookies
*/
async setUser (user, attributes, params = null) {
const results = {
ok: true,
status: 200,
log: []
};
for (const backend of this.#config[user.realm]) {
const r = await global.backends[backend].setUser(user, attributes, params);
results.log.push(backend)
if (!r) {
results.ok = false;
results.status = 500;
return results;
}
}
return results;
}
/**
* Delete user from backend
* @param {{id: string, realm: string}} user
* @param {Object} params authentication params, usually req.cookies
*/
deluser (user, params = null) {}
/**
* Add group to backend
* @param {{id: string}} group
* @param {Object} attributes group attributes
* @param {Object} params authentication params, usually req.cookies
*/
addGroup (group, attributes, params = null) {}
/**
* Get group from backend
* @param {{id: string}} group
* @param {Object} params authentication params, usually req.cookies
*/
getGroup (group, params = null) {}
/**
* Modify group in backend
* @param {{id: string}} group
* @param {Object} attributes new group attributes to modify
* @param {Object} params authentication params, usually req.cookies
*/
setGroup (group, attributes, params = null) {}
/**
* Delete group from backend
* @param {{id: string}} group
* @param {Object} params authentication params, usually req.cookies
*/
delGroup (group, params = null) {}
/**
* Add user to group
* @param {{id: string, realm: string}} user
* @param {{id: string}} group
* @param {Object} params authentication params, usually req.cookies
*/
addUserToGroup (user, group, params = null) {}
/**
* Remove user from group
* @param {{id: string, realm: string}} user
* @param {{id: string}} group
* @param {Object} params authentication params, usually req.cookies
*/
delUserFromGroup (user, group, params = null) {}
}

View File

@ -53,14 +53,19 @@ export default class LocalDB extends DB_BACKEND {
} }
setUser (user, attributes, params = null) { setUser (user, attributes, params = null) {
const username = `${user.id}@${user.realm}`; if (attributes.resources && attributes.cluster && attributes.templates) { // localdb should only deal with these attributes
if (this.#data.users[username]) { const username = `${user.id}@${user.realm}`;
this.#data.users[username] = attributes; if (this.#data.users[username]) {
this.#save(); this.#data.users[username] = attributes;
return true; this.#save();
return true;
}
else {
return false;
}
} }
else { else { // if request is not setting these attributes, then assume its fine but do nothing
return false; return true;
} }
} }

View File

@ -48,10 +48,9 @@ export default class PAASLDAP extends AUTH_BACKEND {
} }
} }
async openSession (credentials) { async openSession (user, password) {
const userRealm = credentials.username.split("@").at(-1); const uid = user.id;
const uid = credentials.username.replace(`@${userRealm}`, ""); const content = { uid, password };
const content = { uid, password: credentials.password };
const result = await this.#request("/ticket", "POST", null, content); const result = await this.#request("/ticket", "POST", null, content);
if (result.ok) { if (result.ok) {
const cookies = setCookie.parse(result.headers["set-cookie"]); const cookies = setCookie.parse(result.headers["set-cookie"]);
@ -74,7 +73,13 @@ export default class PAASLDAP extends AUTH_BACKEND {
} }
async getUser (user, params = null) { async getUser (user, params = null) {
return await this.#request(`/users/${user.id}`, "GET", params); const res = await this.#request(`/users/${user.id}`, "GET", params);
if (res.ok) {
return res.data;
}
else {
return false;
}
} }
async setUser (user, attributes, params = null) { async setUser (user, attributes, params = null) {

View File

@ -13,7 +13,8 @@ export default class PVE extends PVE_BACKEND {
this.#pveRoot = config.root; this.#pveRoot = config.root;
} }
async openSession (credentials) { async openSession (user, password) {
const credentials = { username: `${user.id}@${user.realm}`, password };
const response = await global.pve.requestPVE("/access/ticket", "POST", null, credentials); const response = await global.pve.requestPVE("/access/ticket", "POST", null, credentials);
if (!(response.status === 200)) { if (!(response.status === 200)) {
return response; return response;

View File

@ -23,10 +23,10 @@ router.get("/", async (req, res) => {
class CookieFetcher { class CookieFetcher {
#fetchedBackends = []; #fetchedBackends = [];
#cookies = []; #cookies = [];
async fetchBackends (backends, credentials) { async fetchBackends (backends, user, password) {
for (const backend of backends) { for (const backend of backends) {
if (this.#fetchedBackends.indexOf(backend) === -1) { if (this.#fetchedBackends.indexOf(backend) === -1) {
const response = await backend.openSession(credentials); const response = await global.backends[backend].openSession(user, password);
if (!response.ok) { if (!response.ok) {
return false; return false;
} }
@ -60,13 +60,16 @@ router.post("/ticket", async (req, res) => {
password: req.body.password password: req.body.password
}; };
const domain = global.config.application.domain; const domain = global.config.application.domain;
const userRealm = params.username.split("@").at(-1); // const userRealm = params.username.split("@").at(-1);
const backends = [global.pve, global.db]; const userObj = global.utils.getUserObjFromUsername(params.username);
if (userRealm in global.auth) { let backends = global.userManager.getBackendsByUser(userObj);
backends.push(global.auth[userRealm]); backends = backends.concat(["pve"]);
} // const backends = [global.pve, global.db];
// if (userRealm in global.auth) {
// backends.push(global.auth[userRealm]);
// }
const cm = new CookieFetcher(); const cm = new CookieFetcher();
const success = await cm.fetchBackends(backends, params); const success = await cm.fetchBackends(backends, userObj, params.password);
if (!success) { if (!success) {
res.status(401).send({ auth: false }); res.status(401).send({ auth: false });
return; return;
@ -97,7 +100,7 @@ router.delete("/ticket", async (req, res) => {
res.cookie(cookie, "", { domain, path: "/", expires: expire }); res.cookie(cookie, "", { domain, path: "/", expires: expire });
} }
await global.pve.closeSession(req.cookies); await global.pve.closeSession(req.cookies);
await global.db.closeSession(req.cookies); await global.userManager.closeSession(req.cookies);
res.status(200).send({ auth: false }); res.status(200).send({ auth: false });
}); });
@ -114,24 +117,10 @@ router.post("/password", async (req, res) => {
password: req.body.password password: req.body.password
}; };
const userRealm = params.username.split("@").at(-1); const userObj = global.utils.getUserObjFromUsername(params.username);
const authHandlers = global.config.handlers.auth; const newAttributes = {
const userID = params.username.replace(`@${userRealm}`, ""); userpassword: params.password
const userObj = { id: userID, realm: userRealm }; };
if (userRealm in authHandlers) { const response = await global.userManager.setUser(userObj, newAttributes, req.cookies);
const handler = authHandlers[userRealm]; res.status(response.status).send(response);
const newAttributes = {
userpassword: params.password
};
const response = await handler.setUser(userObj, newAttributes, req.cookies);
if (response.ok) {
res.status(response.status).send(response.data);
}
else {
res.status(response.status).send({ error: response.data.error });
}
}
else {
res.status(501).send({ error: `Auth type ${userRealm} not implemented yet.` });
}
}); });

View File

@ -1,7 +1,6 @@
import { Router } from "express"; import { Router } from "express";
export const router = Router({ mergeParams: true }); export const router = Router({ mergeParams: true });
const db = global.db;
const checkAuth = global.utils.checkAuth; const checkAuth = global.utils.checkAuth;
const approveResources = global.utils.approveResources; const approveResources = global.utils.approveResources;
const getUserResources = global.utils.getUserResources; const getUserResources = global.utils.getUserResources;
@ -29,16 +28,14 @@ router.get(`/:node(${nodeRegexP})/pci`, async (req, res) => {
node: req.params.node node: req.params.node
}; };
const userRealm = req.cookies.username.split("@").at(-1); const userObj = global.utils.getUserObjFromUsername(req.cookies.username);
const userID = req.cookies.username.replace(`@${userRealm}`, "");
const userObj = { id: userID, realm: userRealm };
// check auth // check auth
const auth = await checkAuth(req.cookies, res); const auth = await checkAuth(req.cookies, res);
if (!auth) { if (!auth) {
return; return;
} }
const userNodes = db.getUser(userObj).cluster.nodes; const userNodes = (await global.userManager.getUser(userObj)).cluster.nodes;
if (userNodes[params.node] !== true) { if (userNodes[params.node] !== true) {
res.status(401).send({ auth: false, path: params.node }); res.status(401).send({ auth: false, path: params.node });
res.end(); res.end();
@ -83,9 +80,7 @@ router.post(`${basePath}/resources`, async (req, res) => {
boot: req.body.boot boot: req.body.boot
}; };
const userRealm = req.cookies.username.split("@").at(-1); const userObj = global.utils.getUserObjFromUsername(req.cookies.username);
const userID = req.cookies.username.replace(`@${userRealm}`, "");
const userObj = { id: userID, realm: userRealm };
// check auth for specific instance // check auth for specific instance
const vmpath = `/nodes/${params.node}/${params.type}/${params.vmid}`; const vmpath = `/nodes/${params.node}/${params.type}/${params.vmid}`;
@ -165,9 +160,7 @@ router.post(`${basePath}/create`, async (req, res) => {
rootfssize: req.body.rootfssize rootfssize: req.body.rootfssize
}; };
const userRealm = req.cookies.username.split("@").at(-1); const userObj = global.utils.getUserObjFromUsername(req.cookies.username);
const userID = req.cookies.username.replace(`@${userRealm}`, "");
const userObj = { id: userID, realm: userRealm };
// check auth // check auth
const auth = await checkAuth(req.cookies, res); const auth = await checkAuth(req.cookies, res);
@ -175,7 +168,7 @@ router.post(`${basePath}/create`, async (req, res) => {
return; return;
} }
// get user db config // get user db config
const user = await db.getUser(userObj); const user = await global.userManager.getUser(userObj);
const vmid = Number.parseInt(params.vmid); const vmid = Number.parseInt(params.vmid);
const vmidMin = user.cluster.vmid.min; const vmidMin = user.cluster.vmid.min;
const vmidMax = user.cluster.vmid.max; const vmidMax = user.cluster.vmid.max;

View File

@ -130,9 +130,7 @@ router.post("/:disk/resize", async (req, res) => {
size: req.body.size size: req.body.size
}; };
const userRealm = req.cookies.username.split("@").at(-1); const userObj = global.utils.getUserObjFromUsername(req.cookies.username);
const userID = req.cookies.username.replace(`@${userRealm}`, "");
const userObj = { id: userID, realm: userRealm };
// check auth for specific instance // check auth for specific instance
const vmpath = `/nodes/${params.node}/${params.type}/${params.vmid}`; const vmpath = `/nodes/${params.node}/${params.type}/${params.vmid}`;
@ -192,9 +190,7 @@ router.post("/:disk/move", async (req, res) => {
delete: req.body.delete delete: req.body.delete
}; };
const userRealm = req.cookies.username.split("@").at(-1); const userObj = global.utils.getUserObjFromUsername(req.cookies.username);
const userID = req.cookies.username.replace(`@${userRealm}`, "");
const userObj = { id: userID, realm: userRealm };
// check auth for specific instance // check auth for specific instance
const vmpath = `/nodes/${params.node}/${params.type}/${params.vmid}`; const vmpath = `/nodes/${params.node}/${params.type}/${params.vmid}`;
@ -315,9 +311,7 @@ router.post("/:disk/create", async (req, res) => {
iso: req.body.iso iso: req.body.iso
}; };
const userRealm = req.cookies.username.split("@").at(-1); const userObj = global.utils.getUserObjFromUsername(req.cookies.username);
const userID = req.cookies.username.replace(`@${userRealm}`, "");
const userObj = { id: userID, realm: userRealm };
// check auth for specific instance // check auth for specific instance
const vmpath = `/nodes/${params.node}/${params.type}/${params.vmid}`; const vmpath = `/nodes/${params.node}/${params.type}/${params.vmid}`;

View File

@ -1,7 +1,6 @@
import { Router } from "express"; import { Router } from "express";
export const router = Router({ mergeParams: true }); ; export const router = Router({ mergeParams: true }); ;
const db = global.db;
const checkAuth = global.utils.checkAuth; const checkAuth = global.utils.checkAuth;
const approveResources = global.utils.approveResources; const approveResources = global.utils.approveResources;
@ -32,9 +31,7 @@ router.post("/:netid/create", async (req, res) => {
name: req.body.name name: req.body.name
}; };
const userRealm = req.cookies.username.split("@").at(-1); const userObj = global.utils.getUserObjFromUsername(req.cookies.username);
const userID = req.cookies.username.replace(`@${userRealm}`, "");
const userObj = { id: userID, realm: userRealm };
// check auth for specific instance // check auth for specific instance
const vmpath = `/nodes/${params.node}/${params.type}/${params.vmid}`; const vmpath = `/nodes/${params.node}/${params.type}/${params.vmid}`;
@ -65,7 +62,7 @@ router.post("/:netid/create", async (req, res) => {
return; return;
} }
// setup action // setup action
const nc = db.getUser(userObj).templates.network[params.type]; const nc = (await global.userManager.getUser(userObj)).templates.network[params.type];
const action = {}; const action = {};
if (params.type === "lxc") { if (params.type === "lxc") {
action[`net${params.netid}`] = `name=${params.name},bridge=${nc.bridge},ip=${nc.ip},ip6=${nc.ip6},tag=${nc.vlan},type=${nc.type},rate=${params.rate}`; action[`net${params.netid}`] = `name=${params.name},bridge=${nc.bridge},ip=${nc.ip},ip6=${nc.ip6},tag=${nc.vlan},type=${nc.type},rate=${params.rate}`;
@ -104,9 +101,7 @@ router.post("/:netid/modify", async (req, res) => {
rate: req.body.rate rate: req.body.rate
}; };
const userRealm = req.cookies.username.split("@").at(-1); const userObj = global.utils.getUserObjFromUsername(req.cookies.username);
const userID = req.cookies.username.replace(`@${userRealm}`, "");
const userObj = { id: userID, realm: userRealm };
// check auth for specific instance // check auth for specific instance
const vmpath = `/nodes/${params.node}/${params.type}/${params.vmid}`; const vmpath = `/nodes/${params.node}/${params.type}/${params.vmid}`;

View File

@ -75,9 +75,7 @@ router.post("/:hostpci/modify", async (req, res) => {
pcie: req.body.pcie pcie: req.body.pcie
}; };
const userRealm = req.cookies.username.split("@").at(-1); const userObj = global.utils.getUserObjFromUsername(req.cookies.username);
const userID = req.cookies.username.replace(`@${userRealm}`, "");
const userObj = { id: userID, realm: userRealm };
// check if type is qemu // check if type is qemu
if (params.type !== "qemu") { if (params.type !== "qemu") {
@ -162,9 +160,7 @@ router.post("/create", async (req, res) => {
pcie: req.body.pcie pcie: req.body.pcie
}; };
const userRealm = req.cookies.username.split("@").at(-1); const userObj = global.utils.getUserObjFromUsername(req.cookies.username);
const userID = req.cookies.username.replace(`@${userRealm}`, "");
const userObj = { id: userID, realm: userRealm };
// check if type is qemu // check if type is qemu
if (params.type !== "qemu") { if (params.type !== "qemu") {

View File

@ -165,12 +165,10 @@ if (schemes.interrupt.enabled) {
socket.destroy(); socket.destroy();
} }
else { else {
wsServer.handleUpgrade(req, socket, head, (socket) => { wsServer.handleUpgrade(req, socket, head, async (socket) => {
// get the user pools // get the user pools
const userRealm = cookies.username.split("@").at(-1); const userObj = global.utils.getUserObjFromUsername(cookies.username);
const userID = cookies.username.replace(`@${userRealm}`, ""); const pools = Object.keys((await global.userManager.getUser(userObj)).cluster.pools);
const userObj = { id: userID, realm: userRealm };
const pools = Object.keys(global.db.getUser(userObj).cluster.pools);
// emit the connection to initialize socket // emit the connection to initialize socket
wsServer.emit("connection", socket, cookies.username, pools); wsServer.emit("connection", socket, cookies.username, pools);
}); });

View File

@ -18,9 +18,7 @@ router.get("/dynamic/resources", async (req, res) => {
return; return;
} }
const userRealm = req.cookies.username.split("@").at(-1); const userObj = global.utils.getUserObjFromUsername(req.cookies.username);
const userID = req.cookies.username.replace(`@${userRealm}`, "");
const userObj = { id: userID, realm: userRealm };
const resources = await getUserResources(req, userObj); const resources = await getUserResources(req, userObj);
res.status(200).send(resources); res.status(200).send(resources);
@ -40,9 +38,7 @@ router.get("/config/:key", async (req, res) => {
key: req.params.key key: req.params.key
}; };
const userRealm = req.cookies.username.split("@").at(-1); const userObj = global.utils.getUserObjFromUsername(req.cookies.username);
const userID = req.cookies.username.replace(`@${userRealm}`, "");
const userObj = { id: userID, realm: userRealm };
// check auth // check auth
const auth = await checkAuth(req.cookies, res); const auth = await checkAuth(req.cookies, res);
@ -51,7 +47,7 @@ router.get("/config/:key", async (req, res) => {
} }
const allowKeys = ["resources", "cluster"]; const allowKeys = ["resources", "cluster"];
if (allowKeys.includes(params.key)) { if (allowKeys.includes(params.key)) {
const config = global.db.getUser(userObj); const config = await global.userManager.getUser(userObj);
res.status(200).send(config[params.key]); res.status(200).send(config[params.key]);
} }
else { else {

View File

@ -15,11 +15,9 @@ import { exit } from "process";
export async function checkAuth (cookies, res, vmpath = null) { export async function checkAuth (cookies, res, vmpath = null) {
let auth = false; let auth = false;
const userRealm = cookies.username.split("@").at(-1); const userObj = getUserObjFromUsername(cookies.username);
const userID = cookies.username.replace(`@${userRealm}`, "");
const userObj = { id: userID, realm: userRealm };
if (global.db.getUser(userObj) === null) { if ((await global.userManager.getUser(userObj)) === null) {
auth = false; auth = false;
res.status(401).send({ auth, path: vmpath ? `${vmpath}/config` : "/version", error: `User ${cookies.username} not found in localdb.` }); res.status(401).send({ auth, path: vmpath ? `${vmpath}/config` : "/version", error: `User ${cookies.username} not found in localdb.` });
res.end(); res.end();
@ -113,7 +111,7 @@ async function getAllInstanceConfigs (req, diskprefixes) {
*/ */
export async function getUserResources (req, user) { export async function getUserResources (req, user) {
const dbResources = global.config.resources; const dbResources = global.config.resources;
const userResources = global.db.getUser(user).resources; const userResources = (await global.userManager.getUser(user)).resources;
// setup disk prefixes object // setup disk prefixes object
const diskprefixes = []; const diskprefixes = [];
@ -362,3 +360,10 @@ export function readJSONFile (path) {
exit(1); exit(1);
} }
}; };
export function getUserObjFromUsername (username) {
const userRealm = username.split("@").at(-1);
const userID = username.replace(`@${userRealm}`, "");
const userObj = { id: userID, realm: userRealm };
return userObj;
}