*: Update URL base from /plinth to /freedombox

- Since we are going to be an OpenID Provider, we need to fix the URLs that
other apps will be configured with for authentication. So change now from
/plinth to /freedombox. If done later, it will be harder since all the
configuration files for all dependent apps will need to be updated.

Tests:

- App availability checking works. Request goes to /freedombox URL

- Favicon is served properly and through /favicon.ico URL

- Redirection happens from / to /freedombox directly

- UI is available on /freedombox and on /plinth

- Manual page show /freedombox as the URL in two places

- Static files are successfully served from /freedombox URLs. URLs inside page
start with /freedombox

- backup, bepasty, calibre, config, dynamicdns, ejabberd, featherwiki, gitweb,
ikiwiki, kiwix, miniflux, names, openvpn, shadowsocks, shadowsocksserver,
sharing, shapshot, tiddlywiki, users, wireguard, jsxc, matrixsynapse, first
wizard, storage, samba, tags functional tests work. Backup/restore test for
matrixsynapse fails due to an unrelated bug (server not restarted after
restore).

- Setting the home page works:

  - Having /plinth in the home page configuration works. Shows selection
    correctly.

  - Setting to app works. Shows selection correctly.

  - Setting to user home page (sets /freedombox). Shows selection correctly.

  - Setting to apache default works. Shows selection correctly.

  - Changing back to FreedomBox service works. Shows selection correctly.

- Unit tests work

- Configuration page shows /freedombox in description but not /plinth

- Diagnostics show /freedombox in tests

- Roundcube URL link in email app has /freedombox

- email loads the page /.well-known/autoconfig/mail/config-v1.1.xml correctly

- email app shows /freedombox/apps/roundcube for /roundcube if roundcube is not
installed.

- networks: router configuration page shows URL starting with /freedombox.

- snapshot: Shows URL starting with /freedombox on the app page

- js licenses page uses /freedombox prefix for JSXC.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
Sunil Mohan Adapa 2025-11-17 14:14:41 -08:00 committed by James Valleroy
parent 0d579012d7
commit 168f662a17
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808
51 changed files with 182 additions and 168 deletions

View File

@ -35,7 +35,7 @@ FreedomBox [Manual](https://wiki.debian.org/FreedomBox/Manual/)'s
3. Access FreedomBox UI: 3. Access FreedomBox UI:
UI should be accessible at http://localhost:8000/plinth UI should be accessible at http://localhost:8000/freedombox
If you are installing FreedomBox Service (Plinth) for development purposes, see If you are installing FreedomBox Service (Plinth) for development purposes, see
HACKING.md instead. HACKING.md instead.

View File

@ -230,7 +230,7 @@ provision-dev:
sshpass bash-completion sshpass bash-completion
wait-while-first-setup: wait-while-first-setup:
while [ x$$(curl -k https://localhost/plinth/status/ 2> /dev/null | \ while [ x$$(curl -k https://localhost/freedombox/status/ 2> /dev/null | \
json_pp 2> /dev/null | grep 'is_first_setup_running' | \ json_pp 2> /dev/null | grep 'is_first_setup_running' | \
tr -d '[:space:]' | cut -d':' -f2 ) != 'xfalse' ] ; do \ tr -d '[:space:]' | cut -d':' -f2 ) != 'xfalse' ] ; do \
sleep 1; echo -n .; done sleep 1; echo -n .; done

2
Vagrantfile vendored
View File

@ -28,7 +28,7 @@ Vagrant.configure(2) do |config|
SHELL SHELL
config.vm.provision "tests", run: "never", type: "shell", path: "plinth/tests/functional/install.sh" config.vm.provision "tests", run: "never", type: "shell", path: "plinth/tests/functional/install.sh"
config.vm.post_up_message = "FreedomBox virtual machine is ready config.vm.post_up_message = "FreedomBox virtual machine is ready
for development. Plinth will be available at https://localhost:4430/plinth for development. Plinth will be available at https://localhost:4430/freedombox
(with an invalid SSL certificate). To watch logs: (with an invalid SSL certificate). To watch logs:
$ vagrant ssh $ vagrant ssh
$ sudo freedombox-logs $ sudo freedombox-logs

View File

@ -39,16 +39,16 @@
</If> </If>
## ##
## Redirect traffic on home to /plinth as part of turning the machine ## Redirect traffic on home to /freedombox as part of turning the machine
## into FreedomBox server. Plinth then acts as a portal to reach all ## into FreedomBox server. Plinth then acts as a portal to reach all
## other services. ## other services.
## ##
<IfFile !/etc/apache2/conf-enabled/freedombox-apache-homepage.conf> <IfFile !/etc/apache2/conf-enabled/freedombox-apache-homepage.conf>
RedirectMatch "^/$" "/plinth" RedirectMatch "^/$" "/freedombox"
</IfFile> </IfFile>
## ##
## On all sites, provide FreedomBox on a default path: /plinth ## On all sites, provide FreedomBox on a default path: /freedombox
## ##
## Requires the following Apache modules to be enabled: ## Requires the following Apache modules to be enabled:
## mod_headers ## mod_headers
@ -56,7 +56,7 @@
## mod_proxy_http ## mod_proxy_http
## ##
<Location /freedombox> <Location /freedombox>
ProxyPass http://127.0.0.1:8000/plinth ProxyPass http://127.0.0.1:8000/freedombox
## Send the scheme from user's request to enable Plinth to redirect ## Send the scheme from user's request to enable Plinth to redirect
## URLs, set cookies, set absolute URLs (if any) properly. ## URLs, set cookies, set absolute URLs (if any) properly.
RequestHeader set X-Forwarded-Proto 'https' env=HTTPS RequestHeader set X-Forwarded-Proto 'https' env=HTTPS
@ -70,7 +70,7 @@
RequestHeader unset X-Forwarded-For RequestHeader unset X-Forwarded-For
</Location> </Location>
<Location /plinth> <Location /plinth>
ProxyPass http://127.0.0.1:8000/plinth ProxyPass http://127.0.0.1:8000/freedombox
RequestHeader set X-Forwarded-Proto 'https' env=HTTPS RequestHeader set X-Forwarded-Proto 'https' env=HTTPS
RequestHeader unset X-Forwarded-For RequestHeader unset X-Forwarded-For
</Location> </Location>
@ -82,7 +82,7 @@
<Location ~ ^/favicon\.ico$> <Location ~ ^/favicon\.ico$>
<IfModule mod_rewrite.c> <IfModule mod_rewrite.c>
RewriteEngine On RewriteEngine On
RewriteRule /favicon\.ico$ "/plinth/static/theme/img/favicon.ico" [PT] RewriteRule /favicon\.ico$ "/freedombox/static/theme/img/favicon.ico" [PT]
</IfModule> </IfModule>
</Location> </Location>

View File

@ -73,8 +73,8 @@
<para> <para>
This the URL fragment under which Plinth will provide its services. This the URL fragment under which Plinth will provide its services.
Plinth is shipped with a default value of Plinth is shipped with a default value of
<filename>/plinth</filename>. This means that Plinth will be <filename>/freedombox</filename>. This means that Plinth will be
available as http://localhost:8000/plinth by default. available as http://localhost:8000/freedombox by default.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -194,7 +194,7 @@
<synopsis>$ plinth --server_dir='/myurl'</synopsis> <synopsis>$ plinth --server_dir='/myurl'</synopsis>
<para> <para>
Run Plinth with the '/myurl' prefix. Note that Apache forwards requests Run Plinth with the '/myurl' prefix. Note that Apache forwards requests
to '/plinth' by default, so /myurl is not accessible outside of your to '/freedombox' by default, so /myurl is not accessible outside of your
FreedomBox without adapting the apache configuration. FreedomBox without adapting the apache configuration.
</para> </para>
</example> </example>

View File

