*: 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:
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
HACKING.md instead.

View File

@ -230,7 +230,7 @@ provision-dev:
sshpass bash-completion
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' | \
tr -d '[:space:]' | cut -d':' -f2 ) != 'xfalse' ] ; do \
sleep 1; echo -n .; done

2
Vagrantfile vendored
View File

@ -28,7 +28,7 @@ Vagrant.configure(2) do |config|
SHELL
config.vm.provision "tests", run: "never", type: "shell", path: "plinth/tests/functional/install.sh"
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:
$ vagrant ssh
$ sudo freedombox-logs

View File

@ -39,16 +39,16 @@
</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
## other services.
##
<IfFile !/etc/apache2/conf-enabled/freedombox-apache-homepage.conf>
RedirectMatch "^/$" "/plinth"
RedirectMatch "^/$" "/freedombox"
</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:
## mod_headers
@ -56,7 +56,7 @@
## mod_proxy_http
##
<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
## URLs, set cookies, set absolute URLs (if any) properly.
RequestHeader set X-Forwarded-Proto 'https' env=HTTPS
@ -70,7 +70,7 @@
RequestHeader unset X-Forwarded-For
</Location>
<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 unset X-Forwarded-For
</Location>
@ -82,7 +82,7 @@
<Location ~ ^/favicon\.ico$>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule /favicon\.ico$ "/plinth/static/theme/img/favicon.ico" [PT]
RewriteRule /favicon\.ico$ "/freedombox/static/theme/img/favicon.ico" [PT]
</IfModule>
</Location>

View File

@ -73,8 +73,8 @@
<para>
This the URL fragment under which Plinth will provide its services.
Plinth is shipped with a default value of
<filename>/plinth</filename>. This means that Plinth will be
available as http://localhost:8000/plinth by default.
<filename>/freedombox</filename>. This means that Plinth will be
available as http://localhost:8000/freedombox by default.
</para>
</listitem>
</varlistentry>
@ -194,7 +194,7 @@
<synopsis>$ plinth --server_dir='/myurl'</synopsis>
<para>
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.
</para>
</example>

View File

