Commit Graph
144 Commits
Author SHA1 Message Date
Hornwitser 1a9cbd26b3 Update non-web dependencies
Update non-web related dependencies to their latest version were
possible. It appears yargs has changed its parsing of command line
options to no longer remove a layer of quotes.
2023-07-27 00:35:26 +02:00
Hornwitser 295cc7543a Reverse argument order for sendTo
It makes more sense to put the address first then have the large
structure to send as the second argument to sendTo.  The opposite order
was originally chosen to be similar to that of sendto in BSD sockets.
2023-07-27 00:24:24 +02:00
Hornwitser 183d2921a8 Up timeout of mod-pack roundtrip test 2023-07-26 14:36:01 +02:00
Hornwitser 156d517976 Prefer putting nested structures on new lines
Format arguments to have nested structures start on a new line instead
of inline to make it easier to see where the structures starts and what
structure it is.
2023-07-26 14:27:49 +02:00
Hornwitser adb9ebafe1 Fix broken tests under fast-test 2023-07-25 17:25:39 +02:00
Hornwitser 87172dfb8d Implement basic ingress filtering on controller
Validate messages received on the controller from hosts and control
nodes before handling or forwarding them.  This should prevent
performing actions that are not allowed by the role system and block
simple attacks such as spoofing the source address of a message.
2023-07-25 17:21:44 +02:00
Hornwitser 7f8a700716 Refactor message registration and validation
Split up the action of registring an event or request data class to be
decoded by the Link class and the action of registring a handler for
those requests and events.  This moves the validation work from Link
instantiation time to startup initialisation which makes logic errors
fail on startup instead of failing instantiation of the link when a
connection attempt is made.

Additionally implement a partial validation logic for messages received
using the newly refactored message registration.  This unfortunately
ended up merged with the registration refactor.
2023-06-03 16:47:47 +02:00
Hornwitser bcd94709d2 Refactor link system to JSON serialisable class pattern
Reverse the direction of the API for sending messages from

    messageDefinition.send(link, { content });

to

    link.send(new MessageClass(content));

and convert all message definitions to use the JSON serialisable class
pattern and explicit registration of message handlers, along with a
end-to-end based routing of messages instead of link to link.

The experience I gained from the existing way messages were defined and
sent over links was that it was difficult to understand for people
unfamiliar with the system.  The automatic registration of message
handlers ment that code was being called as if by magic from nowhere
with no easy way to discover it.  The manual forwarding and rules for
what can be sent where and how obscured its working.

The use of pure JSON as both input and output from message handlers made
it tedious to work with.  Data had to be manually converted between the
program representation and the over the wire format, which made handler
code unplesant to write.  Particularly because the over the wire format
used snake_case while the program code uses camelCase for variables.
The idea behind the decision to do it this way was to make it more clear
which data came from the wire and which from the program, and while this
worked it didn't make message handlers any nicer to write.

The direction of the API and magic registration of message handlers also
meant that a future migration to TypeScript would be troublesome.  While
it may be possible to implement, the degree of TypeScript magic required
would go starkly against the principle of keep it simple stupid.

By refactoring to using the JSON serialisable class pattern most of
these issues go away.  There is no longer a need to distinguish the on
wire format of messages with the program representation because the only
place that deals with the wire format of messages are the toJSON and
fromJSON methods on the classes themselves.  Message handlers will work
with proper instances of classes instead of raw data, something that
makes them easier to write, and trivial to type with TypeScript.

End-to-end routing also simplifies sending messages that need to do
mulitple hops to reach the destination.  And removes the need for having
all messages be specified in plugin's info module, as they can be routed
without having to be parsed completely.

