Check url validity for permissions

This commit is contained in:
Josué Tille 2020-04-01 20:42:19 +02:00
parent 98f77e78c9
commit 4303653d77
No known key found for this signature in database
GPG key ID: 716A6C99B04194EF
3 changed files with 75 additions and 5 deletions

View file

@ -309,6 +309,7 @@
"hook_name_unknown": "Unknown hook name '{name:s}'",
"installation_complete": "Installation completed",
"installation_failed": "Something went wrong with the installation",
"invalid_regex": "Invalid regex :'{regex:s}'",
"ip6tables_unavailable": "You cannot play with ip6tables here. You are either in a container or your kernel does not support it",
"iptables_unavailable": "You cannot play with iptables here. You are either in a container or your kernel does not support it",
"log_corrupted_md_file": "The YAML metadata file associated with logs is damaged: '{md_file}\nError: {error}'",
@ -498,6 +499,7 @@
"regenconf_dry_pending_applying": "Checking pending configuration which would have been applied for category '{category}'…",
"regenconf_failed": "Could not regenerate the configuration for category(s): {categories}",
"regenconf_pending_applying": "Applying pending configuration for category '{category}'…",
"regex_with_only_domain": "You can't use a regex for domain, only for path",
"restore_already_installed_app": "An app with the ID '{app:s}' is already installed",
"restore_app_failed": "Could not restore the app '{app:s}'",
"restore_cleaning_failed": "Could not clean up the temporary restoration directory",

View file

@ -396,6 +396,71 @@ def _normalize_domain_path(domain, path):
return domain, path
def _check_and_normalize_permission_path(url):
"""
Check and normalize the urls passed for all permissions
Also check that the Regex is valid
As documented in the 'ynh_permission_create' helper:
If provided, 'url' is assumed to be relative to the app domain/path if they
start with '/'. For example:
/ -> domain.tld/app
/admin -> domain.tld/app/admin
domain.tld/app/api -> domain.tld/app/api
domain.tld -> domain.tld
'url' can be later treated as a regex if it starts with "re:".
For example:
re:/api/[A-Z]*$ -> domain.tld/app/api/[A-Z]*$
re:domain.tld/app/api/[A-Z]*$ -> domain.tld/app/api/[A-Z]*$
"""
import re, sre_constants
# Uri without domain
if url.startwith('re:/'):
regex = url[4:]
# check regex
try:
re.compile(regex)
except sre_constants.error:
raise YunohostError('invalid_regex', regex=regex)
return url
if url.startswith('/'):
return "/" + url.strip("/")
# Uri with domain
domains = domain_list()['domains']
if url.startwith('re:'):
if '/' not in url:
raise YunohostError('regex_with_only_domain')
domain = url[3:].split('/')[0]
path = url[3:].split('/', 1)[1]
if domain not in domains:
raise YunohostError('domain_unknown')
try:
re.compile(path)
except sre_constants.error:
raise YunohostError('invalid_regex', regex=path)
return 're:' + domain + path
else:
domain = url.split('/')[0]
if domain not in domains:
raise YunohostError('domain_unknown')
if '/' in url:
path = '/' + url.split('/', 1)[1].strip('/')
return domain + path
else:
return domain
def _build_dns_conf(domain, ttl=3600):
"""
Internal function that will returns a data structure containing the needed

View file

@ -336,6 +336,7 @@ def permission_url(operation_logger, permission,
clear_urls -- (optional) Clean all urls (url and additional_urls)
"""
from yunohost.utils.ldap import _get_ldap_interface
from yunohost.domain import _check_and_normalize_permission_path
ldap = _get_ldap_interface()
# By default, manipulate main permission
@ -352,20 +353,22 @@ def permission_url(operation_logger, permission,
if url is None:
url = existing_permission["url"]
else:
url = _check_and_normalize_permission_path(url)
current_additional_urls = existing_permission["additional_urls"]
new_additional_urls = copy.copy(current_additional_urls)
if add_url:
for url in add_url:
if url in current_additional_urls:
for ur in add_url:
if ur in current_additional_urls:
logger.warning(m18n.n('additional_urls_already_added', permission=permission, url=url))
else:
new_additional_urls += [url]
new_additional_urls += [_check_and_normalize_permission_path(url)]
if remove_url:
for url in remove_url:
if url not in current_additional_urls:
for ur in remove_url:
if ur not in current_additional_urls:
logger.warning(m18n.n('additional_urls_already_removed', permission=permission, url=url))
new_additional_urls = [u for u in new_additional_urls if u not in remove_url]