@ -13,7 +13,7 @@ from pathlib import Path
from xml.sax.saxutils import escape from xml.sax.saxutils import escape
BASE_URL = 'https://wiki.debian.org/' BASE_URL = 'https://wiki.debian.org/'
LOCAL_BASE = '/plinth/help/manual/{lang}/' LOCAL_BASE = '/freedombox/help/manual/{lang}/'
ICONS_DIR = 'icons' ICONS_DIR = 'icons'
DEFAULT_LANGUAGE = 'en' DEFAULT_LANGUAGE = 'en'
@ -624,21 +624,21 @@ def resolve_url(url, context):
Locally available page in default language => shortcut to local copy: Locally available page in default language => shortcut to local copy:
>>> resolve_url('FreedomBox/Contribute', {'language': '', 'title': ''}) >>> resolve_url('FreedomBox/Contribute', {'language': '', 'title': ''})
'/plinth/help/manual/en/Contribute#' '/freedombox/help/manual/en/Contribute#'
Translated available page => shortcut to local copy: Translated available page => shortcut to local copy:
>>> resolve_url('es/FreedomBox/Contribute', {'language': '', 'title': ''}) >>> resolve_url('es/FreedomBox/Contribute', {'language': '', 'title': ''})
'/plinth/help/manual/es/Contribute#' '/freedombox/help/manual/es/Contribute#'
Available page in default language refferred as translated => shortcut to Available page in default language refferred as translated => shortcut to
local copy: local copy:
>>> resolve_url('en/FreedomBox/Contribute', {'language': '', 'title': ''}) >>> resolve_url('en/FreedomBox/Contribute', {'language': '', 'title': ''})
'/plinth/help/manual/en/Contribute#' '/freedombox/help/manual/en/Contribute#'
Unrecognized language => handle considering it as default language: Unrecognized language => handle considering it as default language:
>>> resolve_url('missing/FreedomBox/Contribute', {'language': '', \ >>> resolve_url('missing/FreedomBox/Contribute', {'language': '', \
'title': ''}) 'title': ''})
'/plinth/help/manual/en/Contribute#' '/freedombox/help/manual/en/Contribute#'
""" """
# Process first all easy, straight forward cases: # Process first all easy, straight forward cases:
@ -1191,11 +1191,11 @@ from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>')
[Paragraph([PlainText('a')]), Paragraph([PlainText('b ')])] [Paragraph([PlainText('a')]), Paragraph([PlainText('b ')])]
>>> parse_wiki('{{{#!wiki caution\\n\\nOnce some other app is set as the \ >>> parse_wiki('{{{#!wiki caution\\n\\nOnce some other app is set as the \
home page, you can only navigate to the !FreedomBox Service (Plinth) by \ home page, you can only navigate to the !FreedomBox Service (Plinth) by \
typing https://myfreedombox.rocks/plinth/ into the browser. <<BR>>\\n\ typing https://myfreedombox.rocks/freedombox/ into the browser. <<BR>>\\n\
''/freedombox'' can also be used as an alias to ''/plinth''\\n}}}') ''/freedombox'' can also be used as an alias to ''/plinth''\\n}}}')
[Admonition('caution', [Paragraph([PlainText('Once some other app is set \ [Admonition('caution', [Paragraph([PlainText('Once some other app is set \
as the home page, you can only navigate to the FreedomBox Service (Plinth) by \ as the home page, you can only navigate to the FreedomBox Service (Plinth) by \
typing '), Url('https://myfreedombox.rocks/plinth/'), PlainText(' into the \ typing '), Url('https://myfreedombox.rocks/freedombox/'), PlainText(' into the \
browser. ')]), Paragraph([PlainText('/freedombox can also be used as an alias \ browser. ')]), Paragraph([PlainText('/freedombox can also be used as an alias \
to /plinth ')])])] to /plinth ')])])]
@ -1761,7 +1761,7 @@ Features introduction</ulink>'
>>> generate_inner_docbook([Link('../../Contribute', \ >>> generate_inner_docbook([Link('../../Contribute', \
[PlainText('Contribute')])], context={'title': 'FreedomBox/Manual/Hardware'}) [PlainText('Contribute')])], context={'title': 'FreedomBox/Manual/Hardware'})
'<ulink url="/plinth/help/manual/en/Contribute#">\ '<ulink url="/freedombox/help/manual/en/Contribute#">\
Contribute</ulink>' Contribute</ulink>'
>>> generate_inner_docbook([Link('/Code', \ >>> generate_inner_docbook([Link('/Code', \
@ -1772,9 +1772,9 @@ Code</ulink>'
>>> generate_inner_docbook([Link('DebianBug:1234', [PlainText('Bug')])]) >>> generate_inner_docbook([Link('DebianBug:1234', [PlainText('Bug')])])
'<ulink url="https://bugs.debian.org/1234#">Bug</ulink>' '<ulink url="https://bugs.debian.org/1234#">Bug</ulink>'
>>> generate_inner_docbook([Link('DebianPkg:plinth', \ >>> generate_inner_docbook([Link('DebianPkg:freedombox', \
[PlainText('Plinth')])]) [PlainText('Plinth')])])
'<ulink url="https://packages.debian.org/plinth#">Plinth</ulink>' '<ulink url="https://packages.debian.org/freedombox#">Plinth</ulink>'
>>> generate_inner_docbook([Link('AliothList:freedombox-discuss', \ >>> generate_inner_docbook([Link('AliothList:freedombox-discuss', \
[PlainText('Discuss')])]) [PlainText('Discuss')])])
@ -1911,7 +1911,7 @@ PlainText(' on it. ')])])
'<para>An alternative to downloading these images is to \ '<para>An alternative to downloading these images is to \
<ulink url="https://wiki.debian.org/InstallingDebianOn/TI/BeagleBone#">\ <ulink url="https://wiki.debian.org/InstallingDebianOn/TI/BeagleBone#">\
install Debian</ulink> on the BeagleBone and then \ install Debian</ulink> on the BeagleBone and then \
<ulink url="/plinth/help/manual/en/Debian#">install \ <ulink url="/freedombox/help/manual/en/Debian#">install \
FreedomBox</ulink> on it. </para>' FreedomBox</ulink> on it. </para>'
>>> generate_inner_docbook([Paragraph([PlainText('After Roundcube is \ >>> generate_inner_docbook([Paragraph([PlainText('After Roundcube is \

View File

@ -16,7 +16,7 @@ data_dir = '/var/lib/plinth'
custom_static_dir = '/var/www/plinth/custom/static' custom_static_dir = '/var/www/plinth/custom/static'
store_file = data_dir + '/plinth.sqlite3' store_file = data_dir + '/plinth.sqlite3'
doc_dir = '/usr/share/freedombox' doc_dir = '/usr/share/freedombox'
server_dir = '/plinth' server_dir = '/freedombox'
# [Network] section # [Network] section
host = '127.0.0.1' host = '127.0.0.1'

View File

@ -85,7 +85,8 @@ def test_remote_backup_location(session_browser):
def _assert_main_page_is_shown(session_browser): def _assert_main_page_is_shown(session_browser):
assert (session_browser.url.endswith('/plinth/')) assert (session_browser.url.endswith('/freedombox/')
or session_browser.url.endswith('/plinth/'))
def _backup_download(session_browser, downloaded_file_info, archive_name): def _backup_download(session_browser, downloaded_file_info, archive_name):
@ -126,7 +127,7 @@ def _backup_schedule_get(browser):
functional.nav_to_module(browser, 'backups') functional.nav_to_module(browser, 'backups')
with functional.wait_for_page_update(browser): with functional.wait_for_page_update(browser):
browser.links.find_by_href( browser.links.find_by_href(
'/plinth/sys/backups/root/schedule/').first.click() '/freedombox/sys/backups/root/schedule/').first.click()
without_apps = [] without_apps = []
elements = browser.find_by_name('backups_schedule-selected_apps') elements = browser.find_by_name('backups_schedule-selected_apps')
@ -158,7 +159,7 @@ def _backup_schedule_set(browser, enable, daily, weekly, monthly, run_at,
functional.nav_to_module(browser, 'backups') functional.nav_to_module(browser, 'backups')
with functional.wait_for_page_update(browser): with functional.wait_for_page_update(browser):
browser.links.find_by_href( browser.links.find_by_href(
'/plinth/sys/backups/root/schedule/').first.click() '/freedombox/sys/backups/root/schedule/').first.click()
if enable: if enable:
browser.find_by_name('backups_schedule-enabled').check() browser.find_by_name('backups_schedule-enabled').check()
@ -192,7 +193,7 @@ def _download_file_logged_in(browser, url, suffix=''):
def _download(browser, archive_name=None): def _download(browser, archive_name=None):
"""Download a backup archive to a temporary file on disk.""" """Download a backup archive to a temporary file on disk."""
functional.nav_to_module(browser, 'backups') functional.nav_to_module(browser, 'backups')
href = f'/plinth/sys/backups/root/download/{archive_name}/' href = f'/freedombox/sys/backups/root/download/{archive_name}/'
url = functional.base_url + href url = functional.base_url + href
file_path = _download_file_logged_in(browser, url, suffix='.tar.gz') file_path = _download_file_logged_in(browser, url, suffix='.tar.gz')
return file_path return file_path
@ -201,22 +202,23 @@ def _download(browser, archive_name=None):
def _open_main_page(browser): def _open_main_page(browser):
"""Open the FreedomBox interface main page.""" """Open the FreedomBox interface main page."""
with functional.wait_for_page_update(browser): with functional.wait_for_page_update(browser):
browser.links.find_by_href('/plinth/').first.click() browser.links.find_by_href('/freedombox/').first.click()
def _upload_and_restore(browser, app_name, downloaded_file_path): def _upload_and_restore(browser, app_name, downloaded_file_path):
"""Upload a backup archive from the disk and perform restore operation.""" """Upload a backup archive from the disk and perform restore operation."""
functional.nav_to_module(browser, 'backups') functional.nav_to_module(browser, 'backups')
with functional.wait_for_page_update(browser): with functional.wait_for_page_update(browser):
browser.links.find_by_href('/plinth/sys/backups/upload/').first.click() browser.links.find_by_href(
'/freedombox/sys/backups/upload/').first.click()
fileinput = browser.find_by_id('id_backups-file') fileinput = browser.find_by_id('id_backups-file')
fileinput.fill(downloaded_file_path) fileinput.fill(downloaded_file_path)
# submit upload form # submit upload form
functional.submit(browser, form_class='form-upload') functional.submit(browser, form_class='form-upload')
# submit restore form # submit restore form
with functional.wait_for_page_update(browser, with functional.wait_for_page_update(
expected_url='/plinth/sys/backups/'): browser, expected_url='/freedombox/sys/backups/'):
functional.submit(browser, form_class='form-restore') functional.submit(browser, form_class='form-restore')
@ -233,7 +235,7 @@ def _add_remote_backup_location(browser, ssh_use_password=True):
_remove_remote_backup_location(browser) _remove_remote_backup_location(browser)
browser.links.find_by_href( browser.links.find_by_href(
'/plinth/sys/backups/repositories/add-remote/').first.click() '/freedombox/sys/backups/repositories/add-remote/').first.click()
browser.find_by_name('repository').fill(REMOTE_PATH) browser.find_by_name('repository').fill(REMOTE_PATH)
password = functional.get_password( password = functional.get_password(
functional.config['DEFAULT']['username']) functional.config['DEFAULT']['username'])

View File

@ -68,7 +68,7 @@ def _set_default_permissions(browser, permissions=''):
def _add_password(browser): def _add_password(browser):
functional.visit(browser, '/plinth/apps/bepasty/add/') functional.visit(browser, '/freedombox/apps/bepasty/add/')
for permission in ['read', 'create', 'list', 'delete', 'admin']: for permission in ['read', 'create', 'list', 'delete', 'admin']:
browser.find_by_css('#id_bepasty-permissions input[value="{}"]'.format( browser.find_by_css('#id_bepasty-permissions input[value="{}"]'.format(
permission)).check() permission)).check()

View File

@ -60,7 +60,7 @@ def _add_library(browser, name):
return return
browser.links.find_by_href( browser.links.find_by_href(
'/plinth/apps/calibre/library/create/').first.click() '/freedombox/apps/calibre/library/create/').first.click()
browser.find_by_id('id_calibre-name').fill(name) browser.find_by_id('id_calibre-name').fill(name)
functional.submit(browser, form_class='form-calibre') functional.submit(browser, form_class='form-calibre')
@ -69,7 +69,7 @@ def _delete_library(browser, name, ignore_missing=False):
"""Delete a library.""" """Delete a library."""
functional.nav_to_module(browser, 'calibre') functional.nav_to_module(browser, 'calibre')
link = browser.links.find_by_href( link = browser.links.find_by_href(
f'/plinth/apps/calibre/library/{name}/delete/') f'/freedombox/apps/calibre/library/{name}/delete/')
if not link: if not link:
if ignore_missing: if ignore_missing:
return return
@ -84,7 +84,7 @@ def _is_library_available(browser, name):
"""Return whether a library is present in the list of libraries.""" """Return whether a library is present in the list of libraries."""
functional.nav_to_module(browser, 'calibre') functional.nav_to_module(browser, 'calibre')
link = browser.links.find_by_href( link = browser.links.find_by_href(
f'/plinth/apps/calibre/library/{name}/delete/') f'/freedombox/apps/calibre/library/{name}/delete/')
return bool(link) return bool(link)

View File

@ -94,7 +94,7 @@ def home_page_url2scid(url: str | None):
if url in ('/plinth/', '/plinth', 'plinth', '/freedombox/', '/freedombox', if url in ('/plinth/', '/plinth', 'plinth', '/freedombox/', '/freedombox',
'freedombox'): 'freedombox'):
return 'plinth' return 'freedombox'
if url and url.startswith('/~'): if url and url.startswith('/~'):
return 'uws-{}'.format(user_of_uws_url(url)) return 'uws-{}'.format(user_of_uws_url(url))
@ -109,8 +109,8 @@ def home_page_url2scid(url: str | None):
def _home_page_scid2url(shortcut_id: str) -> str | None: def _home_page_scid2url(shortcut_id: str) -> str | None:
"""Return the url for the given home page shortcut ID.""" """Return the url for the given home page shortcut ID."""
url: str | None = '/plinth/' url: str | None = '/freedombox/'
if shortcut_id == 'plinth': if shortcut_id == 'freedombox':
pass pass
elif shortcut_id == 'apache-default': elif shortcut_id == 'apache-default':
url = None url = None
@ -134,7 +134,7 @@ def _get_home_page_url() -> str | None:
"""Get the default application for the domain.""" """Get the default application for the domain."""
conf_file = privileged.APACHE_HOMEPAGE_CONFIG conf_file = privileged.APACHE_HOMEPAGE_CONFIG
if not pathlib.Path(conf_file).exists(): if not pathlib.Path(conf_file).exists():
return '/plinth/' return '/freedombox/'
aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD +
augeas.Augeas.NO_MODL_AUTOLOAD) augeas.Augeas.NO_MODL_AUTOLOAD)

View File

@ -24,8 +24,8 @@ def get_homepage_choices():
format_lazy(gettext_lazy("{user}'s website"), user=user)) format_lazy(gettext_lazy("{user}'s website"), user=user))
for user, url in get_users_with_website().items()] for user, url in get_users_with_website().items()]
apache_default = ('apache-default', _('Apache Default')) apache_default = ('apache-default', _('Apache Default'))
plinth = ('plinth', _('FreedomBox Service (Plinth)')) freedombox = ('freedombox', _('FreedomBox Service (Plinth)'))
return [apache_default, plinth] + uws_choices + shortcut_choices return [apache_default, freedombox] + uws_choices + shortcut_choices
class ConfigurationForm(forms.Form): class ConfigurationForm(forms.Form):
@ -39,8 +39,8 @@ class ConfigurationForm(forms.Form):
'case is to set your blog or wiki as the home page when ' 'case is to set your blog or wiki as the home page when '
'someone visits the domain name. Note that once the home ' 'someone visits the domain name. Note that once the home '
'page is set to something other than {box_name} Service ' 'page is set to something other than {box_name} Service '
'(Plinth), your users must explicitly type /plinth or ' '(Plinth), your users must explicitly type /freedombox to '
'/freedombox to reach {box_name} Service (Plinth).'), 'reach {box_name} Service (Plinth).'),
box_name=gettext_lazy(cfg.box_name)), required=False, box_name=gettext_lazy(cfg.box_name)), required=False,
choices=get_homepage_choices) choices=get_homepage_choices)

