Improved webapps directive validation

This commit is contained in:
Marc Aymerich 2015-07-29 09:05:07 +00:00
parent c119ef9bc0
commit ae0968f58f
9 changed files with 55 additions and 55 deletions

View file

@ -426,3 +426,6 @@ Case
# Discount prepaid metric should be more optimal https://orchestra.pangea.org/admin/orders/order/40/ # Discount prepaid metric should be more optimal https://orchestra.pangea.org/admin/orders/order/40/
# -> order.billed_metric besides billed_until # -> order.billed_metric besides billed_until
# websites directives: redirect strip() and allow empty URL_path

View file

@ -34,13 +34,11 @@ class ListSerializer(AccountSerializerMixin, SetPasswordHyperlinkedSerializer):
fields = ('url', 'id', 'name', 'password', 'address_name', 'address_domain', 'admin_email') fields = ('url', 'id', 'name', 'password', 'address_name', 'address_domain', 'admin_email')
postonly_fields = ('name', 'password') postonly_fields = ('name', 'password')
def validate_address_domain(self, attrs, source): def validate_address_domain(self, address_name):
address_domain = attrs.get(source)
address_name = attrs.get('address_name')
if self.instance: if self.instance:
address_domain = address_domain or self.instance.address_domain address_domain = address_domain or self.instance.address_domain
address_name = address_name or self.instance.address_name address_name = address_name or self.instance.address_name
if address_name and not address_domain: if address_name and not address_domain:
raise serializers.ValidationError( raise serializers.ValidationError(
_("address_domains should should be provided when providing an addres_name")) _("address_domains should should be provided when providing an addres_name"))
return attrs return address_name

View file

@ -11,13 +11,15 @@ class PaymentSourceSerializer(AccountSerializerMixin, serializers.HyperlinkedMod
model = PaymentSource model = PaymentSource
fields = ('url', 'id', 'method', 'data', 'is_active') fields = ('url', 'id', 'method', 'data', 'is_active')
def validate_data(self, attrs, source): def validate(self, data):
plugin = PaymentMethod.get(attrs['method']) """ validate data according to method """
data = super(PaymentSourceSerializer, self).validate(data)
plugin = PaymentMethod.get(data['method'])
serializer_class = plugin().get_serializer() serializer_class = plugin().get_serializer()
serializer = serializer_class(data=attrs[source]) serializer = serializer_class(data=data['data'])
if not serializer.is_valid(): if not serializer.is_valid():
raise serializers.ValidationError(serializer.errors) raise serializers.ValidationError(serializer.errors)
return attrs return data
def transform_data(self, obj, value): def transform_data(self, obj, value):
if not obj: if not obj:

View file

@ -48,9 +48,8 @@ def insert_resource_serializers():
except KeyError: except KeyError:
continue continue
# TODO this is a fucking workaround, reimplement this on the proper place # TODO this is a fucking workaround, reimplement this on the proper place
def validate_resources(self, attrs, source, _resources=resources): def validate_resources(self, posted, _resources=resources):
""" Creates missing resources """ """ Creates missing resources """
posted = attrs.get(source, [])
result = [] result = []
resources = list(_resources) resources = list(_resources)
for data in posted: for data in posted:
@ -67,8 +66,7 @@ def insert_resource_serializers():
if not resource.on_demand: if not resource.on_demand:
data.allocated = resource.default_allocation data.allocated = resource.default_allocation
result.append(data) result.append(data)
attrs[source] = result return result
return attrs
viewset = router.get_viewset(model) viewset = router.get_viewset(model)
viewset.serializer_class.validate_resources = validate_resources viewset.serializer_class.validate_resources = validate_resources

View file

@ -62,6 +62,10 @@ class SystemUserFormMixin(object):
};""" % username };""" % username
) )
def clean_directory(self):
directory = self.cleaned_data['directory']
return directory.lstrip('/')
def clean(self): def clean(self):
super(SystemUserFormMixin, self).clean() super(SystemUserFormMixin, self).clean()
cleaned_data = self.cleaned_data cleaned_data = self.cleaned_data
@ -113,6 +117,10 @@ class PermissionForm(forms.Form):
(user.get_base_home(), user.get_base_home()) for user in related_users (user.get_base_home(), user.get_base_home()) for user in related_users
) )
def clean_home_extension(self):
home_extension = self.cleaned_data['home_extension']
return home_extension.lstrip('/')
def clean(self): def clean(self):
cleaned_data = super(PermissionForm, self).clean() cleaned_data = super(PermissionForm, self).clean()
path = os.path.join(cleaned_data['base_home'], cleaned_data['home_extension']) path = os.path.join(cleaned_data['base_home'], cleaned_data['home_extension'])

