deluge: Use privileged decorator for actions

Tests:

- Functional tests succeed
- Setup completes successfully
  - deluge-web service create successfully
  - systemd is reloaded
  - deluge-web is restarted
  - deluged is restarted
- Updating download location sets it in core.conf
  - Deluge web interface reflects that
  - Correct location is shown after update

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
Sunil Mohan Adapa 2022-08-26 16:27:44 -07:00 committed by James Valleroy
parent f9fd1b142a
commit 884e0d69ef
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808
3 changed files with 21 additions and 70 deletions

View File

@ -1,11 +1,8 @@
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
""" """FreedomBox app to configure a Deluge web client."""
FreedomBox app to configure a Deluge web client.
"""
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from plinth import actions
from plinth import app as app_module from plinth import app as app_module
from plinth import frontpage, menu from plinth import frontpage, menu
from plinth.daemon import Daemon from plinth.daemon import Daemon
@ -16,7 +13,7 @@ from plinth.modules.users import add_user_to_share_group
from plinth.modules.users.components import UsersAndGroups from plinth.modules.users.components import UsersAndGroups
from plinth.package import Packages from plinth.package import Packages
from . import manifest from . import manifest, privileged
_description = [ _description = [
_('Deluge is a BitTorrent client that features a Web UI.'), _('Deluge is a BitTorrent client that features a Web UI.'),
@ -96,5 +93,5 @@ class DelugeApp(app_module.App):
"""Install and configure the app.""" """Install and configure the app."""
super().setup(old_version) super().setup(old_version)
add_user_to_share_group(SYSTEM_USER) add_user_to_share_group(SYSTEM_USER)
actions.superuser_run('deluge', ['setup']) privileged.setup()
self.enable() self.enable()

61
actions/deluge → plinth/modules/deluge/privileged.py Executable file → Normal file
View File

@ -1,11 +1,6 @@
#!/usr/bin/python3
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
""" """Configuration helper for BitTorrent web client."""
Configuration helper for BitTorrent web client.
"""
import argparse
import json
import pathlib import pathlib
import subprocess import subprocess
import time import time
@ -13,6 +8,7 @@ import time
import augeas import augeas
from plinth import action_utils from plinth import action_utils
from plinth.actions import privileged
from plinth.modules.deluge.utils import Config from plinth.modules.deluge.utils import Config
DELUGED_DEFAULT_FILE = '/etc/default/deluged' DELUGED_DEFAULT_FILE = '/etc/default/deluged'
@ -53,27 +49,6 @@ WantedBy=multi-user.target
''' # noqa: E501 ''' # noqa: E501
def parse_arguments():
"""Return parsed command line arguments as dictionary."""
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest='subcommand', help='Sub command')
subparsers.add_parser('setup', help='Setup deluge')
subparsers.add_parser('get-configuration',
help='Return the current configuration')
subparser = subparsers.add_parser('set-configuration',
help='Set the configuration parameter')
subparser.add_argument('parameter',
help='Name of the configuration parameter')
subparser.add_argument('value',
help='Value of the configuration parameter')
subparsers.required = True
return parser.parse_args()
def _set_configuration(filename, parameter, value): def _set_configuration(filename, parameter, value):
"""Set the configuration parameter.""" """Set the configuration parameter."""
deluged_is_running = action_utils.service_is_running('deluged') deluged_is_running = action_utils.service_is_running('deluged')
@ -116,25 +91,24 @@ def _set_deluged_daemon_options():
aug.save() aug.save()
def subcommand_get_configuration(_): @privileged
"""Return the current deluged configuration in JSON format.""" def get_configuration() -> dict[str, str]:
"""Return the current deluged configuration."""
with Config(DELUGE_CONF_DIR / 'core.conf') as config: with Config(DELUGE_CONF_DIR / 'core.conf') as config:
download_location = config.content['download_location'] download_location = config.content['download_location']
print(json.dumps({'download_location': download_location})) return {'download_location': download_location}
def subcommand_set_configuration(arguments): @privileged
def set_configuration(download_location: str):
"""Set the deluged configuration.""" """Set the deluged configuration."""
if arguments.parameter != 'download_location': _set_configuration('core.conf', 'download_location', download_location)
return
_set_configuration('core.conf', arguments.parameter, arguments.value)
def subcommand_setup(_): @privileged
def setup():
"""Perform initial setup for deluge.""" """Perform initial setup for deluge."""
with open(DELUGE_WEB_SYSTEMD_SERVICE_PATH, 'w', with open(DELUGE_WEB_SYSTEMD_SERVICE_PATH, 'w',
encoding='utf-8') as file_handle: encoding='utf-8') as file_handle:
file_handle.write(DELUGE_WEB_SYSTEMD_SERVICE) file_handle.write(DELUGE_WEB_SYSTEMD_SERVICE)
@ -180,16 +154,3 @@ def _wait_for_configuration(service, file_name):
if not is_running: if not is_running:
action_utils.service_stop(service) action_utils.service_stop(service)
def main():
"""Parse arguments and perform all duties."""
arguments = parse_arguments()
subcommand = arguments.subcommand.replace('-', '_')
subcommand_method = globals()['subcommand_' + subcommand]
subcommand_method(arguments)
if __name__ == '__main__':
main()

View File

@ -1,20 +1,18 @@
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
""" """Django views for Deluge."""
Django views for Deluge.
"""
import json
from django.contrib import messages from django.contrib import messages
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from plinth import actions, views from plinth import views
from . import privileged
from .forms import DelugeForm from .forms import DelugeForm
class DelugeAppView(views.AppView): class DelugeAppView(views.AppView):
"""Serve configuration page.""" """Serve configuration page."""
diagnostics_module_name = 'deluge' diagnostics_module_name = 'deluge'
form_class = DelugeForm form_class = DelugeForm
app_id = 'deluge' app_id = 'deluge'
@ -22,8 +20,7 @@ class DelugeAppView(views.AppView):
def get_initial(self): def get_initial(self):
"""Get current Deluge server settings.""" """Get current Deluge server settings."""
status = super().get_initial() status = super().get_initial()
configuration = json.loads( configuration = privileged.get_configuration()
actions.superuser_run('deluge', ['get-configuration']))
status['storage_path'] = configuration['download_location'] status['storage_path'] = configuration['download_location']
return status return status
@ -33,12 +30,8 @@ class DelugeAppView(views.AppView):
new_status = form.cleaned_data new_status = form.cleaned_data
if old_status['storage_path'] != new_status['storage_path']: if old_status['storage_path'] != new_status['storage_path']:
new_configuration = [ privileged.set_configuration(
'download_location', new_status['storage_path'] download_location=new_status['storage_path'])
]
actions.superuser_run('deluge',
['set-configuration'] + new_configuration)
messages.success(self.request, _('Configuration updated')) messages.success(self.request, _('Configuration updated'))
return super().form_valid(form) return super().form_valid(form)