View File

@ -21,15 +21,18 @@ def test_homepage_mapping():
func = home_page_url2scid func = home_page_url2scid
assert func(None) == 'apache-default' assert func(None) == 'apache-default'
assert func('/unknown/url') is None assert func('/unknown/url') is None
assert func('/plinth/') == 'plinth' assert func('/plinth/') == 'freedombox'
assert func('/plinth') == 'plinth' assert func('/plinth') == 'freedombox'
assert func('plinth') == 'plinth' assert func('plinth') == 'freedombox'
assert func('/freedombox/') == 'freedombox'
assert func('/freedombox') == 'freedombox'
assert func('freedombox') == 'freedombox'
assert func('/index.html') == 'apache-default' assert func('/index.html') == 'apache-default'
assert func('/~user') == 'uws-user' assert func('/~user') == 'uws-user'
assert func('/~user/whatever/else') == 'uws-user' assert func('/~user/whatever/else') == 'uws-user'
func = _home_page_scid2url func = _home_page_scid2url
assert func('plinth') == '/plinth/' assert func('freedombox') == '/freedombox/'
assert func('apache-default') is None assert func('apache-default') is None
@ -63,7 +66,7 @@ def test_homepage_mapping_skip_ci():
# AC: Return None if it doesn't: # AC: Return None if it doesn't:
os.rmdir(uws_directory) os.rmdir(uws_directory)
assert _home_page_scid2url(uws_scid) == '/plinth/' assert _home_page_scid2url(uws_scid) == '/freedombox/'
@patch( @patch(
@ -102,7 +105,7 @@ def test_homepage_field():
uws_url = uws_url_of_user(user) uws_url = uws_url_of_user(user)
uws_scid = home_page_url2scid(uws_url) uws_scid = home_page_url2scid(uws_url)
default_home_page = 'plinth' default_home_page = 'freedombox'
original_home_page = get_home_page() or default_home_page original_home_page = get_home_page() or default_home_page
change_home_page(default_home_page) # Set to known value explicitly change_home_page(default_home_page) # Set to known value explicitly
@ -113,7 +116,7 @@ def test_homepage_field():
# AC: valid changes actually happen: # AC: valid changes actually happen:
pathlib.Path(uws_directory).mkdir(parents=True) pathlib.Path(uws_directory).mkdir(parents=True)
for scid in ('b', 'a', uws_scid, 'apache-default', 'plinth'): for scid in ('b', 'a', uws_scid, 'apache-default', 'freedombox'):
change_home_page(scid) change_home_page(scid)
assert get_home_page() == scid assert get_home_page() == scid

View File

@ -22,12 +22,12 @@ def test_change_home_page(session_browser):
functional.app_enable(session_browser, 'syncthing') functional.app_enable(session_browser, 'syncthing')
_set_home_page(session_browser, 'syncthing') _set_home_page(session_browser, 'syncthing')
_set_home_page(session_browser, 'plinth') _set_home_page(session_browser, 'freedombox')
assert _check_home_page_redirect(session_browser, 'plinth') assert _check_home_page_redirect(session_browser, 'freedombox')
def _set_home_page(browser, home_page): def _set_home_page(browser, home_page):
if 'plinth' not in home_page and 'apache' not in home_page: if 'freedombox' not in home_page and 'apache' not in home_page:
home_page = 'shortcut-' + home_page home_page = 'shortcut-' + home_page
functional.nav_to_module(browser, 'config') functional.nav_to_module(browser, 'config')
@ -39,4 +39,4 @@ def _set_home_page(browser, home_page):
def _check_home_page_redirect(browser, app_name): def _check_home_page_redirect(browser, app_name):
functional.visit(browser, '/') functional.visit(browser, '/')
return browser.find_by_xpath( return browser.find_by_xpath(
"//a[contains(@href, '/plinth/') and @title='FreedomBox']") "//a[contains(@href, '/freedombox/') and @title='FreedomBox']")

View File

@ -100,7 +100,7 @@ class DiagnosticsApp(app_module.App):
results = super().diagnose() results = super().diagnose()
results.append(diagnose_port_listening(8000, 'tcp4')) results.append(diagnose_port_listening(8000, 'tcp4'))
results.extend( results.extend(
diagnose_url_on_all('http://{host}/plinth/', diagnose_url_on_all('http://{host}/freedombox/',
check_certificate=False)) check_certificate=False))
return results return results

View File

@ -112,7 +112,7 @@ def _configure(browser, config):
functional.nav_to_module(browser, 'dynamicdns') functional.nav_to_module(browser, 'dynamicdns')
functional.click_link_by_href(browser, functional.click_link_by_href(browser,
'/plinth/sys/dynamicdns/domain/add/') '/freedombox/sys/dynamicdns/domain/add/')
for key, value in config.items(): for key, value in config.items():
field_id = f'id_domain-{key}' field_id = f'id_domain-{key}'
if key == 'service_type': if key == 'service_type':
@ -130,7 +130,7 @@ def _configure(browser, config):
def _assert_has_config(browser, config): def _assert_has_config(browser, config):
functional.nav_to_module(browser, 'dynamicdns') functional.nav_to_module(browser, 'dynamicdns')
link = f'/plinth/sys/dynamicdns/domain/{config["domain"]}/edit/' link = f'/freedombox/sys/dynamicdns/domain/{config["domain"]}/edit/'
functional.click_link_by_href(browser, link) functional.click_link_by_href(browser, link)
for key, value in config.items(): for key, value in config.items():
if key == 'password': if key == 'password':
@ -153,6 +153,6 @@ def _get_domains(browser):
def _delete_domain(browser, domain): def _delete_domain(browser, domain):
"""Delete a given domain.""" """Delete a given domain."""
functional.nav_to_module(browser, 'dynamicdns') functional.nav_to_module(browser, 'dynamicdns')
link = f'/plinth/sys/dynamicdns/domain/{domain}/delete/' link = f'/freedombox/sys/dynamicdns/domain/{domain}/delete/'
functional.click_link_by_href(browser, link) functional.click_link_by_href(browser, link)
functional.submit(browser, form_class='form-delete') functional.submit(browser, form_class='form-delete')

View File

@ -118,7 +118,7 @@ def _jsxc_login(browser):
"""Login to JSXC.""" """Login to JSXC."""
username = functional.config['DEFAULT']['username'] username = functional.config['DEFAULT']['username']
password = functional.config['DEFAULT']['password'] password = functional.config['DEFAULT']['password']
functional.visit(browser, '/plinth/apps/jsxc/jsxc/') functional.visit(browser, '/freedombox/apps/jsxc/jsxc/')
assert functional.eventually(browser.find_by_text, assert functional.eventually(browser.find_by_text,
['BOSH Server reachable.']) ['BOSH Server reachable.'])
if browser.find_by_text('relogin'): if browser.find_by_text('relogin'):

View File

@ -38,7 +38,7 @@ _description = [
'they can add aliases to their email address. Necessary aliases ' 'they can add aliases to their email address. Necessary aliases '
'such as "postmaster" are automatically created pointing to the ' 'such as "postmaster" are automatically created pointing to the '
'first admin user.'), box_name=_(cfg.box_name)), 'first admin user.'), box_name=_(cfg.box_name)),
_('<a href="/plinth/apps/roundcube/">Roundcube app</a> provides web ' _('<a href="/freedombox/apps/roundcube/">Roundcube app</a> provides web '
'interface for users to access email.'), 'interface for users to access email.'),
_('During installation, any other email servers in the system will be ' _('During installation, any other email servers in the system will be '
'uninstalled.') 'uninstalled.')

View File

@ -25,12 +25,12 @@
<Location "/.well-known/autoconfig/mail/config-v1.1.xml"> <Location "/.well-known/autoconfig/mail/config-v1.1.xml">
<IfModule mod_rewrite.c> <IfModule mod_rewrite.c>
RewriteEngine On RewriteEngine On
RewriteRule ^ /plinth/apps/email/config.xml [PT] RewriteRule ^ /freedombox/apps/email/config.xml [PT]
</IfModule> </IfModule>
</Location> </Location>
# If Roundcube is not yet installed and the user clicks on 'Launch web client', # If Roundcube is not yet installed and the user clicks on 'Launch web client',
# redirect to the installation page instead of Apache's Not Found page. # redirect to the installation page instead of Apache's Not Found page.
<Location "/roundcube/"> <Location "/roundcube/">
ErrorDocument 404 /plinth/apps/roundcube/ ErrorDocument 404 /freedombox/apps/roundcube/
</Location> </Location>

View File

