mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-14 23:24:52 +09:00
Refactor user and instance manager (#837)
* Refactor UserManager to use Datastore * Rename lib.User to UserDetails also adds to/fromUserDetails * Fix existing tests * Add user class tests * Add tests for finaliseUsers * Move HostDetails to own file with tests * Move InstanceDetails to its own file with tests * Rename HostInfo and add tests * Rename InstanceInfo and add tests - Also changes the names of the host properties related to instances - Also removes the need to specify the location of InstanceInfo * Make json round trip test validate schema * Add InstanceManager * Fix lint errors * Extra tests * Add final test coverage * Add one last test to InstanceManager * Response to comments * Use generator rather than return anonumous generator Co-authored-by: Hornwitser <github@hornwitser.no> * Fix lint issue with generator --------- Co-authored-by: Hornwitser <github@hornwitser.no>
This commit is contained in:
1 parent
5bea930d05
commit
2235294c59
60 files changed
+3371
-1227
No files matched your search
@@ -109,10 +109,12 @@ describe("Integration of Clusterio", function() {
|
||||
describe("clusteriocontroller", function() {
|
||||
describe("bootstrap generate-user-token", function() {
|
||||
it("work for existing user", async function() {
|
||||
slowTest(this);
|
||||
await execController("bootstrap generate-user-token test");
|
||||
});
|
||||
|
||||
it("fails if user does not exist", async function() {
|
||||
slowTest(this);
|
||||
await assert.rejects(
|
||||
execController("bootstrap generate-user-token invalid")
|
||||
);
|
||||
@@ -935,20 +937,22 @@ describe("Integration of Clusterio", function() {
|
||||
});
|
||||
it("should create the user if instructed to", async function() {
|
||||
slowTest(this);
|
||||
getControl().userUpdates = [];
|
||||
const userUpdates = [];
|
||||
getControl().userUpdates = userUpdates;
|
||||
for (let [listName, prop] of lists) {
|
||||
await execCtl(`user set-${listName} --create test_create_${listName}`);
|
||||
let user = (await getUsers()).get(`test_create_${listName}`);
|
||||
assert.equal(user && user[prop], true, `user not created and added to ${listName}`);
|
||||
}
|
||||
assert.equal(getControl().userUpdates.length, 3);
|
||||
assert.equal(userUpdates.length, 6); // 1 for create, 1 for setting the property
|
||||
});
|
||||
it("should send ban reason", async function() {
|
||||
slowTest(this);
|
||||
getControl().userUpdates = [];
|
||||
const userUpdates = [];
|
||||
getControl().userUpdates = userUpdates;
|
||||
await execCtl("user set-banned --create test_ban_reason --reason a-reason");
|
||||
assert.equal(getControl().userUpdates.length, 1);
|
||||
assert.equal(getControl().userUpdates[0].banReason, "a-reason");
|
||||
assert.equal(userUpdates.length, 2); // 1 for create, 1 for ban reason
|
||||
assert.equal(userUpdates[1].banReason, "a-reason");
|
||||
let user = await getUser("test_ban_reason");
|
||||
assert.equal(user.banReason, "a-reason");
|
||||
});
|
||||
@@ -1719,6 +1723,12 @@ describe("Integration of Clusterio", function() {
|
||||
});
|
||||
|
||||
describe("user import", function() {
|
||||
beforeEach(async function() {
|
||||
slowTest(this);
|
||||
await execCtl("user set-admin import_control --revoke --create");
|
||||
await execCtl("user set-banned import_control --pardon");
|
||||
await execCtl("user set-whitelisted import_control --remove");
|
||||
});
|
||||
it("should import users", async function() {
|
||||
await fs.writeJSON(path.join("temp", "test", "import-users.json"), {
|
||||
export_version: "2.0.0.alpha20",
|
||||
@@ -1728,12 +1738,14 @@ describe("Integration of Clusterio", function() {
|
||||
{ username: "import_user_ban_reason", is_banned: true, ban_reason: "banned" },
|
||||
{ username: "import_user_whitelist", is_whitelisted: true },
|
||||
{ username: "import_user_none" },
|
||||
{ username: "import_control", is_admin: true },
|
||||
],
|
||||
});
|
||||
|
||||
await execCtl("user import --users import-users.json");
|
||||
|
||||
const users = await getUsers();
|
||||
assert(users.get("import_control").isAdmin, "import_control was not admin");
|
||||
assert(users.get("import_user_admin").isAdmin, "import_user_admin was not admin");
|
||||
assert(users.get("import_user_banned").isBanned, "import_user_banned was not banned");
|
||||
assert(
|
||||
@@ -1765,6 +1777,7 @@ describe("Integration of Clusterio", function() {
|
||||
await fs.writeJSON(path.join("temp", "test", "import-bans.json"), [
|
||||
{ username: "import_ban_reason", reason: "banned" },
|
||||
"import_ban",
|
||||
"import_control",
|
||||
]);
|
||||
|
||||
await execCtl("user import --bans import-bans.json");
|
||||
@@ -1778,6 +1791,8 @@ describe("Integration of Clusterio", function() {
|
||||
const userBar = users.get("import_ban");
|
||||
assert(userBar.isBanned, "import_ban was not banned");
|
||||
assert.equal(userBar.banReason, "", "import_ban had incorrect ban reason");
|
||||
|
||||
assert(users.get("import_control").isBanned, "import_control was not banned");
|
||||
});
|
||||
it("should import bans by filename", async function() {
|
||||
await fs.writeJSON(path.join("temp", "test", "import-bans.json"), [
|
||||
@@ -1789,11 +1804,13 @@ describe("Integration of Clusterio", function() {
|
||||
});
|
||||
it("should import admins", async function() {
|
||||
await fs.writeJSON(path.join("temp", "test", "import-admins.json"), [
|
||||
"import_admin",
|
||||
"import_admin", "import_control",
|
||||
]);
|
||||
|
||||
await execCtl("user import --admins import-admins.json");
|
||||
assert((await getUsers()).get("import_admin").isAdmin, "import_admin was not admin");
|
||||
const users = await getUsers();
|
||||
assert(users.get("import_admin").isAdmin, "import_admin was not admin");
|
||||
assert(users.get("import_control").isAdmin, "import_control was not admin");
|
||||
});
|
||||
it("should import admins by filename", async function() {
|
||||
await fs.writeJSON(path.join("temp", "test", "import-admins.json"), [
|
||||
@@ -1805,14 +1822,13 @@ describe("Integration of Clusterio", function() {
|
||||
});
|
||||
it("should import whitelist", async function() {
|
||||
await fs.writeJSON(path.join("temp", "test", "import-whitelist.json"), [
|
||||
"import_whitelist",
|
||||
"import_whitelist", "import_control",
|
||||
]);
|
||||
|
||||
await execCtl("user import --whitelist import-whitelist.json");
|
||||
assert(
|
||||
(await getUsers()).get("import_whitelist").isWhitelisted,
|
||||
"import_whitelist was not whitelisted"
|
||||
);
|
||||
const users = await getUsers();
|
||||
assert(users.get("import_whitelist").isWhitelisted, "import_whitelist was not whitelisted");
|
||||
assert(users.get("import_control").isWhitelisted, "import_control was not whitelisted");
|
||||
});
|
||||
it("should import whitelist by filename", async function() {
|
||||
await fs.writeJSON(path.join("temp", "test", "import-whitelist.json"), [
|
||||
@@ -1882,7 +1898,10 @@ describe("Integration of Clusterio", function() {
|
||||
it("should restore users", async function() {
|
||||
await fs.writeJSON(path.join("temp", "test", "restore-users.json"), {
|
||||
export_version: "2.0.0.alpha20",
|
||||
users: [{ username: "restore_user", is_admin: true, is_whitelisted: true }],
|
||||
users: [
|
||||
{ username: "restore_user", is_admin: true, is_whitelisted: true },
|
||||
{ username: "restore_user_two", is_banned: true, ban_reason: "Test" },
|
||||
],
|
||||
});
|
||||
|
||||
await execCtl("user restore restore-users.json");
|
||||
@@ -1892,10 +1911,14 @@ describe("Integration of Clusterio", function() {
|
||||
assert(user.isAdmin, "restore_user was not admin");
|
||||
assert(user.isWhitelisted, "restore_user was not whitelisted");
|
||||
|
||||
const user2 = users.get("restore_user_two");
|
||||
assert(user2.isBanned, "restore_user_two was not banned");
|
||||
assert.equal(user2.banReason, "Test");
|
||||
|
||||
const control = users.get("restore_control");
|
||||
assert(!control.isAdmin, "restore_user was admin");
|
||||
assert(!control.isBanned, "restore_user was banned");
|
||||
assert(!control.isWhitelisted, "restore_user was whitelisted");
|
||||
assert(!control.isAdmin, "restore_control was admin");
|
||||
assert(!control.isBanned, "restore_control was banned");
|
||||
assert(!control.isWhitelisted, "restore_control was whitelisted");
|
||||
|
||||
const data = await fs.readJson(path.join("temp", "test", "users-backup.json"));
|
||||
assert(data.users, "Users array does not exist");
|
||||
@@ -1921,7 +1944,7 @@ describe("Integration of Clusterio", function() {
|
||||
assert(userBar.isBanned, "restore_ban was not banned");
|
||||
assert.equal(userBar.banReason, "", "restore_ban had incorrect ban reason");
|
||||
|
||||
assert(!users.get("restore_control").isBanned, "restore_user was banned");
|
||||
assert(!users.get("restore_control").isBanned, "restore_control was banned");
|
||||
|
||||
const data = await fs.readJson(path.join("temp", "test", "bans-backup.json"));
|
||||
assert(data.indexOf("restore_control") >= 0, "restore_control is missing");
|
||||
@@ -1935,7 +1958,7 @@ describe("Integration of Clusterio", function() {
|
||||
const users = await getUsers();
|
||||
|
||||
assert(users.get("restore_admin").isAdmin, "restore_admin was not admin");
|
||||
assert(!users.get("restore_control").isAdmin, "restore_user was admin");
|
||||
assert(!users.get("restore_control").isAdmin, "restore_control was admin");
|
||||
|
||||
const data = await fs.readJson(path.join("temp", "test", "admins-backup.json"));
|
||||
assert(data.indexOf("restore_control") >= 0, "restore_control is missing");
|
||||
@@ -1949,7 +1972,7 @@ describe("Integration of Clusterio", function() {
|
||||
const users = await getUsers();
|
||||
|
||||
assert(users.get("restore_whitelist").isWhitelisted, "restore_whitelist was not whitelisted");
|
||||
assert(!users.get("restore_control").isWhitelisted, "restore_user was whitelisted");
|
||||
assert(!users.get("restore_control").isWhitelisted, "restore_control was whitelisted");
|
||||
|
||||
const data = await fs.readJson(path.join("temp", "test", "whitelist-backup.json"));
|
||||
assert(data.indexOf("restore_control") >= 0, "restore_control is missing");
|
||||
|
||||
@@ -3,7 +3,7 @@ const assert = require("assert").strict;
|
||||
|
||||
const lib = require("@clusterio/lib");
|
||||
const { Host, Instance, InstanceConnection } = require("@clusterio/host");
|
||||
const { ControlConnection, Controller, HostConnection, InstanceInfo } = require("@clusterio/controller");
|
||||
const { ControlConnection, Controller, HostConnection, InstanceRecord } = require("@clusterio/controller");
|
||||
|
||||
// Although there are no imports, the file has side-effects such as "before" which can effect tests
|
||||
require("./index");
|
||||
@@ -38,8 +38,8 @@ function connectInstance(controller, host, instanceId) {
|
||||
const instanceConfig = new lib.InstanceConfig("host");
|
||||
instanceConfig.set("instance.id", instanceId);
|
||||
instanceConfig.set("instance.assigned_host", host.config.get("host.id"));
|
||||
host.instanceInfos.set(instanceId, { path: "invalid", config: instanceConfig });
|
||||
controller.instances.set(new InstanceInfo(instanceConfig, "stopped"));
|
||||
host.assignedInstances.set(instanceId, { path: "invalid", config: instanceConfig });
|
||||
controller.instances.records.set(new InstanceRecord(instanceConfig, "stopped"));
|
||||
const instance = new Instance(host, instanceSide, "invalid", "invalid", instanceConfig);
|
||||
const instanceConnection = new InstanceConnection(hostSide, host, instance);
|
||||
host.instanceConnections.set(instanceId, instanceConnection);
|
||||
@@ -53,10 +53,7 @@ function connectInstance(controller, host, instanceId) {
|
||||
function connectControl(controller, controlId) {
|
||||
const [controllerSide, controlSide] = lib.VirtualConnector.makePair(addr("controller"), addr({ controlId }));
|
||||
const registerData = new lib.RegisterControlData("", "0.0.0");
|
||||
let user = controller.userManager.getByName("test");
|
||||
if (!user) {
|
||||
user = controller.userManager.createUser("test");
|
||||
}
|
||||
const user = controller.users.getOrCreateUser("test");
|
||||
const controlConnection = new ControlConnection(registerData, controllerSide, controller, user, controlId);
|
||||
controller.wsServer.controlConnections.set(controlId, controlConnection);
|
||||
return new Control(controlSide);
|
||||
|
||||
@@ -5,6 +5,7 @@ const fs = require("fs-extra");
|
||||
const path = require("path");
|
||||
|
||||
const lib = require("@clusterio/lib");
|
||||
const { InstanceManager } = require("@clusterio/controller");
|
||||
const { FactorioServer, _getFactorioVersion } = require("@clusterio/host/dist/node/src/server");
|
||||
const { logger } = lib;
|
||||
|
||||
@@ -78,20 +79,16 @@ describe("Integration of host/src/server", function() {
|
||||
assert(typeof settings === "object");
|
||||
});
|
||||
|
||||
it("contains the settings used by Clusterio", async function() {
|
||||
let keysUsed = new Set([
|
||||
"name", "description", "tags", "visibility", "username", "token",
|
||||
"game_password", "require_user_verification", "allow_commands",
|
||||
"auto_pause",
|
||||
]);
|
||||
it("aligns with the default settings in Clusterio", async function() {
|
||||
const unusedDefaultKeys = new Set(Object.keys(InstanceManager.DefaultFactorioSettings));
|
||||
|
||||
for (let key of Object.keys(settings)) {
|
||||
keysUsed.delete(key);
|
||||
for (const key of Object.keys(settings)) {
|
||||
unusedDefaultKeys.delete(key);
|
||||
}
|
||||
|
||||
assert(
|
||||
keysUsed.size === 0,
|
||||
`Factorio's server-settings.example.json does not contain the key(s) ${[...keysUsed]}`
|
||||
unusedDefaultKeys.size === 0,
|
||||
`Factorio's server-settings.example.json does not contain the key(s) ${[...unusedDefaultKeys]}`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user