The explicit registration of message handlers is something that I
thought would be tedious boilerplate code that could be automated away.
But experience now shows it to be the opposite.  Allthough dull
repetition, the purpose it serves is to link together the code in a way
that humans can easily find.  With explicit registration searching the
name of the message handler in the editor will show the registration that
ties it together with the type of message it handles and the kind of
registration.  With implicit registration searching the name of the
message handler turns up only the handler with no clue as to what calls
it.
2023-04-23 13:19:46 +02:00
Hornwitser 9a967a5779 Refactor JSON serialiable class pattern
Change the JSON seriasiable data classes to use an explicit static
fromJSON method and an optional toJSON method for turning them to and
from JSON.

This improves over the previous pattern of passing the JSON to the
constructor as it frees up the constructor to be able to take whichever
argument types suits the code instead of being beholden to the JSON
serialised form.
2023-02-25 00:02:12 +01:00
Hornwitser 6fc3abafd5 Rename Slave to Host
The role of a slave as a host for Factorio servers is not well reflected
in its name and has caused confusion among users.  Rename slave to host
to better reflect its role as a host of Factorio servers.
2023-02-22 15:30:51 +01:00
Hornwitser 70ad295a89 Rename Master to Controller
The role of the master server as the party controlling every part of the
cluster is not well reflected in its name and has caused confusion among
users on several occasions.  Rename master to controller to better
reflects its role.
2023-02-22 15:30:51 +01:00
Hornwitser 2960db2cca Add revoke user token action
Implement revoking of user tokens to allow lost credentials to be
invalidated.
2023-02-21 22:39:23 +01:00
Hornwitser 0eabdf011b Fix mod loading tests 2023-02-02 01:07:33 +01:00
Hornwitser 91af66e2db Fix export when default mod pack is used 2023-02-02 01:07:08 +01:00
Hornwitser 13e12f7335 Tie data exports to mod packs
Store the export manifest in ModPack to allow mulitple mod packs to have
different data exported. This is necessary as the export contains the
settings prototypes needed to create a proper UI for mod settings.

