Collabora: How to install custom fonts?

Hi all,

I installed nextcloud and collabora from the nethforge repository, and integrated both according to the documentation Nextcloud — NS8 documentation

However, I am unable to install custom fonts: I tried to upload additional fonts in nextcloud Admin Settings / Office, but they are not used by collabora. Nextcloud states

Make sure to set this URL: https://NEXTCLOUD.URL/apps/richdocuments/settings/fonts.json in the coolwsd.xml file of your Collabora Online server to ensure the added fonts get loaded automatically. Please note that http:// will only work for debug builds of Collabora Online. In production you must use https:// for remote font config.

<remote_font_config>
	<url>https://NEXTCLOUD.URL/apps/richdocuments/settings/fonts.json</url>
</remote_font_config>

Can this configuration be added to the collabora application? Or is there another way to add custom fonts?

Thank you!

2 Likes

I think we need to add it as there’s the option to upload fonts in Nextcloud so Collabora should use them.

This one should work but it will be overwritten by next update, it could be done with a systemd override like here to make it persistent but I think it’s better to add the option to the app by default.
@stephdl What do you think? Should I open an issue and a PR?

EDIT:

It’s not that simple, collabora doesn’t know about the nextcloud FQDN…maybe we would need another dropdown field in the collabora settings to choose the right NC instance for the fonts. :thinking:

Enable Nextcloud uploaded fonts in Collabora

Enter collabora:

runagent -m collabora1

Edit the collabora service:

systemctl --user edit --full collabora

At line 18 add the extra param --o:remote_font_config.url=https://nextcloud.yourdomain.tld/apps/richdocuments/settings/fonts.json
It should look like

--env "extra_params=--o:ssl.enable=false --o:ssl.termination=true --o:security.capabilities=false --o:remote_font_config.url=https://nextcloud.yourdomain.tld/apps/richdocuments/settings/fonts.json" \

Restart collabora:

systemctl --user restart collabora

Now the uploaded fonts should be usable in Collabora in Nextcloud.

the use case is complicated with manual steps inside nextcloud (eg, upload custom fonts), so we cannot put a widget inside the UI of collabora, but this should, could be documented

1 Like

How do you decide today which nextcloud instances are allowed to use a collabora instance in case there are multiple nextcloud instances in a cluster?

I think the configuration as proposed by @mrmarkuz makes a lot of sense, not only for the for upload topic, but also for managing access rights.

1 Like

inside nextcloud (get-configuration) we do a query in redis to find all available collabora instances and we populate a dropdown in the UI

1 Like

It’s a challenge because both apps would need to be configured to each other to work together.
And it should be possible to leave it unconfigured to be able to use non-NS8 Nextcloud or Collabora too. So from that point of view documentation maybe is the best and fastest solution.
I thought that a dropdown in collabora that can be left empty (unconfigured) would do the job. One selects the NC instance so we have a variable holding the URL and can use it to configure collabora. If the field is left empty, it’s like it is now.

BTW, ExecStartPost using coolconfig would work too and is maybe easier to manage than with --env:

ExecStartPost=/usr/bin/podman exec collabora coolconfig set remote_font_config.url "https://nextcloud.ns8rockytest.com/apps/richdocuments/settings/fonts.json"

It seems the URL https://somenextcloudurl/apps/richdocuments/settings/fonts.json is provided by the richdocuments (Office) app even if no fonts are installed so that shouldn’t be an issue.

We could document it using a systemd override for persistence but I hope for a better solution.

Couldn’t we do that for collabora too?

Currently one can use the WOPI allow list in the Nextcloud Office app settings but adding the nextcloud instance automatically would improve security.

1 Like

If we want to play

When we configure nextcloud to use collabora
Trigger an event in nextcloud with the nextcloud fqdn and the module_id of collabora as argument
When the collabora see the event, if the module_id in argument is the module_id of collabora, then :

  • we can set in environment the fqdn of nextcloud
  • we can restart the collabora container
  • in the post action we trigger a script with a condition if the fqdn of nextcloud exists then set the custom fonts to nextcloud

In short no UI job, only an event

2 Likes

That’s a good idea using an event.

Enter as collabora user:

runagent -m collabora3

I used --env for the collabora.service file but it could also be done by a script.

systemctl --user edit --full collabora

Edit extra_params:

--env "extra_params=--o:ssl.enable=false --o:ssl.termination=true --o:security.capabilities=false --o:remote_font_config.url=${NEXTCLOUD_FONTS_URL}" \

Create the file ../events/nextcloud-configured/10writenextcloudfontsurltoenv:

