class Instance(umc.modules.Base): def _get_description(self, description): # Try to return the localised description or # use english as a fallback if self.locale.language in description: return description[self.locale.language] elif u'en' in description: return description[u'en'] else: return None @decorators.sanitize(category=sanitizers.ChoicesSanitizer(( u'protocol', u'port', u'address', u'packageName', u'description', ), default=u'port'), pattern=sanitizers.PatternSanitizer(default=u'.*')) @decorators.simple_response def rules_query(self, category, pattern): """Searches for firewall rules requests.options = [ 'category': 'protocol' | 'port' | 'address' | 'package' | 'description', 'pattern': <str>, ] """ def match(rule): if category == u'port': # Check every port number for port in range(*rule.port): match = pattern.match(str(port)) if match: return match else: return False elif category == u'packageName': if rule.package: return pattern.match(rule.package) else: return False elif category == u'description': for language in rule.description.values(): match = pattern.match(language) if match: return match else: return False else: # Simple match for most cases: return pattern.match(getattr(rule, category)) def get_address(address): if address == u'all': return _(u'All addresses') elif address == u'ipv4': return _(u'All IPv4 addresses') elif address == u'ipv6': return _(u'All IPv6 addresses') else: return address # Try to load firewall configuration try: firewall = backend.Firewall() except backend.Error as e: message = _(u"Could not load firewall configuration") MODULE.error(u"%s: %s" % ( message, str(e), )) raise umc.modules.UMC_CommandError(message) result = [] for rule in firewall.rules.values(): if not rule or not match(rule): # rule isn't complete (e.g. missing action) or # rule doesn't match the pattern continue entry = {} entry = { u'identifier': rule.identifier, u'protocol': rule.protocol, u'portStart': rule.port[0], u'portEnd': (rule.port[1] - 1), u'address': get_address(rule.address), u'packageName': rule.package, u'action': rule.action.lower(), u'description': self._get_description(rule.description), } result.append(entry) return result def _add_or_edit(self, iterator, object, edit=False): def get_address(address_type, address_value): if address_type == u'specific': return address_value else: return address_type # Try to load firewall configuration try: firewall = backend.Firewall() except backend.Error as e: message = _(u"Could not load firewall configuration") MODULE.error(u"%s: %s" % ( message, str(e), )) raise umc.modules.UMC_CommandError(message) for (object, ) in iterator: try: if edit: firewall.remove_rule(object[u'identifier']) port = ( object[u'portStart'], (object[u'portEnd'] + 1), ) address = get_address(object[u'addressType'], object[u'addressValue']) rule = backend.Rule(object[u'protocol'], port, address, None, object[u'action'].lower()) firewall.add_rule(rule) except backend.Error as e: if edit: yield { u'object': object[u'identifier'], u'success': False, u'details': str(e), } else: yield { u'success': False, u'details': str(e), } else: yield { u'object': rule.identifier, u'success': True, } # Try to save firewall configuration try: firewall.save() except backend.Error as e: message = _(u"Could not save firewall configuration") MODULE.error(u"%s: %s" % ( message, str(e), )) raise umc.modules.UMC_CommandError(message) @decorators.sanitize( sanitizers.DictSanitizer({ u'object': sanitizers.DictSanitizer( { u'protocol': sanitizers.ChoicesSanitizer( ( u'tcp', u'udp', ), required=True), u'portStart': sanitizers.IntegerSanitizer(minimum=1, maximum=2**16, maximum_strict=True, required=True), u'portEnd': sanitizers.IntegerSanitizer(minimum=1, maximum=2**16, maximum_strict=True, required=True), u'addressType': sanitizers.ChoicesSanitizer(( u'all', u'ipv4', u'ipv6', u'specific', ), required=True), u'addressValue': sanitizers.StringSanitizer(default=u''), u'action': sanitizers.ChoicesSanitizer( ( u'accept', u'reject', u'drop', ), required=True), }, required=True), })) @decorators.multi_response @decorators.log def rules_add(self, iterator, object): """Add the specified new rules: requests.options = [{ 'object': { 'protocol': 'tcp' | 'udp', 'portStart': <int>, 'portEnd': <int>, 'addressType': 'all' | 'ipv4' | 'ipv6' | 'specific', 'addressValue': <string> 'action': 'accept' | 'reject' | 'drop, } }, ] """ return self._add_or_edit(iterator, object, edit=False) @decorators.sanitize(sanitizers.StringSanitizer(required=True)) @decorators.multi_response(single_values=True) @decorators.log def rules_get(self, iterator): """Returns the specified rules requests.options = [ <string>, ] """ def get_address_type(address): if backend.REGEX_RULE_ADDRESS.match(address): return address else: return u'specific' def get_address_value(address): if backend.REGEX_RULE_ADDRESS.match(address): return None else: return address # Try to load firewall configuration try: firewall = backend.Firewall() except backend.Error as e: message = _(u"Could not load firewall configuration") MODULE.error(u"%s: %s" % ( message, str(e), )) raise umc.modules.UMC_CommandError(message) for identifier in iterator: try: rule = firewall.rules[identifier] entry = { u'identifier': rule.identifier, u'protocol': rule.protocol, u'portStart': rule.port[0], u'portEnd': (rule.port[1] - 1), u'addressType': get_address_type(rule.address), u'addressValue': get_address_value(rule.address), u'packageName': rule.package, u'action': rule.action.lower(), u'description': self._get_description(rule.description), } except (backend.Error, KeyError) as e: message = _(u"Could not get firewall rule") MODULE.error(u"%s: %s" % ( message, str(e), )) raise umc.modules.UMC_CommandError(message) else: yield entry @decorators.sanitize( sanitizers.DictSanitizer( { u'object': sanitizers.DictSanitizer({ u'identifier': sanitizers.StringSanitizer(required=True), u'protocol': sanitizers.ChoicesSanitizer( ( u'tcp', u'udp', ), required=True), u'portStart': sanitizers.IntegerSanitizer(minimum=1, maximum=2**16, maximum_strict=True, required=True), u'portEnd': sanitizers.IntegerSanitizer(minimum=1, maximum=2**16, maximum_strict=True, required=True), u'addressType': sanitizers.ChoicesSanitizer(( u'all', u'ipv4', u'ipv6', u'specific', ), required=True), u'addressValue': sanitizers.StringSanitizer(default=u''), u'action': sanitizers.ChoicesSanitizer( ( u'accept', u'reject', u'drop', ), required=True), }), }, required=True)) @decorators.multi_response @decorators.log def rules_put(self, iterator, object): """Edit the specified rules: requests.options = [{ 'object': { 'identifier': <str>, 'protocol': 'tcp' | 'udp', 'portStart': <int>, 'portEnd': <int>, 'addressType': 'all' | 'ipv4' | 'ipv6' | 'specific', 'addressValue': <string> 'action': 'accept' | 'reject' | 'drop, } }, ] """ return self._add_or_edit(iterator, object, edit=True) @decorators.sanitize( sanitizers.DictSanitizer( { u'object': sanitizers.StringSanitizer(required=True), }, required=True)) @decorators.multi_response @decorators.log def rules_remove(self, iterator, object): """Remove the specified rules requests.options = [{ 'object': <string>, }, ] """ # Try to load firewall configuration try: firewall = backend.Firewall() except backend.Error as e: message = _(u"Could not load firewall configuration") MODULE.error(u"%s: %s" % ( message, str(e), )) raise umc.modules.UMC_CommandError(message) for (object, ) in iterator: try: firewall.remove_rule(object) except backend.Error as e: yield { u'object': object, u'success': False, u'details': str(e), } else: yield { u'object': object, u'success': True, } # Try to save firewall configuration try: firewall.save() except backend.Error as e: message = _(u"Could not save firewall configuration") MODULE.error(u"%s: %s" % ( message, str(e), )) raise umc.modules.UMC_CommandError(message)
class Instance(Base): @sanitize(value=s.BooleanSanitizer(required=True)) @simple_response @log def bool(self, value): """ bool is just an int with 1 bit, so: True: 1 == True, 0 == False, isinstance(True, int) False: 2 == True, isinstance(1, bool) """ assert repr(value) in ('True', 'False'), 'Value is not a bool' return '%r' % (value, ) _choices = ('Ja', 2, True, (2, ), [], {}) @sanitize(value=s.ChoicesSanitizer(choices=_choices, required=True)) @simple_response @log def choices(self, value): assert value in self._choices, 'A value is not in choices' assert isinstance(value, type(self._choices[self._choices.index( value)])), 'A choice has the wrong type' # makes sense !;) return '%r' % (value, ) @sanitize(value=s.DictSanitizer({}, required=True)) @simple_response @log def dict(self, value): assert isinstance(value, dict), 'Value is not a dict: %r' % (value) return '%r' % (value, ) @sanitize(value=s.DictSanitizer( { 'foo': s.Sanitizer(), 'bar': s.Sanitizer() }, required=True, allow_other_keys=False)) @simple_response @log def dict_a(self, value): assert set(value) == set( ['foo', 'bar']), 'There are invalid keys: %r' % (list(value)) return '%r' % (value, ) @sanitize(value=s.EmailSanitizer(required=True)) @simple_response @log def email(self, value): assert isinstance(value, basestring) and value.count( '@') == 1, 'Value is not a string or does not contain @: %r' % ( value, ) return '%r' % (value, ) @sanitize(value=s.IntegerSanitizer(required=True)) @simple_response @log def int(self, value): assert isinstance(value, int), 'Value is not an int' # could be long return '%r' % (value, ) @sanitize(value=s.LDAPSearchSanitizer(required=True)) @simple_response @log def ldapsearch(self, value): # TODO return '%r' % (value, ) @sanitize(value=s.ListSanitizer(s.Sanitizer(), required=True)) @simple_response @log def list(self, value): assert isinstance(value, (list, tuple)), 'No List given' return '%r' % (value, ) @sanitize(value=s.ListSanitizer(min_elements=3, max_elements=6, required=True)) @simple_response @log def list_a(self, value): assert 3 <= len(value) <= 6, 'wrong list length: %d' % len(value) return '%r' % (value, ) _mapping = {u'foo': 'bar', b'bar': 1, 'baz': []} @sanitize(value=s.MappingSanitizer(_mapping, required=True)) @simple_response @log def mapping(self, value): assert value in self._mapping.values(), 'Mapping failed: %r' % ( value, ) # TODO: more? return '%r' % (value, ) @sanitize(value=s.PatternSanitizer(required=True)) @simple_response @log def pattern(self, value): import re assert isinstance(value, re._pattern_type) assert value.pattern.count( '.*') < 6, 'pattern contains more than 5 stars' return '%r' % (value, ) @sanitize(value=s.StringSanitizer(required=True)) @simple_response @log def string(self, value): assert isinstance(value, basestring) if not isinstance(value, unicode): # Is it possible that we don't have unicode here? try: value.decode('utf-8') except: assert False, 'no unicode' return '%r' % (value, ) @simple_response @log def simple(self, value, foo='default'): return '%r %r' % (value, foo) @multi_response @log def multi(self, iterator, *values): assert all(map(lambda v: isinstance(v, dict), iterator)) yield '%r %s' % (list(iterator), values) @file_upload def upload(self, request): assert request.command == 'UPLOAD' self.finished(request.id, True) @multi_response(single_values=True) def single(self, iterator, *values): return '%r' % (values)