diff --git a/.gitignore b/.gitignore index e95701f..a60d266 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ *~ -/galene -/galenectl/galenectl +/skald +/skaldctl/skaldctl /data /groups/**/*.json /static/**/*.d.ts diff --git a/CHANGES b/CHANGES index abfe343..37bc7b1 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ +Skald 0.1 (unreleased): + + * Forked from Galene after commit f718385. + * Renamed the project, module, command, control tool, static assets, and + documentation entrypoints from Galene to Skald. + Galene 1.1 (unreleased): * Implemented "galenectl initial-setup". diff --git a/README.md b/README.md index 7cf0cee..64b0ed8 100644 --- a/README.md +++ b/README.md @@ -1,59 +1,47 @@ -# The Galene videoconferencing system +# Skald -Galene is a fully-features videoconferencing system that is easy to deploy -and requires very moderate server resources. It is described at -. +Skald is a hard fork of Galene that is being turned into an audio-only +hall conferencing server. The current development repository is +. ## Quick start ```sh -git clone https://github.com/jech/galene -cd galene +git clone https://git.stormux.org/storm/skald +cd skald CGO_ENABLED=0 go build -ldflags='-s -w' mkdir groups echo '{"users": {"vimes": {"password":"sybil", "permissions":"op"}}}' > groups/night-watch.json -./galene & +./skald & ``` Point your browser at , ignore the unknown certificate warning, and log in with username *vimes* and password *sybil*. -For full installation instructions, please see the file [galene-install.md][1] +For full installation instructions, please see the file [skald-install.md][1] in this directory. ## Documentation - * [galene-install.md][1]: full installation instructions - * [galene.md][2]: usage and administration; - * [galene-client.md][3]: writing clients; - * [galene-protocol.md][4]: the client protocol; - * [galene-api.md][5]: Galene's administrative API. + * [skald-install.md][1]: full installation instructions + * [skald.md][2]: usage and administration; + * [skald-client.md][3]: writing clients; + * [skald-protocol.md][4]: the client protocol; + * [skald-api.md][5]: Skald's administrative API. ## Contributing -In order to contribute to Galene, you may: - - * send patches to [the Galene mailing list][6] by sending mail to - ; - * submit pull requests on GitHub. - -For general discussion, please use the [Galene mailing list][6] (feel free -to send mail without subscribing). Please do not use Github for general -discussion. +Skald is currently being developed at +. ## Further information -Galène's web page is at . +Skald is derived from Galene by Juliusz Chroboczek. Galene's web page is at +. -Answers to common questions and issues are at . - - --- Juliusz Chroboczek - -[1]: -[2]: -[3]: -[4]: -[5]: -[6]: +[1]: +[2]: +[3]: +[4]: +[5]: diff --git a/diskwriter/diskwriter.go b/diskwriter/diskwriter.go index 3eaa708..dbe3395 100644 --- a/diskwriter/diskwriter.go +++ b/diskwriter/diskwriter.go @@ -22,10 +22,10 @@ import ( "github.com/jech/samplebuilder" - gcodecs "github.com/jech/galene/codecs" - "github.com/jech/galene/conn" - "github.com/jech/galene/group" - "github.com/jech/galene/rtptime" + gcodecs "git.stormux.org/storm/skald/codecs" + "git.stormux.org/storm/skald/conn" + "git.stormux.org/storm/skald/group" + "git.stormux.org/storm/skald/rtptime" ) const ( diff --git a/diskwriter/diskwriter_test.go b/diskwriter/diskwriter_test.go index fc64f0c..d3dbfc3 100644 --- a/diskwriter/diskwriter_test.go +++ b/diskwriter/diskwriter_test.go @@ -4,7 +4,7 @@ import ( "testing" "time" - "github.com/jech/galene/rtptime" + "git.stormux.org/storm/skald/rtptime" ) func TestSanitise(t *testing.T) { diff --git a/estimator/estimator.go b/estimator/estimator.go index 0a2afd1..9df772e 100644 --- a/estimator/estimator.go +++ b/estimator/estimator.go @@ -6,7 +6,7 @@ import ( "sync" "time" - "github.com/jech/galene/rtptime" + "git.stormux.org/storm/skald/rtptime" ) type Estimator struct { diff --git a/estimator/estimator_test.go b/estimator/estimator_test.go index c0c5340..4d852b0 100644 --- a/estimator/estimator_test.go +++ b/estimator/estimator_test.go @@ -6,7 +6,7 @@ import ( "testing" "time" - "github.com/jech/galene/rtptime" + "git.stormux.org/storm/skald/rtptime" ) func TestEstimator(t *testing.T) { diff --git a/go.mod b/go.mod index ad04977..5b5aa04 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/jech/galene +module git.stormux.org/storm/skald go 1.21 diff --git a/group/client.go b/group/client.go index 4dfaa8c..71a983b 100644 --- a/group/client.go +++ b/group/client.go @@ -14,7 +14,7 @@ import ( "golang.org/x/crypto/bcrypt" "golang.org/x/crypto/pbkdf2" - "github.com/jech/galene/conn" + "git.stormux.org/storm/skald/conn" ) type RawPassword struct { diff --git a/group/description.go b/group/description.go index 9577be2..47754e1 100644 --- a/group/description.go +++ b/group/description.go @@ -12,7 +12,7 @@ import ( "strings" "time" - "github.com/jech/galene/token" + "git.stormux.org/storm/skald/token" ) var ErrTagMismatch = errors.New("tag mismatch") diff --git a/group/group.go b/group/group.go index 74f4272..eb5fafc 100644 --- a/group/group.go +++ b/group/group.go @@ -20,7 +20,7 @@ import ( "github.com/pion/interceptor" "github.com/pion/webrtc/v4" - "github.com/jech/galene/token" + "git.stormux.org/storm/skald/token" ) var Directory, DataDirectory string diff --git a/ice/ice.go b/ice/ice.go index a4a3602..91ee871 100644 --- a/ice/ice.go +++ b/ice/ice.go @@ -15,7 +15,7 @@ import ( "github.com/pion/webrtc/v4" - "github.com/jech/galene/turnserver" + "git.stormux.org/storm/skald/turnserver" ) type timeoutError struct{} diff --git a/ice/ice_test.go b/ice/ice_test.go index b4d608f..2e2186f 100644 --- a/ice/ice_test.go +++ b/ice/ice_test.go @@ -12,7 +12,7 @@ import ( "github.com/pion/webrtc/v4" - "github.com/jech/galene/turnserver" + "git.stormux.org/storm/skald/turnserver" ) func TestPassword(t *testing.T) { diff --git a/jitter/jitter.go b/jitter/jitter.go index c28bcc0..1877b66 100644 --- a/jitter/jitter.go +++ b/jitter/jitter.go @@ -4,7 +4,7 @@ package jitter import ( "sync/atomic" - "github.com/jech/galene/rtptime" + "git.stormux.org/storm/skald/rtptime" ) type Estimator struct { diff --git a/rtpconn/rtpconn.go b/rtpconn/rtpconn.go index ac5236d..2c9224d 100644 --- a/rtpconn/rtpconn.go +++ b/rtpconn/rtpconn.go @@ -14,16 +14,16 @@ import ( "github.com/pion/sdp/v3" "github.com/pion/webrtc/v4" - "github.com/jech/galene/codecs" - "github.com/jech/galene/conn" - "github.com/jech/galene/estimator" - "github.com/jech/galene/group" - "github.com/jech/galene/ice" - "github.com/jech/galene/jitter" - "github.com/jech/galene/packetcache" - "github.com/jech/galene/packetmap" - "github.com/jech/galene/rtptime" - "github.com/jech/galene/unbounded" + "git.stormux.org/storm/skald/codecs" + "git.stormux.org/storm/skald/conn" + "git.stormux.org/storm/skald/estimator" + "git.stormux.org/storm/skald/group" + "git.stormux.org/storm/skald/ice" + "git.stormux.org/storm/skald/jitter" + "git.stormux.org/storm/skald/packetcache" + "git.stormux.org/storm/skald/packetmap" + "git.stormux.org/storm/skald/rtptime" + "git.stormux.org/storm/skald/unbounded" ) type bitrate struct { diff --git a/rtpconn/rtpconn_test.go b/rtpconn/rtpconn_test.go index a1bed66..ce1dc01 100644 --- a/rtpconn/rtpconn_test.go +++ b/rtpconn/rtpconn_test.go @@ -3,7 +3,7 @@ package rtpconn import ( "testing" - "github.com/jech/galene/rtptime" + "git.stormux.org/storm/skald/rtptime" ) func TestDownTrackAtomics(t *testing.T) { diff --git a/rtpconn/rtpreader.go b/rtpconn/rtpreader.go index 380d297..ecf14ac 100644 --- a/rtpconn/rtpreader.go +++ b/rtpconn/rtpreader.go @@ -8,9 +8,9 @@ import ( "github.com/pion/rtp" "github.com/pion/webrtc/v4" - "github.com/jech/galene/codecs" - "github.com/jech/galene/packetcache" - "github.com/jech/galene/rtptime" + "git.stormux.org/storm/skald/codecs" + "git.stormux.org/storm/skald/packetcache" + "git.stormux.org/storm/skald/rtptime" ) func readLoop(track *rtpUpTrack) { diff --git a/rtpconn/rtpstats.go b/rtpconn/rtpstats.go index 882904e..c55393c 100644 --- a/rtpconn/rtpstats.go +++ b/rtpconn/rtpstats.go @@ -4,8 +4,8 @@ import ( "sort" "time" - "github.com/jech/galene/rtptime" - "github.com/jech/galene/stats" + "git.stormux.org/storm/skald/rtptime" + "git.stormux.org/storm/skald/stats" ) func (c *webClient) GetStats() *stats.Client { diff --git a/rtpconn/rtpwriter.go b/rtpconn/rtpwriter.go index f5e6dbc..7f4f524 100644 --- a/rtpconn/rtpwriter.go +++ b/rtpconn/rtpwriter.go @@ -6,9 +6,9 @@ import ( "sort" "time" - "github.com/jech/galene/conn" - "github.com/jech/galene/packetcache" - "github.com/jech/galene/rtptime" + "git.stormux.org/storm/skald/conn" + "git.stormux.org/storm/skald/packetcache" + "git.stormux.org/storm/skald/rtptime" ) // packetIndex is a request to send a packet from the cache. diff --git a/rtpconn/webclient.go b/rtpconn/webclient.go index b75e698..80889f4 100644 --- a/rtpconn/webclient.go +++ b/rtpconn/webclient.go @@ -17,13 +17,13 @@ import ( "github.com/gorilla/websocket" "github.com/pion/webrtc/v4" - "github.com/jech/galene/conn" - "github.com/jech/galene/diskwriter" - "github.com/jech/galene/estimator" - "github.com/jech/galene/group" - "github.com/jech/galene/ice" - "github.com/jech/galene/token" - "github.com/jech/galene/unbounded" + "git.stormux.org/storm/skald/conn" + "git.stormux.org/storm/skald/diskwriter" + "git.stormux.org/storm/skald/estimator" + "git.stormux.org/storm/skald/group" + "git.stormux.org/storm/skald/ice" + "git.stormux.org/storm/skald/token" + "git.stormux.org/storm/skald/unbounded" ) func errorToWSCloseMessage(id string, err error) (*clientMessage, []byte) { diff --git a/rtpconn/webclient_test.go b/rtpconn/webclient_test.go index 2134ca2..7939579 100644 --- a/rtpconn/webclient_test.go +++ b/rtpconn/webclient_test.go @@ -5,7 +5,7 @@ import ( "reflect" "testing" - "github.com/jech/galene/token" + "git.stormux.org/storm/skald/token" ) var tokens = []string{ diff --git a/rtpconn/whipclient.go b/rtpconn/whipclient.go index fe8e9a2..6ff2ce3 100644 --- a/rtpconn/whipclient.go +++ b/rtpconn/whipclient.go @@ -6,9 +6,9 @@ import ( "net" "sync" - "github.com/jech/galene/conn" - "github.com/jech/galene/group" - "github.com/jech/galene/sdpfrag" + "git.stormux.org/storm/skald/conn" + "git.stormux.org/storm/skald/group" + "git.stormux.org/storm/skald/sdpfrag" "github.com/pion/sdp/v3" "github.com/pion/webrtc/v4" diff --git a/galene-api.md b/skald-api.md similarity index 75% rename from galene-api.md rename to skald-api.md index 0753893..5f32215 100644 --- a/galene-api.md +++ b/skald-api.md @@ -1,9 +1,9 @@ -# Galene's administrative API +# Skald's administrative API -Galene provides an HTTP-based API that can be used to create groups and +Skald provides an HTTP-based API that can be used to create groups and users. For example, in order to create a group, a client may do - PUT /galene-api/v0/.groups/groupname/ + PUT /skald-api/v0/.groups/groupname/ Content-Type: application/json If-None-Match: * @@ -11,12 +11,12 @@ The `If-None-Match` header avoids overwriting an existing group. In order to edit a group definition, a client first does - GET /galene-api/v0/.groups/groupname/ + GET /skald-api/v0/.groups/groupname/ This yields the group definition and an entity tag (in the ETag header). The client then modifies the group defintion, and does - PUT /galene-api/v0/.groups/groupname/ + PUT /skald-api/v0/.groups/groupname/ If-Match: "abcd" where "abcd" is the entity tag returned by the GET request. If the group @@ -27,13 +27,13 @@ in the case of a concurrent modification. ## Endpoints -The API is located under `/galene-api/v0/`. The `/v0/` is a version number, +The API is located under `/skald-api/v0/`. The `/v0/` is a version number, and will be incremented if we ever find out that the current API cannot be extended in a backwards compatible manner. ### Statistics - /galene-api/v0/.stats + /skald-api/v0/.stats Provides a number of statistics about the running server, in JSON. The exact format is undocumented, and may change between versions. The only @@ -41,14 +41,14 @@ allowed methods are HEAD and GET. ### List of groups - /galene-api/v0/.groups/ + /skald-api/v0/.groups/ Returns a list of groups, as a JSON array. The only allowed methods are HEAD and GET. ### Group definition - /galene-api/v0/.groups/groupname + /skald-api/v0/.groups/groupname Contains a "sanitised" group definition in JSON format, analogous to the on-disk format but without any user definitions or cryptographic keys. @@ -57,7 +57,7 @@ content-type is `application/json`. ### Authentication keys - /galene-api/v0/.groups/groupname/.keys + /skald-api/v0/.groups/groupname/.keys Contains the keys used for validation of stateless tokens, encoded as a JSON key set (RFC 7517). Allowed methods are PUT and DELETE. The only @@ -65,16 +65,16 @@ accepted content-type is `application/jwk-set+json`. ### List of users - /galene-api/v0/.groups/groupname/.users/ + /skald-api/v0/.groups/groupname/.users/ Returns a list of users, as a JSON array. The only allowed methods are HEAD and GET. ### User definitions - /galene-api/v0/.groups/groupname/.users/username - /galene-api/v0/.groups/groupname/.empty-user - /galene-api/v0/.groups/groupname/.wildcard-user + /skald-api/v0/.groups/groupname/.users/username + /skald-api/v0/.groups/groupname/.empty-user + /skald-api/v0/.groups/groupname/.wildcard-user Contains a "sanitised" user definition (without any passwords), a JSON object with a single field `permissions`. The entries `.empty-user` and @@ -84,9 +84,9 @@ only accepted content-type is `application/json`. ### Passwords - /galene-api/v0/.groups/groupname/.users/username/.password - /galene-api/v0/.groups/groupname/.empty-user/.password - /galene-api/v0/.groups/groupname/.wildcard-user/.password + /skald-api/v0/.groups/groupname/.users/username/.password + /skald-api/v0/.groups/groupname/.empty-user/.password + /skald-api/v0/.groups/groupname/.wildcard-user/.password Contains the password of a given user. The PUT method takes a full password definition, identical to what can appear in the `"password"` @@ -97,7 +97,7 @@ POST. ### Wildcard user - /galene-api/v0/.groups/groupname/.wildcard-user + /skald-api/v0/.groups/groupname/.wildcard-user Contains a dictionary defining the wildcard user, in the same format as the dictionary defining an ordinary user. Allowed methods are HEAD, GET, @@ -105,14 +105,14 @@ PUT and DELETE. ### Wildcard user password - /galene-api/v0/.groups/groupname/.wildcard-user/.password + /skald-api/v0/.groups/groupname/.wildcard-user/.password This is analogous to the password of an ordinary user. Allowed methods are PUT, POST and DELETE. ### List of stateful tokens - /galene-api/v0/.groups/groupname/.users/username/.tokens/ + /skald-api/v0/.groups/groupname/.users/username/.tokens/ GET returns the list of stateful tokens, as a JSON array. POST creates a new token, and returns its name in the `Location` header. Allowed @@ -120,7 +120,7 @@ methods are HEAD, GET and POST. ### Stateful token - /galene-api/v0/.groups/groupname/.users/username/.tokens/token + /skald-api/v0/.groups/groupname/.users/username/.tokens/token The full contents of a single token, in JSON. The exact format may change between versions, so a client should first GET a token, update one or more diff --git a/galene-client.md b/skald-client.md similarity index 98% rename from galene-client.md rename to skald-client.md index a054ec3..d2f33bc 100644 --- a/galene-client.md +++ b/skald-client.md @@ -4,11 +4,11 @@ The frontend is written in JavaScript and is split into two files: - `protocol.js` contains the low-level functions that interact with the server; - - `galene.js` contains the user interface. + - `skald.js` contains the user interface. A simpler example client can be found in the directory `static/example`. -A new frontend may either implement Galène's client-server protocol from +A new frontend may either implement Skald's client-server protocol from scratch, or it may use the functionality of `protocol.js`. This document documents the latter approach. @@ -197,7 +197,7 @@ audio energy (the square of the volume) for streams in the down direction. # Peer-to-peer file transfer -Galene's client allows users to transfer files during a meeting. The +Skald's client allows users to transfer files during a meeting. The protocol is peer-to-peer: the clients exchange network parameters and cryptographic keys through the server (over messages of type `usermessage`), but all file transfer is performed directly between the diff --git a/galene-install.md b/skald-install.md similarity index 70% rename from galene-install.md rename to skald-install.md index bdb27f5..499365c 100644 --- a/galene-install.md +++ b/skald-install.md @@ -1,8 +1,8 @@ -# Galene installation instructions +# Skald installation instructions ## Basic installation -### Build the Galene binary +### Build the Skald binary Say: @@ -28,8 +28,8 @@ CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags='-s -w' ### Optional: install libraries for background blur -Galene's client uses Google's MediaPipe library to implement background -blur. This library is optional, and if it is absent, Galene will +Skald's client uses Google's MediaPipe library to implement background +blur. This library is optional, and if it is absent, Skald will disable the menu entries for background blur. Optionally install Google's MediaPipe library: @@ -53,8 +53,8 @@ If you don't have `wget` on your system, try using `curl -O` instead. ### Deploy to your server The following instructions assume that your server is called -`galene.example.org` and that you have already created a dedicated user -called `galene`. +`skald.example.org` and that you have already created a dedicated user +called `skald`. First, make sure that the `groups` and `data` directories exist: @@ -62,37 +62,37 @@ First, make sure that the `groups` and `data` directories exist: mkdir groups data ``` -Now copy the `galene` binary, and the directories `static`, `data` and +Now copy the `skald` binary, and the directories `static`, `data` and `groups` to the server: ```sh -rsync -a galene static data groups galene@galene.example.org: +rsync -a skald static data groups skald@skald.example.org: ``` -If you don't have a TLS certificate, Galene will generate a self-signed +If you don't have a TLS certificate, Skald will generate a self-signed certificate (and print a warning to the logs). If you have a certificate, install it in the files `data/cert.pem` and `data/key.pem`: ```sh -ssh galene@galene.example.org -sudo cp /etc/letsencrypt/live/galene.example.org/fullchain.pem data/cert.pem -sudo cp /etc/letsencrypt/live/galene.example.org/privkey.pem data/key.pem -sudo chown galene:galene data/*.pem +ssh skald@skald.example.org +sudo cp /etc/letsencrypt/live/skald.example.org/fullchain.pem data/cert.pem +sudo cp /etc/letsencrypt/live/skald.example.org/privkey.pem data/key.pem +sudo chown skald:skald data/*.pem chmod go-rw data/key.pem ``` Since certificates are regularly rotated, this should be done in a monthly cron job (or a *SystemD* timer unit, if you're feeling particularly kinky). -### Run Galene on the server +### Run Skald on the server Arrange to run the binary on the server. If you never reboot your server, just do: ```sh -ssh galene@galene.example.org +ssh skald@skald.example.org ulimit -n 65536 -nohup ./galene & +nohup ./skald & ``` If you are using *runit*, use a script like the following: @@ -100,58 +100,58 @@ If you are using *runit*, use a script like the following: ```sh #!/bin/sh exec 2>&1 -cd ~galene +cd ~skald ulimit -n 65536 -exec setuidgid galene ./galene +exec setuidgid skald ./skald ``` If you are using *SystemD*, put the following in -`/etc/systemd/system/galene.service` (and then run `systemctl daemon-reload`): +`/etc/systemd/system/skald.service` (and then run `systemctl daemon-reload`): ```ini [Unit] -Description=Galene +Description=Skald After=network.target [Service] Type=simple -WorkingDirectory=/home/galene -User=galene -Group=galene -ExecStart=/home/galene/galene +WorkingDirectory=/home/skald +User=skald +Group=skald +ExecStart=/home/skald/skald LimitNOFILE=65536 [Install] WantedBy=multi-user.target ``` -### Set up galenectl +### Set up skaldctl -There are two ways to administer a Galene instance: by manually editing -JSON files on the server, or by using the `galenectl` utility. -The `galenectl` utility is recommended, since it avoids issues with +There are two ways to administer a Skald instance: by manually editing +JSON files on the server, or by using the `skaldctl` utility. +The `skaldctl` utility is recommended, since it avoids issues with concurrent modifications and is less error-prone than the alternative. -Build the `galenectl` utility, and copy it somewhere on your path: +Build the `skaldctl` utility, and copy it somewhere on your path: ```sh -cd galenectl +cd skaldctl go build -ldflags='-s -w' -sudo cp galenectl /usr/local/bin/ +sudo cp skaldctl /usr/local/bin/ ``` -Now create an administrator password, and set up galenectl: +Now create an administrator password, and set up skaldctl: ```sh -galenectl -admin-username admin initial-setup +skaldctl -admin-username admin initial-setup ``` -This command creates two files: `galenectl.json` and `config.json`. The +This command creates two files: `skaldctl.json` and `config.json`. The former is already at the right place, the latter must be copied to the server's `data/` directory: ```sh -rsync config.json galene@galene.example.org:data/ +rsync config.json skald@skald.example.org:data/ ``` ### Group setup @@ -159,51 +159,51 @@ rsync config.json galene@galene.example.org:data/ Create a group: ```sh -galenectl create-group -group city-watch +skaldctl create-group -group city-watch ``` If you didn't install a TLS certificate above, you will need to run -`galenectl` with the flag `-insecure`: +`skaldctl` with the flag `-insecure`: ```sh -galenectl -insecure create-group -group city-watch +skaldctl -insecure create-group -group city-watch ``` Create an "op", a user with group moderation privileges: ```sh -galenectl create-user -group city-watch -user vimes -permissions op +skaldctl create-user -group city-watch -user vimes -permissions op ``` Set the new user's password: ```sh -galenectl set-password -group city-watch -user vimes +skaldctl set-password -group city-watch -user vimes ``` -You should now be able to test your Galene installation by pointing a web -browser at . +You should now be able to test your Skald installation by pointing a web +browser at . Create an ordinary user: ```sh -galenectl create-user -group city-watch -user fred -galenectl set-password -group city-watch -user fred +skaldctl create-user -group city-watch -user fred +skaldctl set-password -group city-watch -user fred ``` Check the results: ```sh -galenectl list-groups -galenectl list-users -l -group city-watch +skaldctl list-groups +skaldctl list-users -l -group city-watch ``` -Type `galenectl -help`, `galenectl create-group -help`, etc. for more +Type `skaldctl -help`, `skaldctl create-group -help`, etc. for more information. ## Advanced configuration -Galene is designed to be exposed directly to the Internet. If your server +Skald is designed to be exposed directly to the Internet. If your server is behind a firewall or NAT router, some extra configuration is necessary. ### Running behind a firewall @@ -229,7 +229,7 @@ of the following options: and demultiplex the traffic in userspace. At the time of writing, this mechanism is not quite complete, and you will -see Galene attempting to use other ports. Unless you see connection +see Skald attempting to use other ports. Unless you see connection failures, this is nothing to worry about. ### Running behind NAT @@ -238,23 +238,23 @@ If your server is behind NAT, then currently the only option is to use a STUN, or, preferably, TURN server on a separate host, one that is not behind NAT. See Section *Connectivity issues and ICE servers* below. -Galene has some support for running behind NAT without a helpful server, +Skald has some support for running behind NAT without a helpful server, but this has not been exhaustively tested. Please see the section "Connectivity issues and ICE servers" below. ### Running behind a reverse proxy -Galene is designed to be directly exposed to the Internet. In order to -run Galene behind a reverse proxy, you might need to make a number of +Skald is designed to be directly exposed to the Internet. In order to +run Skald behind a reverse proxy, you might need to make a number of tweaks to your configuration. -First, you might need to inform Galene of the URL at which users connect +First, you might need to inform Skald of the URL at which users connect (the reverse proxy's URL) by adding an entry `proxyURL` to your `data/config.json` file: ```json { - "proxyURL": "https://galene.example.org/" + "proxyURL": "https://skald.example.org/" } ``` @@ -272,12 +272,12 @@ location /ws { ``` Finally, in order to avoid TLS termination issues, you may want to run -Galene over plain HTTP instead of HTTPS by using the command-line flag +Skald over plain HTTP instead of HTTPS by using the command-line flag `-insecure`. Note that even if you're using a reverse proxy, clients will attempt to -establish direct UDP flows with Galene and direct TCP connections to -Galene's TURN server; see the section *Configuring your firewall* +establish direct UDP flows with Skald and direct TCP connections to +Skald's TURN server; see the section *Configuring your firewall* above. ## Connectivity issues and ICE servers @@ -290,7 +290,7 @@ that help punching holes in well-behaved NATs, and TURN servers, that serve as relays for traffic. TURN is a superset of STUN: no STUN server is necessary if one or more TURN servers are available. -Galene includes an IPv4-only TURN server, which is controlled by the +Skald includes an IPv4-only TURN server, which is controlled by the `-turn` command-line option. It has the following behaviour: * if its value is set to the empty string `""`, then the built-in server @@ -314,7 +314,7 @@ Galene includes an IPv4-only TURN server, which is controlled by the If the server is not accessible from the Internet, e.g. because of NAT or because it is behind a restrictive firewall, then you should configure -a TURN server that runs on a host that is accessible by both Galene and +a TURN server that runs on a host that is accessible by both Skald and the clients. Disable the built-in TURN server (`-turn ""` or the default `-turn auto`), and provide a working ICE configuration in the file `data/ice-servers.json`. In the case of a single STUN server, it should @@ -340,7 +340,7 @@ look like this: "turn:turn.example.org:443", "turn:turn.example.org:443?transport=tcp" ], - "username": "galene", + "username": "skald", "credential": "secret" } ] @@ -356,7 +356,7 @@ that, then the `ice-servers.json` file should look like this: "turn:turn.example.org:443", "turn:turn.example.org:443?transport=tcp" ], - "username": "galene", + "username": "skald", "credential": "secret", "credentialType": "hmac-sha1" } @@ -365,5 +365,5 @@ that, then the `ice-servers.json` file should look like this: For redundancy, you may set up multiple TURN servers, and ICE will use the first one that works. If an `ice-servers.json` file is present and -Galene's built-in TURN server is enabled, then the external server will be +Skald's built-in TURN server is enabled, then the external server will be used in preference to the built-in server. diff --git a/galene-protocol.md b/skald-protocol.md similarity index 94% rename from galene-protocol.md rename to skald-protocol.md index d8eeeea..ce80346 100644 --- a/galene-protocol.md +++ b/skald-protocol.md @@ -1,4 +1,4 @@ -# Galène's protocol +# Skald's protocol ## Data structures @@ -17,12 +17,12 @@ that do not originate messages (servers) do not need to be assigned an id. ### Stream A stream is a set of related tracks. It is identified by an id, an opaque -string. Streams in Galène are unidirectional. A stream is carried by +string. Streams in Skald are unidirectional. A stream is carried by exactly one peer connection (PC) (multiple streams in a single PC are not allowed). The offerer is also the RTP sender (i.e. all tracks sent by the offerer are of type `sendonly`). -Galène uses a symmetric, asynchronous protocol. In client-server +Skald uses a symmetric, asynchronous protocol. In client-server usage, some messages are only sent in the client to server or in the server to client direction. @@ -53,7 +53,7 @@ All fields are optional except `name`, `location` and `endpoint`. ## Connecting The client connects to the websocket at the URL obtained at the previous -step. Galene uses a symmetric, asynchronous protocol: there are no +step. Skald uses a symmetric, asynchronous protocol: there are no requests and responses, and most messages may be sent by either peer. ## Message syntax @@ -227,7 +227,7 @@ The field `label` is one of `camera`, `screenshare` or `video`, and will be matched against the keys sent by the receiver in their `request` message. The field `sdp` contains the raw SDP string (i.e. the `sdp` field of -a JSEP session description). Galène will interpret the `nack`, +a JSEP session description). Skald will interpret the `nack`, `nack pli`, `ccm fir` and `goog-remb` RTCP feedback types, and act accordingly. @@ -541,13 +541,13 @@ receives the `cancel` message immediately tears down the peer connection # Authorisation protocol -In addition to username/password authentication, Galene supports +In addition to username/password authentication, Skald supports authentication using cryptographic tokens. Two flows are supported: using -an authentication server, where Galene's client requests a token from +an authentication server, where Skald's client requests a token from a third-party server, and using an authentication portal, where -a third-party login portal redirects the user to Galene. Authentication +a third-party login portal redirects the user to Skald. Authentication servers are somewhat simpler to implement, but authentication portals are -more flexible and avoid communicating the user's password to Galene's +more flexible and avoid communicating the user's password to Skald's Javascript code. ## Authentication server @@ -558,24 +558,24 @@ a POST request to the authorisation server URL containing in its body a JSON dictionary of the following form: ```javascript { - "location": "https://galene.example.org/group/groupname/", + "location": "https://skald.example.org/group/groupname/", "username": username, "password": password } ``` If the user is not allowed to join the group, then the authorisation -server replies with a code of 403 ("not authorised"), and Galene will +server replies with a code of 403 ("not authorised"), and Skald will reject the user. If the authentication server has no opinion about whether the user is allowed to join, it replies with a code of 204 ("no -content"), and Galene will proceed with ordinary password authorisation. +content"), and Skald will proceed with ordinary password authorisation. If the user is allowed to join, then the authorisation server replies with a signed JWT (a "JWS") the body of which has the following form: ```javascript { "sub": username, - "aud": "https://galene.example.org/group/groupname/", + "aud": "https://skald.example.org/group/groupname/", "permissions": ["present"], "iat": now, "exp": now + 30s, @@ -593,10 +593,10 @@ a stateful token. ## Authentication portal -If a group's status dictionary has a non-empty `authPortal` field, Galene +If a group's status dictionary has a non-empty `authPortal` field, Skald redirects the user agent to the URL indicated by `authPortal`. The authentication portal performs authorisation, generates a token as above, then redirects back to the group's URL with the token stores in a URL query parameter named `token`: - https://galene.example.org/group/groupname/?token=eyJhbG... + https://skald.example.org/group/groupname/?token=eyJhbG... diff --git a/galene.go b/skald.go similarity index 93% rename from galene.go rename to skald.go index 26b3e60..45f094f 100644 --- a/galene.go +++ b/skald.go @@ -14,13 +14,13 @@ import ( "syscall" "time" - "github.com/jech/galene/diskwriter" - "github.com/jech/galene/group" - "github.com/jech/galene/ice" - "github.com/jech/galene/limit" - "github.com/jech/galene/token" - "github.com/jech/galene/turnserver" - "github.com/jech/galene/webserver" + "git.stormux.org/storm/skald/diskwriter" + "git.stormux.org/storm/skald/group" + "git.stormux.org/storm/skald/ice" + "git.stormux.org/storm/skald/limit" + "git.stormux.org/storm/skald/token" + "git.stormux.org/storm/skald/turnserver" + "git.stormux.org/storm/skald/webserver" ) func main() { diff --git a/galene.md b/skald.md similarity index 82% rename from galene.md rename to skald.md index eef1fa9..11d923f 100644 --- a/galene.md +++ b/skald.md @@ -1,15 +1,15 @@ -# Galene manual +# Skald manual -Please see the file [galene-install.md][1] for installation instructions. +Please see the file [skald-install.md][1] for installation instructions. Please see the section *Server administration* below for detailed administration instructions. ## Usage -Galene includes a web server that, by default, listens on port 8443. -Galene is therefore accessed on URLs such as: +Skald includes a web server that, by default, listens on port 8443. +Skald is therefore accessed on URLs such as: - https://galene.example.org:8443/ + https://skald.example.org:8443/ ### The landing page @@ -87,7 +87,7 @@ commands. In order to generate an invitation link, choose the entry *Invite user* in the group menu. This generates a link of the form - https://galene.example.org:8443/group/city-watch/?token=XXX + https://skald.example.org:8443/group/city-watch/?token=XXX where the *XXX* part, known as the *token*, is a shared secret. Such a link allows password-less login to the group, and may therefore be @@ -102,7 +102,7 @@ Tokens can be created, modified, and expired using the `/invite`, ### File transfer -Galene includes a peer-to-peer, end-to-end encrypted file transfer protocol. +Skald includes a peer-to-peer, end-to-end encrypted file transfer protocol. In order to transfer a file, click on the receiver's entry in the user list and choose *Send file*. @@ -131,7 +131,7 @@ file may look as follows: ```json { "users":{"vetinari": {"password":"lagniappe", "permissions": "admin"}}, - "canonicalHost": "galene.example.org", + "canonicalHost": "skald.example.org", "writableGroups": true } ``` @@ -146,12 +146,12 @@ or, better, with a hashed password: "permissions": "admin" } }, - "canonicalHost": "galene.example.org", + "canonicalHost": "skald.example.org", "writableGroups": true } ``` -The file is initially created using `galenectl initial-setup`, but may be +The file is initially created using `skaldctl initial-setup`, but may be manually edited at any time (there is no need to restart the server). The fields are as follows: @@ -159,7 +159,7 @@ fields are as follows: same syntax as user definitions in groups (see below), except that the only meaningful permission is `"admin"`; - - `writableGroups`: if true, then the API used by `galenectl` can be used + - `writableGroups`: if true, then the API used by `skaldctl` can be used to modify group definitions; if unset or false, then only read-only access is allowed; @@ -167,7 +167,7 @@ fields are as follows: are allowed to access the server; - `allowAdminOrigin` is like `allowOrigin`, but applies to the - administrative API (the one used by `galenectl`); + administrative API (the one used by `skaldctl`); - `proxyURL`: if running behind a reverse proxy, this specifies the root URL that will be visible outside the proxy; @@ -180,28 +180,28 @@ fields are as follows: ## Group definitions Groups are described by JSON files in the `groups/` directory. These -files are normally administered using the `galenectl` utility, but may +files are normally administered using the `skaldctl` utility, but may also be edited manually (there is no need to restart the server). -### Managing groups using `galenectl` +### Managing groups using `skaldctl` #### Creating, modifying, and deleting groups -A group is created using `galenectl create-group`: +A group is created using `skaldctl create-group`: ```sh -galenectl create-group -group city-watch +skaldctl create-group -group city-watch ``` There are a number of options to customise the behaviour of the group, see -`galenectl create-group -help` for a full list. For example, in order to +`skaldctl create-group -help` for a full list. For example, in order to create a group that allows unrestricted creation of tokens, say: ```sh -galenectl create-group -group city-watch -unrestricted-tokens +skaldctl create-group -group city-watch -unrestricted-tokens ``` -For more advanced configuration, `galenectl create-group` can be invoked +For more advanced configuration, `skaldctl create-group` can be invoked with the `-json` flag, in which case it takes a JSON template from standard input. The syntax of a JSON template is just like that of a group definition file (see below), except that it must not contain the fields @@ -209,35 +209,35 @@ definition file (see below), except that it must not contain the fields (see the section *Group description reference* below): ```sh -echo '{"redirect": "https://galene.example.org:8443/group/city-watch/"}' | galenectl create-group -group amcw -json +echo '{"redirect": "https://skald.example.org:8443/group/city-watch/"}' | skaldctl create-group -group amcw -json ``` -Groups are modified using `galenectl update-group`: +Groups are modified using `skaldctl update-group`: ```sh -galenectl update-group -group city-watch -unrestricted-tokens=false +skaldctl update-group -group city-watch -unrestricted-tokens=false ``` -If a JSON template is provided to `galenectl update-group`, then it is +If a JSON template is provided to `skaldctl update-group`, then it is merged with the existing group configuration. Entries may be deleted by setting them to `null` in the template: ```sh -echo '{"redirect": null}' | galenectl update-group -group amcw +echo '{"redirect": null}' | skaldctl update-group -group amcw ``` -A group is deleted using `galenectl delete-group`: +A group is deleted using `skaldctl delete-group`: ```sh -galenectl delete-group -group amcw +skaldctl delete-group -group amcw ``` #### Creating, modifying, and deleting users -A user entry is created with the `galenectl create-user` command: +A user entry is created with the `skaldctl create-user` command: ```sh -galenectl create-user -group city-watch -user vimes -permissions op +skaldctl create-user -group city-watch -user vimes -permissions op ``` If the `-permissions` flag is not specified, it defaults to `present`, @@ -246,14 +246,14 @@ the group. Other useful values are `message`, which allows a user to participate in the chat only, and `observe`, which doesn't allow any active participation. -A user is modified using `galenectl update-user`, and deleted using -`galenectl delete-user`. +A user is modified using `skaldctl update-user`, and deleted using +`skaldctl delete-user`. In order to be useful, a user entry needs to be assigned a password. This -is done with the `galenectl set-password` command: +is done with the `skaldctl set-password` command: ```sh -galenectl set-password -group city-watch -user vimes +skaldctl set-password -group city-watch -user vimes ``` #### The fallback user @@ -262,15 +262,15 @@ It is sometimes useful to allow multiple users to log in using the same password. This can be achieved by defining the *wildcard* user: ```sh -galenectl create-user -group city-watch -wildcard -galenectl set-password -group city-watch -wildcard +skaldctl create-user -group city-watch -wildcard +skaldctl set-password -group city-watch -wildcard ``` For open groups, where any user can login with any password, the wildcard user's password is set to the password of type `wildcard`: ```sh -galenectl set-password -group city-watch -wildcard -type wildcard +skaldctl set-password -group city-watch -wildcard -type wildcard ``` See the section *Client authorisation* below for more information about @@ -279,19 +279,19 @@ password types. #### Automatic subgroups It is sometimes necessary to create a large number of identical groups. -For example, the author has been using Galene to supervise computer +For example, the author has been using Skald to supervise computer science practicals, where up to 40 students are working in groups of two. While it is possible to automate the creation of groups by accessing -Galene's API, by scripting calls to galenectl, or by generating files -directly under `groups/`, Galene provides a facility called *automatic +Skald's API, by scripting calls to skaldctl, or by generating files +directly under `groups/`, Skald provides a facility called *automatic subgroups* that can be used to generate groups on demand. Automatic subgroups are enabled by setting the `"auto-subgroups"` field in the group description: ```sh -galenectl create-group unseen-university -auto-subgroups +skaldctl create-group unseen-university -auto-subgroups ``` Whenever a user attempts to access a subgroup of `unseen-university`, for @@ -303,13 +303,13 @@ group's operator can view the list of populated subgroups with the command #### Managing tokens Tokens are normally managed using the `/invite`, `/reinvite`, and `/expire` -commands in Galene's user interface, but they may also be managed using -the `galenectl` utility's `create-token`, `revoke-token`, `delete-token` +commands in Skald's user interface, but they may also be managed using +the `skaldctl` utility's `create-token`, `revoke-token`, `delete-token` and `list-tokens` commands: ```sh -galenectl create-token -group city-watch -galenectl list-tokens -l -group city-watch +skaldctl create-token -group city-watch +skaldctl list-tokens -l -group city-watch ``` A token that is generated with the `-include-subgroups` flag applies to @@ -317,14 +317,14 @@ the whole hierarchy rooted at the given group, including both ordinary groups and automatically generated subgroups. ```sh -galenectl create-token -group city-watch -include-subgroups +skaldctl create-token -group city-watch -include-subgroups ``` Such a token can be attached to the root of the group hierarchy, and therefore be valid for any group on the server: ```sh -galenectl create-token -group '' -include-subgroups +skaldctl create-token -group '' -include-subgroups ``` ### Group description reference @@ -393,7 +393,7 @@ are optional. The following fields are allowed: A user definition is a dictionary with entries `password` and `permission`. The value of the `password` field is either a plaintext -password, or a hashed password generated for example by the `galenectl +password, or a hashed password generated for example by the `skaldctl hash-password` command. The value of the `permissions` field can either be an array of individual permissions (not recommended), or one of the following strings: @@ -425,7 +425,7 @@ anything except Opus. ## Client Authorisation -Galene implements three authorisation methods: a username/password +Skald implements three authorisation methods: a username/password authorisation scheme, a scheme using stateful tokens, and a mechanism based on cryptographic tokens. The former two mechanisms are intended to be used in standalone installations, while the cryptographic mechanism is @@ -439,13 +439,13 @@ defined directly in the group configuration file, in the `users` and `wildcard-user` entries. The `users` entry is a dictionary that maps user names to user descriptions; the `wildcard-user` is a user description that is used with usernames that don't appear in `users`. These two -entries are usually managed by the `galenectl` utility. +entries are usually managed by the `skaldctl` utility. Every user description is a dictionary with fields `password` and `permissions`. The `password` field may be a literal password string, or a dictionary describing a hashed password or a wildcard. The `permissions` field should be one of `op`, `present`, `message` or -`observe`. (An array of Galene's internal permissions is also allowed, +`observe`. (An array of Skald's internal permissions is also allowed, but this is not recommended, since internal permissions may vary from version to version.) @@ -479,7 +479,7 @@ allows any username with any password. ### Hashed passwords For security reasons, passwords are usually hashed before being stored in -group descriptions (in fact, the `galenectl` utility does not even support +group descriptions (in fact, the `skaldctl` utility does not even support storing plaintext passwords). A hashed password is represented as a JSON dictionary with a field `type` and a number of type-specific fields. @@ -501,14 +501,14 @@ A user entry with a hashed password looks like this: ``` Hashed passwords are normally generated transparently to the user by the -`galenectl set-password` command. When editing group description files -manually, hashed passwords can be generated with the `galenectl hash-password` +`skaldctl set-password` command. When editing group description files +manually, hashed passwords can be generated with the `skaldctl hash-password` utility. ### Stateful tokens -Stateful tokens are created by the `/invite` command in the Galene user -interface or by the `galenectl create-token` command; see the section +Stateful tokens are created by the `/invite` command in the Skald user +interface or by the `skaldctl create-token` command; see the section *Managing tokens* above. They are stored in the file `data/var/tokens.jsonl`, which, on most filesystems, can be safely backed up without stopping the server. @@ -516,7 +516,7 @@ up without stopping the server. ### Cryptographic tokens In many cases, it is useful to delegate authorisation decisions to a third -party, such as an LDAP or OAuth2 client. Galene implements delegation of +party, such as an LDAP or OAuth2 client. Skald implements delegation of authorisation decisions using cryptographic tokens generated by a third party known as an *authorisation server*. Two authorisation servers are available: an [LDAP client][2], and a [sample server written in Python][3]. @@ -564,9 +564,9 @@ Alternatively, the group file may specify an authorisation portal using the `"authPortal"` key. If an authorisation portal is specified, then the default client will redirect initial client connections to the authorisation portal. The authorisation portal is expected to authorise -the client and then redirect it to Galene with the `username` and `token` +the client and then redirect it to Skald with the `username` and `token` query parameters set. -[1]: -[2]: -[3]: +[1]: +[2]: +[3]: diff --git a/galenectl/galenectl.go b/skaldctl/skaldctl.go similarity index 94% rename from galenectl/galenectl.go rename to skaldctl/skaldctl.go index e83dddd..d786f5d 100644 --- a/galenectl/galenectl.go +++ b/skaldctl/skaldctl.go @@ -26,8 +26,8 @@ import ( "golang.org/x/crypto/pbkdf2" "golang.org/x/term" - "github.com/jech/galene/group" - "github.com/jech/galene/token" + "git.stormux.org/storm/skald/group" + "git.stormux.org/storm/skald/token" ) type configuration struct { @@ -55,7 +55,7 @@ var commands = map[string]command{ }, "initial-setup": { command: initialSetupCmd, - description: "initial setup of Galene and galenectl", + description: "initial setup of Skald and skaldctl", }, "set-password": { command: setPasswordCmd, @@ -125,8 +125,8 @@ func main() { log.Fatalf("UserConfigDir: %v", err) } configFile = filepath.Join( - filepath.Join(configdir, "galene"), - "galenectl.json", + filepath.Join(configdir, "skald"), + "skaldctl.json", ) flag.Usage = func() { @@ -332,15 +332,15 @@ func hashPasswordCmd(cmdname string, args []string) { } func initialSetupCmd(cmdname string, args []string) { - var galeneConfigFn string + var skaldConfigFn string cmd := flag.NewFlagSet(cmdname, flag.ExitOnError) setUsage(cmd, cmdname, "%v [option...] %v [option...]\n", os.Args[0], cmdname, ) - cmd.StringVar(&galeneConfigFn, "config", "config.json", - "Galene configuration `file`") + cmd.StringVar(&skaldConfigFn, "config", "config.json", + "Skald configuration `file`") cmd.Parse(args) if cmd.NArg() != 0 { @@ -373,24 +373,24 @@ func initialSetupCmd(cmdname string, args []string) { } } - galeneConfig, err := os.OpenFile(galeneConfigFn, + skaldConfig, err := os.OpenFile(skaldConfigFn, os.O_WRONLY|os.O_CREATE|os.O_CREATE|os.O_EXCL, 0600) if err != nil { - log.Fatalf("Create %v: %v", galeneConfigFn, err) + log.Fatalf("Create %v: %v", skaldConfigFn, err) } - galenectlConfig, err := os.OpenFile(configFile, + skaldctlConfig, err := os.OpenFile(configFile, os.O_WRONLY|os.O_CREATE|os.O_CREATE|os.O_EXCL, 0600) if err != nil { - galeneConfig.Close() - os.Remove(galeneConfigFn) - log.Fatalf("Create %v: %v", galeneConfigFn, err) + skaldConfig.Close() + os.Remove(skaldConfigFn) + log.Fatalf("Create %v: %v", skaldConfigFn, err) } - defer galeneConfig.Close() - defer galenectlConfig.Close() + defer skaldConfig.Close() + defer skaldctlConfig.Close() var users map[string]group.UserDescription if adminPassword != "" { @@ -416,11 +416,11 @@ func initialSetupCmd(cmdname string, args []string) { Users: users, } - encoder := json.NewEncoder(galeneConfig) + encoder := json.NewEncoder(skaldConfig) encoder.SetIndent("", " ") err = encoder.Encode(&config) if err != nil { - log.Fatalf("Encode %v: %v", galeneConfigFn, err) + log.Fatalf("Encode %v: %v", skaldConfigFn, err) } ctlConfig := configuration{ @@ -430,14 +430,14 @@ func initialSetupCmd(cmdname string, args []string) { AdminToken: adminToken, } - ctlEncoder := json.NewEncoder(galenectlConfig) + ctlEncoder := json.NewEncoder(skaldctlConfig) ctlEncoder.SetIndent("", " ") err = ctlEncoder.Encode(&ctlConfig) if err != nil { log.Fatalf("Encode %v: %v", configFile, err) } - fmt.Printf("The file %v has been created. ", galeneConfigFn) + fmt.Printf("The file %v has been created. ", skaldConfigFn) fmt.Printf("Please copy it into your server's\n\"data/\" directory.\n") fmt.Printf("The file %v has been created. ", configFile) fmt.Printf("It contains the administrator's\npassword in cleartext, ") @@ -655,12 +655,12 @@ func setPasswordCmd(cmdname string, args []string) { var u string if wildcard { u, err = url.JoinPath( - serverURL, "/galene-api/v0/.groups", groupname, + serverURL, "/skald-api/v0/.groups", groupname, ".wildcard-user/.password", ) } else { u, err = url.JoinPath( - serverURL, "/galene-api/v0/.groups", groupname, + serverURL, "/skald-api/v0/.groups", groupname, ".users", username, ".password", ) } @@ -710,12 +710,12 @@ func deletePasswordCmd(cmdname string, args []string) { var err error if wildcard { u, err = url.JoinPath( - serverURL, "/galene-api/v0/.groups", groupname, + serverURL, "/skald-api/v0/.groups", groupname, ".wildcard-user/.password", ) } else { u, err = url.JoinPath( - serverURL, "/galene-api/v0/.groups", groupname, + serverURL, "/skald-api/v0/.groups", groupname, ".users", username, ".password", ) } @@ -828,7 +828,7 @@ func createGroupCmd(cmdname string, args []string) { } u, err := url.JoinPath( - serverURL, "/galene-api/v0/.groups", groupname, + serverURL, "/skald-api/v0/.groups", groupname, ) if err != nil { log.Fatalf("Build URL: %v", err) @@ -874,7 +874,7 @@ func deleteGroupCmd(cmdname string, args []string) { } u, err := url.JoinPath( - serverURL, "/galene-api/v0/.groups", groupname, + serverURL, "/skald-api/v0/.groups", groupname, ) if err != nil { log.Fatalf("Build URL: %v", err) @@ -913,7 +913,7 @@ func updateGroupCmd(cmdname string, args []string) { } u, err := url.JoinPath( - serverURL, "/galene-api/v0/.groups", groupname, + serverURL, "/skald-api/v0/.groups", groupname, ) if err != nil { log.Fatalf("Build URL: %v", err) @@ -1025,7 +1025,7 @@ func listUsersCmd(cmdname string, args []string) { os.Exit(1) } - u, err := url.JoinPath(serverURL, "/galene-api/v0/.groups/", groupname, + u, err := url.JoinPath(serverURL, "/skald-api/v0/.groups/", groupname, ".users/") if err != nil { log.Fatalf("Build URL: %v", err) @@ -1072,12 +1072,12 @@ func listUsersCmd(cmdname string, args []string) { func userURL(wildcard bool, groupname, username string) (string, error) { if wildcard { return url.JoinPath( - serverURL, "/galene-api/v0/.groups", groupname, + serverURL, "/skald-api/v0/.groups", groupname, ".wildcard-user", ) } return url.JoinPath( - serverURL, "/galene-api/v0/.groups", groupname, + serverURL, "/skald-api/v0/.groups", groupname, ".users", username, ) } @@ -1250,12 +1250,12 @@ func deleteUserCmd(cmdname string, args []string) { var err error if wildcard { u, err = url.JoinPath( - serverURL, "/galene-api/v0/.groups", groupname, + serverURL, "/skald-api/v0/.groups", groupname, ".wildcard-user", ) } else { u, err = url.JoinPath( - serverURL, "/galene-api/v0/.groups", groupname, + serverURL, "/skald-api/v0/.groups", groupname, ".users", username, ) } @@ -1288,7 +1288,7 @@ func showGroupCmd(cmdname string, args []string) { log.Fatal("Option \"-group\" is required.") } - u, err := url.JoinPath(serverURL, "/galene-api/v0/.groups/", groupname) + u, err := url.JoinPath(serverURL, "/skald-api/v0/.groups/", groupname) if err != nil { log.Fatalf("Build URL: %v", err) } @@ -1315,7 +1315,7 @@ func listGroupsCmd(cmdname string, args []string) { cmd.Parse(args) patterns := cmd.Args() - u, err := url.JoinPath(serverURL, "/galene-api/v0/.groups/") + u, err := url.JoinPath(serverURL, "/skald-api/v0/.groups/") if err != nil { log.Fatalf("Build URL: %v", err) } @@ -1365,7 +1365,7 @@ func listTokensCmd(cmdname string, args []string) { } u, err := url.JoinPath( - serverURL, "/galene-api/v0/.groups/", groupname.value, ".tokens/", + serverURL, "/skald-api/v0/.groups/", groupname.value, ".tokens/", ) if err != nil { @@ -1469,7 +1469,7 @@ func createTokenCmd(cmdname string, args []string) { } u, err := url.JoinPath( - serverURL, "/galene-api/v0/.groups/", groupname.value, ".tokens/", + serverURL, "/skald-api/v0/.groups/", groupname.value, ".tokens/", ) if err != nil { log.Fatalf("Build URL: %v", err) @@ -1505,7 +1505,7 @@ func revokeTokenCmd(cmdname string, args []string) { } u, err := url.JoinPath( - serverURL, "/galene-api/v0/.groups/", groupname.value, + serverURL, "/skald-api/v0/.groups/", groupname.value, ".tokens", token, ) if err != nil { @@ -1544,7 +1544,7 @@ func deleteTokenCmd(cmdname string, args []string) { } u, err := url.JoinPath( - serverURL, "/galene-api/v0/.groups/", groupname.value, + serverURL, "/skald-api/v0/.groups/", groupname.value, ".tokens", token, ) if err != nil { diff --git a/galenectl/galenectl_test.go b/skaldctl/skaldctl_test.go similarity index 97% rename from galenectl/galenectl_test.go rename to skaldctl/skaldctl_test.go index 175206d..5fe8356 100644 --- a/galenectl/galenectl_test.go +++ b/skaldctl/skaldctl_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/jech/galene/group" + "git.stormux.org/storm/skald/group" ) func TestMakePassword(t *testing.T) { diff --git a/static/change-password.html b/static/change-password.html index bff9f96..383f2ee 100644 --- a/static/change-password.html +++ b/static/change-password.html @@ -6,7 +6,7 @@ - + diff --git a/static/example/example.html b/static/example/example.html index e300fc2..9ab1717 100644 --- a/static/example/example.html +++ b/static/example/example.html @@ -1,7 +1,7 @@ - Galène client example + Skald client example diff --git a/static/example/example.js b/static/example/example.js index 5f1263c..efe46d1 100644 --- a/static/example/example.js +++ b/static/example/example.js @@ -1,4 +1,4 @@ -/* Galene client example. */ +/* Skald client example. */ /** * The main function. diff --git a/static/index.html b/static/index.html index 2b54e84..6a051d9 100644 --- a/static/index.html +++ b/static/index.html @@ -1,19 +1,19 @@ - Galène + Skald - +
-