View file

@ -96,6 +96,7 @@ class SystemUser(models.Model):
super(SystemUser, self).save(*args, **kwargs) super(SystemUser, self).save(*args, **kwargs)
def clean(self): def clean(self):
self.directory = self.directory.lstrip('/')
if self.home: if self.home:
self.home = os.path.normpath(self.home) self.home = os.path.normpath(self.home)
if self.directory: if self.directory:

View file

@ -24,20 +24,20 @@ class SystemUserSerializer(AccountSerializerMixin, SetPasswordHyperlinkedSeriali
) )
postonly_fields = ('username', 'password') postonly_fields = ('username', 'password')
def validate(self, attrs): def validate_directory(self, directory):
attrs = super(SystemUserSerializer, self).validate(attrs) return directory.lstrip('/')
user = SystemUser(
username=attrs.get('username') or self.instance.username,
shell=attrs.get('shell') or self.instance.shell,
)
validate_home(user, attrs, self.get_account())
return attrs
def validate_groups(self, attrs, source): def validate(self, data):
groups = attrs.get(source) data = super(SystemUserSerializer, self).validate(data)
user = SystemUser(
username=data.get('username') or self.instance.username,
shell=data.get('shell') or self.instance.shell,
)
validate_home(user, data, self.get_account())
groups = data.get('groups')
if groups: if groups:
for group in groups: for group in groups:
if group.username == attrs['username']: if group.username == data['username']:
raise serializers.ValidationError( raise serializers.ValidationError(
_("Do not make the user member of its group")) _("Do not make the user member of its group"))
return attrs return data

View file

@ -6,7 +6,7 @@ from django.utils.translation import ugettext_lazy as _
from orchestra.contrib.orchestration import Operation from orchestra.contrib.orchestration import Operation
def validate_path_exists(user, path, ): def validate_path_exists(user, path):
user.path_to_validate = path user.path_to_validate = path
log = Operation.execute_action(user, 'validate_path_exists')[0] log = Operation.execute_action(user, 'validate_path_exists')[0]
if 'path does not exists' in log.stderr: if 'path does not exists' in log.stderr:

View file

