mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
Check url validity for permissions
This commit is contained in:
parent
98f77e78c9
commit
4303653d77
3 changed files with 75 additions and 5 deletions
|
@ -309,6 +309,7 @@
|
||||||
"hook_name_unknown": "Unknown hook name '{name:s}'",
|
"hook_name_unknown": "Unknown hook name '{name:s}'",
|
||||||
"installation_complete": "Installation completed",
|
"installation_complete": "Installation completed",
|
||||||
"installation_failed": "Something went wrong with the installation",
|
"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",
|
"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",
|
"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}'",
|
"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_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_failed": "Could not regenerate the configuration for category(s): {categories}",
|
||||||
"regenconf_pending_applying": "Applying pending configuration for category '{category}'…",
|
"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_already_installed_app": "An app with the ID '{app:s}' is already installed",
|
||||||
"restore_app_failed": "Could not restore the app '{app:s}'",
|
"restore_app_failed": "Could not restore the app '{app:s}'",
|
||||||
"restore_cleaning_failed": "Could not clean up the temporary restoration directory",
|
"restore_cleaning_failed": "Could not clean up the temporary restoration directory",
|
||||||
|
|
|
@ -396,6 +396,71 @@ def _normalize_domain_path(domain, path):
|
||||||
return 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):
|
def _build_dns_conf(domain, ttl=3600):
|
||||||
"""
|
"""
|
||||||
Internal function that will returns a data structure containing the needed
|
Internal function that will returns a data structure containing the needed
|
||||||
|
|
|
@ -336,6 +336,7 @@ def permission_url(operation_logger, permission,
|
||||||
clear_urls -- (optional) Clean all urls (url and additional_urls)
|
clear_urls -- (optional) Clean all urls (url and additional_urls)
|
||||||
"""
|
"""
|
||||||
from yunohost.utils.ldap import _get_ldap_interface
|
from yunohost.utils.ldap import _get_ldap_interface
|
||||||
|
from yunohost.domain import _check_and_normalize_permission_path
|
||||||
ldap = _get_ldap_interface()
|
ldap = _get_ldap_interface()
|
||||||
|
|
||||||
# By default, manipulate main permission
|
# By default, manipulate main permission
|
||||||
|
@ -352,20 +353,22 @@ def permission_url(operation_logger, permission,
|
||||||
|
|
||||||
if url is None:
|
if url is None:
|
||||||
url = existing_permission["url"]
|
url = existing_permission["url"]
|
||||||
|
else:
|
||||||
|
url = _check_and_normalize_permission_path(url)
|
||||||
|
|
||||||
current_additional_urls = existing_permission["additional_urls"]
|
current_additional_urls = existing_permission["additional_urls"]
|
||||||
new_additional_urls = copy.copy(current_additional_urls)
|
new_additional_urls = copy.copy(current_additional_urls)
|
||||||
|
|
||||||
if add_url:
|
if add_url:
|
||||||
for url in add_url:
|
for ur in add_url:
|
||||||
if url in current_additional_urls:
|
if ur in current_additional_urls:
|
||||||
logger.warning(m18n.n('additional_urls_already_added', permission=permission, url=url))
|
logger.warning(m18n.n('additional_urls_already_added', permission=permission, url=url))
|
||||||
else:
|
else:
|
||||||
new_additional_urls += [url]
|
new_additional_urls += [_check_and_normalize_permission_path(url)]
|
||||||
|
|
||||||
if remove_url:
|
if remove_url:
|
||||||
for url in remove_url:
|
for ur in remove_url:
|
||||||
if url not in current_additional_urls:
|
if ur not in current_additional_urls:
|
||||||
logger.warning(m18n.n('additional_urls_already_removed', permission=permission, url=url))
|
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]
|
new_additional_urls = [u for u in new_additional_urls if u not in remove_url]
|
||||||
|
|
Loading…
Add table
Reference in a new issue