For now the useLocale and useItemMetadata interfaces uses the manifest
for a default mod pack set in the master config.
2023-02-02 00:28:58 +01:00
Hornwitser 7c6aaeb05d Export settings and all prototypes
Add settings and all prototypes to the export of data done.  Settings
are needed for a settings GUI to function, while prototype data would be
useful to display any sort of information about things from the game.
2023-02-01 15:29:23 +01:00
Hornwitser fb4ffaffed Implement mod pack loading for shared mods
Wipe and reconstruct the instances' mods/ folder using the configured
ModPack for the case were the mods folder is shared with the master
server.  This assumes the master server will check the mod checksums
before sending the start request.
2022-11-10 00:28:50 +01:00
Hornwitser 0ebb2f5858 Add import and export mod-pack commands 2022-11-10 00:28:50 +01:00
Hornwitser 660d0f08a1 Fully specify mod pack Factorio version
Remove support for major only versions of Factorio being specified in
mod packs.
2022-10-15 18:01:54 +02:00
Hornwitser f863aee3c2 Add enabled field for mods in mod packs
Make it possible to disable built in mods like base by providing an
enabled field that can be set to false in mod packs.
2022-10-15 18:01:54 +02:00
Hornwitser 7072b94355 Derive mod filename from name and version
Enforce the filename of uploaded mods match {name}_{version}.zip with
name and version taken from the zip file's info.json entry.  This allows
it to be used as a unique key for the mod and solves part of the issues
with mods having different number of leading zeros in their version.
2022-09-26 00:34:25 +02:00
Hornwitser 9b4ca86650 Rename mod hash field to sha1
The Factorio Mod Portal uses and provides SHA1 hashes of mods, so it
makes sense to align the ModPack and ModInfo structures to sha1 by
renaming the genericly named hash property to sha1.
2022-09-24 21:43:07 +02:00
Hornwitser 3eb63db313 Add search mods request
Add paged search mods request suitable for showing a real time list of
results for a user provided search expression.
2022-09-24 21:10:38 +02:00
Hornwitser 9fb3d6d8db Implement mod pack storage
Add ModPack data type with corresponding storage on the master, messages
to create, update and delete them, as well as commands to invoke them.
The ModPack data type contains a list of mods with versions and optional
sha1 hashes, and mod settings to be used.
2022-09-16 02:44:06 +02:00
Hornwitser 3b57c1e0ae Add shared mods management
Add the ability to manage a set of mods to be shared by the master
server to the rest of the cluster.  This implements storage, uploads,
downloads, deletetion, and listing details of mods but does not actually
do anything with the stored mods.
2022-09-13 19:15:46 +02:00
Hornwitser fc1daa7e71 Bump path traversal test timeout (#472)
Double timeout on these two tests as they sometimes time out on GitHub
Actions.
2022-07-19 21:24:44 +02:00
Hornwitser aadf24db99 Add test for sending user ban_reason 2022-07-16 14:30:06 +02:00
Hornwitser 08e7434d24 Add command to extract play time from save
Add command that extracts play time (and players) from the currently
running save to the recorded instance statistics.  This is useful for
getting correct play time statistics when an existing save game is
imported.
2022-07-13 00:31:02 +02:00
Hornwitser 096f338277 Add live updating of users
Provied a subscription for user updates and send updates whenever the
details of a user account is changed.
2022-07-08 01:00:54 +02:00
Hornwitser 2a221456d9 Fix exported data loading in web interface
Store exported data files with a hash in the filename to allow the new
caching stategy for static files to work with it and provide a manifest
for the web interface to find the exported files with.
2022-06-08 21:01:36 +02:00
Hornwitser c2cb58d088 Comment out command logging in tests
Don't log commands executed while running tests as these spam the output
more than they are useful right now.
2022-03-29 22:55:13 +02:00
Hornwitser 38c249ec70 Implement save transfer
Add ability to move or copy saves between instances.  For instances on
the same slave the saves are transferred with filesystem operations, for
instances on two different slaves the proxy stream interface is used to
send the save via the master server.
2022-03-28 20:42:08 +02:00
Hornwitser 4edc7a2949 Implement rename and copy save
Add ability to rename and copy existing saves on an instance.
2022-03-27 19:59:29 +02:00
Hornwitser 0de964ec02 Reorganise instance save commands
Move create, list, upload and dalete save management commands to its own
'instance save' namespace in the command line interface.
2022-03-27 15:50:42 +02:00
Hornwitser 946847c95d Send save list update after manual save
Trigger a save list update in the event an admin manually saves the game
with the /server-save command.
2022-03-25 23:15:07 +01:00
Hornwitser 1e4d709a06 Implement kill instance
Add ability to kill running instances in case it is desirable to stop
the server without saving over the current save file.
2022-03-25 20:52:31 +01:00
Hornwitser 8de76b5cfe Refactor LineSplitter
Pull the LineSplitter class out of lib/factorio to its own stream module
and refactor it to be based on stream.Transform.  This allows composing
with other streams by piping it around.
2021-12-11 21:31:15 +01:00
Hornwitser 18e9fc8e7c Provide roles and permission for the control user
Add the roles and their permissions for the user the control connection
is connected as along with updates when these change.  This enables the
web interface to know which permissions it has available to it.
2021-09-20 00:52:59 +02:00
Hornwitser e3d8aa1a9b Add limit and order to query log request
Add optional limit to the number of log records to return in the
log query request to avoid having the web interface instance console
download the entire log for only to show a few hundred lines from it.

To make it possible to query the end of the log instead of just the
start add an order option as well.
2021-09-11 19:11:30 +02:00
Hornwitser c59267d5ee Set status to unknown on slave disconnect
Change the instance status to unknown if the slave it's connected to
is disconnected rather than leaving them at their previous state
indefinitely.
2021-09-11 17:12:06 +02:00
Hornwitser de48d807f1 Refactor connector logic
Refine the state flow used in the connector abstractions to better
handle close while connecting and resuming.  The new logic is to close
the connection immediately in these two states instead of continuing
trying to connect and then giving up some point later.

For the connectors the handshake state is split into connecting
and resuming, new is replaced by closed, and the closing state is turned
into a boolean flag as it's possible that closing is desired while
connecting, connected or resuming.  The connecting state is not present
in the server connector because there's nothing for the server to do in
that connector state.

The timeout logic is completely removed, once a connection attempt is
started for the client it will continue to attempt to connect, attempt
to resume dropped connections and attempt reconnects until either an
authentication error occurs or the client explicitly requests to close
the connection.

A new session timeout is added to control how long to attempt to resume
the connection until it's considered dead and invalidated.  This allows
stale connections to give up earlier, and swallow up less data while in
the dropped but not yet invalidated state.

For the client side sending messages while it's connecting has been
changed to throw an error instead of queuing up the message and
(possibly) sending it after the connection is established.  Code
shouldn't try to send messages without knowing if the connection it's
trying to send them over is active or not.
2021-08-30 20:20:49 +02:00
Hornwitser f2c9cd0c62 Don't try stopping if instance is already stopped (#401)
Ignore stop if instance status is already stopped. Fixes instance status
getting stuck at stopping if Factorio exits during startup due to the
stopped status having already been sent at the time stop is invoked.

Fixes #400
2021-08-03 16:08:16 +02:00
Hornwitser dbe01c6c23 Decode master secret from base64 (#398)
The jsonwebtoken accept strings as input for secrets which is
nonsensical from a cryptographic standpoint as the algorithms all
operate on byte sequences.  Worse still, strings are encoded into bytes
using UTF-8, which disallows certain sequences of bytes from appearing
and potentially weakening the cryptography.

For legacy reasons the master secret was encoded into base64 _and passed
as a string to jsonwebtoken_.  This further weakened the crypto as the
bytes that can appear in base 64 is only 1/4 of the 256 possible values
for bytes.  This could significantly weaken the cryptographic strength
of the tokens.

I have known of this issue for quite some time but has put off actually
fixing it for too long now.  Since the master secret is already
documented as being in base 64, decode it as base 64 and pass it as a
byte Buffer to jsonwebtoken.  This will ensure every byte value is
possible in the byte sequence passed to the jsonwebtoken crypto.

The impact of this change is unfortunately that all tokens will become
invalid and will have to be reissued.
2021-07-13 17:16:10 +02:00
Hornwitser 8dc1415404 Skip slaveUpdateEventHandler test on Windows
Due to the lack of a simple way to automate graceful shutdown of a slave
on Windows causing the test to be unreliable, skip it on Windows.
2021-06-21 16:59:04 +02:00
Hornwitser fc08438164 Add generate slave token button
Add a generate slave token button to the web interface and modify the
generateSlaveToken message and corresponding ctl command to have the
slave id be optional.  The random id is the desired behavior when adding
a slave with the installer, as it'll ask for the token for the new slave
and deduce the id from the token.
2021-06-15 14:46:44 +02:00
Hornwitser f37c387d52 Fix instance deleted status not being sent out 2021-06-10 10:26:40 +02:00
Daniel c80be802d1 Merge pull request #384 from Hornwitser/test-fixes
Fix tests on Windows and remove internet requirement to pass
2021-06-10 06:54:52 +02:00
Hornwitser 55f3dac9b6 Fix integration tests requiring internet to work
When factorio starts up with with the require_user_verification setting
turn on it tries to obtain a server padlock from the matchmaking server
and will fail if this does not succeed.  Turn off user verification and
public visibility which require user verification both of which are on
by default for the integration tests so that they work without internet.
2021-06-09 14:53:33 +02:00
Hornwitser 2be91cbd3a Add slave update subscriptions
Allow the web interface to listen for updates to the slave list and
apply it live to the places where slaves are shown in the web interface.
2021-06-02 16:19:18 +02:00
Hornwitser 09e4256c18 Fix hang on missing/wrong Factorio version
Fix the start command hanging if the configured Factorio version for the
instance started is not available on the slave.
2021-06-01 16:38:58 +02:00