mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-01-28 08:03:36 +00:00
- Identify Freedbombox admin who installed the app to be zoph admin. - Implement backup and restore. - Photos directory should remain at /var/lib/zoph, for proper operation of backups. - There remains an issue that the App is enabled before it is configured but will not work correctly until configuration. - OpenStreetMap mapping is enabled. These should be configurable before installation. - Add initial forms.py and views.py to Zoph app, however these are currently unused as urls.py does not invoke the view. When the view is not invoked the Zoph App installs, with single signon, currently as the first LDAP user, rather than the plinth user. - The first user's preferences are not set, and need to be manually set to avoid other errors. * Sunil's changes - Squash commits and re-split them. - Drop documentation as it will be auto populated from wiki later. - Remove outdated validation code from manifest. - Drop some dead code. - Don't send MySQL password over command line for improved security. Instead rely on Unix authentication of root user similar to backup/restore process. - Use JSON for exchanging configuration dump to avoid encoding errors. - Add username validation to avoid a potential SQL injection. - Update description for neural tone and brevity. Add information about how user accounts work in FreedomBox - Fix functional tests. - Drop all code related to changing photos path until it is ready. - Update URL from /zoph to /zoph/ to avoid another redirect. - Fix disabling the app. - Use icon that Zoph uses for favicon as logo. Update copyright file. - Fix spelling unzip. - Minor refactors. Run yapf and isort. - Use subprocess.run() instead of os.popen() everywhere for better security with argument parsing. - Enable OpenStreetMap by default. User have a choice to disable it before using the app. Add label to explain privacy concerns. - Fix dropping database by using --force argument. - Cleanup enabling the app to not enable the app when updating configuration. - Use AppView's default template instead of overriding. - Update functional tests to just check if the app is enabled/disabled as expected. Checking that Zoph site is available will require reliable handling of admin user. Signed-off-by: John Lines <john@paladyn.org> Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org> Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
148 lines
5.0 KiB
Python
Executable File
148 lines
5.0 KiB
Python
Executable File
#!/usr/bin/python3
|
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
"""
|
|
Configuration helper for Zoph server.
|
|
"""
|
|
|
|
import argparse
|
|
import configparser
|
|
import json
|
|
import os
|
|
import re
|
|
import subprocess
|
|
|
|
from plinth import action_utils
|
|
|
|
APACHE_CONF = '/etc/apache2/conf-available/zoph.conf'
|
|
DB_BACKUP_FILE = '/var/lib/plinth/backups-data/zoph-database.sql'
|
|
|
|
|
|
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('pre-install',
|
|
help='Perform Zoph pre-install configuration')
|
|
subparser = subparsers.add_parser('setup',
|
|
help='Perform Zoph configuration setup')
|
|
subparsers.add_parser('get-configuration',
|
|
help='Return the current configuration')
|
|
subparser = subparsers.add_parser('set-configuration',
|
|
help='Configure zoph')
|
|
subparser.add_argument('--admin-user', help='Name of the admin user')
|
|
subparser.add_argument('--enable-osm', help='Enable OpenSteetMap maps')
|
|
subparsers.add_parser('is-configured', help='return true if configured')
|
|
subparsers.add_parser('dump-database', help='Dump database to file')
|
|
subparsers.add_parser('restore-database',
|
|
help='Restore database from file')
|
|
|
|
subparsers.required = True
|
|
return parser.parse_args()
|
|
|
|
|
|
def subcommand_pre_install(_):
|
|
"""Preseed debconf values before packages are installed."""
|
|
action_utils.debconf_set_selections([
|
|
'zoph zoph/dbconfig-install boolean true',
|
|
'zoph zoph/mysql/admin-user string root'
|
|
])
|
|
|
|
|
|
def subcommand_get_configuration(_):
|
|
"""Return the current configuration."""
|
|
configuration = {}
|
|
process = subprocess.run(['zoph', '--dump-config'], stdout=subprocess.PIPE,
|
|
check=True)
|
|
for line in process.stdout.decode().splitlines():
|
|
name, value = line.partition(':')[::2]
|
|
configuration[name.strip()] = value[1:]
|
|
|
|
print(json.dumps(configuration))
|
|
|
|
|
|
def _zoph_configure(key, value):
|
|
"""Set a configure value in Zoph."""
|
|
subprocess.run(['zoph', '--config', key, value], check=True)
|
|
|
|
|
|
def subcommand_setup(_):
|
|
"""Setup Zoph configuration."""
|
|
_zoph_configure('import.enable', 'true')
|
|
_zoph_configure('import.upload', 'true')
|
|
_zoph_configure('import.rotate', 'true')
|
|
_zoph_configure('path.unzip', 'unzip')
|
|
_zoph_configure('path.untar', 'tar xvf')
|
|
_zoph_configure('path.ungz', 'gunzip')
|
|
|
|
# Maps using OpenStreetMap is enabled by default.
|
|
_zoph_configure('maps.provider', 'osm')
|
|
|
|
|
|
def _get_db_name():
|
|
"""Return the name of the database configured by dbconfig."""
|
|
config = configparser.ConfigParser()
|
|
config.read_file(open('/etc/zoph.ini', 'r'))
|
|
return config['zoph']['db_name'].strip('"')
|
|
|
|
|
|
def subcommand_set_configuration(arguments):
|
|
"""Setup Zoph Apache configuration."""
|
|
_zoph_configure('interface.user.remote', 'true')
|
|
|
|
# Note that using OpenSteetmap as a mapping provider is a very nice
|
|
# feature, but some people may regard its use as a privacy issue
|
|
if arguments.enable_osm:
|
|
value = 'osm' if arguments.enable_osm == 'True' else ''
|
|
_zoph_configure('maps.provider', value)
|
|
|
|
if arguments.admin_user:
|
|
# Edit the database to rename the admin user to FreedomBox admin user.
|
|
admin_user = arguments.admin_user
|
|
if not re.match(r'^[\w.@][\w.@-]+\Z', admin_user, flags=re.ASCII):
|
|
# Check to avoid SQL injection
|
|
raise ValueError('Invalid username')
|
|
|
|
query = f"UPDATE zoph_users SET user_name='{admin_user}' \
|
|
WHERE user_name='admin';"
|
|
|
|
subprocess.run(['mysql', _get_db_name()], input=query.encode(),
|
|
check=True)
|
|
|
|
|
|
def subcommand_is_configured(_):
|
|
"""Print whether zoph app is configured."""
|
|
subprocess.run(['zoph', '--get-config', 'interface.user.remote'],
|
|
check=True)
|
|
|
|
|
|
def subcommand_dump_database(_):
|
|
"""Dump database to file."""
|
|
db_name = _get_db_name()
|
|
os.makedirs(os.path.dirname(DB_BACKUP_FILE), exist_ok=True)
|
|
with open(DB_BACKUP_FILE, 'w') as db_backup_file:
|
|
subprocess.run(['mysqldump', db_name], stdout=db_backup_file,
|
|
check=True)
|
|
|
|
|
|
def subcommand_restore_database(_):
|
|
"""Restore database from file."""
|
|
db_name = _get_db_name()
|
|
subprocess.run(['mysqladmin', '--force', 'drop', db_name])
|
|
subprocess.run(['mysqladmin', 'create', db_name], check=True)
|
|
with open(DB_BACKUP_FILE, 'r') as db_restore_file:
|
|
subprocess.run(['mysql', db_name], stdin=db_restore_file, check=True)
|
|
|
|
|
|
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()
|