@ -84,12 +84,13 @@ class SiteDirective(Plugin):
if errors: if errors:
raise ValidationError(errors) raise ValidationError(errors)
def validate(self, website): def validate(self, directive):
if self.regex and not re.match(self.regex, website.value): directive.value = directive.value.strip()
if self.regex and not re.match(self.regex, directive.value):
raise ValidationError({ raise ValidationError({
'value': ValidationError(_("'%(value)s' does not match %(regex)s."), 'value': ValidationError(_("'%(value)s' does not match %(regex)s."),
params={ params={
'value': website.value, 'value': directive.value,
'regex': self.regex 'regex': self.regex
}), }),
}) })
@ -99,20 +100,25 @@ class Redirect(SiteDirective):
name = 'redirect' name = 'redirect'
verbose_name = _("Redirection") verbose_name = _("Redirection")
help_text = _("<tt>&lt;website path&gt; &lt;destination URL&gt;</tt>") help_text = _("<tt>&lt;website path&gt; &lt;destination URL&gt;</tt>")
regex = r'^[^ ]+\s[^ ]+$' regex = r'^[^ ]*\s[^ ]+$'
group = SiteDirective.HTTPD group = SiteDirective.HTTPD
unique_value = True unique_value = True
unique_location = True unique_location = True
def validate(self, directive):
""" inserts default url path if not provided """
values = directive.value.strip().split()
if len(values) == 1:
values.insert(0, '/')
directive.value = ' '.join(values)
super(Redirect, self).validate(directive)
class Proxy(SiteDirective):
class Proxy(Redirect):
name = 'proxy' name = 'proxy'
verbose_name = _("Proxy") verbose_name = _("Proxy")
help_text = _("<tt>&lt;website path&gt; &lt;target URL&gt;</tt>") help_text = _("<tt>&lt;website path&gt; &lt;target URL&gt;</tt>")
regex = r'^[^ ]+\shttp[^ ]+(timeout=[0-9]{1,3}|retry=[0-9]|\s)*$' regex = r'^[^ ]+\shttp[^ ]+(timeout=[0-9]{1,3}|retry=[0-9]|\s)*$'
group = SiteDirective.HTTPD
unique_value = True
unique_location = True
class ErrorDocument(SiteDirective): class ErrorDocument(SiteDirective):
@ -132,27 +138,21 @@ class SSLCA(SiteDirective):
name = 'ssl-ca' name = 'ssl-ca'
verbose_name = _("SSL CA") verbose_name = _("SSL CA")
help_text = _("Filesystem path of the CA certificate file.") help_text = _("Filesystem path of the CA certificate file.")
regex = r'^[^ ]+$' regex = r'^/[^ ]+$'
group = SiteDirective.SSL group = SiteDirective.SSL
unique_name = True unique_name = True
class SSLCert(SiteDirective): class SSLCert(SSLCA):
name = 'ssl-cert' name = 'ssl-cert'
verbose_name = _("SSL cert") verbose_name = _("SSL cert")
help_text = _("Filesystem path of the certificate file.") help_text = _("Filesystem path of the certificate file.")
regex = r'^[^ ]+$'
group = SiteDirective.SSL
unique_name = True
class SSLKey(SiteDirective): class SSLKey(SSLCA):
name = 'ssl-key' name = 'ssl-key'
verbose_name = _("SSL key") verbose_name = _("SSL key")
help_text = _("Filesystem path of the key file.") help_text = _("Filesystem path of the key file.")
regex = r'^[^ ]+$'
group = SiteDirective.SSL
unique_name = True
class SecRuleRemove(SiteDirective): class SecRuleRemove(SiteDirective):
@ -164,13 +164,11 @@ class SecRuleRemove(SiteDirective):
unique_location = True unique_location = True
class SecEngine(SiteDirective): class SecEngine(SecRuleRemove):
name = 'sec-engine' name = 'sec-engine'
verbose_name = _("SecRuleEngine Off") verbose_name = _("SecRuleEngine Off")
help_text = _("URL path with disabled modsecurity engine.") help_text = _("URL path with disabled modsecurity engine.")
regex = r'^/[^ ]*$' regex = r'^/[^ ]*$'
group = SiteDirective.SEC
unique_value = True
class WordPressSaaS(SiteDirective): class WordPressSaaS(SiteDirective):
@ -183,21 +181,13 @@ class WordPressSaaS(SiteDirective):
unique_location = True unique_location = True
class DokuWikiSaaS(SiteDirective): class DokuWikiSaaS(WordPressSaaS):
name = 'dokuwiki-saas' name = 'dokuwiki-saas'
verbose_name = "DokuWiki SaaS" verbose_name = "DokuWiki SaaS"
help_text = _("URL path for mounting wordpress multisite.") help_text = _("URL path for mounting wordpress multisite.")
group = SiteDirective.SAAS
regex = r'^/[^ ]*$'
unique_value = True
unique_location = True
class DrupalSaaS(SiteDirective): class DrupalSaaS(WordPressSaaS):
name = 'drupal-saas' name = 'drupal-saas'
verbose_name = "Drupdal SaaS" verbose_name = "Drupdal SaaS"
help_text = _("URL path for mounting wordpress multisite.") help_text = _("URL path for mounting wordpress multisite.")
group = SiteDirective.SAAS
regex = r'^/[^ ]*$'
unique_value = True
unique_location = True