Galène

+

Skald

@@ -30,7 +30,7 @@
diff --git a/static/management.js b/static/management.js index c059e23..8cd11d7 100644 --- a/static/management.js +++ b/static/management.js @@ -159,7 +159,7 @@ async function updateObject(url, values, etag) { * @returns {Promise>} */ async function listGroups() { - return await listObjects('/galene-api/v0/.groups/'); + return await listObjects('/skald-api/v0/.groups/'); } /** @@ -170,7 +170,7 @@ async function listGroups() { * @returns {Promise} */ async function getGroup(group, etag) { - return await getObject(`/galene-api/v0/.groups/${group}`, etag); + return await getObject(`/skald-api/v0/.groups/${group}`, etag); } /** @@ -180,7 +180,7 @@ async function getGroup(group, etag) { * @param {Object} [values] */ async function createGroup(group, values) { - return await createObject(`/galene-api/v0/.groups/${group}`, values); + return await createObject(`/skald-api/v0/.groups/${group}`, values); } /** @@ -190,7 +190,7 @@ async function createGroup(group, values) { * @param {string} [etag] */ async function deleteGroup(group, etag) { - return await deleteObject(`/galene-api/v0/.groups/${group}`, etag); + return await deleteObject(`/skald-api/v0/.groups/${group}`, etag); } /** @@ -203,7 +203,7 @@ async function deleteGroup(group, etag) { * @param {string} [etag] */ async function updateGroup(group, values, etag) { - return await updateObject(`/galene-api/v0/.groups/${group}`, values); + return await updateObject(`/skald-api/v0/.groups/${group}`, values); } /** @@ -213,7 +213,7 @@ async function updateGroup(group, values, etag) { * @returns {Promise>} */ async function listUsers(group) { - return await listObjects(`/galene-api/v0/.groups/${group}/.users/`); + return await listObjects(`/skald-api/v0/.groups/${group}/.users/`); } /** @@ -225,11 +225,11 @@ async function listUsers(group) { */ function userURL(group, user, wildcard) { if(wildcard) - return `/galene-api/v0/.groups/${group}/.wildcard-user`; + return `/skald-api/v0/.groups/${group}/.wildcard-user`; else if(user === "") - return `/galene-api/v0/.groups/${group}/.empty-user`; + return `/skald-api/v0/.groups/${group}/.empty-user`; else - return `/galene-api/v0/.groups/${group}/.users/${user}` + return `/skald-api/v0/.groups/${group}/.users/${user}` } /** @@ -320,7 +320,7 @@ async function setPassword(group, user, wildcard, password, oldpassword) { * @returns {Promise>} */ async function listTokens(group) { - return await listObjects(`/galene-api/v0/.groups/${group}/.tokens/`); + return await listObjects(`/skald-api/v0/.groups/${group}/.tokens/`); } /** @@ -332,7 +332,7 @@ async function listTokens(group) { * @returns {Promise} */ async function getToken(group, token, etag) { - return await getObject(`/galene-api/v0/.groups/${group}/.tokens/${token}`, + return await getObject(`/skald-api/v0/.groups/${group}/.tokens/${token}`, etag); } @@ -353,7 +353,7 @@ async function createToken(group, template) { } let r = await fetch( - `/galene-api/v0/.groups/${group}/.tokens/`, + `/skald-api/v0/.groups/${group}/.tokens/`, options); if(!r.ok) throw httpError(r); @@ -373,6 +373,6 @@ async function updateToken(group, token, etag) { if(!token.token) throw new Error("Unnamed token"); return await updateObject( - `/galene-api/v0/.groups/${group}/.tokens/${token.token}`, + `/skald-api/v0/.groups/${group}/.tokens/${token.token}`, token, etag); } diff --git a/static/protocol.js b/static/protocol.js index b206191..250c033 100644 --- a/static/protocol.js +++ b/static/protocol.js @@ -1619,7 +1619,7 @@ function TransferredFile(sc, userid, id, up, username, name, mimetype, size) { * The negotiated file-transfer protocol version. * * This is the version of the file-transfer protocol, and is not - * necessarily equal to the version of the Galene protocol used by the + * necessarily equal to the version of the Skald protocol used by the * server connection. * * @type {string} diff --git a/static/galene.css b/static/skald.css similarity index 99% rename from static/galene.css rename to static/skald.css index 64782e5..d8bccf6 100644 --- a/static/galene.css +++ b/static/skald.css @@ -1109,7 +1109,7 @@ legend { border-right: 1px solid #dcdcdc; } -#left-sidebar .galene-header { +#left-sidebar .skald-header { display: inline-block; } @@ -1127,7 +1127,7 @@ header .collapse:hover { color: #c2a4e0; } -.galene-header { +.skald-header { font-size: 1.3rem; font-weight: 900; color: #dbd9d9; diff --git a/static/galene.html b/static/skald.html similarity index 98% rename from static/galene.html rename to static/skald.html index c632f56..d75fdf7 100644 --- a/static/galene.html +++ b/static/skald.html @@ -1,12 +1,12 @@ - Galène + Skald - + @@ -20,7 +20,7 @@