@ -27,7 +27,7 @@ class TestFeatherWikiApp(functional.BaseAppTests):
return return
session_browser.links.find_by_href( session_browser.links.find_by_href(
'/plinth/apps/featherwiki/create/').first.click() '/freedombox/apps/featherwiki/create/').first.click()
session_browser.find_by_id('id_featherwiki-name').fill(course_1) session_browser.find_by_id('id_featherwiki-name').fill(course_1)
functional.submit(session_browser, form_class='form-featherwiki') functional.submit(session_browser, form_class='form-featherwiki')
@ -73,7 +73,7 @@ class TestFeatherWikiApp(functional.BaseAppTests):
new_course = 'A Midsummer Night\'s Dream' new_course = 'A Midsummer Night\'s Dream'
new_file_name = 'A_Midsummer_Nights_Dream.html' new_file_name = 'A_Midsummer_Nights_Dream.html'
self._get_links_in_app_page( self._get_links_in_app_page(
session_browser, '/plinth/apps/featherwiki/' + file_name_1 + session_browser, '/freedombox/apps/featherwiki/' + file_name_1 +
'/rename/').first.click() '/rename/').first.click()
session_browser.find_by_id('id_featherwiki-new_name').fill(new_course) session_browser.find_by_id('id_featherwiki-new_name').fill(new_course)
functional.submit(session_browser, form_class='form-featherwiki') functional.submit(session_browser, form_class='form-featherwiki')
@ -87,7 +87,7 @@ class TestFeatherWikiApp(functional.BaseAppTests):
test_wiki_file = str(_test_data_dir / 'dummy_wiki.html') test_wiki_file = str(_test_data_dir / 'dummy_wiki.html')
session_browser.links.find_by_href( session_browser.links.find_by_href(
'/plinth/apps/featherwiki/upload/').first.click() '/freedombox/apps/featherwiki/upload/').first.click()
session_browser.attach_file('featherwiki-file', test_wiki_file) session_browser.attach_file('featherwiki-file', test_wiki_file)
functional.submit(session_browser, form_class='form-featherwiki') functional.submit(session_browser, form_class='form-featherwiki')
@ -98,7 +98,7 @@ class TestFeatherWikiApp(functional.BaseAppTests):
self._create_wiki_file(session_browser) self._create_wiki_file(session_browser)
self._get_links_in_app_page( self._get_links_in_app_page(
session_browser, '/plinth/apps/featherwiki/' + file_name_1 + session_browser, '/freedombox/apps/featherwiki/' + file_name_1 +
'/delete/').first.click() '/delete/').first.click()
functional.submit(session_browser, form_class='form-delete') functional.submit(session_browser, form_class='form-delete')

View File

@ -144,7 +144,8 @@ def _create_repo(browser, repo, access=None, ok_if_exists=False):
"""Create repository.""" """Create repository."""
if not _repo_exists(browser, repo, access): if not _repo_exists(browser, repo, access):
_delete_repo(browser, repo, ignore_missing=True) _delete_repo(browser, repo, ignore_missing=True)
browser.links.find_by_href('/plinth/apps/gitweb/create/').first.click() browser.links.find_by_href(
'/freedombox/apps/gitweb/create/').first.click()
browser.find_by_id('id_gitweb-name').fill(repo) browser.find_by_id('id_gitweb-name').fill(repo)
if access == 'private': if access == 'private':
browser.find_by_id('id_gitweb-is_private').check() browser.find_by_id('id_gitweb-is_private').check()
@ -182,7 +183,7 @@ def _delete_repo(browser, repo, ignore_missing=False):
if repo.endswith('.git'): if repo.endswith('.git'):
repo = repo[:-4] repo = repo[:-4]
delete_link = browser.links.find_by_href( delete_link = browser.links.find_by_href(
'/plinth/apps/gitweb/{}/delete/'.format(repo)) '/freedombox/apps/gitweb/{}/delete/'.format(repo))
if delete_link or not ignore_missing: if delete_link or not ignore_missing:
delete_link.first.click() delete_link.first.click()
functional.submit(browser, form_class='form-delete') functional.submit(browser, form_class='form-delete')
@ -192,7 +193,7 @@ def _edit_repo_metadata(browser, repo, metadata):
"""Set repository metadata.""" """Set repository metadata."""
functional.nav_to_module(browser, 'gitweb') functional.nav_to_module(browser, 'gitweb')
browser.links.find_by_href( browser.links.find_by_href(
'/plinth/apps/gitweb/{}/edit/'.format(repo)).first.click() '/freedombox/apps/gitweb/{}/edit/'.format(repo)).first.click()
browser.find_by_id('id_gitweb-name').fill(metadata['name']) browser.find_by_id('id_gitweb-name').fill(metadata['name'])
browser.find_by_id('id_gitweb-description').fill(metadata['description']) browser.find_by_id('id_gitweb-description').fill(metadata['description'])
browser.find_by_id('id_gitweb-owner').fill(metadata['owner']) browser.find_by_id('id_gitweb-owner').fill(metadata['owner'])
@ -214,7 +215,7 @@ def _get_repo_metadata(browser, repo):
"""Get repository metadata.""" """Get repository metadata."""
functional.nav_to_module(browser, 'gitweb') functional.nav_to_module(browser, 'gitweb')
browser.links.find_by_href( browser.links.find_by_href(
'/plinth/apps/gitweb/{}/edit/'.format(repo)).first.click() '/freedombox/apps/gitweb/{}/edit/'.format(repo)).first.click()
metadata = {} metadata = {}
for item in ['name', 'description', 'owner']: for item in ['name', 'description', 'owner']:
metadata[item] = browser.find_by_id('id_gitweb-' + item).value metadata[item] = browser.find_by_id('id_gitweb-' + item).value
@ -318,7 +319,7 @@ def _set_default_branch(browser, repo, branch):
"""Set default branch of the repository.""" """Set default branch of the repository."""
functional.nav_to_module(browser, 'gitweb') functional.nav_to_module(browser, 'gitweb')
browser.links.find_by_href( browser.links.find_by_href(
'/plinth/apps/gitweb/{}/edit/'.format(repo)).first.click() '/freedombox/apps/gitweb/{}/edit/'.format(repo)).first.click()
browser.find_by_id('id_gitweb-default_branch').select(branch) browser.find_by_id('id_gitweb-default_branch').select(branch)
functional.submit(browser, form_class='form-gitweb') functional.submit(browser, form_class='form-gitweb')
@ -327,7 +328,7 @@ def _set_repo_access(browser, repo, access):
"""Set repository as public or private.""" """Set repository as public or private."""
functional.nav_to_module(browser, 'gitweb') functional.nav_to_module(browser, 'gitweb')
browser.links.find_by_href( browser.links.find_by_href(
'/plinth/apps/gitweb/{}/edit/'.format(repo)).first.click() '/freedombox/apps/gitweb/{}/edit/'.format(repo)).first.click()
if access == 'private': if access == 'private':
browser.find_by_id('id_gitweb-is_private').check() browser.find_by_id('id_gitweb-is_private').check()
else: else:

View File

@ -34,7 +34,7 @@ def _create_wiki_if_needed(browser):
wiki = browser.links.find_by_href('/ikiwiki/wiki') wiki = browser.links.find_by_href('/ikiwiki/wiki')
if not wiki: if not wiki:
browser.links.find_by_href( browser.links.find_by_href(
'/plinth/apps/ikiwiki/create/').first.click() '/freedombox/apps/ikiwiki/create/').first.click()
browser.find_by_id('id_ikiwiki-name').fill('wiki') browser.find_by_id('id_ikiwiki-name').fill('wiki')
browser.find_by_id('id_ikiwiki-admin_name').fill( browser.find_by_id('id_ikiwiki-admin_name').fill(
functional.config['DEFAULT']['username']) functional.config['DEFAULT']['username'])
@ -47,7 +47,7 @@ def _delete_wiki(browser):
"""Delete wiki.""" """Delete wiki."""
functional.nav_to_module(browser, 'ikiwiki') functional.nav_to_module(browser, 'ikiwiki')
browser.links.find_by_href( browser.links.find_by_href(
'/plinth/apps/ikiwiki/wiki/delete/').first.click() '/freedombox/apps/ikiwiki/wiki/delete/').first.click()
functional.submit(browser, form_class='form-delete') functional.submit(browser, form_class='form-delete')

View File

@ -74,7 +74,8 @@ class TestKiwixApp(functional.BaseAppTests):
def _add_package(browser, file_name): def _add_package(browser, file_name):
"""Add a package by uploading the ZIM file in kiwix app page.""" """Add a package by uploading the ZIM file in kiwix app page."""
browser.links.find_by_href('/plinth/apps/kiwix/package/add/').first.click() browser.links.find_by_href(
'/freedombox/apps/kiwix/package/add/').first.click()
browser.attach_file('kiwix-file', file_name) browser.attach_file('kiwix-file', file_name)
functional.submit(browser, form_class='form-kiwix') functional.submit(browser, form_class='form-kiwix')
@ -98,7 +99,7 @@ def _delete_package(browser, zim_id):
"""Delete a content package from the kiwix app page.""" """Delete a content package from the kiwix app page."""
functional.nav_to_module(browser, 'kiwix') functional.nav_to_module(browser, 'kiwix')
link = browser.links.find_by_href( link = browser.links.find_by_href(
f'/plinth/apps/kiwix/package/{zim_id}/delete/') f'/freedombox/apps/kiwix/package/{zim_id}/delete/')
if not link: if not link:
raise ValueError('ZIM file missing!') raise ValueError('ZIM file missing!')

View File

@ -59,7 +59,8 @@ class TestMinifluxApp(functional.BaseAppTests):
def _fill_credentials_form(browser, href): def _fill_credentials_form(browser, href):
"""Fill the user credentials form in Miniflux app.""" """Fill the user credentials form in Miniflux app."""
functional.nav_to_module(browser, 'miniflux') functional.nav_to_module(browser, 'miniflux')
functional.click_link_by_href(browser, f'/plinth/apps/miniflux/{href}/') functional.click_link_by_href(browser,
f'/freedombox/apps/miniflux/{href}/')
browser.fill('miniflux-username', CREDENTIALS['username']) browser.fill('miniflux-username', CREDENTIALS['username'])
browser.fill('miniflux-password', CREDENTIALS['password']) browser.fill('miniflux-password', CREDENTIALS['password'])

View File

@ -24,7 +24,7 @@ def test_change_hostname(session_browser):
def _get_hostname(browser): def _get_hostname(browser):
functional.visit(browser, '/plinth/sys/names/hostname/') functional.visit(browser, '/freedombox/sys/names/hostname/')
return browser.find_by_id('id_hostname-hostname').value return browser.find_by_id('id_hostname-hostname').value

View File

