Move a bunch of function from domain.py to app.py because it's much simpler to have them here

This commit is contained in:
Alexandre Aubin 2020-09-30 17:38:42 +02:00
parent 1ce1ecc2be
commit 07cec39af5
4 changed files with 81 additions and 90 deletions

View file

@ -317,7 +317,6 @@ def app_change_url(operation_logger, app, domain, path):
""" """
from yunohost.hook import hook_exec, hook_callback from yunohost.hook import hook_exec, hook_callback
from yunohost.domain import _normalize_domain_path, _assert_no_conflicting_apps
installed = _is_installed(app) installed = _is_installed(app)
if not installed: if not installed:
@ -1309,10 +1308,6 @@ def app_register_url(app, domain, path):
path -- The path to be registered (e.g. /coffee) path -- The path to be registered (e.g. /coffee)
""" """
# This line can't be moved on top of file, otherwise it creates an infinite
# loop of import with tools.py...
from .domain import _assert_no_conflicting_apps, _normalize_domain_path
domain, path = _normalize_domain_path(domain, path) domain, path = _normalize_domain_path(domain, path)
# We cannot change the url of an app already installed simply by changing # We cannot change the url of an app already installed simply by changing
@ -2586,8 +2581,6 @@ def _parse_args_in_yunohost_format(user_answers, argument_questions):
def _validate_and_normalize_webpath(manifest, args_dict, app_folder): def _validate_and_normalize_webpath(manifest, args_dict, app_folder):
from yunohost.domain import _assert_no_conflicting_apps, _normalize_domain_path
# If there's only one "domain" and "path", validate that domain/path # If there's only one "domain" and "path", validate that domain/path
# is an available url and normalize the path. # is an available url and normalize the path.
@ -2627,6 +2620,82 @@ def _validate_and_normalize_webpath(manifest, args_dict, app_folder):
_assert_no_conflicting_apps(domain, "/", full_domain=True) _assert_no_conflicting_apps(domain, "/", full_domain=True)
def _normalize_domain_path(domain, path):
# We want url to be of the format :
# some.domain.tld/foo
# Remove http/https prefix if it's there
if domain.startswith("https://"):
domain = domain[len("https://"):]
elif domain.startswith("http://"):
domain = domain[len("http://"):]
# Remove trailing slashes
domain = domain.rstrip("/").lower()
path = "/" + path.strip("/")
return domain, path
def _get_conflicting_apps(domain, path, ignore_app=None):
"""
Return a list of all conflicting apps with a domain/path (it can be empty)
Keyword argument:
domain -- The domain for the web path (e.g. your.domain.tld)
path -- The path to check (e.g. /coffee)
ignore_app -- An optional app id to ignore (c.f. the change_url usecase)
"""
from yunohost.domain import domain_list
domain, path = _normalize_domain_path(domain, path)
# Abort if domain is unknown
if domain not in domain_list()['domains']:
raise YunohostError('domain_name_unknown', domain=domain)
# Fetch apps map
apps_map = app_map(raw=True)
# Loop through all apps to check if path is taken by one of them
conflicts = []
if domain in apps_map:
# Loop through apps
for p, a in apps_map[domain].items():
if a["id"] == ignore_app:
continue
if path == p:
conflicts.append((p, a["id"], a["label"]))
# We also don't want conflicts with other apps starting with
# same name
elif path.startswith(p) or p.startswith(path):
conflicts.append((p, a["id"], a["label"]))
return conflicts
def _assert_no_conflicting_apps(domain, path, ignore_app=None, full_domain=False):
conflicts = _get_conflicting_apps(domain, path, ignore_app)
if conflicts:
apps = []
for path, app_id, app_label in conflicts:
apps.append(" * {domain:s}{path:s}{app_label:s} ({app_id:s})".format(
domain=domain,
path=path,
app_id=app_id,
app_label=app_label,
))
if full_domain:
raise YunohostError('app_full_domain_unavailable', domain=domain)
else:
raise YunohostError('app_location_unavailable', apps="\n".join(apps))
def _make_environment_dict(args_dict, prefix="APP_ARG_"): def _make_environment_dict(args_dict, prefix="APP_ARG_"):
""" """
Convert a dictionnary containing manifest arguments Convert a dictionnary containing manifest arguments

View file