#!/usr/bin/env python3

import json
import sys
import agent
import os

event_input = json.load(sys.stdin)

if event_input['module_id'] == os.getenv('MODULE_ID'):
    agent.set_env("NEXTCLOUD_FONTS_URL",event_input.get("nextcloud_fonts_url",""))
    agent.dump_env()
    agent.run_helper('systemctl', '--user', 'restart', 'collabora.service').check_returncode()

Set execute permission:

chmod +x ../events/nextcloud-configured/10writenextcloudfontsurltoenv

Fire event as root (to simulate the event that should be published by nextcloud):

redis-cli PUBLISH module/nextcloud4/event/nextcloud-configured '{"module_id": "collabora3", "nextcloud_fonts_url": "https://nextcloud.ns8rockytest.com/apps/richdocuments/settings/fonts.json"}'

To be continued with the nextcloud part…

1 Like

publish an event looks like this ns8-mail/imageroot/actions/configure-module/90publish_srv_keys at 96666beb1963036f358dc52c223e9a4017d88d27 · NethServer/ns8-mail · GitHub

I think it should be here, probably we need to rewrite the file to python :

1 Like

Hold on, @davidep would see another (better) way, based on task delegation like we do for mailadm role and reveal-master-credentials action

Imapsync for example is able to trigger the action reveal-master-credentials in the mail module

a bit more complicated but better because we know the collabora module to talk

1 Like

Good idea, so we need a new role like cloudadm?
I’m going to test that the next days…

1 Like

Why not. We could also get the idea to remove the link between collabora and nextcloud when we remove collabora. This time we could use an event because several nextcloud could use the same colabora instance IIRC

1 Like

In the imapsync example one selects the mail server in UI so there’s the MAIL_SERVER env var that holds the right mail instance. How can we find the right Nextcloud module id for Collabora?

EDIT:

Maybe reverse it like allow Nextcloud to use a Collabora action “set-fonts-url”?

Nextcloud knows the url and the module id of the collabora instance so nextcloud can trigger a task to collabora

  • in the build script of nextcloud allows the cloudadm to any collabora instance (see mailadm)
  • define in collabora a cloudadm role to delegate the action you need (in create-module but also it needs to be tought for upgrade)
  • create the action in collabora to set the url to custom fonts
  • trigger from nextcloud the action to collabora

After an event could be done when collabora is removed

1 Like

In this case I’d name the role “colladm”.

‘collaboraadm’

1 Like

Unfortunately Nextcloud only knows the URL but not the module id of the collabora instance. (COLLABORA_HOST=collabora.ns8rockytest.com)
Is there a way to get the module ID out of the URL? Maybe via traefik or redis?

EDIT:

This one could work: ns8-nextcloud/imageroot/actions/get-configuration/20read at de30159def86f06a195de6e7a6f1bdb7b68dd662 · NethServer/ns8-nextcloud · GitHub

EDIT2:

The task is working. Next step is the event and then I’d open issue/PRs.

../actions/create-module/30grants

#!/bin/bash

set -e    # exit immediately if an error occurs
exec 1>&2 # ensure any output is sent to stderr

redis-exec SADD "${AGENT_ID}/roles/collaboraadm" "set-fonts-url"

../actions/set-fonts-url/20set_fonts_url

#!/usr/bin/env python3

import json
import sys
import agent
import os

request = json.load(sys.stdin)
fonts_url = request['fonts_url']
agent.set_env('NEXTCLOUD_FONTS_URL', fonts_url)
agent.run_helper("systemctl", "--user", "try-restart", "collabora.service").check_returncode()

../actions/configure-module/85trigger_set_fonts_url_task

#!/usr/bin/env python3

import os
import agent

rdb = agent.redis_connect(privileged=False)

with open('config.env', 'r') as file:
    while line := file.readline():
        if line.startswith('OVERWRITEHOST'):
            nextcloud_fqdn = line.split('=')[1].strip()
        if line.startswith('COLLABORA_HOST'):
            collabora_fqdn = line.split('=')[1].strip()

for c in rdb.scan_iter('module/collabora*/environment'):
    name = c.removeprefix('module/').removesuffix('/environment')
    url = rdb.hget(c, 'TRAEFIK_HOST')
    if url == collabora_fqdn:
        response = agent.tasks.run(f"module/" + name, action='set-fonts-url', data={
            'fonts_url': 'https://' + nextcloud_fqdn + '/apps/richdocuments/settings/fonts.json'
            },
	    )
	agent.assert_exp(response['exit_code'] == 0)
1 Like