Draupnir unable to use Synapse Admin commands
Closed this issue · 11 comments
Matrix Setup
I'm relatively new to setting up Matrix and am trying to use Draupnir for moderation. We utilize the spantaleev/matrix-docker-ansible-deploy
Ansible playbook.
The following related YAML vars have been set up:
matrix_bot_draupnir_enabled: true
matrix_bot_draupnir_access_token: "{{ draupnir_access_token }}"
matrix_bot_draupnir_management_room: "!<redacted>:example.org"
Draupnir Setup
I registered the draupnir.bot
account using the following account (without Admin) at first:
ansible-playbook -i inventory/hosts setup.yml --extra-vars='username=bot.draupnir password=<redacted> admin=no' --tags=register-user
However, afterwards I gave it Server Admin using Synapse Admin, see below:
Issue summary
I am getting the following error when trying to use !draupnir hijack room #general:example.org @bartvdbraak:example.org
:
Either the command is disabled or Mjolnir is not running as homeserver administrator.
I even gave it a new access token after making it server administrator.
Any idea what I might be doing wrong here?
Hjack is default disabled in mdad draupnir config. Its enabled via putting the following in your config if memory serves. Config extension is a bit funny behaving at times. But ye thats the fix for this and thank you for the issue report as that reminds me i need to update the Draupnir docs to say this is a thing.
Probably could even add a variable to quickly flip this to true so config extension isnt needed. And that would be backwards compatible with anyone who has this in their config extension as config extension overrides the default template.
matrix_bot_draupnir_configuration_extension_yaml: |
admin:
enableMakeRoomAdminCommand: true
I should add the ammendment that i have knowledge of reports that people have had issues with the admin API in mdad with draupnir. But i dont know if that issue is universal or was specific to one person.
Ofc the admin API access may have to be enabled and that information is found upstream in mdad documentation i hope.
Adding
matrix_bot_draupnir_configuration_extension_yaml: |
admin:
enableMakeRoomAdminCommand: true
Unfortunately didn't fix it. I will investigate a bit further.
This is what the /matrix/draupnir/config/production.yaml
file looks like:
accessToken: syt_<redacted>
admin:
enableMakeRoomAdminCommand: true
autojoinOnlyIfManager: true
automaticallyRedactForReasons:
- spam
- advertising
backgroundDelayMS: 500
commands:
additionalPrefixes:
- draupnir-bot
- draupnir_bot
- draupnir
allowNoPrefix: false
ban:
defaultReasons:
- spam
- brigading
- harassment
- disagreement
confirmWildcardBan: true
dataPath: /data
disableServerACL: 'false'
displayReports: false
fasterMembershipChecks: false
health:
healthz:
address: 0.0.0.0
enabled: false
endpoint: /healthz
healthyStatus: 200
port: 8080
unhealthyStatus: 418
homeserverUrl: http://matrix-traefik:8008
logLevel: INFO
managementRoom: '!<redacted>:<redacted>.org'
noop: false
pollReports: false
protectAllJoinedRooms: false
rawHomeserverUrl: http://matrix-traefik:8008
recordIgnoredInvites: false
syncOnStartup: true
verifyPermissionsOnStartup: true
I checked where this message stems from, which is
// !mjolnir make admin <room> [<user ID>]
export async function execMakeRoomAdminCommand(roomId: string, event: any, mjolnir: Mjolnir, parts: string[]) {
const isAdmin = await mjolnir.isSynapseAdmin();
if (!mjolnir.config.admin?.enableMakeRoomAdminCommand || !isAdmin) {
const message = "Either the command is disabled or I am not running as homeserver administrator.";
const reply = RichReply.createFor(roomId, event, message, message);
reply['msgtype'] = "m.notice";
mjolnir.client.sendMessage(roomId, reply);
return;
}
let err = await mjolnir.makeUserRoomAdmin(await mjolnir.client.resolveRoom(parts[3]), parts[4]);
if (err instanceof Error || typeof (err) === "string") {
const errMsg = "Failed to process command:";
const message = typeof (err) === "string" ? `${errMsg}: ${err}` : `${errMsg}: ${err.message}`;
const reply = RichReply.createFor(roomId, event, message, message);
reply['msgtype'] = "m.notice";
mjolnir.client.sendMessage(roomId, reply);
return;
} else {
await mjolnir.client.unstableApis.addReactionToEvent(roomId, event['event_id'], '✅');
}
}
And isSynapseAdmin
is defined as:
public async isSynapseAdmin(): Promise<boolean> {
try {
const endpoint = `/_synapse/admin/v1/users/${await this.client.getUserId()}/admin`;
const response = await this.client.doRequest("GET", endpoint);
return response['admin'];
} catch (e) {
LogService.error("Mjolnir", "Error determining if Mjolnir is a server admin:");
LogService.error("Mjolnir", extractRequestError(e));
return false; // assume not
}
}
I checked if that would respond correctly with the current configured access token:
$ curl 'https://matrix.<redacted>.org/_synapse/admin/v1/users/@bot.draupnir:<redacted>.org/admin' -H 'Authorization: Bearer syt_<redacted>'
{"admin":true}
Could it be that the issue lies with the following?
I have this configured:
homeserverUrl: http://matrix-traefik:8008
If I get into the Draupnir container and start a Node.js REPL (docker exec -it <container-id> node
), and run it as follows:
const http = require('http');
http.get({
hostname: 'matrix-traefik',
port: 8008,
path: '/_synapse/admin/v1/users/@bot.draupnir:<redacted>.org/admin',
headers: {
'Authorization': 'Bearer syt_<redacted>'
}
}, (res) => {
let data = '';
res.on('data', chunk => data += chunk);
res.on('end', () => console.log('Response:', data));
}).on('error', (e) => console.error(`Problem with request: ${e.message}`));
I get:
> Response: 404 page not found
Thanks for troubleshooting this and yes your running into the Admin API not visible from container bug in mdad. That means its time to file an upstream issue i would susspect.
And it also happens to exceed my personal knowledge of how the playbook works internally so i cant be too much help on that front.
Anyways this whole adventure has exposed a legitimate bug in Draupnir so i am thankful of that.
You're a beast! Thanks!
Anything I can configure as a workaround for now?
spantaleev/matrix-docker-ansible-deploy#3308 (comment) claims to have a solution and its what i am deriving the proper fix for this from.
I fixed it on my server by adding:
matrix_synapse_reverse_proxy_companion_enabled: true
matrix_synapse_reverse_proxy_companion_container_labels_additional_labels: |
############################################################
# #
# Internal Synapse Admin API (/_synapse/client) #
# #
############################################################
traefik.http.routers.matrix-synapse-reverse-proxy-companion-internal-client-synapse-client-api.rule=PathPrefix(`/_synapse/client`)
traefik.http.routers.matrix-synapse-reverse-proxy-companion-internal-client-synapse-client-api.service=matrix-synapse-reverse-proxy-companion-client-api
traefik.http.routers.matrix-synapse-reverse-proxy-companion-internal-client-synapse-client-api.entrypoints=matrix-internal-matrix-client-api
############################################################
# #
# /Internal Synapse Admin API (/_synapse/client) #
# #
############################################################
############################################################
# #
# Internal Synapse Admin API (/_synapse/admin) #
# #
############################################################
traefik.http.routers.matrix-synapse-reverse-proxy-companion-internal-client-synapse-admin-api.rule=PathPrefix(`/_synapse/admin`)
traefik.http.routers.matrix-synapse-reverse-proxy-companion-internal-client-synapse-admin-api.service=matrix-synapse-reverse-proxy-companion-client-api
traefik.http.routers.matrix-synapse-reverse-proxy-companion-internal-client-synapse-admin-api.entrypoints=matrix-internal-matrix-client-api
############################################################
# #
# /Internal Synapse Admin API (/_synapse/admin) #
# #
############################################################
with
matrix_bot_draupnir_enabled: true
matrix_bot_draupnir_access_token: "{{ draupnir_access_token }}"
matrix_bot_draupnir_management_room: "!xxxxx:example.org"
matrix_bot_draupnir_configuration_extension_yaml: |
admin:
enableMakeRoomAdminCommand: true