@ -31,7 +31,7 @@ from moulinette.core import MoulinetteError
from yunohost.utils.error import YunohostError from yunohost.utils.error import YunohostError
from moulinette.utils.log import getActionLogger from moulinette.utils.log import getActionLogger
from yunohost.app import app_ssowatconf, _installed_apps, _get_app_settings from yunohost.app import app_ssowatconf, _installed_apps, _get_app_settings, _get_conflicting_apps
from yunohost.regenconf import regen_conf, _force_clear_hashes, _process_regen_conf from yunohost.regenconf import regen_conf, _force_clear_hashes, _process_regen_conf
from yunohost.utils.network import get_public_ip from yunohost.utils.network import get_public_ip
from yunohost.log import is_unit_operation from yunohost.log import is_unit_operation
@ -349,66 +349,6 @@ def domain_cert_renew(domain_list, force=False, no_checks=False, email=False, st
return yunohost.certificate.certificate_renew(domain_list, force, no_checks, email, staging) return yunohost.certificate.certificate_renew(domain_list, force, no_checks, email, staging)
def _get_conflicting_apps(domain, path, ignore_app=None):
"""
Return a list of all conflicting apps with a domain/path (it can be empty)
Keyword argument:
domain -- The domain for the web path (e.g. your.domain.tld)
path -- The path to check (e.g. /coffee)
ignore_app -- An optional app id to ignore (c.f. the change_url usecase)
"""
domain, path = _normalize_domain_path(domain, path)
# Abort if domain is unknown
if domain not in domain_list()['domains']:
raise YunohostError('domain_name_unknown', domain=domain)
# This import cannot be put on top of file because it would create a
# recursive import...
from yunohost.app import app_map
# Fetch apps map
apps_map = app_map(raw=True)
# Loop through all apps to check if path is taken by one of them
conflicts = []
if domain in apps_map:
# Loop through apps
for p, a in apps_map[domain].items():
if a["id"] == ignore_app:
continue
if path == p:
conflicts.append((p, a["id"], a["label"]))
# We also don't want conflicts with other apps starting with
# same name
elif path.startswith(p) or p.startswith(path):
conflicts.append((p, a["id"], a["label"]))
return conflicts
def _assert_no_conflicting_apps(domain, path, ignore_app=None, full_domain=False):
conflicts = _get_conflicting_apps(domain, path, ignore_app)
if conflicts:
apps = []
for path, app_id, app_label in conflicts:
apps.append(" * {domain:s}{path:s}{app_label:s} ({app_id:s})".format(
domain=domain,
path=path,
app_id=app_id,
app_label=app_label,
))
if full_domain:
raise YunohostError('app_full_domain_unavailable', domain=domain)
else:
raise YunohostError('app_location_unavailable', apps="\n".join(apps))
def domain_url_available(domain, path): def domain_url_available(domain, path):
""" """
Check availability of a web path Check availability of a web path
@ -432,24 +372,6 @@ def _set_maindomain(domain):
f.write(domain) f.write(domain)
def _normalize_domain_path(domain, path):
# We want url to be of the format :
# some.domain.tld/foo
# Remove http/https prefix if it's there
if domain.startswith("https://"):
domain = domain[len("https://"):]
elif domain.startswith("http://"):
domain = domain[len("http://"):]
# Remove trailing slashes
domain = domain.rstrip("/").lower()
path = "/" + path.strip("/")
return domain, path
def _build_dns_conf(domain, ttl=3600, include_empty_AAAA_if_no_ipv6=False): def _build_dns_conf(domain, ttl=3600, include_empty_AAAA_if_no_ipv6=False):
""" """
Internal function that will returns a data structure containing the needed Internal function that will returns a data structure containing the needed

View file

@ -676,8 +676,8 @@ def _validate_and_sanitize_permission_url(url, app_base_path, app):
re:domain.tld/app/api/[A-Z]*$ -> domain.tld/app/api/[A-Z]*$ re:domain.tld/app/api/[A-Z]*$ -> domain.tld/app/api/[A-Z]*$
""" """
from yunohost.domain import domain_list, _assert_no_conflicting_apps from yunohost.domain import domain_list
from yunohost.app import _assert_no_conflicting_apps
domains = domain_list()['domains'] domains = domain_list()['domains']

View file

@ -4,8 +4,8 @@ import os
from conftest import get_test_apps_dir from conftest import get_test_apps_dir
from yunohost.utils.error import YunohostError from yunohost.utils.error import YunohostError
from yunohost.app import app_install, app_remove from yunohost.app import app_install, app_remove, _normalize_domain_path
from yunohost.domain import _get_maindomain, domain_url_available, _normalize_domain_path from yunohost.domain import _get_maindomain, domain_url_available
from yunohost.permission import _validate_and_sanitize_permission_url from yunohost.permission import _validate_and_sanitize_permission_url
# Get main domain # Get main domain