@ -13,7 +13,7 @@ from pathlib import Path
from xml.sax.saxutils import escape
BASE_URL = 'https://wiki.debian.org/'
LOCAL_BASE = '/plinth/help/manual/{lang}/'
LOCAL_BASE = '/freedombox/help/manual/{lang}/'
ICONS_DIR = 'icons'
DEFAULT_LANGUAGE = 'en'
@ -624,21 +624,21 @@ def resolve_url(url, context):
Locally available page in default language => shortcut to local copy:
>>> resolve_url('FreedomBox/Contribute', {'language': '', 'title': ''})
'/plinth/help/manual/en/Contribute#'
'/freedombox/help/manual/en/Contribute#'
Translated available page => shortcut to local copy:
>>> 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
local copy:
>>> 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:
>>> resolve_url('missing/FreedomBox/Contribute', {'language': '', \
'title': ''})
'/plinth/help/manual/en/Contribute#'
'/freedombox/help/manual/en/Contribute#'
"""
# Process first all easy, straight forward cases:
@ -1191,11 +1191,11 @@ from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>')
[Paragraph([PlainText('a')]), Paragraph([PlainText('b ')])]
>>> 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 \
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}}}')
[Admonition('caution', [Paragraph([PlainText('Once some other app is set \
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 \
to /plinth ')])])]
@ -1761,7 +1761,7 @@ Features introduction</ulink>'
>>> generate_inner_docbook([Link('../../Contribute', \
[PlainText('Contribute')])], context={'title': 'FreedomBox/Manual/Hardware'})
'<ulink url="/plinth/help/manual/en/Contribute#">\
'<ulink url="/freedombox/help/manual/en/Contribute#">\
Contribute</ulink>'
>>> generate_inner_docbook([Link('/Code', \
@ -1772,9 +1772,9 @@ Code</ulink>'
>>> generate_inner_docbook([Link('DebianBug:1234', [PlainText('Bug')])])
'<ulink url="https://bugs.debian.org/1234#">Bug</ulink>'
>>> generate_inner_docbook([Link('DebianPkg:plinth', \
>>> generate_inner_docbook([Link('DebianPkg:freedombox', \
[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', \
[PlainText('Discuss')])])
@ -1911,7 +1911,7 @@ PlainText(' on it. ')])])
'<para>An alternative to downloading these images is to \
<ulink url="https://wiki.debian.org/InstallingDebianOn/TI/BeagleBone#">\
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>'
>>> 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'
store_file = data_dir + '/plinth.sqlite3'
doc_dir = '/usr/share/freedombox'
server_dir = '/plinth'
server_dir = '/freedombox'
# [Network] section
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):
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):
@ -126,7 +127,7 @@ def _backup_schedule_get(browser):
functional.nav_to_module(browser, 'backups')
with functional.wait_for_page_update(browser):
browser.links.find_by_href(
'/plinth/sys/backups/root/schedule/').first.click()
'/freedombox/sys/backups/root/schedule/').first.click()
without_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')
with functional.wait_for_page_update(browser):
browser.links.find_by_href(
'/plinth/sys/backups/root/schedule/').first.click()
'/freedombox/sys/backups/root/schedule/').first.click()
if enable:
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):
"""Download a backup archive to a temporary file on disk."""
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
file_path = _download_file_logged_in(browser, url, suffix='.tar.gz')
return file_path
@ -201,22 +202,23 @@ def _download(browser, archive_name=None):
def _open_main_page(browser):
"""Open the FreedomBox interface main page."""
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):
"""Upload a backup archive from the disk and perform restore operation."""
functional.nav_to_module(browser, 'backups')
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.fill(downloaded_file_path)
# submit upload form
functional.submit(browser, form_class='form-upload')
# submit restore form
with functional.wait_for_page_update(browser,
expected_url='/plinth/sys/backups/'):
with functional.wait_for_page_update(
browser, expected_url='/freedombox/sys/backups/'):
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)
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)
password = functional.get_password(
functional.config['DEFAULT']['username'])

View File

@ -68,7 +68,7 @@ def _set_default_permissions(browser, permissions=''):
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']:
browser.find_by_css('#id_bepasty-permissions input[value="{}"]'.format(
permission)).check()

View File

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

View File

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

View File

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

View File

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

View File

@ -22,12 +22,12 @@ def test_change_home_page(session_browser):
functional.app_enable(session_browser, 'syncthing')
_set_home_page(session_browser, 'syncthing')
_set_home_page(session_browser, 'plinth')
assert _check_home_page_redirect(session_browser, 'plinth')
_set_home_page(session_browser, 'freedombox')
assert _check_home_page_redirect(session_browser, 'freedombox')
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
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):
functional.visit(browser, '/')
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.append(diagnose_port_listening(8000, 'tcp4'))
results.extend(
diagnose_url_on_all('http://{host}/plinth/',
diagnose_url_on_all('http://{host}/freedombox/',
check_certificate=False))
return results

View File

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

View File

@ -118,7 +118,7 @@ def _jsxc_login(browser):
"""Login to JSXC."""
username = functional.config['DEFAULT']['username']
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,
['BOSH Server reachable.'])
if browser.find_by_text('relogin'):

View File

@ -38,7 +38,7 @@ _description = [
'they can add aliases to their email address. Necessary aliases '
'such as "postmaster" are automatically created pointing to the '
'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.'),
_('During installation, any other email servers in the system will be '
'uninstalled.')

View File

@ -25,12 +25,12 @@
<Location "/.well-known/autoconfig/mail/config-v1.1.xml">
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^ /plinth/apps/email/config.xml [PT]
RewriteRule ^ /freedombox/apps/email/config.xml [PT]
</IfModule>
</Location>
# 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.
<Location "/roundcube/">
ErrorDocument 404 /plinth/apps/roundcube/
ErrorDocument 404 /freedombox/apps/roundcube/
</Location>

View File

@ -27,7 +27,7 @@ class TestFeatherWikiApp(functional.BaseAppTests):
return
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)
functional.submit(session_browser, form_class='form-featherwiki')
@ -73,7 +73,7 @@ class TestFeatherWikiApp(functional.BaseAppTests):
new_course = 'A Midsummer Night\'s Dream'
new_file_name = 'A_Midsummer_Nights_Dream.html'
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()
session_browser.find_by_id('id_featherwiki-new_name').fill(new_course)
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')
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)
functional.submit(session_browser, form_class='form-featherwiki')
@ -98,7 +98,7 @@ class TestFeatherWikiApp(functional.BaseAppTests):
self._create_wiki_file(session_browser)
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()
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."""
if not _repo_exists(browser, repo, access):
_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)
if access == 'private':
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'):
repo = repo[:-4]
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:
delete_link.first.click()
functional.submit(browser, form_class='form-delete')
@ -192,7 +193,7 @@ def _edit_repo_metadata(browser, repo, metadata):
"""Set repository metadata."""
functional.nav_to_module(browser, 'gitweb')
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-description').fill(metadata['description'])
browser.find_by_id('id_gitweb-owner').fill(metadata['owner'])
@ -214,7 +215,7 @@ def _get_repo_metadata(browser, repo):
"""Get repository metadata."""
functional.nav_to_module(browser, 'gitweb')
browser.links.find_by_href(
'/plinth/apps/gitweb/{}/edit/'.format(repo)).first.click()
'/freedombox/apps/gitweb/{}/edit/'.format(repo)).first.click()
metadata = {}
for item in ['name', 'description', 'owner']:
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."""
functional.nav_to_module(browser, 'gitweb')
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)
functional.submit(browser, form_class='form-gitweb')
@ -327,7 +328,7 @@ def _set_repo_access(browser, repo, access):
"""Set repository as public or private."""
functional.nav_to_module(browser, 'gitweb')
browser.links.find_by_href(
'/plinth/apps/gitweb/{}/edit/'.format(repo)).first.click()
'/freedombox/apps/gitweb/{}/edit/'.format(repo)).first.click()
if access == 'private':
browser.find_by_id('id_gitweb-is_private').check()
else:

View File

@ -34,7 +34,7 @@ def _create_wiki_if_needed(browser):
wiki = browser.links.find_by_href('/ikiwiki/wiki')
if not wiki:
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-admin_name').fill(
functional.config['DEFAULT']['username'])
@ -47,7 +47,7 @@ def _delete_wiki(browser):
"""Delete wiki."""
functional.nav_to_module(browser, 'ikiwiki')
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')

View File

@ -74,7 +74,8 @@ class TestKiwixApp(functional.BaseAppTests):
def _add_package(browser, file_name):
"""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)
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."""
functional.nav_to_module(browser, 'kiwix')
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:
raise ValueError('ZIM file missing!')

View File

@ -59,7 +59,8 @@ class TestMinifluxApp(functional.BaseAppTests):
def _fill_credentials_form(browser, href):
"""Fill the user credentials form in Miniflux app."""
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-password', CREDENTIALS['password'])

View File

@ -24,7 +24,7 @@ def test_change_hostname(session_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

View File

@ -32,7 +32,7 @@
{% blocktrans trimmed %}
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
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 %}
</p>

View File

@ -4,6 +4,7 @@ Functional, browser based tests for openvpn app.
"""
import pytest
from plinth.tests import functional
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."""
browser.visit(base_url)
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)

View File

@ -38,7 +38,7 @@ class TestShadowsocksApp(functional.BaseAppTests):
def _configure(browser, server, password):
"""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_password').fill(password)
functional.submit(browser, form_class='form-configuration')
@ -46,7 +46,7 @@ def _configure(browser, server, password):
def _get_configuration(browser):
"""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
password = browser.find_by_id('id_password').value
return server, password

View File

@ -38,13 +38,13 @@ class TestShadowsocksServerApp(functional.BaseAppTests):
def _configure(browser, password):
"""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)
functional.submit(browser, form_class='form-configuration')
def _get_configuration(browser):
"""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
return password

View File

@ -80,7 +80,7 @@ def _remove_share(browser, name):
def _add_share(browser, name, path, group):
"""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-path', path)
browser.find_by_css(
@ -102,7 +102,7 @@ def _edit_share(browser, old_name, new_name, path, group):
def _get_share(browser, name):
"""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]
@ -148,4 +148,4 @@ def _verify_nonexistant_share(browser, name):
def _verify_inaccessible_share(browser, name):
"""Verify that given URL for a given share name denies permission."""
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.'),
_('Snapshots currently work on btrfs file systems only and on the root '
'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. ')
]

View File

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

View File

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

View File

@ -27,7 +27,7 @@ class TestTiddlyWikiApp(functional.BaseAppTests):
return
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)
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_file_name = 'A_Midsummer_Nights_Dream.html'
self._get_links_in_app_page(
session_browser,
'/plinth/apps/tiddlywiki/' + file_name + '/rename/').first.click()
session_browser, '/freedombox/apps/tiddlywiki/' + file_name +
'/rename/').first.click()
session_browser.find_by_id('id_tiddlywiki-new_name').fill(
new_wiki_name)
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')
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)
functional.submit(session_browser, form_class='form-tiddlywiki')
@ -100,8 +100,8 @@ class TestTiddlyWikiApp(functional.BaseAppTests):
self._create_wiki_file(session_browser)
self._get_links_in_app_page(
session_browser,
'/plinth/apps/tiddlywiki/' + file_name + '/delete/').first.click()
session_browser, '/freedombox/apps/tiddlywiki/' + file_name +
'/delete/').first.click()
functional.submit(session_browser, form_class='form-delete')
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):
functional.nav_to_module(browser, 'users')
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_confirm_password').fill(_admin_password)
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):
"""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_confirm_password').fill(_admin_password)
functional.submit(browser, form_class='form-update')
@ -319,7 +320,8 @@ def _set_email(browser, username, email):
def _get_email(browser, username):
"""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
@ -330,13 +332,13 @@ def _check_language(browser, language_code):
def _get_ssh_keys(browser, username=None):
functional.visit(browser, '/plinth/')
functional.visit(browser, '/freedombox/')
if username is None:
browser.find_by_id('id_user_menu').click()
functional.click_and_wait(browser,
browser.find_by_id('id_user_edit_menu'))
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
@ -346,7 +348,7 @@ def _set_ssh_keys(browser, ssh_keys, username=None):
functional.click_and_wait(browser,
browser.find_by_id('id_user_edit_menu'))
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
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):
functional.visit(browser, '/plinth/sys/users/{}/edit/'.format(username))
functional.visit(browser,
'/freedombox/sys/users/{}/edit/'.format(username))
if status == 'inactive':
browser.find_by_id('id_is_active').uncheck()
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'))
else:
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
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):
"""Return the href for client show page."""
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):
"""Check whether a client key exists."""

View File

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

View File

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

View File

@ -1,7 +1,7 @@
{"shortcuts": [{
"name": "NextCloud",
"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": [{
"name": "nextcloud",
"platforms": [{

View File

@ -1,7 +1,7 @@
{"shortcuts": [{
"name": "NextCloud2",
"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": [{
"name": "nextcloud",
"platforms": [{

View File

@ -1,7 +1,7 @@
{"shortcuts": [{
"name": "NextCloud",
"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": [{
"name": "nextcloud",
"platforms": [{

View File

@ -48,7 +48,7 @@ base_url = config['DEFAULT']['url']
# unlisted sites just use '/' + site_name as url
_site_url = {
'wiki': '/ikiwiki',
'jsxc': '/plinth/apps/jsxc/jsxc/',
'jsxc': '/freedombox/apps/jsxc/jsxc/',
'cockpit': '/_cockpit/',
'syncthing': '/syncthing/',
'rssbridge': '/rss-bridge/',
@ -377,7 +377,7 @@ def _run_first_wizard(browser):
username = config['DEFAULT']['username'],
password = config['DEFAULT']['password']
welcome_url = base_url + '/plinth/firstboot/welcome/'
welcome_url = base_url + '/freedombox/firstboot/welcome/'
browser.visit(welcome_url)
if browser.url != welcome_url:
# 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:
password = get_password(username)
# 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)
user_menu = browser.find_by_id('id_user_menu')
@ -409,7 +409,7 @@ def login_with_account(browser, url, username, password=None):
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:
click_and_wait(browser, login_button.first)
browser.fill('username', username)
@ -423,7 +423,7 @@ def logout(browser):
"""Log out of the FreedomBox interface."""
# Navigate to the home page if logout form is not found
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
if browser.find_by_css('.form-logout'):
@ -436,13 +436,13 @@ def logout(browser):
#################
def nav_to_module(browser, module):
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:
browser.visit(required_url)
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.select(domain_name)
submit(browser, form_class='form-configuration')
@ -603,7 +603,7 @@ def running_inside_container():
#############################
def set_hostname(browser, hostname: str):
"""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)
submit(browser, form_class='form-hostname')
@ -613,8 +613,8 @@ def domain_add(browser, domain_name: str):
if domain_name in domain_list(browser):
return
visit(browser, '/plinth/sys/names/')
click_link_by_href(browser, '/plinth/sys/names/domains/')
visit(browser, '/freedombox/sys/names/')
click_link_by_href(browser, '/freedombox/sys/names/domains/')
browser.find_by_id('id_domain-add-domain_name').fill(domain_name)
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):
return
visit(browser, '/plinth/sys/names/')
visit(browser, '/freedombox/sys/names/')
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')
def domain_list(browser) -> list[str]:
"""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')
return [element.text for element in elements]
@ -659,12 +659,12 @@ def _click_button_and_confirm(browser, href, form_class):
if buttons:
submit(browser, element=buttons.first)
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):
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')
@ -674,7 +674,7 @@ def backup_create(browser, app_name, archive_name=None):
if 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)
eventually(browser.find_by_css, args=['.select-all'])
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):
"""Restore a given app from a backup archive."""
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')
@ -708,7 +708,7 @@ def networks_set_firewall_zone(browser, zone):
'and contains(@class, "connection-status-label")]/following::a').first
network_id = device['href'].split('/')[-3]
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)
browser.select('zone', zone)
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:
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_password1').fill(password)
@ -763,7 +763,7 @@ def create_user(browser, name, password=None, groups=[], email=None):
def delete_user(browser, name):
"""Delete a user."""
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_confirm_password').fill(
@ -775,13 +775,14 @@ def delete_user(browser, name):
'#user-delete-confirm-dialog button.confirm').first
eventually(lambda: 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):
"""Check if a user with a given name exists."""
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
@ -789,7 +790,7 @@ def user_set_language(browser, language_code):
"""Change user's preferred UI language."""
username = config['DEFAULT']['username']
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="' +
language_code + '"]').first.click()
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):
"""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
@pytest.fixture(name='bittorrent_tag')
def fixture_bittorrent_tag(session_browser):
"""Click on the BitTorrent tag."""
bittorrent_tag = '/plinth/apps/?tag=BitTorrent'
bittorrent_tag = '/freedombox/apps/?tag=BitTorrent'
functional.login(session_browser)
functional.nav_to_module(session_browser, 'transmission')
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
with functional.wait_for_page_update(
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.type('file sharing')
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
with functional.wait_for_page_update(
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()
session_browser.find_by_css(
".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):
"""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
assert 'Compartir' in badge.text
search_input = session_browser.find_by_id('add-tag-input').first
with functional.wait_for_page_update(
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.type('Marcadores')
search_input.type(Keys.ENTER)

View File

@ -63,7 +63,7 @@ class TestSetupMiddleware:
@patch('django.urls.reverse', return_value='users:login')
def test_404_urls(reverse, middleware, kwargs):
"""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)
assert response is None
@ -71,7 +71,7 @@ class TestSetupMiddleware:
@patch('django.urls.reverse', return_value='users:login')
def test_url_not_an_application(reverse, middleware, kwargs):
"""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)
assert response is None
@ -83,7 +83,7 @@ class TestSetupMiddleware:
resolve.return_value.namespaces = ['mockapp']
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()
response = middleware.process_view(request, **kwargs)
assert response is None
@ -99,7 +99,7 @@ class TestSetupMiddleware:
resolve.return_value.namespaces = ['mockapp']
view = Mock()
setup_view.as_view.return_value = view
request = RequestFactory().get('/plinth/mockapp')
request = RequestFactory().get('/freedombox/mockapp')
request.session = MagicMock()
# 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
# Admin user can collect result
request = RequestFactory().get('/plinth/mockapp')
request = RequestFactory().get('/freedombox/mockapp')
request.resolver_match = Mock()
user = User(username='adminuser')
user.save()
@ -175,7 +175,7 @@ class TestSetupMiddleware:
messages_success.reset_mock()
messages_error.reset_mock()
operation_manager.collect_results.reset_mock()
request = RequestFactory().get('/plinth/mockapp')
request = RequestFactory().get('/freedombox/mockapp')
user = User(username='johndoe')
user.save()
request.user = user
@ -201,7 +201,7 @@ class TestAdminMiddleware:
@pytest.fixture(name='web_request')
def fixture_web_request():
"""Fixture for returning kwargs."""
web_request = RequestFactory().get('/plinth/mockapp')
web_request = RequestFactory().get('/freedombox/mockapp')
web_request.user = Mock()
return web_request

