mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-03-18 09:10:49 +00:00
freedombox Debian release 24.25
-----BEGIN PGP SIGNATURE----- iQJKBAABCgA0FiEEfWrbdQ+RCFWJSEvmd8DHXntlCAgFAmdg7jgWHGp2YWxsZXJv eUBtYWlsYm94Lm9yZwAKCRB3wMdee2UICKLqEACU/BYpXt9WrO4S7vKAlIU44t+H NZRD1RYzjWwGyPGELXwPFl5gFnP9RGyRwmpbM4Z96cWSEVN0rXsDWRUxgXXHXN0e 0bMJGXvwBj6DeXmeKaUZDlHfRfvl8UDOdmmC6DZ5gb2Tb5cCB4od/VTUxyBbN8W/ +bcpkKo3/7qnYTKZkjY5rs2zvUqTctNs8CK6yr3iFY0Dec8uzkdRmN7XG2pljIF/ VwjO8oKSBu3thX+XisuVuibZNWYrYiwzvcrLqD4d1ihgcVUdXdUWQw7QK42LGkxS V4CdA4idB5eR+QN/DZoTMDiHZ058Qzjl47Bv4EISlcatikJhjB38B8+lnM0hvEmN CcIOb5CxeT5dFnZIPjflAPeC1vWInvVOIeH4Std40VOUsKD3hyX7tlEZrenFVEsr M/gvizpUPfwrolUxb7eYBeyeR2zNCRXpy/+PhhkfzrnRb69SnllIx79OAaZFVLFC SGCx91LI/DeOR/7La+RtWPcpdLdBgflXHRWMQx6Y/hDMWPkWzQJp4PrsLXodeSVg qzyUAXY7aEjs4C81+ycTziN1zVa4YJEWJ1ikIyVui2mKFmUXzOeG6Ks/HszpJsQ1 TbDGhCoDms1k0Gr1OLHVEYA/tKee5WFK1ENx9yAMmh+txSxjvRH/m1c/9w+Ud0TN IqHwrdV1hB0hz2XF8w== =OYVr -----END PGP SIGNATURE----- gpgsig -----BEGIN PGP SIGNATURE----- iQJKBAABCgA0FiEEfWrbdQ+RCFWJSEvmd8DHXntlCAgFAmdkEnIWHGp2YWxsZXJv eUBtYWlsYm94Lm9yZwAKCRB3wMdee2UICI6TD/9O2m1eQAicZNmqYfrVfW8mhNHD pPsZD1G8Sglf+75QcjxD4J9fC/PBfortyTRmESuzeoYkCs3iN3SoTkq3P9NSEYzs plzISzrBRy2FDnMXAGGfs4Mhtmj6ZfQe2BbU1tHX0z8ojnxn6Y3ohjUEr6VWz75M D1gB1ORtvMHv4JLCDu7ZGsPFAubM5Ah3wU9IZRX8X6NtG+XG+EzTEVeb0sJ1QstA JABiZVjCyf2JcQc8aXViVbn6ZPIqVnAXv9C0Vo0nKAY11bbEw6j5BZ9/TIUbg0UA HA+8HwIOJVf4yk18yOcRrOHxKDHxjZ4NJJKtBq/AoQPlrC45ogCZ0HSOLmanf5Ge lPQaLCr8VnNyDBxaEofVIclm3HNKXqtyAvoGWqQKhAnyuuCKxWwLaq46/XLta6FN Zin6O7kaZrwDPihRC3dMIxEJ6I3dZnWZd4BrSZwKPzh3Sksl0WRMTaFf6aqUhWrq +ven3zUBkUnSDHR8VquxcRZRmLEs3heJEILeeeHQAebIpPhcXlzi3aPOKT9XaLj2 0Q5mWY6KIcmzxrR5G9fQyDtV2Gs9hlgVY0Dy0Kq0ptjM63vfy4zNPmPsidvKvITl nCZGGOyqq0Y/aGh6pOEKsHBGwXrWPgfwDZcLsFs20MsZO91Ff0WzJHQG8/ZmFZEf AXOn/YCM+kqa5gLA9Q== =0LIo -----END PGP SIGNATURE----- Merge tag 'v24.25' into debian/bookworm-backports freedombox Debian release 24.25 Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
commit
561d43d61f
@ -19,7 +19,8 @@ RUN apt-get build-dep -y .
|
||||
RUN apt-get install -y build-essential \
|
||||
# Test dependencies
|
||||
sshpass parted \
|
||||
sudo python3-pip
|
||||
sudo python3-pip \
|
||||
python3-flake8
|
||||
|
||||
# Module dependencies
|
||||
RUN apt-get install -y $(./run --list-dependencies)
|
||||
|
||||
@ -83,7 +83,7 @@ RedirectMatch "^/$" "/plinth"
|
||||
##
|
||||
<LocationMatch "^/(plinth|freedombox)">
|
||||
Header set Referrer-Policy 'same-origin'
|
||||
Header set Content-Security-Policy "font-src 'self'; frame-src 'none'; img-src 'self'; manifest-src 'none'; media-src 'none'; object-src 'none'; script-src 'self'; style-src 'self'; worker-src 'self'; default-src 'self'; base-uri 'none'; sandbox allow-scripts allow-popups allow-popups-to-escape-sandbox allow-forms allow-same-origin allow-downloads; form-action 'self'; frame-ancestors 'none'; block-all-mixed-content;"
|
||||
Header set Content-Security-Policy "font-src 'self'; frame-src 'none'; img-src 'self' data:; manifest-src 'none'; media-src 'none'; object-src 'none'; script-src 'self'; style-src 'self'; worker-src 'self'; default-src 'self'; base-uri 'none'; sandbox allow-scripts allow-popups allow-popups-to-escape-sandbox allow-forms allow-same-origin allow-downloads; form-action 'self'; frame-ancestors 'none'; block-all-mixed-content;"
|
||||
Header set X-Content-Type-Options 'nosniff'
|
||||
</LocationMatch>
|
||||
|
||||
|
||||
112
debian/changelog
vendored
112
debian/changelog
vendored
@ -1,3 +1,115 @@
|
||||
freedombox (24.25) unstable; urgency=medium
|
||||
|
||||
[ Burak Yavuz ]
|
||||
* Translated using Weblate (Turkish)
|
||||
|
||||
[ 109247019824 ]
|
||||
* Translated using Weblate (Bulgarian)
|
||||
* Translated using Weblate (Bulgarian)
|
||||
|
||||
[ Besnik Bleta ]
|
||||
* Translated using Weblate (Albanian)
|
||||
|
||||
[ Ettore Atalan ]
|
||||
* Translated using Weblate (German)
|
||||
|
||||
[ 大王叫我来巡山 ]
|
||||
* Translated using Weblate (Chinese (Simplified Han script))
|
||||
|
||||
[ Jiří Podhorecký ]
|
||||
* Translated using Weblate (Czech)
|
||||
|
||||
[ Paul Lettich ]
|
||||
* Translated using Weblate (German)
|
||||
|
||||
[ John Doe ]
|
||||
* Translated using Weblate (French)
|
||||
|
||||
[ Sunil Mohan Adapa ]
|
||||
* tags: Fix issue with JS init on a page without tags
|
||||
* notifications: Don't error when dismissing missing notifications
|
||||
* help: Add a class to the help index page
|
||||
* ui: Align app icons in the center for home, apps, and help pages
|
||||
* ui: Allow users to provide a CSS file to customize styling
|
||||
* Translated using Weblate (Russian)
|
||||
* Translated using Weblate (Russian)
|
||||
* ui: Switch to using bootstrap 5 (Closes: #1088412, #1088577)
|
||||
* networks: Fix minor typo in template related to signal strength
|
||||
* ui: Drop use of badge-* utility classes for newer replacements
|
||||
* apache: Relax content security policy to allow data: URL
|
||||
* networks: Use new accordion component from Bootstrap 5
|
||||
* networks: Fix issue with loading create PPPoE form
|
||||
* firewalld: Reduce severity for alert about service on internal zone
|
||||
* help: Update the privacy notice on status log page
|
||||
* diagnostics: Fix trimming an i18n string
|
||||
* matrixsynapse: Fix trimming an i18n string
|
||||
* ui: Use Bootstrap 5 styling for all alerts
|
||||
* power: Refactor display of package manager busy alerts
|
||||
* ui: Rename data- attributes to data-bs- for Bootstrap 5
|
||||
* ui: app, system: Revert to earlier width for card lists
|
||||
* ui: Show disabled form elements as grey for Bootstrap 5
|
||||
* ui: Fix overflow of exception text in message
|
||||
* ui: users: Fix close button for confirmation dialog for Bootstrap 5
|
||||
* ui: app: Fix an incorrect HTML tag nesting
|
||||
* ui: Reduce the gap at the top of the pages
|
||||
* ui: diagnostics: Fix layout of repair buttons
|
||||
* ui: diagnostics: Fix gap between headings
|
||||
* ui: forms: Fix margins for form labels for Bootstrap 5
|
||||
* ui: backups: Drop unused styling in verify host key page
|
||||
* ui: Restore spacing between form elements in Bootstrap 5
|
||||
* ui: snapshots: Fix horizontal form styling margins for Bootstrap 5
|
||||
* ui: snapshots: Fix horizontal form layout on mobiles for Bootstrap 5
|
||||
* ui: Fix toggle button styling for Bootstrap 5
|
||||
* ui: Allow underlining for most links due to Bootstrap 5
|
||||
* ui: Restyle tags, remove underlining of text
|
||||
* ui: Accept default styling of Bootstrap 5 for warning button
|
||||
* ui: Update custom button styles for Bootstrap 5
|
||||
* ui: samba: Fix layout regressions with Bootstrap 5
|
||||
* ui: Fix styling in dismiss button in form errors for Bootstrap 5
|
||||
* ui: Update styling for navbar menu items
|
||||
* ui: Workaround dropdowns not working with Bootstrap 5
|
||||
* ui: Use collapse instead of dropdown for notification in Bootstrap 5
|
||||
* ui: Fix issue with notifications icon showing twice in mobile view
|
||||
* ui: Fix flash of notifications popdown during page load
|
||||
* ui: Style the 'Log out' item properly
|
||||
* ui: Don't use nav-link inside card
|
||||
* ui: Cleanup use of colors with CSS variables
|
||||
* ui: Fix placement of tags menu under tags input with Bootstrap 5
|
||||
* diagnostics: tests: functional: Pick errors more specifically
|
||||
* tests: functional: Disable smooth scrolling from Bootstrap 5
|
||||
* ui: firewall: Fix styling with Bootstrap 5
|
||||
* ui: backups: Use Bootstrap color variables instead of static values
|
||||
* ui: help: Fix alignment issue with footer links in about page
|
||||
* action_utils: Add utility to ensure that service is stopped
|
||||
* deluge: Cleanup and simplify setup code
|
||||
* letsencrypt: Declare explicit dependency on openssl
|
||||
* openvpn: Declare explicit dependency on openssl
|
||||
* sso: Switch using cryptography module instead of OpenSSL.crypto
|
||||
(Closes: #1088760)
|
||||
* ci: Add flake8 to gitlabci container
|
||||
* d/control: Drop version specification on dependencies for Bookworm
|
||||
* d/control: Drop unnecessary recommendations
|
||||
* i2p: Drop app as it has not been available in Debian for a while
|
||||
|
||||
[ Veiko Aasa ]
|
||||
* tags: tests: Fix deprecated webdriver attribute
|
||||
* tests: functional: Don't try disable app after tests if app was not installed
|
||||
* tests: functional: Fix app installation test skipped on slow machines
|
||||
* deluge: Fix app installation on Debian testing
|
||||
|
||||
[ James Valleroy ]
|
||||
* radicale: Update link to supported clients
|
||||
* locale: Update translation strings
|
||||
* doc: Fetch latest manual
|
||||
|
||||
[ Carles Pina i Estany ]
|
||||
* Added po-debconf Catalan translation
|
||||
|
||||
[ gfbdrgng ]
|
||||
* Translated using Weblate (Russian)
|
||||
|
||||
-- James Valleroy <jvalleroy@mailbox.org> Mon, 16 Dec 2024 21:32:08 -0500
|
||||
|
||||
freedombox (24.24~bpo12+1) bookworm-backports; urgency=medium
|
||||
|
||||
* Rebuild for bookworm-backports.
|
||||
|
||||
70
debian/control
vendored
70
debian/control
vendored
@ -17,7 +17,7 @@ Build-Depends:
|
||||
docbook-xsl,
|
||||
e2fsprogs,
|
||||
gir1.2-nm-1.0,
|
||||
libjs-bootstrap4,
|
||||
libjs-bootstrap5,
|
||||
pybuild-plugin-pyproject,
|
||||
python3-all:any,
|
||||
python3-apt,
|
||||
@ -26,18 +26,17 @@ Build-Depends:
|
||||
python3-build,
|
||||
python3-cherrypy3,
|
||||
python3-configobj,
|
||||
python3-cryptography,
|
||||
python3-dbus,
|
||||
python3-django (>= 1.11),
|
||||
python3-django-axes (>= 5.0.0),
|
||||
python3-django,
|
||||
python3-django-axes,
|
||||
python3-django-captcha,
|
||||
# Explictly depend on ipware as it is optional dependecy for future versions
|
||||
# of django-axes.
|
||||
python3-django-ipware (>= 3),
|
||||
python3-django-stronghold (>= 0.3.0),
|
||||
# Explictly depend on ipware as it is optional dependecy of django-axes
|
||||
python3-django-ipware,
|
||||
python3-django-stronghold,
|
||||
python3-gi,
|
||||
python3-markupsafe,
|
||||
python3-mypy,
|
||||
python3-openssl,
|
||||
python3-pampy,
|
||||
python3-paramiko,
|
||||
python3-pexpect,
|
||||
@ -51,8 +50,8 @@ Build-Depends:
|
||||
python3-ruamel.yaml,
|
||||
python3-setuptools,
|
||||
python3-setuptools-git,
|
||||
# python3-tomli is not available in Bullseye
|
||||
python3-tomli | python3-coverage (<< 6.0),
|
||||
# python3-tomli is needed by python3-coverage when pyproject.toml is used
|
||||
python3-tomli,
|
||||
python3-typeshed,
|
||||
python3-yaml,
|
||||
sshpass,
|
||||
@ -66,17 +65,11 @@ Rules-Requires-Root: no
|
||||
|
||||
Package: freedombox
|
||||
Breaks:
|
||||
freedombox-setup (<< 0.13~),
|
||||
plinth (<< 0.46.0~),
|
||||
# Ensure fuse gets replaced by fuse3 on upgrades from buster s.t. sshfs can be installed.
|
||||
fuse (<< 3),
|
||||
# If ufw is installed, remove it. See issue 2247.
|
||||
ufw,
|
||||
Replaces:
|
||||
freedombox-setup (<< 0.13~),
|
||||
plinth (<< 0.46.0~),
|
||||
Architecture: all
|
||||
Provides: plinth
|
||||
Depends:
|
||||
${python3:Depends},
|
||||
${misc:Depends},
|
||||
@ -98,7 +91,7 @@ Depends:
|
||||
ldapscripts,
|
||||
# For gdbus used to call hooks into service
|
||||
libglib2.0-bin,
|
||||
libjs-bootstrap4,
|
||||
libjs-bootstrap5,
|
||||
libjs-jquery,
|
||||
lsof,
|
||||
netcat-openbsd,
|
||||
@ -112,12 +105,11 @@ Depends:
|
||||
python3-cherrypy3,
|
||||
python3-configobj,
|
||||
python3-dbus,
|
||||
python3-django (>= 1.11),
|
||||
python3-django-axes (>= 5.0.0),
|
||||
python3-django,
|
||||
python3-django-axes,
|
||||
python3-django-captcha,
|
||||
# Explictly depend on ipware as it is optional dependecy for future versions
|
||||
# of django-axes.
|
||||
python3-django-ipware (>= 3),
|
||||
# Explictly depend on ipware as it is optional dependecy of django-axes
|
||||
python3-django-ipware,
|
||||
python3-django-stronghold,
|
||||
python3-gi,
|
||||
python3-markupsafe,
|
||||
@ -132,31 +124,13 @@ Depends:
|
||||
sudo,
|
||||
wget,
|
||||
# Ensure fuse gets replaced by fuse3 on upgrades from buster s.t. sshfs can be installed.
|
||||
fuse3 (>= 3),
|
||||
fuse3,
|
||||
Recommends:
|
||||
# Priority: standard
|
||||
bzip2,
|
||||
# Provides brctl for controlling bridges
|
||||
bridge-utils,
|
||||
# Read, write to char devices
|
||||
devio,
|
||||
# Create, repair DOS filesystems
|
||||
dosfstools,
|
||||
# Priority: standard
|
||||
file,
|
||||
# Wifi firmware
|
||||
firmware-ath9k-htc,
|
||||
# FreedomBox documentation
|
||||
freedombox-doc-en,
|
||||
freedombox-doc-es,
|
||||
# Monitor system resources
|
||||
htop,
|
||||
# Monitor network traffic statistics
|
||||
iftop,
|
||||
# Basic network utitlity ping
|
||||
iputils-ping,
|
||||
# Manage wireless devices
|
||||
iw,
|
||||
# Resolve .local address using mDNS
|
||||
libnss-mdns,
|
||||
# Resolve current hostname without /etc/hosts
|
||||
@ -169,22 +143,10 @@ Recommends:
|
||||
locales-all,
|
||||
# Priority: standard
|
||||
openssh-client,
|
||||
# Priority: standard
|
||||
pciutils,
|
||||
# Used by unattended-upgrades to check if running on AC power
|
||||
powermgmt-base,
|
||||
# fuser, pstree and other utilities
|
||||
# fuser, killall, pstree and other utilities
|
||||
psmisc,
|
||||
# Tool to kill WLAN, Bluetooth and moble broadband
|
||||
rfkill,
|
||||
# Monitor network traffic
|
||||
tcpdump,
|
||||
# Basic editor, VIM style
|
||||
vim-tiny,
|
||||
# Priority: standard
|
||||
whois,
|
||||
# Basic editor, Emacs style
|
||||
zile,
|
||||
Description: easy to manage, privacy oriented home server
|
||||
FreedomBox is designed to be your own inexpensive server at home. It runs free
|
||||
software and offers an increasing number of services ranging from a calendar or
|
||||
|
||||
36
debian/po/ca.po
vendored
Normal file
36
debian/po/ca.po
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
# Catalan translation of plinth's debconf messages
|
||||
# Copyright © 2024 Free Software Foundation, Inc.
|
||||
# This file is distributed under the same license as the plinth package.
|
||||
# poc senderi <pocsenderi@protonmail.com>, 2024.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: plinth\n"
|
||||
"Report-Msgid-Bugs-To: plinth@packages.debian.org\n"
|
||||
"POT-Creation-Date: 2019-11-18 18:11-0500\n"
|
||||
"PO-Revision-Date: 2024-11-05 22:18+0100\n"
|
||||
"Language: ca\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Last-Translator: poc senderi <pocsenderi@protonmail.com>\n"
|
||||
"Language-Team: Catalan <debian-l10n-catalan@lists.debian.org>\n"
|
||||
"X-Generator: Poedit 2.4.2\n"
|
||||
|
||||
#. Type: note
|
||||
#. Description
|
||||
#: ../templates:1001
|
||||
msgid "FreedomBox first wizard secret - ${secret}"
|
||||
msgstr "Secret per a l'engegada inicial del «wizard» de FreedomBox - ${secret}"
|
||||
|
||||
#. Type: note
|
||||
#. Description
|
||||
#: ../templates:1001
|
||||
msgid ""
|
||||
"Please note down the above secret. You will be asked to enter this in the "
|
||||
"first screen after you launch the FreedomBox web interface. In case you lose "
|
||||
"it, you can retrieve it by running the following command:"
|
||||
msgstr ""
|
||||
"Anoteu el secret anterior. Us serà demanat a la primera pantalla després "
|
||||
"d'engegar la interfície web del FreedomBox. En cas que el perdeu, el podeu "
|
||||
"recuperar executant la següent ordre:"
|
||||
1
debian/source/lintian-overrides
vendored
1
debian/source/lintian-overrides
vendored
@ -8,5 +8,4 @@ very-long-line-length-in-source-file * [doc/manual/*.raw.wiki:*]
|
||||
very-long-line-length-in-source-file * [plinth/modules/deluge/tests/data/sample.torrent:*]
|
||||
very-long-line-length-in-source-file * [plinth/modules/transmission/tests/data/sample.torrent:*]
|
||||
very-long-line-length-in-source-file * [doc/visual_design/FreedomBox-Logo.7z:*]
|
||||
very-long-line-length-in-source-file * [plinth/modules/i2p/tests/data/router.config:*]
|
||||
very-long-line-length-in-source-file * [COPYING.md:*]
|
||||
|
||||
2
debian/tests/control
vendored
2
debian/tests/control
vendored
@ -14,5 +14,5 @@ Restrictions: needs-root, breaks-testbed
|
||||
# Run unit and integration tests on installed files.
|
||||
#
|
||||
Test-Command: PYTHONPATH='/usr/lib/python3/dist-packages/' py.test-3 -p no:cacheprovider --cov=plinth --cov-report=html:debci/htmlcov --cov-report=term
|
||||
Depends: git, python3-openssl, python3-pytest, python3-pytest-cov, python3-pytest-django, python3-tomli | python3-coverage (<< 6.0), @
|
||||
Depends: git, python3-pytest, python3-pytest-cov, python3-pytest-django, python3-tomli, @
|
||||
Restrictions: breaks-testbed
|
||||
|
||||
@ -206,10 +206,10 @@ autodoc_mock_imports = [
|
||||
'captcha',
|
||||
'cherrypy',
|
||||
'configobj',
|
||||
'cryptography',
|
||||
'dbus',
|
||||
'gi',
|
||||
'markupsafe',
|
||||
'OpenSSL',
|
||||
'pam',
|
||||
'paramiko',
|
||||
'psutil',
|
||||
|
||||
@ -27,7 +27,7 @@ Installing !FreedomBox changes your Debian system in many important ways. This
|
||||
|
||||
Check the Troubleshooting section below, for any tips or workarounds that might help during the install.
|
||||
|
||||
1. [[InstallingDebianOn|Install Debian]] 12 (bookworm), or Unstable (sid) on your hardware.
|
||||
1. [[InstallingDebianOn|Install Debian]] 12 (Bookworm) or newer on your hardware. During installation choosing "Btrfs" for root filesystem type is recommended as !FreedomBox uses it take regular snapshots of the system.
|
||||
|
||||
1. Update your package list.
|
||||
|
||||
|
||||
@ -1,36 +0,0 @@
|
||||
#language en
|
||||
|
||||
##TAG:TRANSLATION-HEADER-START
|
||||
~- [[de/FreedomBox/Manual/I2P|Deutsch]] - [[FreedomBox/Manual/I2P|English]] - [[es/FreedomBox/Manual/I2P|Español]] - [[DebianWiki/EditorGuide#translation|(+)]] -~
|
||||
##TAG:TRANSLATION-HEADER-END
|
||||
<<TableOfContents()>>
|
||||
|
||||
## BEGIN_INCLUDE
|
||||
|
||||
== I2P (Anonymity Network) ==
|
||||
||<tablestyle="float: right;"> {{attachment:I2P-icon_en_V01.png|I2P icon}} ||
|
||||
|
||||
=== About I2P ===
|
||||
The Invisible Internet Project is an anonymous network layer intended to protect communication from censorship and surveillance. I2P provides anonymity by sending encrypted traffic through a volunteer-run network distributed around the world.
|
||||
|
||||
=== Services Offered ===
|
||||
|
||||
The following services are offered via I2P in !FreedomBox by default. Additional services may be available when enabled from I2P router console that can be launched from !FreedomBox web interface.
|
||||
|
||||
* '''Anonymous Internet browsing''': I2P can be used to browse Internet anonymously. For this, configure your browser (preferable a Tor Browser) to connect to I2P proxy. This can be done by setting HTTP proxy and HTTPS proxy to ''freedombox.local'' (or your !FreedomBox's local IP address) and ports to ''4444'' and ''4445'' respectively. This service is available only when you are reaching !FreedomBox using local network (networks in internal zone) and not available when connecting to !FreedomBox from the Internet. One exception to this is when you connect to !FreedomBox's VPN service from Internet you can still use this service.
|
||||
* '''Reaching eepsites''': I2P network can host websites that can remain anonymous. These are called eepsites and end with .i2p in their domain name. For example, http://i2p-projekt.i2p/ is the website for I2P project in the I2P network. eepsites are not reachable using a regular browser via regular Internet connection. To browse eepsites, your browser needs to be configured to use HTTP, HTTPS proxies as described above. This service is available only when you are reaching !FreedomBox using local network (networks in internal zone) and not available when connecting to !FreedomBox from the Internet. One exception to this is when you connect to !FreedomBox's VPN service from Internet you can still use this service.
|
||||
* '''Anonymous torrent downloads''': I2PSnark, an application for anonymously downloading and sharing files over the !BitTorrent network is available in I2P and enabled by default in !FreedomBox. This application is controlled via a web interface that can be launched from 'Anonymous torrents' section of I2P app in !FreedomBox web interface or from the I2P router console interface. Only logged-in users belonging to 'Manage I2P application' group can use this service.
|
||||
* '''IRC network''': I2P network contains an IRC network called Irc2P. This network hosts the I2P project's official IRC channel among other channels. This service is enabled by default in !FreedomBox. To use it, open your favourite IRC client. Then configure it to connect to host ''freedombox.local'' (or your !FreedomBox's local IP address) with port number ''6668''. This service is available only when you are reaching !FreedomBox using local network (networks in internal zone) and not available when connecting to !FreedomBox from the Internet. One exception to this is when you connect to !FreedomBox's VPN service from Internet you can still use this service.
|
||||
* '''I2P router console''': This is the central management interface for I2P. It shows the current status of I2P, bandwidth statistics and allows modifying various configuration settings. You can tune your participation in the I2P network and use/edit a list of your favourite I2P sites (eepsites). Only logged-in users belonging to 'Manage I2P application' group can use this service.
|
||||
|
||||
=== External links ===
|
||||
|
||||
* Upstream website: https://geti2p.net/en/
|
||||
* User documentation: https://i2pd.readthedocs.io/en/latest/
|
||||
|
||||
|
||||
## END_INCLUDE
|
||||
|
||||
Back to [[FreedomBox/Features|Features introduction]] or [[FreedomBox/Manual|manual]] pages.
|
||||
|
||||
<<Include(FreedomBox/Portal)>>
|
||||
58
doc/manual/en/Nextcloud.raw.wiki
Normal file
58
doc/manual/en/Nextcloud.raw.wiki
Normal file
@ -0,0 +1,58 @@
|
||||
#language en
|
||||
|
||||
##TAG:TRANSLATION-HEADER-START
|
||||
~- [[FreedomBox/Manual/Nextcloud|English]] - [[DebianWiki/EditorGuide#translation|(+)]] -~
|
||||
##TAG:TRANSLATION-HEADER-END
|
||||
|
||||
<<TableOfContents()>>
|
||||
|
||||
## BEGIN_INCLUDE
|
||||
|
||||
== Nextcloud (File Storage & Collaboration) ==
|
||||
||<tablestyle="float: right;"> {{attachment:nextcloud.png|Nextcloud icon}} ||
|
||||
|
||||
'''Available since''': !FreedomBox 24.8
|
||||
|
||||
Nextcloud is considered experimental in !FreedomBox having to do with the integration of the Nextcloud container in the !FreedomBox system.
|
||||
|
||||
=== What is Nextcloud? ===
|
||||
|
||||
This page is new and needs a Nexcloud user to help with the content. This could be you!
|
||||
|
||||
Nextcloud is a self-hosted productivity platform which provides private and secure functions for file sharing, collaborative work, and more. Nextcloud includes the Nextcloud server, client applications for desktop computers, and mobile clients. The Nextcloud server provides a well integrated web interface.
|
||||
|
||||
All users of !FreedomBox can use Nextcloud. To perform administrative actions, use the "nextcloud-admin" user after setting a password here.
|
||||
|
||||
Please note that Nextcloud is installed and run inside a container provided by the Nextcloud community. Security, quality, privacy and legal reviews are done by the upstream project and not by Debian/FreedomBox. Updates are performed following an independent cycle.
|
||||
|
||||
{{{#!wiki comment
|
||||
=== Screenshot ===
|
||||
Please add a screenshot of your Nextcloud suitable for public display.
|
||||
}}}
|
||||
|
||||
|
||||
{{{#!wiki comment
|
||||
=== Using Nextcloud ===
|
||||
If you are a Nextcloud user share how this is done.
|
||||
}}}
|
||||
|
||||
=== External Links ===
|
||||
|
||||
* Upstream Project: https://nextcloud.com/
|
||||
* Upstream documentation: https://nextcloud.com/support/
|
||||
* Upstream support forum: https://help.nextcloud.com/
|
||||
* Debian Nextcloud wiki: https://wiki.debian.org/Nextcloud
|
||||
|
||||
{{{#!wiki comment
|
||||
=== Client Apps ===
|
||||
If this app has or needs client applications (apart from a web browser) list these here. As a Debian pure-blend the FreedomBox wiki should be suggesting client software that adheres to the Debian Free Software Guidelines. If this is not possible it should be noted.
|
||||
}}}
|
||||
|
||||
## END_INCLUDE
|
||||
|
||||
Back to [[FreedomBox/Features|Features introduction]] or [[FreedomBox/Manual|manual]] pages.
|
||||
|
||||
<<Include(FreedomBox/Portal)>>
|
||||
|
||||
----
|
||||
CategoryFreedomBox
|
||||
@ -127,7 +127,6 @@ The following services are known to '''work''':
|
||||
* [[FreedomBox/Manual/Privoxy|Privoxy]],
|
||||
* [[FreedomBox/Manual/Tor|Tor Socks]],
|
||||
* [[FreedomBox/Manual/Shadowsocks|Shadowsocks]],
|
||||
* [[FreedomBox/Manual/I2P|I2P Proxy]] and
|
||||
* [[FreedomBox/Manual/Samba|Samba]].
|
||||
|
||||
Some services are known '''not''' to work at this time:
|
||||
|
||||
@ -8,6 +8,82 @@ For more technical details, see the [[https://salsa.debian.org/freedombox-team/f
|
||||
|
||||
The following are the release notes for each !FreedomBox version.
|
||||
|
||||
== FreedomBox 24.25 (2024-12-16) ==
|
||||
|
||||
=== Highlights ===
|
||||
|
||||
* deluge: Fix app installation on Debian testing
|
||||
* notifications: Don't error when dismissing missing notifications
|
||||
* ui: Switch to using bootstrap 5
|
||||
|
||||
=== Other Changes ===
|
||||
|
||||
* action_utils: Add utility to ensure that service is stopped
|
||||
* apache: Relax content security policy to allow data: URL
|
||||
* ci: Add flake8 to gitlabci container
|
||||
* d/control: Drop unnecessary recommendations
|
||||
* d/control: Drop version specification on dependencies for Bookworm
|
||||
* debian: Added po-debconf Catalan translation
|
||||
* deluge: Cleanup and simplify setup code
|
||||
* diagnostics: Fix trimming an i18n string
|
||||
* diagnostics: tests: functional: Pick errors more specifically
|
||||
* firewalld: Reduce severity for alert about service on internal zone
|
||||
* help: Add a class to the help index page
|
||||
* help: Update the privacy notice on status log page
|
||||
* i2p: Drop app as it has not been available in Debian for a while
|
||||
* letsencrypt: Declare explicit dependency on openssl
|
||||
* locale: Update translations for Albanian, Bulgarian, Chinese (Simplified Han script), Czech, French, German, Russian, Turkish
|
||||
* matrixsynapse: Fix trimming an i18n string
|
||||
* networks: Fix issue with loading create PPPoE form
|
||||
* networks: Fix minor typo in template related to signal strength
|
||||
* networks: Use new accordion component from Bootstrap 5
|
||||
* openvpn: Declare explicit dependency on openssl
|
||||
* power: Refactor display of package manager busy alerts
|
||||
* radicale: Update link to supported clients
|
||||
* sso: Switch using cryptography module instead of OpenSSL.crypto
|
||||
* tags: Fix issue with JS init on a page without tags
|
||||
* tags: tests: Fix deprecated webdriver attribute
|
||||
* tests: functional: Disable smooth scrolling from Bootstrap 5
|
||||
* tests: functional: Don't try disable app after tests if app was not installed
|
||||
* tests: functional: Fix app installation test skipped on slow machines
|
||||
* ui: Accept default styling of Bootstrap 5 for warning button
|
||||
* ui: Align app icons in the center for home, apps, and help pages
|
||||
* ui: Allow underlining for most links due to Bootstrap 5
|
||||
* ui: Allow users to provide a CSS file to customize styling
|
||||
* ui: Cleanup use of colors with CSS variables
|
||||
* ui: Don't use nav-link inside card
|
||||
* ui: Drop use of badge-* utility classes for newer replacements
|
||||
* ui: Fix flash of notifications popdown during page load
|
||||
* ui: Fix issue with notifications icon showing twice in mobile view
|
||||
* ui: Fix overflow of exception text in message
|
||||
* ui: Fix placement of tags menu under tags input with Bootstrap 5
|
||||
* ui: Fix styling in dismiss button in form errors for Bootstrap 5
|
||||
* ui: Fix toggle button styling for Bootstrap 5
|
||||
* ui: Reduce the gap at the top of the pages
|
||||
* ui: Rename data- attributes to data-bs- for Bootstrap 5
|
||||
* ui: Restore spacing between form elements in Bootstrap 5
|
||||
* ui: Restyle tags, remove underlining of text
|
||||
* ui: Show disabled form elements as grey for Bootstrap 5
|
||||
* ui: Style the 'Log out' item properly
|
||||
* ui: Update custom button styles for Bootstrap 5
|
||||
* ui: Update styling for navbar menu items
|
||||
* ui: Use Bootstrap 5 styling for all alerts
|
||||
* ui: Use collapse instead of dropdown for notification in Bootstrap 5
|
||||
* ui: Workaround dropdowns not working with Bootstrap 5
|
||||
* ui: app, system: Revert to earlier width for card lists
|
||||
* ui: app: Fix an incorrect HTML tag nesting
|
||||
* ui: backups: Drop unused styling in verify host key page
|
||||
* ui: backups: Use Bootstrap color variables instead of static values
|
||||
* ui: diagnostics: Fix gap between headings
|
||||
* ui: diagnostics: Fix layout of repair buttons
|
||||
* ui: firewall: Fix styling with Bootstrap 5
|
||||
* ui: forms: Fix margins for form labels for Bootstrap 5
|
||||
* ui: help: Fix alignment issue with footer links in about page
|
||||
* ui: samba: Fix layout regressions with Bootstrap 5
|
||||
* ui: snapshots: Fix horizontal form layout on mobiles for Bootstrap 5
|
||||
* ui: snapshots: Fix horizontal form styling margins for Bootstrap 5
|
||||
* ui: users: Fix close button for confirmation dialog for Bootstrap 5
|
||||
|
||||
== FreedomBox 24.24 (2024-11-18) ==
|
||||
|
||||
=== Highlights ===
|
||||
|
||||
@ -16,7 +16,6 @@ You can grant access to your !FreedomBox for other users. Provide the Username w
|
||||
* feed-reader
|
||||
* freedombox-share
|
||||
* git-access
|
||||
* i2p
|
||||
* minidlna
|
||||
* syncthing
|
||||
* web-search
|
||||
|
||||
@ -24,7 +24,6 @@
|
||||
<<Include(FreedomBox/Manual/Email, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
<<Include(FreedomBox/Manual/FeatherWiki, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
<<Include(FreedomBox/Manual/GitWeb, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
<<Include(FreedomBox/Manual/I2P, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
<<Include(FreedomBox/Manual/Ikiwiki, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
<<Include(FreedomBox/Manual/Infinoted, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
<<Include(FreedomBox/Manual/Janus, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
@ -35,6 +34,7 @@
|
||||
<<Include(FreedomBox/Manual/MiniDLNA, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
<<Include(FreedomBox/Manual/Miniflux, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
<<Include(FreedomBox/Manual/Mumble, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
<<Include(FreedomBox/Manual/Nextcloud, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
<<Include(FreedomBox/Manual/OpenVPN, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
<<Include(FreedomBox/Manual/Privoxy, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
<<Include(FreedomBox/Manual/Quassel, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 23 KiB |
BIN
doc/manual/en/images/nextcloud.png
Normal file
BIN
doc/manual/en/images/nextcloud.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
@ -27,7 +27,7 @@ Installing !FreedomBox changes your Debian system in many important ways. This
|
||||
|
||||
Check the Troubleshooting section below, for any tips or workarounds that might help during the install.
|
||||
|
||||
1. [[InstallingDebianOn|Install Debian]] 12 (bookworm), or Unstable (sid) on your hardware.
|
||||
1. [[InstallingDebianOn|Install Debian]] 12 (Bookworm) or newer on your hardware. During installation choosing "Btrfs" for root filesystem type is recommended as !FreedomBox uses it take regular snapshots of the system.
|
||||
|
||||
1. Update your package list.
|
||||
|
||||
|
||||
@ -1,35 +0,0 @@
|
||||
#language es
|
||||
|
||||
<<Include(FreedomBox/Manual/I2P, ,from="^##TAG:TRANSLATION-HEADER-START",to="^##TAG:TRANSLATION-HEADER-END")>>
|
||||
|
||||
<<TableOfContents()>>
|
||||
|
||||
## BEGIN_INCLUDE
|
||||
|
||||
== I2P (Red anónima) ==
|
||||
||<tablestyle="float: right;"> {{attachment:FreedomBox/Manual/I2P/I2P-icon_en_V01.png|I2P icon}} ||
|
||||
|
||||
=== Acerca de I2P ===
|
||||
El ''Proyecto Internet Invisible (I2P)'' es una capa anonimizadora de red concebida para protejer las comunicaciones de la censura y la vigilancia. I2P proporciona anonimato enviando tráfico cifrado a través de una red distribuída alrededor del mundo gestionada por voluntarios.
|
||||
|
||||
=== Servicios Ofrecidos ===
|
||||
|
||||
Los siguientes servicios se ofrecen en !FreedomBox a través de I2P de serie. Se pueden habilitar más servicios desde la consola de enrutado I2P que se puede abrir desde el interfaz web de !FreedomBox.
|
||||
|
||||
* '''Navegación web anónima''': I2P se puede usar para navegar por la web de forma anónima. Para ello configura tu navegador (preferíblemente un navegador Tor) para conectar al proxy I2P. Esto se puede hacer estableciendo los proxies HTTP y HTTPS a ''freedombox.local'' (o la IP local de tu !FreedomBox) con sus respectivos puertos a ''4444'' y ''4445''. Este servicio está disponible sólo cuando accedes a la !FreedomBox usando la red local (redes de la zona ''interna'' del cortaguegos) y no cuando llegas a la !FreedomBox desde Internet. Una excepción a esto es cuando te conectas al servicio VPN de la !FreedomBox desde Internet, en cuyo caso sí puedes usar el servicio de navegación web anónima a través de I2P.
|
||||
* '''Acceso a eepsites''': La red I2P puede albergar sitios web anónimos llamados eepsites cuyo nombre de dominio acaba en `.i2p`. Por ejemplo, `http://i2p-projekt.i2p/` es el sitio web del proyecto I2P en la red I2P. Los eepsites son inaccesibles a un navegador normal a través de una conexión Internet normal. Para navegar a los eepsites tu navegador necesita configurarse para usar los proxies HTTP y HTTPS como se describió antes. Este servicio solo está disponible cuando accedes a la !FreedomBox usando la red local (redes de la zona ''interna'' del cortaguegos) y no cuando llegas a la !FreedomBox desde Internet. Una excepción a esto es cuando te conectas al servicio VPN de la !FreedomBox desde Internet, en cuyo caso sí puedes usar el servicio de acceso a eepsites a través de I2P.
|
||||
* '''Descargas anónima de torrentes''': I2PSnark, una aplicación para descargar y compartir archivos anónimamente mediante la red !BitTorrent está disponible y habilitada por defecto en !FreedomBox. Esta aplicación se controla mediante un interfaz web que se puede abrir desde la sección ''Torrentes Anonimos'' de la app I2P en el interfaz web de !FreedomBox o de la consola de enrutado I2P. Solo los usuarios ingresados pertenecientes al grupo ''Manage I2P application'' pueden usar este servicio.
|
||||
* '''Red IRC''': La red I2P contiene una red IRC llamada Irc2P. Esta red alberga el canal IRC oficial del proyecto I2P, entre otros. Este servicio viene habilitdo de serie en !FreedomBox. Para usarlo abre tu cliente IRC favorito y configuralo para conectar con ''freedombox.local'' (o la IP local de tu !FreedomBox) en el puerto ''6668''. Este servicio solo está disponible cuando accedes a la !FreedomBox usando la red local (redes de la zona ''interna'' del cortaguegos) y no cuando llegas a la !FreedomBox desde Internet. Una excepción a esto es cuando te conectas al servicio VPN de la !FreedomBox desde Internet, en cuyo caso sí puedes usar el servicio de IRC a través de I2P.
|
||||
* '''Consola de enrutado I2P''': Este es el interfaz central de administración de I2P. Muestra el estado actual de I2P, estadísticas de ancho de banda y permite modificar varias preferencias de configuración. Puedes adecuar tu participación en la red I2P y usar/editar una lista con tus sitios I2P (eepsites) favoritos. Solo los usuarios ingresados pertenecientes al grupo ''Manage I2P application'' pueden usar este servicio.
|
||||
|
||||
=== Enlaces externos ===
|
||||
|
||||
* Sitio web: https://geti2p.net/es/
|
||||
* Documentación de uso (en inglés): https://i2pd.readthedocs.io/en/latest/
|
||||
|
||||
|
||||
## END_INCLUDE
|
||||
|
||||
Volver a la [[es/FreedomBox/Features|descripción de Funcionalidades]] o a las páginas del [[es/FreedomBox/Manual|manual]].
|
||||
|
||||
<<Include(es/FreedomBox/Portal)>>
|
||||
@ -24,7 +24,6 @@
|
||||
<<Include(FreedomBox/Manual/Email, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
<<Include(FreedomBox/Manual/FeatherWiki, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
<<Include(FreedomBox/Manual/GitWeb, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
<<Include(FreedomBox/Manual/I2P, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
<<Include(FreedomBox/Manual/Ikiwiki, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
<<Include(FreedomBox/Manual/Infinoted, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
<<Include(FreedomBox/Manual/Janus, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
@ -35,6 +34,7 @@
|
||||
<<Include(FreedomBox/Manual/MiniDLNA, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
<<Include(FreedomBox/Manual/Miniflux, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
<<Include(FreedomBox/Manual/Mumble, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
<<Include(FreedomBox/Manual/Nextcloud, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
<<Include(FreedomBox/Manual/OpenVPN, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
<<Include(FreedomBox/Manual/Privoxy, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
<<Include(FreedomBox/Manual/Quassel, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
|
||||
@ -125,7 +125,6 @@ Los siguientes servicios '''funcionan''' con OpenVPN:
|
||||
* [[es/FreedomBox/Manual/Privoxy|Privoxy]],
|
||||
* [[es/FreedomBox/Manual/Tor|Tor Socks]],
|
||||
* [[es/FreedomBox/Manual/Shadowsocks|Shadowsocks]],
|
||||
* [[es/FreedomBox/Manual/I2P|I2P Proxy]] and
|
||||
* [[es/FreedomBox/Manual/Samba|Samba]].
|
||||
|
||||
Algunos servicios '''no''' funcionan aún con OpenVPN:
|
||||
|
||||
@ -8,6 +8,82 @@ For more technical details, see the [[https://salsa.debian.org/freedombox-team/f
|
||||
|
||||
The following are the release notes for each !FreedomBox version.
|
||||
|
||||
== FreedomBox 24.25 (2024-12-16) ==
|
||||
|
||||
=== Highlights ===
|
||||
|
||||
* deluge: Fix app installation on Debian testing
|
||||
* notifications: Don't error when dismissing missing notifications
|
||||
* ui: Switch to using bootstrap 5
|
||||
|
||||
=== Other Changes ===
|
||||
|
||||
* action_utils: Add utility to ensure that service is stopped
|
||||
* apache: Relax content security policy to allow data: URL
|
||||
* ci: Add flake8 to gitlabci container
|
||||
* d/control: Drop unnecessary recommendations
|
||||
* d/control: Drop version specification on dependencies for Bookworm
|
||||
* debian: Added po-debconf Catalan translation
|
||||
* deluge: Cleanup and simplify setup code
|
||||
* diagnostics: Fix trimming an i18n string
|
||||
* diagnostics: tests: functional: Pick errors more specifically
|
||||
* firewalld: Reduce severity for alert about service on internal zone
|
||||
* help: Add a class to the help index page
|
||||
* help: Update the privacy notice on status log page
|
||||
* i2p: Drop app as it has not been available in Debian for a while
|
||||
* letsencrypt: Declare explicit dependency on openssl
|
||||
* locale: Update translations for Albanian, Bulgarian, Chinese (Simplified Han script), Czech, French, German, Russian, Turkish
|
||||
* matrixsynapse: Fix trimming an i18n string
|
||||
* networks: Fix issue with loading create PPPoE form
|
||||
* networks: Fix minor typo in template related to signal strength
|
||||
* networks: Use new accordion component from Bootstrap 5
|
||||
* openvpn: Declare explicit dependency on openssl
|
||||
* power: Refactor display of package manager busy alerts
|
||||
* radicale: Update link to supported clients
|
||||
* sso: Switch using cryptography module instead of OpenSSL.crypto
|
||||
* tags: Fix issue with JS init on a page without tags
|
||||
* tags: tests: Fix deprecated webdriver attribute
|
||||
* tests: functional: Disable smooth scrolling from Bootstrap 5
|
||||
* tests: functional: Don't try disable app after tests if app was not installed
|
||||
* tests: functional: Fix app installation test skipped on slow machines
|
||||
* ui: Accept default styling of Bootstrap 5 for warning button
|
||||
* ui: Align app icons in the center for home, apps, and help pages
|
||||
* ui: Allow underlining for most links due to Bootstrap 5
|
||||
* ui: Allow users to provide a CSS file to customize styling
|
||||
* ui: Cleanup use of colors with CSS variables
|
||||
* ui: Don't use nav-link inside card
|
||||
* ui: Drop use of badge-* utility classes for newer replacements
|
||||
* ui: Fix flash of notifications popdown during page load
|
||||
* ui: Fix issue with notifications icon showing twice in mobile view
|
||||
* ui: Fix overflow of exception text in message
|
||||
* ui: Fix placement of tags menu under tags input with Bootstrap 5
|
||||
* ui: Fix styling in dismiss button in form errors for Bootstrap 5
|
||||
* ui: Fix toggle button styling for Bootstrap 5
|
||||
* ui: Reduce the gap at the top of the pages
|
||||
* ui: Rename data- attributes to data-bs- for Bootstrap 5
|
||||
* ui: Restore spacing between form elements in Bootstrap 5
|
||||
* ui: Restyle tags, remove underlining of text
|
||||
* ui: Show disabled form elements as grey for Bootstrap 5
|
||||
* ui: Style the 'Log out' item properly
|
||||
* ui: Update custom button styles for Bootstrap 5
|
||||
* ui: Update styling for navbar menu items
|
||||
* ui: Use Bootstrap 5 styling for all alerts
|
||||
* ui: Use collapse instead of dropdown for notification in Bootstrap 5
|
||||
* ui: Workaround dropdowns not working with Bootstrap 5
|
||||
* ui: app, system: Revert to earlier width for card lists
|
||||
* ui: app: Fix an incorrect HTML tag nesting
|
||||
* ui: backups: Drop unused styling in verify host key page
|
||||
* ui: backups: Use Bootstrap color variables instead of static values
|
||||
* ui: diagnostics: Fix gap between headings
|
||||
* ui: diagnostics: Fix layout of repair buttons
|
||||
* ui: firewall: Fix styling with Bootstrap 5
|
||||
* ui: forms: Fix margins for form labels for Bootstrap 5
|
||||
* ui: help: Fix alignment issue with footer links in about page
|
||||
* ui: samba: Fix layout regressions with Bootstrap 5
|
||||
* ui: snapshots: Fix horizontal form layout on mobiles for Bootstrap 5
|
||||
* ui: snapshots: Fix horizontal form styling margins for Bootstrap 5
|
||||
* ui: users: Fix close button for confirmation dialog for Bootstrap 5
|
||||
|
||||
== FreedomBox 24.24 (2024-11-18) ==
|
||||
|
||||
=== Highlights ===
|
||||
|
||||
@ -16,7 +16,6 @@ Puedes otorgar acceso a tu !FreedomBox a otros usuarios. Proporciona el nombre d
|
||||
* feed-reader
|
||||
* freedombox-share
|
||||
* git-access
|
||||
* i2p
|
||||
* minidlna
|
||||
* syncthing
|
||||
* web-search
|
||||
|
||||
@ -22,7 +22,6 @@
|
||||
<<Include(es/FreedomBox/Manual/ejabberd, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
<<Include(es/FreedomBox/Manual/Email, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
<<Include(es/FreedomBox/Manual/GitWeb, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
<<Include(es/FreedomBox/Manual/I2P, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
<<Include(es/FreedomBox/Manual/Ikiwiki, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
<<Include(es/FreedomBox/Manual/Infinoted, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
<<Include(es/FreedomBox/Manual/Janus, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 23 KiB |
@ -3,4 +3,4 @@
|
||||
Package init file.
|
||||
"""
|
||||
|
||||
__version__ = '24.24'
|
||||
__version__ = '24.25'
|
||||
|
||||
@ -64,6 +64,20 @@ def service_ensure_running(service_name):
|
||||
service_disable(service_name)
|
||||
|
||||
|
||||
@contextmanager
|
||||
def service_ensure_stopped(service_name):
|
||||
"""Ensure a service is stopped and return to previous state."""
|
||||
starting_state = service_is_running(service_name)
|
||||
if starting_state:
|
||||
service_disable(service_name)
|
||||
|
||||
try:
|
||||
yield starting_state
|
||||
finally:
|
||||
if starting_state:
|
||||
service_enable(service_name)
|
||||
|
||||
|
||||
def service_is_enabled(service_name, strict_check=False):
|
||||
"""Check if service is enabled in systemd.
|
||||
|
||||
|
||||
@ -121,6 +121,15 @@ def splinter_wait_time():
|
||||
return 0.01
|
||||
|
||||
|
||||
@pytest.fixture(scope='session')
|
||||
def splinter_driver_kwargs():
|
||||
"""Disable smooth scrolling to fix 'Element x not clickable' errors."""
|
||||
from selenium.webdriver.firefox.options import Options
|
||||
driver_options = Options()
|
||||
driver_options.set_preference('general.smoothScroll', False)
|
||||
return {'options': driver_options}
|
||||
|
||||
|
||||
@pytest.fixture(scope='session')
|
||||
def splinter_browser_load_condition():
|
||||
"""When a page it loaded, wait until <body> is available."""
|
||||
|
||||
@ -8,7 +8,7 @@ import re
|
||||
from django.utils.translation import gettext as _
|
||||
from django.utils.translation import gettext_noop
|
||||
|
||||
from plinth import cfg
|
||||
from plinth import cfg, web_server
|
||||
from plinth.utils import is_user_admin
|
||||
|
||||
|
||||
@ -35,6 +35,7 @@ def common(request):
|
||||
'active_menu_urls': active_menu_urls,
|
||||
'box_name': _(cfg.box_name),
|
||||
'user_is_admin': is_user_admin(request, True),
|
||||
'user_css': web_server.get_user_css(),
|
||||
'notifications': notifications_context['notifications'],
|
||||
'notifications_max_severity': notifications_context['max_severity']
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -9,15 +9,15 @@
|
||||
}
|
||||
|
||||
.mount-error {
|
||||
color: orange;
|
||||
color: var(--bs-warning);
|
||||
}
|
||||
|
||||
.mount-success {
|
||||
color: black;
|
||||
color: var(--bs-body-color);
|
||||
}
|
||||
|
||||
.encrypted {
|
||||
color: green;
|
||||
color: var(--bs-success);
|
||||
}
|
||||
|
||||
.inline-block {
|
||||
|
||||
@ -15,13 +15,19 @@
|
||||
|
||||
{{ form|bootstrap }}
|
||||
|
||||
<div class="alert alert-warning" role="alert">
|
||||
{% blocktrans trimmed %}
|
||||
The credentials for this repository are stored on your {{ box_name }}.
|
||||
<br />
|
||||
To restore a backup on a new {{ box_name }} you need the SSH
|
||||
credentials and, if chosen, the encryption passphrase.
|
||||
{% endblocktrans %}
|
||||
<div class="alert alert-warning d-flex align-items-center" role="alert">
|
||||
<div class="me-2">
|
||||
<span class="fa fa-exclamation-triangle" aria-hidden="true"></span>
|
||||
<span class="visually-hidden">{% trans "Caution:" %}</span>
|
||||
</div>
|
||||
<div>
|
||||
{% blocktrans trimmed %}
|
||||
The credentials for this repository are stored on your {{ box_name }}.
|
||||
<br />
|
||||
To restore a backup on a new {{ box_name }} you need the SSH credentials
|
||||
and, if chosen, the encryption passphrase.
|
||||
{% endblocktrans %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="submit" class="btn btn-primary"
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table" id="archives-list">
|
||||
<thead class="collapsible-button" data-toggle="collapse" data-target="#{{ uuid }}">
|
||||
<thead class="collapsible-button" data-bs-toggle="collapse" data-bs-target="#{{ uuid }}">
|
||||
<tr>
|
||||
<th colspan="2">
|
||||
<span class="fa fa-chevron-right fa-fw" aria-hidden="true"></span>
|
||||
|
||||
@ -22,13 +22,17 @@
|
||||
</p>
|
||||
|
||||
{% if max_filesize %}
|
||||
<div class="alert alert-warning" role="alert">
|
||||
<span class="fa fa-exclamation-triangle" aria-hidden="true"></span>
|
||||
<span class="sr-only">{% trans "Caution:" %}</span>
|
||||
{% blocktrans trimmed %}
|
||||
You have {{ max_filesize }} available to restore a backup.
|
||||
Exceeding this limit can leave your {{ box_name }} unusable.
|
||||
{% endblocktrans %}
|
||||
<div class="alert alert-warning d-flex align-items-center" role="alert">
|
||||
<div class="me-2">
|
||||
<span class="fa fa-exclamation-triangle" aria-hidden="true"></span>
|
||||
<span class="visually-hidden">{% trans "Caution:" %}</span>
|
||||
</div>
|
||||
<div>
|
||||
{% blocktrans trimmed %}
|
||||
You have {{ max_filesize }} available to restore a backup.
|
||||
Exceeding this limit can leave your {{ box_name }} unusable.
|
||||
{% endblocktrans %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
@ -21,7 +21,13 @@
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
{% if form.keyscan_error %}
|
||||
<pre class="alert alert-danger">{{ form.keyscan_error }}</pre>
|
||||
<div class="alert alert-danger d-flex align-items-center">
|
||||
<div class="me-2">
|
||||
<span class="fa fa-exclamation-triangle" aria-hidden="true"></span>
|
||||
<span class="visually-hidden">{% trans "Caution:" %}</span>
|
||||
</div>
|
||||
<pre class="mb-0">{{ form.keyscan_error }}</pre>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<p>
|
||||
@ -35,12 +41,12 @@
|
||||
<section>
|
||||
<p>
|
||||
<a class="btn btn-default collapsed collapsible-button"
|
||||
data-toggle="collapse" href="#help" aria-expanded="false">
|
||||
data-bs-toggle="collapse" href="#help" aria-expanded="false">
|
||||
<span class="fa fa-chevron-right fa-fw" aria-hidden="true"></span>
|
||||
{% trans "How to verify?" %}
|
||||
</a>
|
||||
</p>
|
||||
<div class="collapse card-body" id="help">
|
||||
<div class="collapse" id="help">
|
||||
<p>
|
||||
{% blocktrans trimmed %}
|
||||
Run the following command on the SSH host machine. The output
|
||||
|
||||
@ -11,6 +11,7 @@ from plinth.modules.apache.components import Webserver
|
||||
from plinth.modules.backups.components import BackupRestore
|
||||
from plinth.modules.firewall.components import (Firewall,
|
||||
FirewallLocalProtection)
|
||||
from plinth.modules.upgrades import get_current_release
|
||||
from plinth.modules.users import add_user_to_share_group
|
||||
from plinth.modules.users.components import UsersAndGroups
|
||||
from plinth.package import Packages
|
||||
@ -26,12 +27,26 @@ _description = [
|
||||
SYSTEM_USER = 'debian-deluged'
|
||||
|
||||
|
||||
class DelugePackages(Packages):
|
||||
"""Mark deluge app as not available in Debian Bookworm.
|
||||
|
||||
deluge-web is broken in Debian Bookworm. Related bug report:
|
||||
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1031593
|
||||
"""
|
||||
|
||||
def has_unavailable_packages(self) -> bool | None:
|
||||
if get_current_release()[1] == 'bookworm':
|
||||
return True
|
||||
|
||||
return super().has_unavailable_packages()
|
||||
|
||||
|
||||
class DelugeApp(app_module.App):
|
||||
"""FreedomBox app for Deluge."""
|
||||
|
||||
app_id = 'deluge'
|
||||
|
||||
_version = 8
|
||||
_version = 9
|
||||
|
||||
def __init__(self) -> None:
|
||||
"""Create components for the app."""
|
||||
@ -64,7 +79,7 @@ class DelugeApp(app_module.App):
|
||||
allowed_groups=list(groups))
|
||||
self.add(shortcut)
|
||||
|
||||
packages = Packages('packages-deluge', ['deluged', 'deluge-web'])
|
||||
packages = DelugePackages('packages-deluge', ['deluged', 'deluge-web'])
|
||||
self.add(packages)
|
||||
|
||||
dropin_configs = DropinConfigs(
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
[Service]
|
||||
ExecStart=
|
||||
ExecStart=/usr/bin/deluge-web --config /var/lib/deluged/config/ --base=deluge --do-not-daemonize
|
||||
LockPersonality=yes
|
||||
NoNewPrivileges=yes
|
||||
PrivateDevices=yes
|
||||
PrivateTmp=yes
|
||||
ProtectControlGroups=yes
|
||||
ProtectKernelLogs=yes
|
||||
ProtectKernelModules=yes
|
||||
ProtectKernelTunables=yes
|
||||
ProtectSystem=yes
|
||||
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
|
||||
RestrictRealtime=yes
|
||||
StateDirectory=deluged
|
||||
SystemCallArchitectures=native
|
||||
@ -13,7 +13,7 @@ clients = [{
|
||||
|
||||
backup = {
|
||||
'config': {
|
||||
'directories': ['/var/lib/deluged/.config']
|
||||
'directories': ['/var/lib/deluged/config']
|
||||
},
|
||||
'services': ['deluged', 'deluge-web']
|
||||
}
|
||||
|
||||
@ -3,69 +3,21 @@
|
||||
|
||||
import pathlib
|
||||
import shutil
|
||||
import subprocess
|
||||
import time
|
||||
|
||||
import augeas
|
||||
|
||||
from plinth import action_utils
|
||||
from plinth.actions import privileged
|
||||
from plinth.modules.deluge.utils import Config
|
||||
|
||||
DELUGED_DEFAULT_FILE = '/etc/default/deluged'
|
||||
DELUGE_CONF_DIR = pathlib.Path('/var/lib/deluged/.config/deluge/')
|
||||
|
||||
DELUGE_WEB_SYSTEMD_SERVICE_PATH = '/etc/systemd/system/deluge-web.service'
|
||||
DELUGE_WEB_SYSTEMD_SERVICE = '''
|
||||
#
|
||||
# This file is managed and overwritten by Plinth. If you wish to edit
|
||||
# it, disable Deluge in Plinth, remove this file and manage it manually.
|
||||
#
|
||||
[Unit]
|
||||
Description=Deluge Web Interface
|
||||
Documentation=man:deluge-web(1)
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
ExecStart=bash -c "/usr/bin/deluge-web --base=deluge $(/usr/bin/deluge-web --version | grep deluge-web | cut -f2 -d' ' | grep -q '^1.' && echo '' || echo '--do-not-daemonize')"
|
||||
Restart=on-failure
|
||||
User=debian-deluged
|
||||
Group=debian-deluged
|
||||
LockPersonality=yes
|
||||
NoNewPrivileges=yes
|
||||
PrivateDevices=yes
|
||||
PrivateTmp=yes
|
||||
ProtectControlGroups=yes
|
||||
ProtectKernelLogs=yes
|
||||
ProtectKernelModules=yes
|
||||
ProtectKernelTunables=yes
|
||||
ProtectSystem=yes
|
||||
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
|
||||
RestrictRealtime=yes
|
||||
StateDirectory=deluged
|
||||
SystemCallArchitectures=native
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
''' # noqa: E501
|
||||
DELUGE_CONF_DIR = pathlib.Path('/var/lib/deluged/config/')
|
||||
|
||||
|
||||
def _set_configuration(filename, parameter, value):
|
||||
"""Set the configuration parameter."""
|
||||
deluged_is_running = action_utils.service_is_running('deluged')
|
||||
if deluged_is_running:
|
||||
action_utils.service_stop('deluged')
|
||||
deluge_web_is_running = action_utils.service_is_running('deluge-web')
|
||||
if deluge_web_is_running:
|
||||
action_utils.service_stop('deluge-web')
|
||||
|
||||
with Config(DELUGE_CONF_DIR / filename) as config:
|
||||
config.content[parameter] = value
|
||||
|
||||
if deluged_is_running:
|
||||
action_utils.service_start('deluged')
|
||||
if deluge_web_is_running:
|
||||
action_utils.service_start('deluge-web')
|
||||
with action_utils.service_ensure_stopped('deluge-web'):
|
||||
with action_utils.service_ensure_stopped('deluged'):
|
||||
with Config(DELUGE_CONF_DIR / filename) as config:
|
||||
config.content[parameter] = value
|
||||
|
||||
|
||||
def _get_host_id():
|
||||
@ -78,20 +30,6 @@ def _get_host_id():
|
||||
return config.content['hosts'][0][0]
|
||||
|
||||
|
||||
def _set_deluged_daemon_options():
|
||||
"""Set deluged daemon options."""
|
||||
aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD +
|
||||
augeas.Augeas.NO_MODL_AUTOLOAD)
|
||||
aug.set('/augeas/load/Shellvars/lens', 'Shellvars.lns')
|
||||
aug.set('/augeas/load/Shellvars/incl[last() + 1]', DELUGED_DEFAULT_FILE)
|
||||
aug.load()
|
||||
aug.set('/files' + DELUGED_DEFAULT_FILE + '/ENABLE_DELUGED', '1')
|
||||
# overwrite daemon args, use default config directory (same as deluge-web)
|
||||
aug.set('/files' + DELUGED_DEFAULT_FILE + '/DAEMON_ARGS',
|
||||
'"-d -l /var/log/deluged/daemon.log -L info"')
|
||||
aug.save()
|
||||
|
||||
|
||||
@privileged
|
||||
def get_configuration() -> dict[str, str]:
|
||||
"""Return the current deluged configuration."""
|
||||
@ -110,56 +48,44 @@ def set_configuration(download_location: str):
|
||||
@privileged
|
||||
def setup():
|
||||
"""Perform initial setup for deluge."""
|
||||
with open(DELUGE_WEB_SYSTEMD_SERVICE_PATH, 'w',
|
||||
encoding='utf-8') as file_handle:
|
||||
file_handle.write(DELUGE_WEB_SYSTEMD_SERVICE)
|
||||
old_service_path = pathlib.Path('/etc/systemd/system/deluge-web.service')
|
||||
if old_service_path.exists():
|
||||
old_service_path.unlink(missing_ok=True)
|
||||
|
||||
_set_deluged_daemon_options()
|
||||
|
||||
subprocess.check_call(['systemctl', 'daemon-reload'])
|
||||
|
||||
# Restarting an old deluge-web service stops also possible deluged process
|
||||
# that was started from the web interface.
|
||||
action_utils.service_daemon_reload()
|
||||
action_utils.service_try_restart('deluged')
|
||||
action_utils.service_try_restart('deluge-web')
|
||||
|
||||
# Wait until core configuration is available so that status of the app can
|
||||
# be shown properly.
|
||||
_wait_for_configuration('deluged', 'core.conf')
|
||||
_wait_for_configuration()
|
||||
|
||||
# Configure deluge-web to autoconnect to the default deluged daemon.
|
||||
_wait_for_configuration('deluge-web', 'web.conf')
|
||||
host_id = _get_host_id()
|
||||
_set_configuration('web.conf', 'default_daemon', host_id)
|
||||
|
||||
|
||||
def _wait_for_configuration(service, file_name):
|
||||
def _wait_for_configuration():
|
||||
"""Wait until configuration file has been created."""
|
||||
conf_file = DELUGE_CONF_DIR / file_name
|
||||
if conf_file.exists():
|
||||
core_file = DELUGE_CONF_DIR / 'core.conf'
|
||||
web_file = DELUGE_CONF_DIR / 'web.conf'
|
||||
if core_file.exists() and web_file.exists():
|
||||
return
|
||||
|
||||
# deluge-web creates files on first run. deluged on the other than differs
|
||||
# in version. Older version in Debian Buster creates the files after a
|
||||
# restart while newer versions create the files on first run. The following
|
||||
# approach is slightly better for create-on-exit case.
|
||||
is_running = action_utils.service_is_running(service)
|
||||
for interval in range(7):
|
||||
action_utils.service_restart(service)
|
||||
if conf_file.exists():
|
||||
break
|
||||
# deluge-web and deluged create files on first run.
|
||||
with action_utils.service_ensure_running('deluged'):
|
||||
with action_utils.service_ensure_running('deluge-web'):
|
||||
for _ in range(60):
|
||||
if core_file.exists() and web_file.exists():
|
||||
break
|
||||
|
||||
print('Waiting for {service} configuration')
|
||||
time.sleep(2**interval) # Exponentially increase the time waited
|
||||
else:
|
||||
raise Exception(f'Unable to setup {service}.')
|
||||
|
||||
if not is_running:
|
||||
action_utils.service_stop(service)
|
||||
time.sleep(1)
|
||||
else:
|
||||
raise Exception('Unable to setup configuration')
|
||||
|
||||
|
||||
@privileged
|
||||
def uninstall():
|
||||
"""Remove configuration and service files."""
|
||||
# /etc/default/deluged is removed on purge
|
||||
pathlib.Path(DELUGE_WEB_SYSTEMD_SERVICE_PATH).unlink(missing_ok=True)
|
||||
shutil.rmtree(DELUGE_CONF_DIR, ignore_errors=True)
|
||||
|
||||
@ -35,14 +35,12 @@ class TestDelugeApp(functional.BaseAppTests):
|
||||
'nogroupuser')
|
||||
assert not functional.is_available(session_browser, 'deluge')
|
||||
|
||||
functional.login(session_browser)
|
||||
|
||||
def test_upload_torrent(self, session_browser):
|
||||
"""Test uploading a torrent."""
|
||||
functional.app_enable(session_browser, 'deluge')
|
||||
_remove_all_torrents(session_browser)
|
||||
_upload_sample_torrent(session_browser)
|
||||
assert _get_number_of_torrents(session_browser) == 1
|
||||
assert len(_get_torrents(session_browser)) == 1
|
||||
|
||||
@pytest.mark.backups
|
||||
def test_backup_restore(self, session_browser):
|
||||
@ -55,7 +53,7 @@ class TestDelugeApp(functional.BaseAppTests):
|
||||
_remove_all_torrents(session_browser)
|
||||
functional.backup_restore(session_browser, 'deluge', 'test_deluge')
|
||||
assert functional.service_is_running(session_browser, 'deluge')
|
||||
assert _get_number_of_torrents(session_browser) == 1
|
||||
assert len(_get_torrents(session_browser)) == 1
|
||||
|
||||
|
||||
def _get_active_window_title(browser):
|
||||
@ -81,49 +79,30 @@ def _ensure_logged_in(browser):
|
||||
# After a backup restore, service may not be available immediately
|
||||
functional.eventually(service_is_available)
|
||||
|
||||
time.sleep(1) # Wait for Ext.js application in initialize
|
||||
functional.eventually(browser.is_element_present_by_id, ['add'])
|
||||
|
||||
if _get_active_window_title(browser) != 'Login':
|
||||
return
|
||||
def logged_in():
|
||||
active_window_title = _get_active_window_title(browser)
|
||||
|
||||
browser.find_by_id('_password').first.fill('deluge')
|
||||
_click_active_window_button(browser, 'Login')
|
||||
# Change Default Password window appears once.
|
||||
if active_window_title == 'Change Default Password':
|
||||
_click_active_window_button(browser, 'No')
|
||||
|
||||
assert functional.eventually(
|
||||
lambda: _get_active_window_title(browser) != 'Login')
|
||||
functional.eventually(browser.is_element_not_present_by_css,
|
||||
args=['#add.x-item-disabled'], timeout=0.3)
|
||||
if active_window_title == 'Login':
|
||||
browser.find_by_id('_password').first.fill('deluge')
|
||||
_click_active_window_button(browser, 'Login')
|
||||
|
||||
return browser.is_element_not_present_by_css('#add .x-item-disabled')
|
||||
|
||||
def _open_connection_manager(browser):
|
||||
"""Open the connection manager dialog if not already open."""
|
||||
title = 'Connection Manager'
|
||||
if _get_active_window_title(browser) == title:
|
||||
return
|
||||
|
||||
browser.find_by_css('button.x-deluge-connection-manager').first.click()
|
||||
functional.eventually(lambda: _get_active_window_title(browser) == title)
|
||||
|
||||
|
||||
def _ensure_connected(browser):
|
||||
"""Type the connection password if required and start Deluge daemon."""
|
||||
_ensure_logged_in(browser)
|
||||
|
||||
# Change Default Password window appears once.
|
||||
if _get_active_window_title(browser) == 'Change Default Password':
|
||||
_click_active_window_button(browser, 'No')
|
||||
|
||||
assert functional.eventually(browser.is_element_not_present_by_css,
|
||||
args=['#add.x-item-disabled'])
|
||||
functional.eventually(logged_in)
|
||||
|
||||
|
||||
def _remove_all_torrents(browser):
|
||||
"""Remove all torrents from deluge."""
|
||||
_ensure_connected(browser)
|
||||
|
||||
while browser.find_by_css('#torrentGrid .torrent-name'):
|
||||
browser.find_by_css('#torrentGrid .torrent-name').first.click()
|
||||
_ensure_logged_in(browser)
|
||||
|
||||
for torrent in _get_torrents(browser):
|
||||
torrent.click()
|
||||
# Click remove toolbar button
|
||||
browser.find_by_id('remove').first.click()
|
||||
|
||||
@ -155,9 +134,9 @@ def _click_active_window_button(browser, button_text):
|
||||
|
||||
def _upload_sample_torrent(browser):
|
||||
"""Upload a sample torrent into deluge."""
|
||||
_ensure_connected(browser)
|
||||
_ensure_logged_in(browser)
|
||||
|
||||
number_of_torrents = _get_number_of_torrents(browser)
|
||||
number_of_torrents = len(_get_torrents(browser))
|
||||
|
||||
# Click add toolbar button
|
||||
browser.find_by_id('add').first.click()
|
||||
@ -168,35 +147,20 @@ def _upload_sample_torrent(browser):
|
||||
|
||||
file_path = os.path.join(os.path.dirname(__file__), 'data',
|
||||
'sample.torrent')
|
||||
|
||||
if browser.find_by_id('fileUploadForm'): # deluge-web 2.x
|
||||
browser.attach_file('file', file_path)
|
||||
else: # deluge-web 1.x
|
||||
browser.find_by_css('button.x-deluge-add-file').first.click()
|
||||
|
||||
# Add from file window appears
|
||||
functional.eventually(
|
||||
lambda: _get_active_window_title(browser) == 'Add from File')
|
||||
|
||||
# Attach file
|
||||
browser.attach_file('file', file_path)
|
||||
|
||||
# Click Add
|
||||
_click_active_window_button(browser, 'Add')
|
||||
|
||||
functional.eventually(
|
||||
lambda: _get_active_window_title(browser) == 'Add Torrents')
|
||||
browser.attach_file('file', file_path)
|
||||
|
||||
# Click Add
|
||||
time.sleep(1)
|
||||
_click_active_window_button(browser, 'Add')
|
||||
|
||||
functional.eventually(
|
||||
lambda: _get_number_of_torrents(browser) > number_of_torrents)
|
||||
lambda: len(_get_torrents(browser)) > number_of_torrents)
|
||||
|
||||
|
||||
def _get_number_of_torrents(browser):
|
||||
"""Return the number torrents currently in deluge."""
|
||||
_ensure_connected(browser)
|
||||
def _get_torrents(browser):
|
||||
"""Return list of torrents currently in deluge."""
|
||||
_ensure_logged_in(browser)
|
||||
# wait until torrent list is loaded
|
||||
functional.eventually(browser.is_element_present_by_css, ['.x-deluge-all'])
|
||||
|
||||
return len(browser.find_by_css('#torrentGrid .torrent-name'))
|
||||
return browser.find_by_css('#torrentGrid .torrent-name')
|
||||
|
||||
@ -9,27 +9,35 @@
|
||||
|
||||
<h2>{% trans "Diagnostic Results" %}</h2>
|
||||
|
||||
<div class="row align-items-center justify-content-between">
|
||||
<h3>{% blocktrans %}App: {{ app_name }}{% endblocktrans %}</h3>
|
||||
<section>
|
||||
<div class="d-flex align-items-center justify-content-between">
|
||||
<h3>{% blocktrans %}App: {{ app_name }}{% endblocktrans %}</h3>
|
||||
|
||||
{% if show_repair %}
|
||||
<form class="form form-diagnostics-repair-button" method="post"
|
||||
action="{% url 'diagnostics:repair' app_id=app_id %}">
|
||||
{% csrf_token %}
|
||||
<input type="submit" class="btn btn-default"
|
||||
name="repair" value="{% trans "Try to repair" %}"/>
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if results %}
|
||||
{% include "diagnostics_results.html" with results=results %}
|
||||
{% elif exception %}
|
||||
<div class="alert alert-danger" role="alert">
|
||||
{{ exception }}
|
||||
{% if show_repair %}
|
||||
<form class="form form-diagnostics-repair-button" method="post"
|
||||
action="{% url 'diagnostics:repair' app_id=app_id %}">
|
||||
{% csrf_token %}
|
||||
<input type="submit" class="btn btn-default"
|
||||
name="repair" value="{% trans "Try to repair" %}"/>
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
<p>{% trans "This app does not support diagnostics" %}</p>
|
||||
{% endif %}
|
||||
|
||||
{% if results %}
|
||||
{% include "diagnostics_results.html" with results=results %}
|
||||
{% elif exception %}
|
||||
<div class="alert alert-danger d-flex align-items-center" role="alert">
|
||||
<div class="me-2">
|
||||
<span class="fa fa-exclamation-triangle" aria-hidden="true"></span>
|
||||
<span class="visually-hidden">{% trans "Caution:" %}</span>
|
||||
</div>
|
||||
<div>
|
||||
{{ exception }}
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<p>{% trans "This app does not support diagnostics" %}</p>
|
||||
{% endif %}
|
||||
</section>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
@ -33,32 +33,40 @@
|
||||
{% if results %}
|
||||
<h3>{% trans "Results" %}</h3>
|
||||
{% for app_id, app_data in results.results.items %}
|
||||
<div class="row align-items-center justify-content-between">
|
||||
<h4>
|
||||
{% blocktrans with app_name=app_data.name %}
|
||||
App: {{app_name}}
|
||||
{% endblocktrans %}
|
||||
</h4>
|
||||
<section>
|
||||
<div class="d-flex align-items-center justify-content-between">
|
||||
<h4>
|
||||
{% blocktrans trimmed with app_name=app_data.name %}
|
||||
App: {{app_name}}
|
||||
{% endblocktrans %}
|
||||
</h4>
|
||||
|
||||
{% if app_data.show_repair %}
|
||||
<form class="form form-diagnostics-repair-button" method="post"
|
||||
action="{% url 'diagnostics:repair' app_id=app_id %}">
|
||||
{% csrf_token %}
|
||||
<input type="submit" class="btn btn-default"
|
||||
name="repair" value="{% trans "Try to repair" %}"/>
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if app_data.diagnosis %}
|
||||
{% include "diagnostics_results.html" with results=app_data.diagnosis %}
|
||||
{% elif app_data.exception %}
|
||||
<div class="alert alert-danger" role="alert">
|
||||
{{ app_data.exception }}
|
||||
{% if app_data.show_repair %}
|
||||
<form class="form form-diagnostics-repair-button" method="post"
|
||||
action="{% url 'diagnostics:repair' app_id=app_id %}">
|
||||
{% csrf_token %}
|
||||
<input type="submit" class="btn btn-default"
|
||||
name="repair" value="{% trans "Try to repair" %}"/>
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
<p><span class="fa fa-hourglass-o"></span></p>
|
||||
{% endif %}
|
||||
|
||||
{% if app_data.diagnosis %}
|
||||
{% include "diagnostics_results.html" with results=app_data.diagnosis %}
|
||||
{% elif app_data.exception %}
|
||||
<div class="alert alert-danger d-flex align-items-center" role="alert">
|
||||
<div class="me-2">
|
||||
<span class="fa fa-exclamation-triangle" aria-hidden="true"></span>
|
||||
<span class="visually-hidden">{% trans "Caution:" %}</span>
|
||||
</div>
|
||||
<div>
|
||||
{{ app_data.exception }}
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<p><span class="fa fa-hourglass-o"></span></p>
|
||||
{% endif %}
|
||||
</section>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
@ -18,13 +18,13 @@
|
||||
<td>{{ result.translated_description }}</td>
|
||||
<td class="diagnostics-result">
|
||||
{% if result.result == 'passed' %}
|
||||
<span class="badge badge-success">{% trans result.result %}</span>
|
||||
<span class="badge text-bg-success">{% trans result.result %}</span>
|
||||
{% elif result.result == 'failed' %}
|
||||
<span class="badge badge-danger">{% trans result.result %}</span>
|
||||
<span class="badge text-bg-danger">{% trans result.result %}</span>
|
||||
{% elif result.result == 'error' or result.result == 'warning' %}
|
||||
<span class="badge badge-warning">{% trans result.result %}</span>
|
||||
<span class="badge text-bg-warning">{% trans result.result %}</span>
|
||||
{% elif result.result == 'skipped' %}
|
||||
<span class="badge badge-secondary">{% trans result.result %}</span>
|
||||
<span class="badge text-bg-secondary">{% trans result.result %}</span>
|
||||
{% else %}
|
||||
{{ result.result }}
|
||||
{% endif %}
|
||||
|
||||
@ -28,11 +28,11 @@
|
||||
<td>{{ domain.timestamp|timesince }}</td>
|
||||
<td>
|
||||
{% if domain.result %}
|
||||
<span class="badge badge-success">
|
||||
<span class="badge text-bg-success">
|
||||
{% trans "Success" %}
|
||||
</span>
|
||||
{% else %}
|
||||
<span class="badge badge-warning">
|
||||
<span class="badge text-bg-warning">
|
||||
{% trans "Failed" %}
|
||||
</span>
|
||||
{% endif %}
|
||||
|
||||
@ -2,12 +2,9 @@
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
a.dropdown-toggle {
|
||||
color: black;
|
||||
}
|
||||
|
||||
a.dropdown-toggle:hover {
|
||||
.app-name > a.dropdown-toggle {
|
||||
text-decoration: none;
|
||||
color: var(--bs-table-color-state, var(--bs-table-color-type, var(--bs-table-color)));
|
||||
}
|
||||
|
||||
td.service {
|
||||
@ -22,7 +19,3 @@ td.service {
|
||||
.service-status {
|
||||
width: 11rem;
|
||||
}
|
||||
|
||||
tr.collapse {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
@ -28,18 +28,18 @@
|
||||
<tr>
|
||||
<td class="app-name">
|
||||
<a class="dropdown-toggle" href="#"
|
||||
data-toggle="collapse" role="button"
|
||||
data-target=".{{component.component_id}}"
|
||||
data-bs-toggle="collapse" role="button"
|
||||
data-bs-target=".{{component.component_id}}"
|
||||
aria-expanded="false"
|
||||
aria-controls="{{component.component_id}}">
|
||||
{{ component.name }}</a>
|
||||
</td>
|
||||
<td class="app-status">
|
||||
{% if component.is_enabled %}
|
||||
<span class='badge badge-success'>
|
||||
<span class='badge text-bg-success'>
|
||||
{% trans "Enabled" %}</span>
|
||||
{% else %}
|
||||
<span class='badge badge-warning'>
|
||||
<span class='badge text-bg-warning'>
|
||||
{% trans "Disabled" %}</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
@ -54,16 +54,16 @@
|
||||
</td>
|
||||
<td class="service-status">
|
||||
{% if port.name in internal_enabled_ports and port.name in external_enabled_ports %}
|
||||
<span class='badge badge-success'>
|
||||
<span class='badge text-bg-success'>
|
||||
{% trans "Permitted" %}</span>
|
||||
{% elif port.name in internal_enabled_ports %}
|
||||
<span class='badge badge-warning'>
|
||||
<span class='badge text-bg-warning'>
|
||||
{% trans "Permitted (internal only)" %}</span>
|
||||
{% elif port.name in external_enabled_ports %}
|
||||
<span class='badge badge-warning'>
|
||||
<span class='badge text-bg-warning'>
|
||||
{% trans "Permitted (external only)" %}</span>
|
||||
{% else %}
|
||||
<span class='badge badge-danger'>
|
||||
<span class='badge text-bg-danger'>
|
||||
{% trans "Blocked" %}</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
|
||||
@ -14,22 +14,34 @@
|
||||
</p>
|
||||
|
||||
{% if version %}
|
||||
<div class="alert {% if new_version %}alert-warning{% else %}alert-success{% endif %}">
|
||||
{% blocktrans trimmed %}
|
||||
You are running {{ os_release }} and {{ box_name }} version {{ version }}.
|
||||
{% endblocktrans %}
|
||||
<div class="alert {% if new_version %}alert-warning{% else %}alert-success{% endif %}
|
||||
d-flex align-items-center">
|
||||
<div class="me-2">
|
||||
{% if new_version %}
|
||||
<span class="fa fa-exclamation-triangle" aria-hidden="true"></span>
|
||||
<span class="visually-hidden">{% trans "Caution:" %}</span>
|
||||
{% else %}
|
||||
<span class="fa fa-check-circle" aria-hidden="true"></span>
|
||||
<span class="visually-hidden">{% trans "Success:" %}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div>
|
||||
{% blocktrans trimmed %}
|
||||
You are running {{ os_release }} and {{ box_name }} version {{ version }}.
|
||||
{% endblocktrans %}
|
||||
|
||||
{% if new_version %}
|
||||
{% url 'upgrades:index' as upgrades_url %}
|
||||
{% blocktrans trimmed %}
|
||||
There is a new {{ box_name }} version
|
||||
<a href="{{ upgrades_url }}">available</a>.
|
||||
{% endblocktrans %}
|
||||
{% else %}
|
||||
{% blocktrans trimmed %}
|
||||
{{ box_name }} is up to date.
|
||||
{% endblocktrans %}
|
||||
{% endif %}
|
||||
{% if new_version %}
|
||||
{% url 'upgrades:index' as upgrades_url %}
|
||||
{% blocktrans trimmed %}
|
||||
There is a new {{ box_name }} version
|
||||
<a href="{{ upgrades_url }}">available</a>.
|
||||
{% endblocktrans %}
|
||||
{% else %}
|
||||
{% blocktrans trimmed %}
|
||||
{{ box_name }} is up to date.
|
||||
{% endblocktrans %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
@ -53,7 +53,7 @@
|
||||
</p>
|
||||
<p>
|
||||
<a class="btn btn-default collapsed collapsible-button" role="button"
|
||||
data-toggle="collapse" href="#collapse-issues" aria-expanded="false"
|
||||
data-bs-toggle="collapse" href="#collapse-issues" aria-expanded="false"
|
||||
aria-controls="collapse-issues">
|
||||
<span class="fa fa-chevron-right fa-fw" aria-hidden="true"></span>
|
||||
{% trans "Show issues" %}
|
||||
|
||||
@ -7,6 +7,8 @@
|
||||
{% load firstboot_extras %}
|
||||
{% load static %}
|
||||
|
||||
{% block body_class %}help-page{% endblock %}
|
||||
|
||||
{% block content-container %}
|
||||
<div class="container content-container">
|
||||
<h2>{% trans "Help" %}</h2>
|
||||
|
||||
@ -18,14 +18,18 @@
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
|
||||
<p class="alert alert-warning">
|
||||
<span class="fa fa-exclamation-triangle" aria-hidden="true"></span>
|
||||
<span class="sr-only">{% trans "Caution:" %}</span>
|
||||
{% blocktrans trimmed %}
|
||||
Please remove any passwords or other personal information from
|
||||
the log before submitting the bug report.
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
<div class="alert alert-warning d-flex align-items-center">
|
||||
<div class="me-2">
|
||||
<span class="fa fa-exclamation-triangle" aria-hidden="true"></span>
|
||||
<span class="visually-hidden">{% trans "Caution:" %}</span>
|
||||
</div>
|
||||
<div>
|
||||
{% blocktrans trimmed %}
|
||||
Please remove any personal information from the log before submitting
|
||||
the bug report.
|
||||
{% endblocktrans %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
<pre class="status-log">{{ data }}</pre>
|
||||
|
||||
@ -172,12 +172,12 @@ MANUAL_PAGES = ('Apache_userdir', 'APU', 'Backups', 'BananaPro', 'BeagleBone',
|
||||
'DateTime', 'Debian', 'Deluge', 'Developer', 'Diagnostics',
|
||||
'Download', 'DynamicDNS', 'ejabberd', 'Firewall',
|
||||
'freedombox-manual', 'GettingHelp', 'GitWeb', 'Hardware',
|
||||
'I2P', 'Ikiwiki', 'Infinoted', 'Introduction', 'JSXC',
|
||||
'LetsEncrypt', 'Maker', 'MatrixSynapse', 'MediaWiki',
|
||||
'Minetest', 'MiniDLNA', 'Mumble', 'NameServices', 'Networks',
|
||||
'OpenVPN', 'OrangePiZero', 'PageKite', 'pcDuino3',
|
||||
'Performance', 'PineA64+', 'PioneerEdition', 'Plinth', 'Power',
|
||||
'Privoxy', 'Quassel', 'QuickStart', 'Radicale', 'RaspberryPi2',
|
||||
'Ikiwiki', 'Infinoted', 'Introduction', 'JSXC', 'LetsEncrypt',
|
||||
'Maker', 'MatrixSynapse', 'MediaWiki', 'Minetest', 'MiniDLNA',
|
||||
'Mumble', 'NameServices', 'Networks', 'OpenVPN',
|
||||
'OrangePiZero', 'PageKite', 'pcDuino3', 'Performance',
|
||||
'PineA64+', 'PioneerEdition', 'Plinth', 'Power', 'Privoxy',
|
||||
'Quassel', 'QuickStart', 'Radicale', 'RaspberryPi2',
|
||||
'RaspberryPi3B+', 'RaspberryPi3B', 'RaspberryPi4B',
|
||||
'ReleaseNotes', 'Rock64', 'RockPro64', 'Roundcube', 'Samba',
|
||||
'Searx', 'SecureShell', 'Security', 'ServiceDiscovery',
|
||||
|
||||
@ -1,122 +0,0 @@
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
"""FreedomBox app to configure I2P."""
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from plinth import app as app_module
|
||||
from plinth import frontpage, menu
|
||||
from plinth.config import DropinConfigs
|
||||
from plinth.daemon import Daemon
|
||||
from plinth.modules.apache.components import Webserver
|
||||
from plinth.modules.backups.components import BackupRestore
|
||||
from plinth.modules.firewall.components import (Firewall,
|
||||
FirewallLocalProtection)
|
||||
from plinth.modules.i2p.resources import FAVORITES
|
||||
from plinth.modules.users.components import UsersAndGroups
|
||||
from plinth.package import Packages
|
||||
|
||||
from . import manifest, privileged
|
||||
|
||||
_description = [
|
||||
_('The Invisible Internet Project is an anonymous network layer intended '
|
||||
'to protect communication from censorship and surveillance. I2P '
|
||||
'provides anonymity by sending encrypted traffic through a '
|
||||
'volunteer-run network distributed around the world.'),
|
||||
_('Find more information about I2P on their project '
|
||||
'<a href="https://geti2p.net" target="_blank">homepage</a>.'),
|
||||
_('The first visit to the provided web interface will initiate the '
|
||||
'configuration process.')
|
||||
]
|
||||
|
||||
tunnels_to_manage = {
|
||||
'I2P HTTP Proxy': 'i2p-http-proxy-freedombox',
|
||||
'I2P HTTPS Proxy': 'i2p-https-proxy-freedombox',
|
||||
'Irc2P': 'i2p-irc-freedombox'
|
||||
}
|
||||
|
||||
|
||||
class I2PApp(app_module.App):
|
||||
"""FreedomBox app for I2P."""
|
||||
|
||||
app_id = 'i2p'
|
||||
|
||||
_version = 3
|
||||
|
||||
def __init__(self) -> None:
|
||||
"""Create components for the app."""
|
||||
super().__init__()
|
||||
|
||||
groups = {'i2p': _('Manage I2P application')}
|
||||
|
||||
info = app_module.Info(app_id=self.app_id, version=self._version,
|
||||
name=_('I2P'), icon_filename='i2p',
|
||||
short_description=_('Anonymity Network'),
|
||||
description=_description, manual_page='I2P',
|
||||
clients=manifest.clients, tags=manifest.tags)
|
||||
self.add(info)
|
||||
|
||||
menu_item = menu.Menu('menu-i2p', info.name, info.short_description,
|
||||
info.icon_filename, 'i2p:index',
|
||||
parent_url_name='apps')
|
||||
self.add(menu_item)
|
||||
|
||||
shortcut = frontpage.Shortcut('shortcut-i2p', info.name,
|
||||
short_description=info.short_description,
|
||||
icon=info.icon_filename, url='/i2p/',
|
||||
clients=info.clients,
|
||||
login_required=True,
|
||||
allowed_groups=list(groups))
|
||||
self.add(shortcut)
|
||||
|
||||
packages = Packages('packages-i2p', ['i2p'])
|
||||
self.add(packages)
|
||||
|
||||
dropin_configs = DropinConfigs('dropin-configs-i2p', [
|
||||
'/etc/apache2/conf-available/i2p-freedombox.conf',
|
||||
])
|
||||
self.add(dropin_configs)
|
||||
|
||||
firewall = Firewall('firewall-i2p-web', info.name,
|
||||
ports=['http', 'https'], is_external=True)
|
||||
self.add(firewall)
|
||||
|
||||
firewall = Firewall('firewall-i2p-proxies', _('I2P Proxy'),
|
||||
ports=tunnels_to_manage.values(),
|
||||
is_external=False)
|
||||
self.add(firewall)
|
||||
|
||||
firewall_local_protection = FirewallLocalProtection(
|
||||
'firewall-local-protection-i2p', ['7657'])
|
||||
self.add(firewall_local_protection)
|
||||
|
||||
webserver = Webserver('webserver-i2p', 'i2p-freedombox',
|
||||
urls=['https://{host}/i2p/'])
|
||||
self.add(webserver)
|
||||
|
||||
daemon = Daemon('daemon-i2p', 'i2p', listen_ports=[(7657, 'tcp6')])
|
||||
self.add(daemon)
|
||||
|
||||
users_and_groups = UsersAndGroups('users-and-groups-i2p',
|
||||
groups=groups)
|
||||
self.add(users_and_groups)
|
||||
|
||||
backup_restore = BackupRestore('backup-restore-i2p', **manifest.backup)
|
||||
self.add(backup_restore)
|
||||
|
||||
def setup(self, old_version):
|
||||
"""Install and configure the app."""
|
||||
super().setup(old_version)
|
||||
|
||||
if not old_version:
|
||||
self.disable()
|
||||
# Add favorites to the configuration
|
||||
for fav in FAVORITES:
|
||||
privileged.add_favorite(fav['name'], fav['url'],
|
||||
fav.get('description'),
|
||||
fav.get('icon'))
|
||||
|
||||
# Tunnels to all interfaces
|
||||
for tunnel in tunnels_to_manage:
|
||||
privileged.set_tunnel_property(tunnel, 'interface', '0.0.0.0')
|
||||
|
||||
self.enable()
|
||||
@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<service>
|
||||
<short>I2P HTTP Proxy</short>
|
||||
<description>The Invisible Internet Project is an anonymous network layer intended to protect communication from censorship and surveillance. I2P provides anonymity by sending encrypted traffic through a volunteer-run network distributed around the world. Enable this if a running an I2P server with HTTP proxy and wish to connect into the I2P network to browse eepsites.</description>
|
||||
<port protocol="tcp" port="4444"/>
|
||||
</service>
|
||||
@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<service>
|
||||
<short>I2P HTTPS Proxy</short>
|
||||
<description>The Invisible Internet Project is an anonymous network layer intended to protect communication from censorship and surveillance. I2P provides anonymity by sending encrypted traffic through a volunteer-run network distributed around the world. Enable this if a running an I2P server with HTTPS proxy and wish to connect into the I2P network to browse eepsites.</description>
|
||||
<port protocol="tcp" port="4445"/>
|
||||
</service>
|
||||
@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<service>
|
||||
<short>I2P IRC Tunnel</short>
|
||||
<description>The Invisible Internet Project is an anonymous network layer intended to protect communication from censorship and surveillance. I2P provides anonymity by sending encrypted traffic through a volunteer-run network distributed around the world. Enable this if a running an I2P server with IRC tunnel and wish to access the Irc2P network.</description>
|
||||
<port protocol="tcp" port="6668"/>
|
||||
</service>
|
||||
@ -1,30 +0,0 @@
|
||||
##
|
||||
## On all sites, provide I2P on a default path: /i2p
|
||||
##
|
||||
## Requires the following Apache modules to be enabled:
|
||||
## mod_headers
|
||||
## mod_proxy
|
||||
## mod_proxy_http
|
||||
## mod_proxy_html
|
||||
##
|
||||
<Location /i2p>
|
||||
# Disable compression
|
||||
# As soon as it has to be chunked, it doesn't work
|
||||
RequestHeader unset Accept-Encoding
|
||||
|
||||
ProxyPass http://localhost:7657
|
||||
ProxyPassReverse http://localhost:7657
|
||||
|
||||
# Rewrite absolute urls from i2p to pass through apache
|
||||
ProxyHTMLEnable On
|
||||
ProxyHTMLURLMap / /i2p/
|
||||
|
||||
Include includes/freedombox-single-sign-on.conf
|
||||
<IfModule mod_auth_pubtkt.c>
|
||||
TKTAuthToken "admin" "i2p"
|
||||
</IfModule>
|
||||
</Location>
|
||||
|
||||
# Catch some other root i2p addresses
|
||||
# These are most likely generated by javascript
|
||||
RedirectMatch "^/(i2p[^/]+.*)" "/i2p/$1"
|
||||
@ -1 +0,0 @@
|
||||
plinth.modules.i2p
|
||||
@ -1,232 +0,0 @@
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
"""
|
||||
Various helpers for the I2P app.
|
||||
"""
|
||||
|
||||
import os
|
||||
import re
|
||||
from collections import OrderedDict
|
||||
|
||||
import augeas
|
||||
|
||||
I2P_CONF_DIR = '/var/lib/i2p/i2p-config'
|
||||
FILE_TUNNEL_CONF = os.path.join(I2P_CONF_DIR, 'i2ptunnel.config')
|
||||
TUNNEL_IDX_REGEX = re.compile(r'tunnel.(\d+).name$')
|
||||
I2P_ROUTER_CONF = os.path.join(I2P_CONF_DIR, 'router.config')
|
||||
|
||||
|
||||
class TunnelEditor():
|
||||
"""Helper to edit I2P tunnel configuration file using augeas.
|
||||
|
||||
:type aug: augeas.Augeas
|
||||
|
||||
"""
|
||||
def __init__(self, conf_filename=None, idx=None):
|
||||
self.conf_filename = conf_filename or FILE_TUNNEL_CONF
|
||||
self.idx = idx
|
||||
self.aug = None
|
||||
|
||||
@property
|
||||
def lines(self):
|
||||
"""Return lines from configuration file."""
|
||||
if self.aug:
|
||||
return self.aug.match('/files{}/*'.format(self.conf_filename))
|
||||
|
||||
return []
|
||||
|
||||
def read_conf(self):
|
||||
"""Load an instance of Augeaus for processing APT configuration.
|
||||
|
||||
Chainable method.
|
||||
|
||||
"""
|
||||
self.aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD +
|
||||
augeas.Augeas.NO_MODL_AUTOLOAD)
|
||||
self.aug.set('/augeas/load/Properties/lens', 'Properties.lns')
|
||||
self.aug.set('/augeas/load/Properties/incl[last() + 1]',
|
||||
self.conf_filename)
|
||||
self.aug.load()
|
||||
|
||||
return self
|
||||
|
||||
def write_conf(self):
|
||||
"""Write changes to the configuration file to disk.
|
||||
|
||||
Chainable method.
|
||||
|
||||
"""
|
||||
self.aug.save()
|
||||
return self
|
||||
|
||||
def set_tunnel_idx(self, name):
|
||||
"""Finds the index of the tunnel with the given name.
|
||||
|
||||
Chainable method.
|
||||
|
||||
:type name: basestring
|
||||
|
||||
"""
|
||||
for prop in self.aug.match('/files{}/*'.format(self.conf_filename)):
|
||||
match = TUNNEL_IDX_REGEX.search(prop)
|
||||
if match and self.aug.get(prop) == name:
|
||||
self.idx = int(match.group(1))
|
||||
return self
|
||||
|
||||
raise ValueError('No tunnel called {}'.format(name))
|
||||
|
||||
def calc_prop_path(self, tunnel_prop):
|
||||
"""Calculates the property name as found in the properties files.
|
||||
|
||||
:type tunnel_prop: str
|
||||
:rtype: basestring
|
||||
|
||||
"""
|
||||
calced_prop_path = \
|
||||
'/files{filepath}/tunnel.{idx}.{tunnel_prop}'.format(
|
||||
idx=self.idx,
|
||||
tunnel_prop=tunnel_prop,
|
||||
filepath=self.conf_filename)
|
||||
return calced_prop_path
|
||||
|
||||
def set_tunnel_prop(self, tunnel_prop, value):
|
||||
"""Updates a tunnel's property.
|
||||
|
||||
The idx has to be set and the property has to exist in the config file
|
||||
and belong to the tunnel's properties.
|
||||
|
||||
See calc_prop_path.
|
||||
|
||||
Chainable method.
|
||||
|
||||
:param tunnel_prop:
|
||||
:type tunnel_prop: str
|
||||
:param value:
|
||||
:type value: basestring | int
|
||||
:return:
|
||||
:rtype:
|
||||
|
||||
"""
|
||||
if self.idx is None:
|
||||
raise ValueError(
|
||||
'Please init the tunnel index before calling this method')
|
||||
|
||||
calc_prop_path = self.calc_prop_path(tunnel_prop)
|
||||
self.aug.set(calc_prop_path, value)
|
||||
return self
|
||||
|
||||
def __getitem__(self, tunnel_prop):
|
||||
ret = self.aug.get(self.calc_prop_path(tunnel_prop))
|
||||
if ret is None:
|
||||
raise KeyError('Unknown property {}'.format(tunnel_prop))
|
||||
|
||||
return ret
|
||||
|
||||
def __setitem__(self, tunnel_prop, value):
|
||||
self.aug.set(self.calc_prop_path(tunnel_prop), value)
|
||||
|
||||
|
||||
class RouterEditor():
|
||||
"""Helper to edit I2P router configuration file using augeas.
|
||||
|
||||
:type aug: augeas.Augeas
|
||||
|
||||
"""
|
||||
|
||||
FAVORITE_PROP = 'routerconsole.favorites'
|
||||
FAVORITE_TUPLE_SIZE = 4
|
||||
|
||||
def __init__(self, filename=None):
|
||||
self.conf_filename = filename or I2P_ROUTER_CONF
|
||||
self.aug = None
|
||||
|
||||
def read_conf(self):
|
||||
"""Load an instance of Augeaus for processing APT configuration.
|
||||
|
||||
Chainable method.
|
||||
|
||||
"""
|
||||
self.aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD +
|
||||
augeas.Augeas.NO_MODL_AUTOLOAD)
|
||||
self.aug.set('/augeas/load/Properties/lens', 'Properties.lns')
|
||||
self.aug.set('/augeas/load/Properties/incl[last() + 1]',
|
||||
self.conf_filename)
|
||||
self.aug.load()
|
||||
return self
|
||||
|
||||
def write_conf(self):
|
||||
"""Write changes to the configuration file to disk.
|
||||
|
||||
Chainable method.
|
||||
|
||||
"""
|
||||
self.aug.save()
|
||||
return self
|
||||
|
||||
@property
|
||||
def favorite_property(self):
|
||||
"""Return the favourites property from configuration file."""
|
||||
return '/files{filename}/{prop}'.format(filename=self.conf_filename,
|
||||
prop=self.FAVORITE_PROP)
|
||||
|
||||
def add_favorite(self, name, url, description=None, icon=None):
|
||||
"""Add a favorite to the router configuration file.
|
||||
|
||||
Favorites are in a single string and separated by ','. none of the
|
||||
incoming params can therefore use commas. I2P replaces the commas by
|
||||
dots.
|
||||
|
||||
That's ok for the name and description, but not for the url and icon.
|
||||
|
||||
:type name: basestring
|
||||
:type url: basestring
|
||||
:type description: basestring
|
||||
:type icon: basestring
|
||||
|
||||
"""
|
||||
if not description:
|
||||
description = ''
|
||||
|
||||
if not icon:
|
||||
icon = '/themes/console/images/eepsite.png'
|
||||
|
||||
if ',' in url:
|
||||
raise ValueError('URL cannot contain commas')
|
||||
|
||||
if ',' in icon:
|
||||
raise ValueError('Icon cannot contain commas')
|
||||
|
||||
name = name.replace(',', '.')
|
||||
description = description.replace(',', '.')
|
||||
|
||||
prop = self.favorite_property
|
||||
favorites = self.aug.get(prop) or ''
|
||||
new_favorite = '{name},{description},{url},{icon},'.format(
|
||||
name=name, description=description, url=url, icon=icon)
|
||||
self.aug.set(prop, favorites + new_favorite)
|
||||
return self
|
||||
|
||||
def get_favorites(self):
|
||||
"""Return list of favorites."""
|
||||
favs_string = self.aug.get(self.favorite_property) or ''
|
||||
favs_split = favs_string.split(',')
|
||||
|
||||
# There's a trailing comma --> 1 extra
|
||||
favs_len = len(favs_split)
|
||||
if favs_len > 0:
|
||||
favs_split = favs_split[:-1]
|
||||
favs_len = len(favs_split)
|
||||
|
||||
if favs_len % self.FAVORITE_TUPLE_SIZE:
|
||||
raise SyntaxError("Invalid number of fields in favorite line")
|
||||
|
||||
favs = OrderedDict()
|
||||
for index in range(0, favs_len, self.FAVORITE_TUPLE_SIZE):
|
||||
next_index = index + self.FAVORITE_TUPLE_SIZE
|
||||
name, description, url, icon = favs_split[index:next_index]
|
||||
favs[url] = {
|
||||
'name': name,
|
||||
'description': description,
|
||||
'icon': icon
|
||||
}
|
||||
|
||||
return favs
|
||||
@ -1,43 +0,0 @@
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
"""
|
||||
Application manifest for I2P.
|
||||
"""
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
_package_id = 'net.geti2p.i2p'
|
||||
_download_url = 'https://geti2p.net/download'
|
||||
|
||||
clients = [{
|
||||
'name':
|
||||
_('I2P'),
|
||||
'platforms': [{
|
||||
'type': 'web',
|
||||
'url': '/i2p/'
|
||||
}, {
|
||||
'type': 'package',
|
||||
'format': 'deb',
|
||||
'name': 'i2p',
|
||||
}, {
|
||||
'type': 'download',
|
||||
'os': 'gnu-linux',
|
||||
'url': _download_url,
|
||||
}, {
|
||||
'type': 'download',
|
||||
'os': 'macos',
|
||||
'url': _download_url,
|
||||
}, {
|
||||
'type': 'download',
|
||||
'os': 'windows',
|
||||
'url': _download_url,
|
||||
}]
|
||||
}]
|
||||
|
||||
backup = {
|
||||
'secrets': {
|
||||
'directories': ['/var/lib/i2p/i2p-config']
|
||||
},
|
||||
'services': ['i2p']
|
||||
}
|
||||
|
||||
tags = [_('Anonymity network'), _('Censorship resistance')]
|
||||
@ -1,24 +0,0 @@
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
"""Configure I2P."""
|
||||
|
||||
from plinth.actions import privileged
|
||||
from plinth.modules.i2p.helpers import RouterEditor, TunnelEditor
|
||||
|
||||
|
||||
@privileged
|
||||
def set_tunnel_property(name: str, property_: str, value: str):
|
||||
"""Modify the configuration file for a certain tunnel."""
|
||||
editor = TunnelEditor()
|
||||
editor \
|
||||
.read_conf() \
|
||||
.set_tunnel_idx(name) \
|
||||
.set_tunnel_prop(property_, value) \
|
||||
.write_conf()
|
||||
|
||||
|
||||
@privileged
|
||||
def add_favorite(name: str, url: str, description: str | None,
|
||||
icon: str | None):
|
||||
"""Add a favorite to router.config."""
|
||||
editor = RouterEditor()
|
||||
editor.read_conf().add_favorite(name, url, description, icon).write_conf()
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user