140 lines
3.6 KiB
JavaScript
140 lines
3.6 KiB
JavaScript
import { readFileSync, writeFileSync } from "fs";
|
|
import { exit } from "process";
|
|
import { DB_BACKEND } from "./backends.js";
|
|
|
|
export default class LocalDB extends DB_BACKEND {
|
|
#path = null;
|
|
#data = null;
|
|
#defaultuser = null;
|
|
|
|
constructor (config) {
|
|
super();
|
|
const path = config.dbfile;
|
|
try {
|
|
this.#path = path;
|
|
this.#load();
|
|
this.#defaultuser = global.config.defaultuser;
|
|
}
|
|
catch {
|
|
console.log(`error: ${path} was not found. Please follow the directions in the README to initialize localdb.json.`);
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Load db from local file system. Reads from file path store in path.
|
|
*/
|
|
#load () {
|
|
this.#data = JSON.parse(readFileSync(this.#path));
|
|
}
|
|
|
|
/**
|
|
* Save db to local file system. Saves to file path stored in path.
|
|
*/
|
|
#save () {
|
|
writeFileSync(this.#path, JSON.stringify(this.#data));
|
|
}
|
|
|
|
addUser (user, attributes, params) {
|
|
const username = `${user.id}@${user.realm}`;
|
|
if (this.#data.users[username]) { // user already exists
|
|
return {
|
|
ok: false,
|
|
status: 1,
|
|
message: "User already exists"
|
|
};
|
|
}
|
|
else {
|
|
attributes = attributes || this.#defaultuser;
|
|
this.#data.users[username] = attributes;
|
|
this.#save();
|
|
return null;
|
|
}
|
|
}
|
|
|
|
getUser (user, params) {
|
|
const requestedUser = `${user.id}@${user.realm}`;
|
|
const requestingUser = params.username; // assume checkAuth has been run, which already checks that username matches PVE token
|
|
// user can access a user's db data if they are an admin OR are requesting own data
|
|
const authorized = this.#data.users[requestingUser].cluster.admin || requestingUser === requestedUser;
|
|
if (authorized && this.#data.users[requestedUser]) {
|
|
return this.#data.users[requestedUser];
|
|
}
|
|
else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
async getAllUsers (params) {
|
|
const requestingUser = params.username; // assume checkAuth has been run, which already checks that username matches PVE token
|
|
if (this.#data.users[requestingUser].cluster.admin === true) {
|
|
return this.#data.users;
|
|
}
|
|
else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
setUser (user, attributes, params) {
|
|
if (attributes.resources && attributes.cluster && attributes.templates) { // localdb should only deal with these attributes
|
|
const username = `${user.id}@${user.realm}`;
|
|
if (this.#data.users[username]) {
|
|
this.#data.users[username] = attributes;
|
|
this.#save();
|
|
return true;
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
}
|
|
else { // if request is not setting these attributes, then assume its fine but do nothing
|
|
return true;
|
|
}
|
|
}
|
|
|
|
delUser (user, params) {
|
|
const username = `${user.id}@${user.realm}`;
|
|
if (this.#data.users[username]) {
|
|
delete this.#data.users[username];
|
|
this.#save();
|
|
return true;
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// group methods not implemented because db backend does not store groups
|
|
addGroup (group, atrributes, params) {}
|
|
getGroup (group, params) {}
|
|
getAllGroups (params) {
|
|
return null;
|
|
}
|
|
setGroup (group, attributes, params) {}
|
|
delGroup (group, params) {}
|
|
|
|
// assume that adding to group also adds to group's pool
|
|
addUserToGroup (user, group, params) {
|
|
const username = `${user.id}@${user.realm}`;
|
|
if (this.#data.users[username]) {
|
|
this.#data.users[username].cluster.pools[group.id] = true;
|
|
return true;
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// assume that adding to group also adds to group's pool
|
|
delUserFromGroup (user, group, params) {
|
|
const username = `${user.id}@${user.realm}`;
|
|
if (this.#data.users[username] && this.#data.users[username].cluster.pools[group.id]) {
|
|
delete this.#data.users[username].cluster.pools[group.id];
|
|
return true;
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
}
|
|
}
|