@ -32,7 +32,7 @@
{% blocktrans trimmed %} {% blocktrans trimmed %}
If you don't have control over your router, choose not to configure it. To If you don't have control over your router, choose not to configure it. To
see options to overcome this limitation, choose 'I dont have a public IP address' option see options to overcome this limitation, choose 'I dont have a public IP address' option
in <a href="/plinth/sys/networks/internet-connection-type/">Internet connection type selection</a>. in <a href="/freedombox/sys/networks/internet-connection-type/">Internet connection type selection</a>.
{% endblocktrans %} {% endblocktrans %}
</p> </p>

View File

@ -4,6 +4,7 @@ Functional, browser based tests for openvpn app.
""" """
import pytest import pytest
from plinth.tests import functional from plinth.tests import functional
pytestmark = [pytest.mark.apps, pytest.mark.openvpn] pytestmark = [pytest.mark.apps, pytest.mark.openvpn]
@ -64,5 +65,5 @@ def _download_profile(browser):
"""Return the content of the current user's OpenVPN profile.""" """Return the content of the current user's OpenVPN profile."""
browser.visit(base_url) browser.visit(base_url)
browser.links.find_by_href(shortcut_href).click() browser.links.find_by_href(shortcut_href).click()
profile_url = f'{base_url}/plinth/apps/openvpn/profile/' profile_url = f'{base_url}/freedombox/apps/openvpn/profile/'
return functional.download_file(browser, profile_url) return functional.download_file(browser, profile_url)

View File

@ -38,7 +38,7 @@ class TestShadowsocksApp(functional.BaseAppTests):
def _configure(browser, server, password): def _configure(browser, server, password):
"""Configure shadowsocks client with given server details.""" """Configure shadowsocks client with given server details."""
functional.visit(browser, '/plinth/apps/shadowsocks/') functional.visit(browser, '/freedombox/apps/shadowsocks/')
browser.find_by_id('id_server').fill(server) browser.find_by_id('id_server').fill(server)
browser.find_by_id('id_password').fill(password) browser.find_by_id('id_password').fill(password)
functional.submit(browser, form_class='form-configuration') functional.submit(browser, form_class='form-configuration')
@ -46,7 +46,7 @@ def _configure(browser, server, password):
def _get_configuration(browser): def _get_configuration(browser):
"""Return the server and password currently configured in shadowsocks.""" """Return the server and password currently configured in shadowsocks."""
functional.visit(browser, '/plinth/apps/shadowsocks/') functional.visit(browser, '/freedombox/apps/shadowsocks/')
server = browser.find_by_id('id_server').value server = browser.find_by_id('id_server').value
password = browser.find_by_id('id_password').value password = browser.find_by_id('id_password').value
return server, password return server, password

View File

@ -38,13 +38,13 @@ class TestShadowsocksServerApp(functional.BaseAppTests):
def _configure(browser, password): def _configure(browser, password):
"""Configure Shadowsocks Server with given details.""" """Configure Shadowsocks Server with given details."""
functional.visit(browser, '/plinth/apps/shadowsocksserver/') functional.visit(browser, '/freedombox/apps/shadowsocksserver/')
browser.find_by_id('id_password').fill(password) browser.find_by_id('id_password').fill(password)
functional.submit(browser, form_class='form-configuration') functional.submit(browser, form_class='form-configuration')
def _get_configuration(browser): def _get_configuration(browser):
"""Return the password currently configured in Shadowsocks Server.""" """Return the password currently configured in Shadowsocks Server."""
functional.visit(browser, '/plinth/apps/shadowsocksserver/') functional.visit(browser, '/freedombox/apps/shadowsocksserver/')
password = browser.find_by_id('id_password').value password = browser.find_by_id('id_password').value
return password return password

View File

@ -80,7 +80,7 @@ def _remove_share(browser, name):
def _add_share(browser, name, path, group): def _add_share(browser, name, path, group):
"""Add a share in sharing app.""" """Add a share in sharing app."""
functional.visit(browser, '/plinth/apps/sharing/add/') functional.visit(browser, '/freedombox/apps/sharing/add/')
browser.fill('sharing-name', name) browser.fill('sharing-name', name)
browser.fill('sharing-path', path) browser.fill('sharing-path', path)
browser.find_by_css( browser.find_by_css(
@ -102,7 +102,7 @@ def _edit_share(browser, old_name, new_name, path, group):
def _get_share(browser, name): def _get_share(browser, name):
"""Return the row for a given share.""" """Return the row for a given share."""
functional.visit(browser, '/plinth/apps/sharing/') functional.visit(browser, '/freedombox/apps/sharing/')
return browser.find_by_id('share-{}'.format(name))[0] return browser.find_by_id('share-{}'.format(name))[0]
@ -148,4 +148,4 @@ def _verify_nonexistant_share(browser, name):
def _verify_inaccessible_share(browser, name): def _verify_inaccessible_share(browser, name):
"""Verify that given URL for a given share name denies permission.""" """Verify that given URL for a given share name denies permission."""
functional.visit(browser, f'/share/{name}') functional.visit(browser, f'/share/{name}')
functional.eventually(lambda: '/plinth' in browser.url, args=[]) functional.eventually(lambda: '/freedombox' in browser.url, args=[])

View File

@ -24,7 +24,7 @@ _description = [
'automatically cleaned up according to the settings below.'), 'automatically cleaned up according to the settings below.'),
_('Snapshots currently work on btrfs file systems only and on the root ' _('Snapshots currently work on btrfs file systems only and on the root '
'partition only. Snapshots are not a replacement for ' 'partition only. Snapshots are not a replacement for '
'<a href="/plinth/sys/backups">backups</a> since ' '<a href="/freedombox/sys/backups">backups</a> since '
'they can only be stored on the same partition. ') 'they can only be stored on the same partition. ')
] ]

View File

@ -61,7 +61,7 @@ def _empty_snapshots_list(browser):
def _delete_all(browser): def _delete_all(browser):
functional.visit(browser, '/plinth/sys/snapshot/manage/') functional.visit(browser, '/freedombox/sys/snapshot/manage/')
delete_button = browser.find_by_name('delete_selected').first delete_button = browser.find_by_name('delete_selected').first
if not delete_button['disabled']: if not delete_button['disabled']:
browser.find_by_id('select-all').check() browser.find_by_id('select-all').check()
@ -73,13 +73,13 @@ def _delete_all(browser):
def _create_snapshot(browser): def _create_snapshot(browser):
functional.visit(browser, '/plinth/sys/snapshot/manage/') functional.visit(browser, '/freedombox/sys/snapshot/manage/')
create_button = browser.find_by_name('create').first create_button = browser.find_by_name('create').first
functional.submit(browser, element=create_button) functional.submit(browser, element=create_button)
def _get_count(browser): def _get_count(browser):
functional.visit(browser, '/plinth/sys/snapshot/manage/') functional.visit(browser, '/freedombox/sys/snapshot/manage/')
# Subtract 1 for table header # Subtract 1 for table header
return len(browser.find_by_xpath('//tr')) - 1 return len(browser.find_by_xpath('//tr')) - 1

View File

@ -1,11 +1,11 @@
<RequireALL> <RequireALL>
<IfModule mod_auth_pubtkt.c> <IfModule mod_auth_pubtkt.c>
TKTAuthPublicKey /etc/apache2/auth-pubtkt-keys/pubkey.pem TKTAuthPublicKey /etc/apache2/auth-pubtkt-keys/pubkey.pem
TKTAuthLoginURL /plinth/accounts/sso/login/ TKTAuthLoginURL /freedombox/accounts/sso/login/
TKTAuthBackArgName next TKTAuthBackArgName next
TKTAuthDigest SHA512 TKTAuthDigest SHA512
TKTAuthRefreshURL /plinth/accounts/sso/refresh/ TKTAuthRefreshURL /freedombox/accounts/sso/refresh/
TKTAuthUnauthURL /plinth TKTAuthUnauthURL /freedombox
AuthType mod_auth_pubtkt AuthType mod_auth_pubtkt
AuthName "FreedomBox Single Sign On" AuthName "FreedomBox Single Sign On"
Require valid-user Require valid-user

View File

@ -27,7 +27,7 @@ class TestTiddlyWikiApp(functional.BaseAppTests):
return return
session_browser.links.find_by_href( session_browser.links.find_by_href(
'/plinth/apps/tiddlywiki/create/').first.click() '/freedombox/apps/tiddlywiki/create/').first.click()
session_browser.find_by_id('id_tiddlywiki-name').fill(wiki_name) session_browser.find_by_id('id_tiddlywiki-name').fill(wiki_name)
functional.submit(session_browser, form_class='form-tiddlywiki') functional.submit(session_browser, form_class='form-tiddlywiki')
@ -74,8 +74,8 @@ class TestTiddlyWikiApp(functional.BaseAppTests):
new_wiki_name = 'A Midsummer Night\'s Dream' new_wiki_name = 'A Midsummer Night\'s Dream'
new_file_name = 'A_Midsummer_Nights_Dream.html' new_file_name = 'A_Midsummer_Nights_Dream.html'
self._get_links_in_app_page( self._get_links_in_app_page(
session_browser, session_browser, '/freedombox/apps/tiddlywiki/' + file_name +
'/plinth/apps/tiddlywiki/' + file_name + '/rename/').first.click() '/rename/').first.click()
session_browser.find_by_id('id_tiddlywiki-new_name').fill( session_browser.find_by_id('id_tiddlywiki-new_name').fill(
new_wiki_name) new_wiki_name)
functional.submit(session_browser, form_class='form-tiddlywiki') functional.submit(session_browser, form_class='form-tiddlywiki')
@ -89,7 +89,7 @@ class TestTiddlyWikiApp(functional.BaseAppTests):
test_wiki_file = str(_test_data_dir / 'dummy_wiki.html') test_wiki_file = str(_test_data_dir / 'dummy_wiki.html')
session_browser.links.find_by_href( session_browser.links.find_by_href(
'/plinth/apps/tiddlywiki/upload/').first.click() '/freedombox/apps/tiddlywiki/upload/').first.click()
session_browser.attach_file('tiddlywiki-file', test_wiki_file) session_browser.attach_file('tiddlywiki-file', test_wiki_file)
functional.submit(session_browser, form_class='form-tiddlywiki') functional.submit(session_browser, form_class='form-tiddlywiki')
@ -100,8 +100,8 @@ class TestTiddlyWikiApp(functional.BaseAppTests):
self._create_wiki_file(session_browser) self._create_wiki_file(session_browser)
self._get_links_in_app_page( self._get_links_in_app_page(
session_browser, session_browser, '/freedombox/apps/tiddlywiki/' + file_name +
'/plinth/apps/tiddlywiki/' + file_name + '/delete/').first.click() '/delete/').first.click()
functional.submit(session_browser, form_class='form-delete') functional.submit(session_browser, form_class='form-delete')
self._assert_wiki_present(session_browser, file_name, present=False) self._assert_wiki_present(session_browser, file_name, present=False)

View File