View File

@ -337,7 +337,7 @@ def test_list_filter_user_and_group(note, user):
@patch('plinth.notification.gettext')
def test_display_context(gettext, note, user, rf):
"""Test display context for a notification."""
request = rf.get('/plinth/help/about/')
request = rf.get('/freedombox/help/about/')
data = {
'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):
"""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.save()
@ -412,7 +412,7 @@ def test_display_context_body_template(note, user, load_cfg, rf):
context = Notification.get_display_context(request, user)
context_note = context['notifications'][0]
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

View File

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

View File

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

View File

@ -44,7 +44,7 @@ def test_static_files_mount(mount, load_cfg):
calls = [
call(
None, '/plinth/a', {
None, '/freedombox/a', {
'/': {
'tools.staticdir.root': '/b',
'tools.staticdir.on': True,
@ -52,7 +52,7 @@ def test_static_files_mount(mount, load_cfg):
}
}),
call(
None, '/plinth/c', {
None, '/freedombox/c', {
'/': {
'tools.staticdir.root': '/d',
'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
web path will be prepended with the FreedomBox's configured base web
path. For example, {'/foo': '/usr/share/foo'} means that
'/usr/share/foo/bar.png' will be served over '/plinth/foo/bar.png' if
FreedomBox is configured to be served on '/plinth'.
'/usr/share/foo/bar.png' will be served over '/freedombox/foo/bar.png'
if FreedomBox is configured to be served on '/freedombox'.
"""
super().__init__(component_id)

View File

@ -26,7 +26,7 @@
twitter-bootstap3</a></td>
</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>
<a href="http://www.gnu.org/licenses/agpl-3.0.html">
GNU Affero General Public License, version 3 or later</a>

View File

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