diff --git a/TODO.md b/TODO.md
index c3daa469..3c038876 100644
--- a/TODO.md
+++ b/TODO.md
@@ -449,3 +449,6 @@ mkhomedir_helper or create ssh homes with bash.rc and such
# show base and total desglosed
# CLOSE&DOWNLOAD doesn't redirect to anything, confusing for users
+
+
+# Reverse lOgHistory order by date (lastest first)
diff --git a/orchestra/contrib/mailboxes/backends.py b/orchestra/contrib/mailboxes/backends.py
index dd8201fc..ec766975 100644
--- a/orchestra/contrib/mailboxes/backends.py
+++ b/orchestra/contrib/mailboxes/backends.py
@@ -16,7 +16,7 @@ from .models import Address, Mailbox
logger = logging.getLogger(__name__)
-class SieveFilteringMixin(object):
+class SieveFilteringMixin:
def generate_filter(self, mailbox, context):
name, content = mailbox.get_filtering()
for box in re.findall(r'fileinto\s+"([^"]+)"', content):
@@ -114,14 +114,14 @@ class UNIXUserMaildirBackend(SieveFilteringMixin, ServiceController):
self.append(textwrap.dedent("""
nohup bash -c '{ sleep 2 && killall -u %(user)s -s KILL; }' &> /dev/null &
killall -u %(user)s || true
- # Restart because of Postfix SASL caches credentials
- userdel %(user)s || true && RESTART_POSTFIX=1
+ # Restart because of Postfix SASL caching credentials
+ userdel %(user)s && RESTART_POSTFIX=1 || true
groupdel %(user)s || true""") % context
)
def commit(self):
self.append('[[ $RESTART_POSTFIX -eq 1 ]] && service postfix restart')
- super(UNIXUserMaildirBackend, self).commit()
+ super().commit()
def get_context(self, mailbox):
context = {
@@ -374,11 +374,11 @@ class PostfixAddressBackend(PostfixAddressVirtualDomainBackend):
)
def save(self, address):
- context = super(PostfixAddressBackend, self).save(address)
+ context = super().save(address)
self.update_virtual_alias_maps(address, context)
def delete(self, address):
- context = super(PostfixAddressBackend, self).save(address)
+ context = super().save(address)
self.exclude_virtual_alias_maps(context)
def commit(self):
@@ -418,7 +418,7 @@ class DovecotMaildirDisk(ServiceMonitor):
)
def prepare(self):
- super(DovecotMaildirDisk, self).prepare()
+ super().prepare()
current_date = self.current_date.strftime("%Y-%m-%d %H:%M:%S %Z")
self.append(textwrap.dedent("""\
function monitor () {
diff --git a/orchestra/contrib/webapps/options.py b/orchestra/contrib/webapps/options.py
index 2b238937..220d2d93 100644
--- a/orchestra/contrib/webapps/options.py
+++ b/orchestra/contrib/webapps/options.py
@@ -106,14 +106,33 @@ class PHPEnableFunctions(PHPAppOption):
def validate(self):
# Clean value removing spaces
self.instance.value = self.instance.value.replace(' ', '')
- super(PHPEnableFunctions, self).validate()
+ super().validate()
+
+
+class PHPDisableFunctions(PHPAppOption):
+ name = 'disable_functions'
+ verbose_name = _("Disable functions")
+ help_text = _("This directive allows you to disable certain functions for security reasons. "
+ "It takes on a comma-delimited list of function names. disable_functions is not "
+ "affected by Safe Mode. Default disabled fuctions include:
"
+ "%s") % ',
'.join([
+ ','.join(settings.WEBAPPS_PHP_DISABLED_FUNCTIONS[i:i+10])
+ for i in range(0, len(settings.WEBAPPS_PHP_DISABLED_FUNCTIONS), 10)
+ ])
+ regex = r'^[\w\.,-]+$'
+ comma_separated = True
+
+ def validate(self):
+ # Clean value removing spaces
+ self.instance.value = self.instance.value.replace(' ', '')
+ super().validate()
class PHPAllowURLInclude(PHPAppOption):
name = 'allow_url_include'
verbose_name = _("Allow URL include")
help_text = _("Allows the use of URL-aware fopen wrappers with include, include_once, require, "
- "require_once (On or Off).")
+ "require_once (On or Off).")
regex = r'^(On|Off|on|off)$'
diff --git a/orchestra/contrib/webapps/settings.py b/orchestra/contrib/webapps/settings.py
index 5c49b587..4fc97bc2 100644
--- a/orchestra/contrib/webapps/settings.py
+++ b/orchestra/contrib/webapps/settings.py
@@ -220,6 +220,7 @@ WEBAPPS_ENABLED_OPTIONS = Setting('WEBAPPS_ENABLED_OPTIONS', (
'orchestra.contrib.webapps.options.Timeout',
'orchestra.contrib.webapps.options.Processes',
'orchestra.contrib.webapps.options.PHPEnableFunctions',
+ 'orchestra.contrib.webapps.options.PHPDisableFunctions',
'orchestra.contrib.webapps.options.PHPAllowURLInclude',
'orchestra.contrib.webapps.options.PHPAllowURLFopen',
'orchestra.contrib.webapps.options.PHPAutoAppendFile',
diff --git a/orchestra/contrib/webapps/types/php.py b/orchestra/contrib/webapps/types/php.py
index 59c1aac3..fdbc279b 100644
--- a/orchestra/contrib/webapps/types/php.py
+++ b/orchestra/contrib/webapps/types/php.py
@@ -90,14 +90,14 @@ class PHPApp(AppType):
# Disable functions
if self.PHP_DISABLED_FUNCTIONS:
enable_functions = init_vars.pop('enable_functions', '')
- if enable_functions or self.is_fpm:
+ disable_functions = set(init_vars.pop('disable_functions', '').split(','))
+ if disable_functions or enable_functions or self.is_fpm:
# FPM: Defining 'disable_functions' or 'disable_classes' will not overwrite previously
# defined php.ini values, but will append the new value
enable_functions = set(enable_functions.split(','))
- disable_functions = []
for function in self.PHP_DISABLED_FUNCTIONS:
if function not in enable_functions:
- disable_functions.append(function)
+ disable_functions.add(function)
init_vars['disable_functions'] = ','.join(disable_functions)
# Process timeout
if timeout:
diff --git a/orchestra/templates/admin/orchestra/menu.html b/orchestra/templates/admin/orchestra/menu.html
index 40188e4b..8d71d4fa 100644
--- a/orchestra/templates/admin/orchestra/menu.html
+++ b/orchestra/templates/admin/orchestra/menu.html
@@ -1,24 +1,24 @@
-{% load i18n admin_tools_menu_tags %}
+{% load i18n admin_tools_menu_tags staticfiles %}
{% if menu.children %}
-
+