@ -303,7 +303,7 @@ def _should_not_connect_passwordless_over_ssh(session_browser,
def _rename_user(browser, old_name, new_name): def _rename_user(browser, old_name, new_name):
functional.nav_to_module(browser, 'users') functional.nav_to_module(browser, 'users')
functional.click_link_by_href(browser, functional.click_link_by_href(browser,
f'/plinth/sys/users/{old_name}/edit/') f'/freedombox/sys/users/{old_name}/edit/')
browser.find_by_id('id_username').fill(new_name) browser.find_by_id('id_username').fill(new_name)
browser.find_by_id('id_confirm_password').fill(_admin_password) browser.find_by_id('id_confirm_password').fill(_admin_password)
functional.submit(browser, form_class='form-update') functional.submit(browser, form_class='form-update')
@ -311,7 +311,8 @@ def _rename_user(browser, old_name, new_name):
def _set_email(browser, username, email): def _set_email(browser, username, email):
"""Set the email field value for a user.""" """Set the email field value for a user."""
functional.visit(browser, '/plinth/sys/users/{}/edit/'.format(username)) functional.visit(browser,
'/freedombox/sys/users/{}/edit/'.format(username))
browser.find_by_id('id_email').fill(email) browser.find_by_id('id_email').fill(email)
browser.find_by_id('id_confirm_password').fill(_admin_password) browser.find_by_id('id_confirm_password').fill(_admin_password)
functional.submit(browser, form_class='form-update') functional.submit(browser, form_class='form-update')
@ -319,7 +320,8 @@ def _set_email(browser, username, email):
def _get_email(browser, username): def _get_email(browser, username):
"""Return the email field value for a user.""" """Return the email field value for a user."""
functional.visit(browser, '/plinth/sys/users/{}/edit/'.format(username)) functional.visit(browser,
'/freedombox/sys/users/{}/edit/'.format(username))
return browser.find_by_id('id_email').value return browser.find_by_id('id_email').value
@ -330,13 +332,13 @@ def _check_language(browser, language_code):
def _get_ssh_keys(browser, username=None): def _get_ssh_keys(browser, username=None):
functional.visit(browser, '/plinth/') functional.visit(browser, '/freedombox/')
if username is None: if username is None:
browser.find_by_id('id_user_menu').click() browser.find_by_id('id_user_menu').click()
functional.click_and_wait(browser, functional.click_and_wait(browser,
browser.find_by_id('id_user_edit_menu')) browser.find_by_id('id_user_edit_menu'))
else: else:
functional.visit(browser, f'/plinth/sys/users/{username}/edit/') functional.visit(browser, f'/freedombox/sys/users/{username}/edit/')
return browser.find_by_id('id_ssh_keys').text return browser.find_by_id('id_ssh_keys').text
@ -346,7 +348,7 @@ def _set_ssh_keys(browser, ssh_keys, username=None):
functional.click_and_wait(browser, functional.click_and_wait(browser,
browser.find_by_id('id_user_edit_menu')) browser.find_by_id('id_user_edit_menu'))
else: else:
functional.visit(browser, f'/plinth/sys/users/{username}/edit/') functional.visit(browser, f'/freedombox/sys/users/{username}/edit/')
current_user = browser.find_by_id('id_user_menu_link').text current_user = browser.find_by_id('id_user_menu_link').text
auth_password = functional.get_password(current_user) auth_password = functional.get_password(current_user)
@ -358,7 +360,8 @@ def _set_ssh_keys(browser, ssh_keys, username=None):
def _set_user_status(browser, username, status): def _set_user_status(browser, username, status):
functional.visit(browser, '/plinth/sys/users/{}/edit/'.format(username)) functional.visit(browser,
'/freedombox/sys/users/{}/edit/'.format(username))
if status == 'inactive': if status == 'inactive':
browser.find_by_id('id_is_active').uncheck() browser.find_by_id('id_is_active').uncheck()
elif status == 'active': elif status == 'active':
@ -376,7 +379,8 @@ def _change_password(browser, new_password, current_password=None,
browser, browser.find_by_id('id_change_password_menu')) browser, browser.find_by_id('id_change_password_menu'))
else: else:
functional.visit( functional.visit(
browser, '/plinth/sys/users/{}/change_password/'.format(username)) browser,
'/freedombox/sys/users/{}/change_password/'.format(username))
current_user = browser.find_by_id('id_user_menu_link').text current_user = browser.find_by_id('id_user_menu_link').text
auth_password = current_password or functional.get_password(current_user) auth_password = current_password or functional.get_password(current_user)

View File

@ -44,7 +44,7 @@ class TestWireguardApp(functional.BaseAppTests):
def _get_client_href(key): def _get_client_href(key):
"""Return the href for client show page.""" """Return the href for client show page."""
key = urllib.parse.quote(urllib.parse.quote(key, safe='')) key = urllib.parse.quote(urllib.parse.quote(key, safe=''))
return f'/plinth/apps/wireguard/client/{key}/show/' return f'/freedombox/apps/wireguard/client/{key}/show/'
def _client_exists(self, browser, key): def _client_exists(self, browser, key):
"""Check whether a client key exists.""" """Check whether a client key exists."""

View File

