searx: Use privileged decorator for actions

Tests:

- Functional tests work
- Initial setup works
  - UWSGI configuration is created and daemon is running.
- Enabling and disabling public access works. Public access file is
  created/removed. App page shows current value. If exception is raised, error
  is shown properly.
- Setting safe search to all three values works. Configuration file is updated
  properly. App page shows current value properly. If exception is raised, error
  is shown properly.

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 10:19:08 -07:00 committed by James Valleroy
parent 8db063b59b
commit 52f42a4f74
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808
4 changed files with 33 additions and 86 deletions

View File

@ -1,13 +1,10 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
"""
FreedomBox app to configure Searx.
"""
"""FreedomBox app to configure Searx."""
import os
from django.utils.translation import gettext_lazy as _
from plinth import actions
from plinth import app as app_module
from plinth import frontpage, menu
from plinth.modules.apache.components import Uwsgi, Webserver
@ -16,7 +13,7 @@ from plinth.modules.firewall.components import Firewall
from plinth.modules.users.components import UsersAndGroups
from plinth.package import Packages
from . import manifest
from . import manifest, privileged
_description = [
_('Searx is a privacy-respecting Internet metasearch engine. '
@ -95,9 +92,9 @@ class SearxApp(app_module.App):
def setup(self, old_version):
"""Install and configure the app."""
super().setup(old_version)
actions.superuser_run('searx', ['setup'])
privileged.setup()
if not old_version or old_version < 3:
actions.superuser_run('searx', ['disable-public-access'])
privileged.disable_public_access()
self.enable()
self.set_shortcut_login_required(True)
@ -115,12 +112,6 @@ class SearxWebserverAuth(Webserver):
super().enable()
def get_safe_search_setting():
"""Get the current value of the safe search setting for Searx."""
value = actions.superuser_run('searx', ['get-safe-search'])
return int(value.strip())
def is_public_access_enabled():
"""Check whether public access is enabled for Searx."""
return os.path.exists(manifest.PUBLIC_ACCESS_SETTING_FILE)
@ -128,7 +119,7 @@ def is_public_access_enabled():
def enable_public_access():
"""Allow Searx app to be accessed by anyone with access."""
actions.superuser_run('searx', ['enable-public-access'])
privileged.enable_public_access()
app = app_module.App.get('searx')
app.get_component('webserver-searx-auth').disable()
app.set_shortcut_login_required(False)
@ -136,7 +127,7 @@ def enable_public_access():
def disable_public_access():
"""Allow Searx app to be accessed by logged-in users only."""
actions.superuser_run('searx', ['disable-public-access'])
privileged.disable_public_access()
app = app_module.App.get('searx')
app.get_component('webserver-searx-auth').enable()
app.set_shortcut_login_required(True)

View File

@ -1,7 +1,5 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
"""
Django form for configuring Searx.
"""
"""Django form for configuring Searx."""
from django import forms
from django.utils.translation import gettext_lazy as _
@ -9,6 +7,7 @@ from django.utils.translation import gettext_lazy as _
class SearxForm(forms.Form):
"""Searx configuration form."""
safe_search = forms.ChoiceField(
label=_('Safe Search'), help_text=_(
'Select the default family filter to apply to your search results.'

76
actions/searx → plinth/modules/searx/privileged.py Executable file → Normal file
View File

@ -1,10 +1,6 @@
#!/usr/bin/python3
# SPDX-License-Identifier: AGPL-3.0-or-later
"""
Configuration helper for searx.
"""
"""Configure searx."""
import argparse
import gzip
import os
import pathlib
@ -15,6 +11,7 @@ import augeas
import yaml
from plinth import action_utils
from plinth.actions import privileged
from plinth.modules.searx.manifest import PUBLIC_ACCESS_SETTING_FILE
from plinth.utils import gunzip
@ -23,34 +20,6 @@ SETTINGS_FILE = '/etc/searx/settings.yml'
UWSGI_FILE = '/etc/uwsgi/apps-available/searx.ini'
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='Perform post-installation operations for Searx')
subparsers.add_parser('enable-public-access',
help='Enable public access to the Searx application')
subparsers.add_parser(
'disable-public-access',
help='Disable public access to the Searx application')
safe_search = subparsers.add_parser(
'set-safe-search',
help='Set the default filter for safe search on Searx')
safe_search.add_argument(
'filter', type=int,
help='Filter results. 0: None, 1: Moderate, 2: Strict')
subparsers.add_parser('get-safe-search',
help='Print the value of the safe search setting.')
subparsers.required = True
return parser.parse_args()
def _copy_uwsgi_configuration():
"""Copy example uwsgi configuration
@ -100,21 +69,22 @@ def _set_safe_search(settings):
settings['search']['safe_search'] = 1
def subcommand_set_safe_search(arguments):
@privileged
def set_safe_search(filter_: int):
"""Set safe search filter for search results."""
value = arguments.filter
settings = read_settings()
settings['search']['safe_search'] = value
settings['search']['safe_search'] = filter_
write_settings(settings)
def subcommand_get_safe_search(_):
"""Print the value of the safe search setting."""
@privileged
def get_safe_search() -> int:
"""Return the value of the safe search setting."""
if os.path.exists(SETTINGS_FILE):
settings = read_settings()
print(settings['search']['safe_search'])
return int(settings['search']['safe_search'])
else:
print(0)
return 0
def read_settings():
@ -138,15 +108,16 @@ def _get_example_settings_file():
def _update_search_engines(settings):
"""Updates settings with the latest supported search engines."""
"""Update settings with the latest supported search engines."""
example_settings_file = _get_example_settings_file()
open_func = gzip.open if example_settings_file.suffix == '.gz' else open
with open_func(example_settings_file, 'rb') as example_settings:
settings['engines'] = yaml.safe_load(example_settings)['engines']
def subcommand_setup(_):
"""Post installation actions for Searx"""
@privileged
def setup():
"""Post installation actions for Searx."""
_copy_uwsgi_configuration()
_update_uwsgi_configuration()
@ -169,25 +140,14 @@ def subcommand_setup(_):
action_utils.service_restart('uwsgi')
def subcommand_enable_public_access(_):
@privileged
def enable_public_access():
"""Enable public access to the SearX application."""
open(PUBLIC_ACCESS_SETTING_FILE, 'w', encoding='utf-8').close()
def subcommand_disable_public_access(_):
@privileged
def disable_public_access():
"""Disable public access to the SearX application."""
if os.path.exists(PUBLIC_ACCESS_SETTING_FILE):
os.remove(PUBLIC_ACCESS_SETTING_FILE)
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,29 +1,27 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
"""
Django views for Searx.
"""
"""Django views for Searx."""
from django.contrib import messages
from django.utils.translation import gettext as _
from plinth import actions
from plinth import app as app_module
from plinth import views
from plinth.errors import ActionError
from plinth.modules import searx
from . import privileged
from .forms import SearxForm
class SearxAppView(views.AppView):
"""Serve configuration page."""
app_id = 'searx'
form_class = SearxForm
def get_initial(self):
"""Return the status of the service to fill in the form."""
initial = super().get_initial()
initial['safe_search'] = searx.get_safe_search_setting()
initial['safe_search'] = privileged.get_safe_search()
initial['public_access'] = searx.is_public_access_enabled() and \
app_module.App.get('searx').is_enabled()
return initial
@ -35,10 +33,9 @@ class SearxAppView(views.AppView):
if str(old_data['safe_search']) != form_data['safe_search']:
try:
actions.superuser_run(
'searx', ['set-safe-search', form_data['safe_search']])
privileged.set_safe_search(int(form_data['safe_search']))
messages.success(self.request, _('Configuration updated.'))
except ActionError:
except Exception:
messages.error(self.request,
_('An error occurred during configuration.'))
@ -49,7 +46,7 @@ class SearxAppView(views.AppView):
else:
searx.disable_public_access()
messages.success(self.request, _('Configuration updated.'))
except ActionError:
except Exception:
messages.error(self.request,
_('An error occurred during configuration.'))