searx: Add option to allow public access to the application

[jvalleroy] Resolved merge conflict to use shortcut component.

Fixes #1590

Signed-off-by: Joseph Nuthalapati <njoseph@thoughtworks.com>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
Joseph Nuthalapati 2019-05-27 19:14:01 +05:30 committed by James Valleroy
parent 6a9133c305
commit 2d85b61199
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808
10 changed files with 138 additions and 22 deletions

View File

@ -20,11 +20,11 @@ Configuration helper for searx.
"""
import argparse
import augeas
import os
import secrets
import shutil
import augeas
import yaml
from plinth import action_utils
@ -45,6 +45,12 @@ def parse_arguments():
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')
@ -81,7 +87,8 @@ def _update_uwsgi_configuration():
aug.set('/augeas/load/inifile/lens', 'Puppet.lns')
aug.set('/augeas/load/inifile/incl[last() + 1]', UWSGI_FILE)
aug.load()
aug.set('/files/etc/uwsgi/apps-available/searx.ini/uwsgi/autoload', 'false')
aug.set('/files/etc/uwsgi/apps-available/searx.ini/uwsgi/autoload',
'false')
aug.save()
@ -153,14 +160,26 @@ def subcommand_enable(_):
"""Enable web configuration and reload."""
action_utils.uwsgi_enable('searx')
action_utils.webserver_enable('searx-freedombox')
action_utils.webserver_enable('searx-freedombox-auth')
def subcommand_disable(_):
"""Disable web configuration and reload."""
action_utils.webserver_disable('searx-freedombox')
action_utils.webserver_disable('searx-freedombox-auth')
action_utils.uwsgi_disable('searx')
def subcommand_enable_public_access(_):
"""Enable public access to the SearX application."""
action_utils.webserver_disable('searx-freedombox-auth')
def subcommand_disable_public_access(_):
"""Disable public access to the SearX application."""
action_utils.webserver_enable('searx-freedombox-auth')
def main():
"""Parse arguments and perform all duties."""
arguments = parse_arguments()

View File

@ -38,3 +38,18 @@ Scenario: Disable searx application
Given the searx application is enabled
When I disable the searx application
Then the searx site should not be available
Scenario: Enable public access
Given the searx application is enabled
And I enable public access in searx
And I'm a logged out user
Then searx app should be visible on the front page
And the searx site should be available
Scenario: Disable public access
Given the searx application is enabled
And I disable public access in searx
And I'm a logged out user
Then searx app should not be visible on the front page
And the searx site should not be available

View File

@ -423,3 +423,26 @@ def openvpn_profile_downloadable(browser):
def openvpn_profile_download_compare(browser, openvpn_download_profile):
new_profile = application.openvpn_download_profile(browser)
assert openvpn_download_profile == new_profile
@given('I enable public access in searx')
def searx_enable_public_access(browser):
application.searx_enable_public_access(browser)
@given('I disable public access in searx')
def searx_disable_public_access(browser):
application.searx_disable_public_access(browser)
@then(parsers.parse('{app_name:w} app should be visible on the front page'))
def app_visible_on_front_page(browser, app_name):
shortcuts = application.find_on_front_page(browser, app_name)
assert len(shortcuts) == 1
@then(
parsers.parse('{app_name:w} app should not be visible on the front page'))
def app_visible_on_front_page(browser, app_name):
shortcuts = application.find_on_front_page(browser, app_name)
assert len(shortcuts) == 0

View File

@ -469,3 +469,23 @@ def openvpn_download_profile(browser):
interface.nav_to_module(browser, 'openvpn')
url = browser.find_by_css('.form-profile')['action']
return _download_file(browser, url)
def searx_enable_public_access(browser):
"""Enable Public Access in SearX"""
interface.nav_to_module(browser, 'searx')
browser.find_by_id('id_public_access').check()
interface.submit(browser, form_class='form-configuration')
def searx_disable_public_access(browser):
"""Enable Public Access in SearX"""
interface.nav_to_module(browser, 'searx')
browser.find_by_id('id_public_access').uncheck()
interface.submit(browser, form_class='form-configuration')
def find_on_front_page(browser, app_name):
browser.visit(default_url)
shortcuts = browser.find_link_by_href(f'/{app_name}/')
return shortcuts

View File

@ -21,7 +21,6 @@ import pathlib
import time
import requests
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
@ -45,10 +44,14 @@ def get_site_url(site_name):
def is_available(browser, site_name):
browser.visit(config['DEFAULT']['url'] + get_site_url(site_name))
url_to_visit = config['DEFAULT']['url'] + get_site_url(site_name)
browser.visit(url_to_visit)
time.sleep(3)
browser.reload()
return '404' not in browser.title
not_404 = '404' not in browser.title
# A trailing slash might be appended by Apache redirect rules
no_redirect = url_to_visit.strip('/') == browser.url.strip('/')
return not_404 and no_redirect
def access_url(browser, site_name):

View File

@ -30,7 +30,7 @@ from .manifest import backup, clients
clients = clients
version = 2
version = 3
managed_services = ['searx']
@ -68,10 +68,17 @@ class SearxApp(app_module.App):
shortcut = frontpage.Shortcut(
'shortcut-searx', name, short_description=short_description,
icon='searx', url='/searx/', clients=clients, login_required=True,
icon='searx', url='/searx/', clients=clients,
login_required=(not is_public_access_enabled()),
allowed_groups=[group[0]])
self.add(shortcut)
def set_shortcut_login_required(self, login_required):
"""Change the login_required property of shortcut."""
shortcut = self.remove('shortcut-searx')
shortcut.login_required = login_required
self.add(shortcut)
def init():
"""Intialize the module."""
@ -95,8 +102,12 @@ def setup(helper, old_version=None):
"""Install and configure the module."""
helper.install(managed_packages)
helper.call('post', actions.superuser_run, 'searx', ['setup'])
if not old_version:
if not old_version or old_version < 3:
helper.call('post', actions.superuser_run, 'searx', ['enable'])
helper.call('post', actions.superuser_run, 'searx',
['disable-public-access'])
app.set_shortcut_login_required(True)
app.enable()
global service
if service is None:
@ -108,11 +119,16 @@ def setup(helper, old_version=None):
def get_safe_search_setting():
"""Get the current value of the safe search setting for Seax."""
"""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 not action_utils.webserver_is_enabled('searx-freedombox-auth')
def is_enabled():
"""Return whether the module is enabled."""
return (action_utils.webserver_is_enabled('searx-freedombox')

View File

@ -0,0 +1,9 @@
<Location /searx/>
Include includes/freedombox-single-sign-on.conf
<IfModule mod_auth_pubtkt.c>
TKTAuthToken "web-search" "admin"
</IfModule>
ProxyPass unix:/run/uwsgi/app/searx/socket|uwsgi://uwsgi-uds-searx/
</Location>

View File

@ -9,12 +9,6 @@
<Location /searx/>
Include includes/freedombox-single-sign-on.conf
<IfModule mod_auth_pubtkt.c>
TKTAuthToken "web-search" "admin"
</IfModule>
ProxyPass unix:/run/uwsgi/app/searx/socket|uwsgi://uwsgi-uds-searx/
</Location>

View File

@ -26,8 +26,11 @@ from plinth.forms import ServiceForm
class SearxForm(ServiceForm):
"""Searx configuration form."""
safe_search = forms.ChoiceField(label=_('Safe Search'), help_text=_(
'Select the default family filter to apply to your search results.'),
choices=((0, _('None')),
(1, _('Moderate')),
(2, _('Strict'))))
safe_search = forms.ChoiceField(
label=_('Safe Search'), help_text=_(
'Select the default family filter to apply to your search results.'
), choices=((0, _('None')), (1, _('Moderate')), (2, _('Strict'))))
public_access = forms.BooleanField(
label=_('Public Access'), help_text=_(
'Allow this application to be used by anyone who can reach it.'),
required=False)

View File

@ -23,8 +23,9 @@ from django.utils.translation import ugettext as _
from plinth import actions, views
from plinth.errors import ActionError
from plinth.modules.searx import (clients, description,
get_safe_search_setting, manual_page)
from plinth.modules.searx import (add_shortcut, clients, description,
get_safe_search_setting,
is_public_access_enabled, manual_page)
from .forms import SearxForm
@ -43,6 +44,7 @@ class SearxServiceView(views.ServiceView):
"""Return the status of the service to fill in the form."""
initial = super().get_initial()
initial['safe_search'] = get_safe_search_setting()
initial['public_access'] = is_public_access_enabled()
return initial
def form_valid(self, form):
@ -59,4 +61,16 @@ class SearxServiceView(views.ServiceView):
messages.error(self.request,
_('An error occurred during configuration.'))
if old_data['public_access'] != form_data['public_access']:
try:
if form_data['public_access']:
actions.superuser_run('searx', ['enable-public-access'])
else:
actions.superuser_run('searx', ['disable-public-access'])
add_shortcut()
messages.success(self.request, _('Configuration updated.'))
except ActionError as e:
messages.error(self.request,
_('An error occurred during configuration.'))
return super().form_valid(form)