@ -114,7 +114,7 @@ FILE_UPLOAD_HANDLERS = [
] ]
# Overridden based on the configuration key server_dir # Overridden based on the configuration key server_dir
FORCE_SCRIPT_NAME = '/plinth' FORCE_SCRIPT_NAME = '/freedombox'
# FreedomBox apps are appended to this list # FreedomBox apps are appended to this list
INSTALLED_APPS = [ INSTALLED_APPS = [
@ -190,7 +190,7 @@ SESSION_ENGINE = 'django.contrib.sessions.backends.file'
SESSION_FILE_PATH = '/var/lib/plinth/sessions' SESSION_FILE_PATH = '/var/lib/plinth/sessions'
# Overridden based on configuration key server_dir # Overridden based on configuration key server_dir
STATIC_URL = '/plinth/static/' STATIC_URL = '/freedombox/static/'
# STRONGHOLD_PUBLIC_URLS=(r'^captcha/', ) # STRONGHOLD_PUBLIC_URLS=(r'^captcha/', )

View File

@ -1,7 +1,7 @@
[Path] [Path]
file_root = %(parent_dir)s file_root = %(parent_dir)s
data_dir = %(file_root)s/data/var/lib/plinth data_dir = %(file_root)s/data/var/lib/plinth
server_dir = /plinth server_dir = /freedombox
doc_dir = %(file_root)s/doc doc_dir = %(file_root)s/doc
custom_static_dir = %(file_root)s/data/var/www/plinth/custom/static custom_static_dir = %(file_root)s/data/var/www/plinth/custom/static
store_file = %(data_dir)s/plinth.sqlite3 store_file = %(data_dir)s/plinth.sqlite3

View File

@ -1,7 +1,7 @@
{"shortcuts": [{ {"shortcuts": [{
"name": "NextCloud", "name": "NextCloud",
"description": [ "Nextcloud is a suite of client-server software for creating and using file hosting services." ], "description": [ "Nextcloud is a suite of client-server software for creating and using file hosting services." ],
"icon_url": "/plinth/custom/static/themes/default/icons/nextcloud.png", "icon_url": "/freedombox/custom/static/themes/default/icons/nextcloud.png",
"clients": [{ "clients": [{
"name": "nextcloud", "name": "nextcloud",
"platforms": [{ "platforms": [{

View File

@ -1,7 +1,7 @@
{"shortcuts": [{ {"shortcuts": [{
"name": "NextCloud2", "name": "NextCloud2",
"description": [ "Nextcloud is a suite of client-server software for creating and using file hosting services." ], "description": [ "Nextcloud is a suite of client-server software for creating and using file hosting services." ],
"icon_url": "/plinth/custom/static/themes/default/icons/nextcloud.png", "icon_url": "/freedombox/custom/static/themes/default/icons/nextcloud.png",
"clients": [{ "clients": [{
"name": "nextcloud", "name": "nextcloud",
"platforms": [{ "platforms": [{

View File

@ -1,7 +1,7 @@
{"shortcuts": [{ {"shortcuts": [{
"name": "NextCloud", "name": "NextCloud",
"description": [ "Nextcloud is a suite of client-server software for creating and using file hosting services." ], "description": [ "Nextcloud is a suite of client-server software for creating and using file hosting services." ],
"icon_url": "/plinth/custom/static/themes/default/icons/nextcloud.png", "icon_url": "/freedombox/custom/static/themes/default/icons/nextcloud.png",
"clients": [{ "clients": [{
"name": "nextcloud", "name": "nextcloud",
"platforms": [{ "platforms": [{

View File

@ -48,7 +48,7 @@ base_url = config['DEFAULT']['url']
# unlisted sites just use '/' + site_name as url # unlisted sites just use '/' + site_name as url
_site_url = { _site_url = {
'wiki': '/ikiwiki', 'wiki': '/ikiwiki',
'jsxc': '/plinth/apps/jsxc/jsxc/', 'jsxc': '/freedombox/apps/jsxc/jsxc/',
'cockpit': '/_cockpit/', 'cockpit': '/_cockpit/',
'syncthing': '/syncthing/', 'syncthing': '/syncthing/',
'rssbridge': '/rss-bridge/', 'rssbridge': '/rss-bridge/',
@ -377,7 +377,7 @@ def _run_first_wizard(browser):
username = config['DEFAULT']['username'], username = config['DEFAULT']['username'],
password = config['DEFAULT']['password'] password = config['DEFAULT']['password']
welcome_url = base_url + '/plinth/firstboot/welcome/' welcome_url = base_url + '/freedombox/firstboot/welcome/'
browser.visit(welcome_url) browser.visit(welcome_url)
if browser.url != welcome_url: if browser.url != welcome_url:
# We got redirected because first wizard is already complete. Don't # We got redirected because first wizard is already complete. Don't
@ -398,7 +398,7 @@ def login_with_account(browser, url, username, password=None):
if password is None: if password is None:
password = get_password(username) password = get_password(username)
# XXX: Find a way to remove the hardcoded jsxc URL # XXX: Find a way to remove the hardcoded jsxc URL
if '/plinth/' not in browser.url or '/jsxc/jsxc' in browser.url: if '/freedombox/' not in browser.url or '/jsxc/jsxc' in browser.url:
browser.visit(url) browser.visit(url)
user_menu = browser.find_by_id('id_user_menu') user_menu = browser.find_by_id('id_user_menu')
@ -409,7 +409,7 @@ def login_with_account(browser, url, username, password=None):
logout(browser) logout(browser)
login_button = browser.links.find_by_href('/plinth/accounts/login/') login_button = browser.links.find_by_href('/freedombox/accounts/login/')
if login_button: if login_button:
click_and_wait(browser, login_button.first) click_and_wait(browser, login_button.first)
browser.fill('username', username) browser.fill('username', username)
@ -423,7 +423,7 @@ def logout(browser):
"""Log out of the FreedomBox interface.""" """Log out of the FreedomBox interface."""
# Navigate to the home page if logout form is not found # Navigate to the home page if logout form is not found
if not browser.find_by_css('.form-logout'): if not browser.find_by_css('.form-logout'):
visit(browser, '/plinth/') visit(browser, '/freedombox/')
# We are not logged in if the home page does not contain logout form # We are not logged in if the home page does not contain logout form
if browser.find_by_css('.form-logout'): if browser.find_by_css('.form-logout'):
@ -436,13 +436,13 @@ def logout(browser):
################# #################
def nav_to_module(browser, module): def nav_to_module(browser, module):
sys_or_apps = 'sys' if module in _sys_modules else 'apps' sys_or_apps = 'sys' if module in _sys_modules else 'apps'
required_url = base_url + f'/plinth/{sys_or_apps}/{module}/' required_url = base_url + f'/freedombox/{sys_or_apps}/{module}/'
if browser.url != required_url: if browser.url != required_url:
browser.visit(required_url) browser.visit(required_url)
def app_select_domain_name(browser, app_name, domain_name): def app_select_domain_name(browser, app_name, domain_name):
browser.visit('{}/plinth/apps/{}/setup/'.format(base_url, app_name)) browser.visit('{}/freedombox/apps/{}/setup/'.format(base_url, app_name))
drop_down = browser.find_by_id('id_domain_name') drop_down = browser.find_by_id('id_domain_name')
drop_down.select(domain_name) drop_down.select(domain_name)
submit(browser, form_class='form-configuration') submit(browser, form_class='form-configuration')
@ -603,7 +603,7 @@ def running_inside_container():
############################# #############################
def set_hostname(browser, hostname: str): def set_hostname(browser, hostname: str):
"""Configure the system hostname.""" """Configure the system hostname."""
visit(browser, '/plinth/sys/names/hostname/') visit(browser, '/freedombox/sys/names/hostname/')
browser.find_by_id('id_hostname-hostname').fill(hostname) browser.find_by_id('id_hostname-hostname').fill(hostname)
submit(browser, form_class='form-hostname') submit(browser, form_class='form-hostname')
@ -613,8 +613,8 @@ def domain_add(browser, domain_name: str):
if domain_name in domain_list(browser): if domain_name in domain_list(browser):
return return
visit(browser, '/plinth/sys/names/') visit(browser, '/freedombox/sys/names/')
click_link_by_href(browser, '/plinth/sys/names/domains/') click_link_by_href(browser, '/freedombox/sys/names/domains/')
browser.find_by_id('id_domain-add-domain_name').fill(domain_name) browser.find_by_id('id_domain-add-domain_name').fill(domain_name)
submit(browser, form_class='form-domain-add') submit(browser, form_class='form-domain-add')
@ -624,15 +624,15 @@ def domain_remove(browser, domain_name: str):
if domain_name not in domain_list(browser): if domain_name not in domain_list(browser):
return return
visit(browser, '/plinth/sys/names/') visit(browser, '/freedombox/sys/names/')
click_link_by_href(browser, click_link_by_href(browser,
f'/plinth/sys/names/domains/{domain_name}/delete/') f'/freedombox/sys/names/domains/{domain_name}/delete/')
submit(browser, form_class='form-delete') submit(browser, form_class='form-delete')
def domain_list(browser) -> list[str]: def domain_list(browser) -> list[str]:
"""Return a list of domains configured.""" """Return a list of domains configured."""
visit(browser, '/plinth/sys/names/') visit(browser, '/freedombox/sys/names/')
elements = browser.find_by_css('td.names-domain-column') elements = browser.find_by_css('td.names-domain-column')
return [element.text for element in elements] return [element.text for element in elements]
@ -659,12 +659,12 @@ def _click_button_and_confirm(browser, href, form_class):
if buttons: if buttons:
submit(browser, element=buttons.first) submit(browser, element=buttons.first)
submit(browser, form_class=form_class, submit(browser, form_class=form_class,
expected_url='/plinth/sys/backups/') expected_url='/freedombox/sys/backups/')
def _backup_delete_archive_by_name(browser, archive_name): def _backup_delete_archive_by_name(browser, archive_name):
nav_to_module(browser, 'backups') nav_to_module(browser, 'backups')
href = f'/plinth/sys/backups/root/delete/{archive_name}/' href = f'/freedombox/sys/backups/root/delete/{archive_name}/'
_click_button_and_confirm(browser, href, 'form-delete') _click_button_and_confirm(browser, href, 'form-delete')
@ -674,7 +674,7 @@ def backup_create(browser, app_name, archive_name=None):
if archive_name: if archive_name:
_backup_delete_archive_by_name(browser, archive_name) _backup_delete_archive_by_name(browser, archive_name)
buttons = browser.links.find_by_href('/plinth/sys/backups/create/') buttons = browser.links.find_by_href('/freedombox/sys/backups/create/')
submit(browser, element=buttons.first) submit(browser, element=buttons.first)
eventually(browser.find_by_css, args=['.select-all']) eventually(browser.find_by_css, args=['.select-all'])
browser.find_by_css('.select-all').first.uncheck() browser.find_by_css('.select-all').first.uncheck()
@ -690,7 +690,7 @@ def backup_create(browser, app_name, archive_name=None):
def backup_restore(browser, app_name, archive_name=None): def backup_restore(browser, app_name, archive_name=None):
"""Restore a given app from a backup archive.""" """Restore a given app from a backup archive."""
nav_to_module(browser, 'backups') nav_to_module(browser, 'backups')
href = f'/plinth/sys/backups/root/restore-archive/{archive_name}/' href = f'/freedombox/sys/backups/root/restore-archive/{archive_name}/'
_click_button_and_confirm(browser, href, 'form-restore') _click_button_and_confirm(browser, href, 'form-restore')
@ -708,7 +708,7 @@ def networks_set_firewall_zone(browser, zone):
'and contains(@class, "connection-status-label")]/following::a').first 'and contains(@class, "connection-status-label")]/following::a').first
network_id = device['href'].split('/')[-3] network_id = device['href'].split('/')[-3]
device.click() device.click()
edit_url = '/plinth/sys/networks/{}/edit/'.format(network_id) edit_url = '/freedombox/sys/networks/{}/edit/'.format(network_id)
click_link_by_href(browser, edit_url) click_link_by_href(browser, edit_url)
browser.select('zone', zone) browser.select('zone', zone)
submit(browser, form_class='form-connection-edit') submit(browser, form_class='form-connection-edit')
@ -742,7 +742,7 @@ def create_user(browser, name, password=None, groups=[], email=None):
if password is None: if password is None:
password = get_password(name) password = get_password(name)
click_link_by_href(browser, '/plinth/sys/users/create/') click_link_by_href(browser, '/freedombox/sys/users/create/')
browser.find_by_id('id_username').fill(name) browser.find_by_id('id_username').fill(name)
browser.find_by_id('id_password1').fill(password) browser.find_by_id('id_password1').fill(password)
@ -763,7 +763,7 @@ def create_user(browser, name, password=None, groups=[], email=None):
def delete_user(browser, name): def delete_user(browser, name):
"""Delete a user.""" """Delete a user."""
nav_to_module(browser, 'users') nav_to_module(browser, 'users')
click_link_by_href(browser, f'/plinth/sys/users/{name}/edit/') click_link_by_href(browser, f'/freedombox/sys/users/{name}/edit/')
browser.find_by_id('id_delete').check() browser.find_by_id('id_delete').check()
browser.find_by_id('id_confirm_password').fill( browser.find_by_id('id_confirm_password').fill(
@ -775,13 +775,14 @@ def delete_user(browser, name):
'#user-delete-confirm-dialog button.confirm').first '#user-delete-confirm-dialog button.confirm').first
eventually(lambda: confirm_button.visible) eventually(lambda: confirm_button.visible)
assert confirm_button.visible assert confirm_button.visible
click_and_wait(browser, confirm_button, expected_url='/plinth/sys/users/') click_and_wait(browser, confirm_button,
expected_url='/freedombox/sys/users/')
def user_exists(browser, name): def user_exists(browser, name):
"""Check if a user with a given name exists.""" """Check if a user with a given name exists."""
nav_to_module(browser, 'users') nav_to_module(browser, 'users')
links = browser.links.find_by_href(f'/plinth/sys/users/{name}/edit/') links = browser.links.find_by_href(f'/freedombox/sys/users/{name}/edit/')
return len(links) == 1 return len(links) == 1
@ -789,7 +790,7 @@ def user_set_language(browser, language_code):
"""Change user's preferred UI language.""" """Change user's preferred UI language."""
username = config['DEFAULT']['username'] username = config['DEFAULT']['username']
admin_password = config['DEFAULT']['password'] admin_password = config['DEFAULT']['password']
visit(browser, '/plinth/sys/users/{}/edit/'.format(username)) visit(browser, '/freedombox/sys/users/{}/edit/'.format(username))
browser.find_by_xpath('//select[@id="id_language"]//option[@value="' + browser.find_by_xpath('//select[@id="id_language"]//option[@value="' +
language_code + '"]').first.click() language_code + '"]').first.click()
browser.find_by_id('id_confirm_password').fill(admin_password) browser.find_by_id('id_confirm_password').fill(admin_password)

View File

@ -13,14 +13,14 @@ pytestmark = [pytest.mark.tags]
def _is_app_listed(session_browser, app): def _is_app_listed(session_browser, app):
"""Assert that the specified app is listed on the page.""" """Assert that the specified app is listed on the page."""
app_links = session_browser.links.find_by_href(f'/plinth/apps/{app}/') app_links = session_browser.links.find_by_href(f'/freedombox/apps/{app}/')
assert len(app_links) == 1 assert len(app_links) == 1
@pytest.fixture(name='bittorrent_tag') @pytest.fixture(name='bittorrent_tag')
def fixture_bittorrent_tag(session_browser): def fixture_bittorrent_tag(session_browser):
"""Click on the BitTorrent tag.""" """Click on the BitTorrent tag."""
bittorrent_tag = '/plinth/apps/?tag=BitTorrent' bittorrent_tag = '/freedombox/apps/?tag=BitTorrent'
functional.login(session_browser) functional.login(session_browser)
functional.nav_to_module(session_browser, 'transmission') functional.nav_to_module(session_browser, 'transmission')
with functional.wait_for_page_update(session_browser, timeout=10, with functional.wait_for_page_update(session_browser, timeout=10,
@ -50,7 +50,7 @@ def test_search_for_tag(session_browser, bittorrent_tag):
search_input = session_browser.find_by_id('add-tag-input').first search_input = session_browser.find_by_id('add-tag-input').first
with functional.wait_for_page_update( with functional.wait_for_page_update(
session_browser, timeout=10, session_browser, timeout=10,
expected_url='/plinth/apps/?tag=BitTorrent&tag=File+sharing'): expected_url='/freedombox/apps/?tag=BitTorrent&tag=File+sharing'):
search_input.click() search_input.click()
search_input.type('file sharing') search_input.type('file sharing')
search_input.type(Keys.ENTER) search_input.type(Keys.ENTER)
@ -64,7 +64,7 @@ def test_click_on_tag(session_browser, bittorrent_tag):
search_input = session_browser.find_by_id('add-tag-input').first search_input = session_browser.find_by_id('add-tag-input').first
with functional.wait_for_page_update( with functional.wait_for_page_update(
session_browser, timeout=10, session_browser, timeout=10,
expected_url='/plinth/apps/?tag=BitTorrent&tag=File+sync'): expected_url='/freedombox/apps/?tag=BitTorrent&tag=File+sync'):
search_input.click() search_input.click()
session_browser.find_by_css( session_browser.find_by_css(
".dropdown-item[data-tag='File sync']").click() ".dropdown-item[data-tag='File sync']").click()
@ -75,14 +75,14 @@ def test_click_on_tag(session_browser, bittorrent_tag):
def test_tag_localization(session_browser, locale): def test_tag_localization(session_browser, locale):
"""Test that tags are localized and tests in done localized.""" """Test that tags are localized and tests in done localized."""
functional.visit(session_browser, '/plinth/apps/?tag=Sharing') functional.visit(session_browser, '/freedombox/apps/?tag=Sharing')
badge = session_browser.find_by_css('.tag[data-tag="Sharing"]').first badge = session_browser.find_by_css('.tag[data-tag="Sharing"]').first
assert 'Compartir' in badge.text assert 'Compartir' in badge.text
search_input = session_browser.find_by_id('add-tag-input').first search_input = session_browser.find_by_id('add-tag-input').first
with functional.wait_for_page_update( with functional.wait_for_page_update(
session_browser, timeout=10, session_browser, timeout=10,
expected_url='/plinth/apps/?tag=Sharing&tag=Bookmarks'): expected_url='/freedombox/apps/?tag=Sharing&tag=Bookmarks'):
search_input.click() search_input.click()
search_input.type('Marcadores') search_input.type('Marcadores')
search_input.type(Keys.ENTER) search_input.type(Keys.ENTER)

View File

@ -63,7 +63,7 @@ class TestSetupMiddleware:
@patch('django.urls.reverse', return_value='users:login') @patch('django.urls.reverse', return_value='users:login')
def test_404_urls(reverse, middleware, kwargs): def test_404_urls(reverse, middleware, kwargs):
"""Test how middleware deals with 404 URLs.""" """Test how middleware deals with 404 URLs."""
request = RequestFactory().get('/plinth/non-existing-url') request = RequestFactory().get('/freedombox/non-existing-url')
response = middleware.process_view(request, **kwargs) response = middleware.process_view(request, **kwargs)
assert response is None assert response is None
@ -71,7 +71,7 @@ class TestSetupMiddleware:
@patch('django.urls.reverse', return_value='users:login') @patch('django.urls.reverse', return_value='users:login')
def test_url_not_an_application(reverse, middleware, kwargs): def test_url_not_an_application(reverse, middleware, kwargs):
"""Test that none is returned for URLs that are not applications.""" """Test that none is returned for URLs that are not applications."""
request = RequestFactory().get('/plinth/') request = RequestFactory().get('/freedombox/')
response = middleware.process_view(request, **kwargs) response = middleware.process_view(request, **kwargs)
assert response is None assert response is None
@ -83,7 +83,7 @@ class TestSetupMiddleware:
resolve.return_value.namespaces = ['mockapp'] resolve.return_value.namespaces = ['mockapp']
app.get_setup_state = lambda: app_module.App.SetupState.UP_TO_DATE app.get_setup_state = lambda: app_module.App.SetupState.UP_TO_DATE
request = RequestFactory().get('/plinth/mockapp') request = RequestFactory().get('/freedombox/mockapp')
request.user = AnonymousUser() request.user = AnonymousUser()
response = middleware.process_view(request, **kwargs) response = middleware.process_view(request, **kwargs)
assert response is None assert response is None
@ -99,7 +99,7 @@ class TestSetupMiddleware:
resolve.return_value.namespaces = ['mockapp'] resolve.return_value.namespaces = ['mockapp']
view = Mock() view = Mock()
setup_view.as_view.return_value = view setup_view.as_view.return_value = view
request = RequestFactory().get('/plinth/mockapp') request = RequestFactory().get('/freedombox/mockapp')
request.session = MagicMock() request.session = MagicMock()
# Verify that anonymous users cannot access the setup page # Verify that anonymous users cannot access the setup page
@ -152,7 +152,7 @@ class TestSetupMiddleware:
app.get_setup_state = lambda: app_module.App.SetupState.UP_TO_DATE app.get_setup_state = lambda: app_module.App.SetupState.UP_TO_DATE
# Admin user can collect result # Admin user can collect result
request = RequestFactory().get('/plinth/mockapp') request = RequestFactory().get('/freedombox/mockapp')
request.resolver_match = Mock() request.resolver_match = Mock()
user = User(username='adminuser') user = User(username='adminuser')
user.save() user.save()
@ -175,7 +175,7 @@ class TestSetupMiddleware:
messages_success.reset_mock() messages_success.reset_mock()
messages_error.reset_mock() messages_error.reset_mock()
operation_manager.collect_results.reset_mock() operation_manager.collect_results.reset_mock()
request = RequestFactory().get('/plinth/mockapp') request = RequestFactory().get('/freedombox/mockapp')
user = User(username='johndoe') user = User(username='johndoe')
user.save() user.save()
request.user = user request.user = user
@ -201,7 +201,7 @@ class TestAdminMiddleware:
@pytest.fixture(name='web_request') @pytest.fixture(name='web_request')
def fixture_web_request(): def fixture_web_request():
"""Fixture for returning kwargs.""" """Fixture for returning kwargs."""
web_request = RequestFactory().get('/plinth/mockapp') web_request = RequestFactory().get('/freedombox/mockapp')
web_request.user = Mock() web_request.user = Mock()
return web_request return web_request

View File

@ -337,7 +337,7 @@ def test_list_filter_user_and_group(note, user):
@patch('plinth.notification.gettext') @patch('plinth.notification.gettext')
def test_display_context(gettext, note, user, rf): def test_display_context(gettext, note, user, rf):
"""Test display context for a notification.""" """Test display context for a notification."""
request = rf.get('/plinth/help/about/') request = rf.get('/freedombox/help/about/')
data = { data = {
'test-key1': 'test-value1', 'test-key1': 'test-value1',
@ -396,7 +396,7 @@ def test_display_context(gettext, note, user, rf):
def test_display_context_body_template(note, user, load_cfg, rf): def test_display_context_body_template(note, user, load_cfg, rf):
"""Test display context for a notification with body template.""" """Test display context for a notification with body template."""
request = rf.get('/plinth/help/about/') request = rf.get('/freedombox/help/about/')
note.body_template = 'invalid-template.html' note.body_template = 'invalid-template.html'
note.save() note.save()
@ -412,7 +412,7 @@ def test_display_context_body_template(note, user, load_cfg, rf):
context = Notification.get_display_context(request, user) context = Notification.get_display_context(request, user)
context_note = context['notifications'][0] context_note = context['notifications'][0]
assert context_note['body'].content == \ assert context_note['body'].content == \
b'Test notification body /plinth/help/about/\n' b'Test notification body /freedombox/help/about/\n'
@pytest.mark.django_db @pytest.mark.django_db

View File

@ -36,7 +36,7 @@ class TestIsAdminUser:
@pytest.fixture(name='web_request') @pytest.fixture(name='web_request')
def fixture_web_request(): def fixture_web_request():
"""Setup each test case before execution.""" """Setup each test case before execution."""
web_request = RequestFactory().get('/plinth/mockapp') web_request = RequestFactory().get('/freedombox/mockapp')
web_request.user = Mock() web_request.user = Mock()
web_request.session = MagicMock() web_request.session = MagicMock()
return web_request return web_request

View File

@ -57,7 +57,7 @@ def test_get_breadcrumbs(rf, test_menu):
@pytest.mark.parametrize('url', [ @pytest.mark.parametrize('url', [
'/plinth/login/', '/freedombox/login/',
'/', '/',
'safe', 'safe',
]) ])
@ -71,11 +71,11 @@ def test_is_safe_url_valid_url(url):
[ [
'', '',
None, None,
'\\plinth', '\\freedombox',
'///plinth', '///freedombox',
'https://example.com/plinth/login/', 'https://example.com/freedombox/login/',
'https:///example.com', 'https:///example.com',
'https:///plinth/login', 'https:///freedombox/login',
'ftp://example.com', 'ftp://example.com',
'https://[aabb::ccdd', # Invalid IPv6 'https://[aabb::ccdd', # Invalid IPv6
]) ])

View File

@ -44,7 +44,7 @@ def test_static_files_mount(mount, load_cfg):
calls = [ calls = [
call( call(
None, '/plinth/a', { None, '/freedombox/a', {
'/': { '/': {
'tools.staticdir.root': '/b', 'tools.staticdir.root': '/b',
'tools.staticdir.on': True, 'tools.staticdir.on': True,
@ -52,7 +52,7 @@ def test_static_files_mount(mount, load_cfg):
} }
}), }),
call( call(
None, '/plinth/c', { None, '/freedombox/c', {
'/': { '/': {
'tools.staticdir.root': '/d', 'tools.staticdir.root': '/d',
'tools.staticdir.on': True, 'tools.staticdir.on': True,

View File

@ -162,8 +162,8 @@ class StaticFiles(app_module.FollowerComponent):
static files from the directory are served over the given web path. The static files from the directory are served over the given web path. The
web path will be prepended with the FreedomBox's configured base web web path will be prepended with the FreedomBox's configured base web
path. For example, {'/foo': '/usr/share/foo'} means that path. For example, {'/foo': '/usr/share/foo'} means that
'/usr/share/foo/bar.png' will be served over '/plinth/foo/bar.png' if '/usr/share/foo/bar.png' will be served over '/freedombox/foo/bar.png'
FreedomBox is configured to be served on '/plinth'. if FreedomBox is configured to be served on '/freedombox'.
""" """
super().__init__(component_id) super().__init__(component_id)

View File

@ -26,7 +26,7 @@
twitter-bootstap3</a></td> twitter-bootstap3</a></td>
</tr> </tr>
<tr> <tr>
<td><a href="/plinth/static/jsxc/jsxc-plinth.js">jsxc-plinth.js</a></td> <td><a href="/freedombox/static/jsxc/jsxc-plinth.js">jsxc-plinth.js</a></td>
<td> <td>
<a href="http://www.gnu.org/licenses/agpl-3.0.html"> <a href="http://www.gnu.org/licenses/agpl-3.0.html">
GNU Affero General Public License, version 3 or later</a> GNU Affero General Public License, version 3 or later</a>

View File

@ -227,7 +227,7 @@ document.addEventListener('DOMContentLoaded', async () => {
try { try {
setInstallButtonState(false); setInstallButtonState(false);
const response = await fetch(`/plinth/is-available/${appId}/`, { const response = await fetch(`/freedombox/is-available/${appId}/`, {
timeout: 2 * 60 * 1000 // 2 minutes timeout: 2 * 60 * 1000 // 2 minutes
}); });