Example #1
0
def processPath(path, invoker, encoder, values=None):
    '''
    Process the gateway path marking groups for all property types present in the path.
    
    @param path: Path
        The path to process as a gateway pattern.
    @param invoker: Invoker
        The invoker to process the pattern based on.
    @param encoder: IEncoderPath
        The path encoder used for processing to path.
    @param values: dictionary{TypeProperty: string}
        The static values to be placed on the path, as a key the type property that has the value.
    @return: tuple(string, list[TypeProperty])
        Returns the gateway path and the property types that the path has markers for.
    '''
    assert isinstance(path, Path), 'Invalid path %s' % path
    assert isinstance(invoker, Invoker), 'Invalid invoker %s' % invoker
    assert isinstance(encoder, IEncoderPath), 'Invalid path encoder %s' % encoder
    
    replaceMarkers, types = [], []
    for propertyType in propertyTypesOf(path, invoker):
        assert isinstance(propertyType, TypeProperty), 'Invalid property type %s' % propertyType
        
        if values:
            assert isinstance(values, dict), 'Invalid values %s' % values
            value = values.get(propertyType)
            if value is not None:
                assert isinstance(value, str), 'Invalid value %s' % value
                replaceMarkers.append(value)
                continue
            
        replaceMarkers.append('{%s}' % len(types))
        types.append(propertyType)
    
    return encoder.encode(path, invalid=ReplacerWithMarkers().register(replaceMarkers)), types
Example #2
0
    def process(self, node, invoker):
        '''
        Process the structure for the provided node and invoker.
        
        @param node: Node
            The node to process for.
        @param invoker: Invoker
            The invoker to process.
        @return: tuple(list[TypeProperty], @see: StructNode.process)|None
            The list of path property types.
        '''
        assert isinstance(node, Node), 'Invalid node %s' % node

        structNode = self.structNodes.get(node)
        if structNode is None:
            structNode = self.structNodes[node] = StructNode()
        assert isinstance(structNode, StructNode)
        data = structNode.process(invoker)
        if data is None: return

        typesPath = self.typesPaths.get(node)
        if typesPath is None:
            typesPath = self.typesPaths[node] = (propertyTypesOf(
                node, invoker), )
        return typesPath + data
Example #3
0
 def _processPatternWithSecured(self, path, invoker, replacer):
     '''
     Process the access pattern for secured by using the path and replacer.
     
     @param path: Path
         The path to process the pattern based on.
     @param invoker: Invoker
         The invoker to process the pattern based on.
     @param replacer: PatternReplacer
         The replacer to use on the path.
     @return: string
         It returns the pattern
     '''
     assert isinstance(path, Path), 'Invalid path %s' % path
     assert isinstance(invoker, Invoker), 'Invalid invoker %s' % invoker
     assert isinstance(replacer, ReplacerWithMarkers), 'Invalid replacer %s' % replacer
     
     replaceMarkers = []
     for propertyType in propertyTypesOf(path, invoker):
         assert isinstance(propertyType, TypeProperty), 'Invalid property type %s' % propertyType
         
         if propertyType.isOf(int): replaceMarkers.append('[0-9\\-]+')
         elif propertyType.isOf(str): replaceMarkers.append('[^\\/]+')
         else: raise Exception('Unusable type \'%s\'' % propertyType)
     
     replacer.register(replaceMarkers)
     pattern = ''.join(('\\/'.join(path.toPaths(self.converterPath, replacer)), '[\\/]?(?:\\.|$)'))
     return pattern
Example #4
0
 def processFilter(self, rfilter, provider, marker, encoder):
     '''
     Process the provided filter.
     
     @param rfilter: Filter
         The resource filter to process.
     @param provider: callable|None
         The callable used in solving the authenticated values.
     @param marker: string
         The resource marker to place in the filter path, this marker is used to identify the group in the gateway pattern.
     @param encoder: IEncoderPath
         The encoder path to be used for the gateways resource paths and patterns.
     @return: string|None
         The marked filter path, None if the filter is invalid.
     '''
     assert isinstance(rfilter, Filter), 'Invalid filter %s' % rfilter
     assert isinstance(rfilter.filter, IAclFilter), 'Invalid filter %s of %s' % (rfilter.filter, rfilter)
     typeService = typeFor(rfilter.filter)
     assert isinstance(typeService, TypeService), 'Invalid filter %s, is not a REST service' % rfilter.filter
     assert isinstance(marker, str), 'Invalid marker %s' % marker
     assert isinstance(encoder, IEncoderPath), 'Invalid encoder path %s' % encoder
     
     path = self._cacheFilters.get(typeService)
     if not path:
         nodes = findNodesFor(self.resourcesRoot, typeService, 'isAllowed')
         if not nodes:
             log.error('The filter service %s cannot be located in the resources tree', typeService)
             return
         if len(nodes) > 1:
             log.error('To many nodes for service %s in the resources tree, don\'t know which one to use', typeService)
             return
         
         node = nodes[0]
         assert isinstance(node, Node)
         path = pathForNode(node)
         
         if __debug__:
             # Just checking that the properties are ok
             propertyTypes = propertyTypesOf(path, node.get)
             assert len(propertyTypes) == 2, 'Invalid path %s for filter' % path
             indexAuth = propertyTypes.index(rfilter.authenticated)
             assert indexAuth >= 0, 'Invalid authenticated %s for path %s' % (rfilter.authenticated, path)
             indexRsc = propertyTypes.index(rfilter.resource)
             assert indexRsc >= 0, 'Invalid resource %s for path %s' % (rfilter.resource, path)
             assert indexAuth < indexRsc, 'Invalid path %s, improper order for types' % path
 
     assert isinstance(path, Path), 'Invalid path %s' % path
     if provider:
         assert callable(provider), 'Invalid authenticated provider %s' % provider
         valueAuth = provider(rfilter.authenticated)
     else: valueAuth = None
     if valueAuth is None:
         log.error('The filter service %s has not authenticated value for %s', typeService, rfilter.authenticated)
         return
     
     return encoder.encode(path, invalid=ReplacerWithMarkers().register((valueAuth, marker)), quoted=False)
Example #5
0
 def _processFilters(self, filters, replacer):
     '''
     Process the filters into path filters.
     
     @param filters: Iterable(Filter)
         The filters to process.
     @param replacer: PatternReplacer
         The replacer to use on the path.
     @return: dictionary{TypeProperty, tuple(string, dictionary{TypeProperty: string}}
         A dictionary containing {resource type, (marked path, {authenticated type: marker}}
     '''
     assert isinstance(filters, Iterable), 'Invalid filters %s' % filter
     assert isinstance(replacer, ReplacerWithMarkers), 'Invalid replacer %s' % replacer
     
     filtersWithPath = {}
     for resourceFilter in filters:
         assert isinstance(resourceFilter, Filter), 'Invalid filter %s' % filter
         assert isinstance(resourceFilter.filter, IAclFilter), \
         'Invalid filter object %s for resource filter %s' % (resourceFilter.filter, resourceFilter)
         typeService = typeFor(resourceFilter.filter)
         assert isinstance(typeService, TypeService), \
         'Invalid filter %s, it needs to be mapped as a REST service' % resourceFilter.filter
         pathAndMarkers = self._cacheFilters.get(typeService)
         if not pathAndMarkers:
             nodes = findNodesFor(self.resourcesRoot, typeService, 'isAllowed')
             if not nodes:
                 log.error('The filter service %s cannot be located in the resources tree', typeService)
                 continue
             if len(nodes) > 1:
                 log.error('To many nodes for service %s in the resources tree, don\'t know which one to use', typeService)
                 continue
             node = nodes[0]
             assert isinstance(node, Node)
             path = pathForNode(node)
             assert isinstance(path, Path)
             
             if __debug__:
                 # Just checking that the properties are ok
                 propertyTypes = propertyTypesOf(path, node.get)
                 assert len(propertyTypes) == 2, 'Invalid path %s for filter' % path
                 indexAuth = propertyTypes.index(resourceFilter.authenticated)
                 assert indexAuth >= 0, 'Invalid authenticated %s for path %s' % (resourceFilter.authenticated, path)
                 indexRsc = propertyTypes.index(resourceFilter.resource)
                 assert indexRsc >= 0, 'Invalid resource %s for path %s' % (resourceFilter.resource, path)
                 assert indexAuth < indexRsc, 'Invalid path %s, improper order for types' % path
             
             markerAuth = markerFor(resourceFilter.authenticated)
             replacer.register((markerAuth, '*'))
             pathMarked = '/'.join(path.toPaths(self.converterPath, replacer))
             pathAndMarkers = self._cacheFilters[typeService] = (pathMarked, {resourceFilter.authenticated: markerAuth})
             
         filtersWithPath[resourceFilter.resource] = pathAndMarkers
     return filtersWithPath
Example #6
0
def processPattern(path, invoker, encoder, values=None):
    '''
    Process the gateway pattern creating groups for all property types present in the path.
    
    @param path: Path
        The path to process as a gateway pattern.
    @param invoker: Invoker
        The invoker to process the pattern based on.
    @param encoder: IEncoderPath
        The path encoder used for processing to path.
    @param values: dictionary{TypeProperty: string}
        The static values to be placed on the path, as a key the type property that has the value.
    @return: tuple(string, list[TypeProperty])
        Returns the gateway pattern and the property types that the pattern has capturing groups for.
    '''
    assert isinstance(path, Path), 'Invalid path %s' % path
    assert isinstance(invoker, Invoker), 'Invalid invoker %s' % invoker
    assert isinstance(encoder,
                      IEncoderPath), 'Invalid path encoder %s' % encoder

    replaceMarkers, types = [], []
    for propertyType in propertyTypesOf(path, invoker):
        assert isinstance(
            propertyType,
            TypeProperty), 'Invalid property type %s' % propertyType

        if values:
            assert isinstance(values, dict), 'Invalid values %s' % values
            value = values.get(propertyType)
            if value is not None:
                assert isinstance(value, str), 'Invalid value %s' % value
                replaceMarkers.append(re.escape(value))
                continue

        if propertyType.isOf(int): replaceMarkers.append('([0-9\\-]+)')
        elif propertyType.isOf(str): replaceMarkers.append('([^\\/]+)')
        else: raise Exception('Unusable type \'%s\'' % propertyType)
        types.append(propertyType)

    pattern = encoder.encodePattern(
        path, invalid=ReplacerWithMarkers().register(replaceMarkers))
    return '%s[\\/]?(?:\\.|$)' % pattern, types
Example #7
0
 def _processPatternWithFilters(self, path, invoker, filtersWithPath, replacer):
     '''
     Process the access pattern for filters by using the path and replacer.
     
     @param path: Path
         The path to process the pattern based on.
     @param invoker: Invoker
         The invoker to process the pattern based on.
     @param filtersWithPath: dictionary{TypeProperty, tuple(string, dictionary{TypeProperty: string}}
         A dictionary containing {resource type, (marked path, {authenticated type: marker}}
     @param replacer: PatternReplacer
         The replacer to use on the path.
     @return: tuple(string, list[string]|None, dictionary{TypeProperty: string}|None)
         Basically it returns the (pattern, filters if available, markers if available)
     '''
     assert isinstance(path, Path), 'Invalid path %s' % path
     assert isinstance(invoker, Invoker), 'Invalid invoker %s' % invoker
     assert isinstance(replacer, ReplacerWithMarkers), 'Invalid replacer %s' % replacer
     
     filters, markers, replaceMarkers = None, None, []
     for propertyType in propertyTypesOf(path, invoker):
         assert isinstance(propertyType, TypeProperty), 'Invalid property type %s' % propertyType
         pathAndMarkers = filtersWithPath.get(propertyType)
         if pathAndMarkers:
             filter, markers = pathAndMarkers
             if filters is None: filters = [filter]
             else: filters.append(filter)
             if markers is None: markers = dict(markers)
             else: markers.update(markers)
             isFiltered = True
         else: isFiltered = False
         
         if propertyType.isOf(int): replaceMarkers.append('([0-9\\-]+)' if isFiltered else '[0-9\\-]+')
         elif propertyType.isOf(str): replaceMarkers.append('([^\\/]+)' if isFiltered else '[^\\/]+')
         else: raise Exception('Unusable type \'%s\'' % propertyType)
     
     replacer.register(replaceMarkers)
     pattern = ''.join(('\\/'.join(path.toPaths(self.converterPath, replacer)), '[\\/]?(?:\\.|$)'))
     return pattern, filters, markers
Example #8
0
 def process(self, node, invoker):
     '''
     Process the structure for the provided node and invoker.
     
     @param node: Node
         The node to process for.
     @param invoker: Invoker
         The invoker to process.
     @return: tuple(list[TypeProperty], @see: StructNode.process)|None
         The list of path property types.
     '''
     assert isinstance(node, Node), 'Invalid node %s' % node
     
     structNode = self.structNodes.get(node)
     if structNode is None: structNode = self.structNodes[node] = StructNode()
     assert isinstance(structNode, StructNode)
     data = structNode.process(invoker)
     if data is None: return
     
     typesPath = self.typesPaths.get(node)
     if typesPath is None: typesPath = self.typesPaths[node] = (propertyTypesOf(node, invoker),)
     return typesPath + data
Example #9
0
def processPath(path, invoker, encoder, values=None):
    '''
    Process the gateway path marking groups for all property types present in the path.
    
    @param path: Path
        The path to process as a gateway pattern.
    @param invoker: Invoker
        The invoker to process the pattern based on.
    @param encoder: IEncoderPath
        The path encoder used for processing to path.
    @param values: dictionary{TypeProperty: string}
        The static values to be placed on the path, as a key the type property that has the value.
    @return: tuple(string, list[TypeProperty])
        Returns the gateway path and the property types that the path has markers for.
    '''
    assert isinstance(path, Path), 'Invalid path %s' % path
    assert isinstance(invoker, Invoker), 'Invalid invoker %s' % invoker
    assert isinstance(encoder,
                      IEncoderPath), 'Invalid path encoder %s' % encoder

    replaceMarkers, types = [], []
    for propertyType in propertyTypesOf(path, invoker):
        assert isinstance(
            propertyType,
            TypeProperty), 'Invalid property type %s' % propertyType

        if values:
            assert isinstance(values, dict), 'Invalid values %s' % values
            value = values.get(propertyType)
            if value is not None:
                assert isinstance(value, str), 'Invalid value %s' % value
                replaceMarkers.append(value)
                continue

        replaceMarkers.append('{%s}' % len(types))
        types.append(propertyType)

    return encoder.encode(
        path, invalid=ReplacerWithMarkers().register(replaceMarkers)), types
Example #10
0
def processPattern(path, invoker, encoder, values=None):
    '''
    Process the gateway pattern creating groups for all property types present in the path.
    
    @param path: Path
        The path to process as a gateway pattern.
    @param invoker: Invoker
        The invoker to process the pattern based on.
    @param encoder: IEncoderPath
        The path encoder used for processing to path.
    @param values: dictionary{TypeProperty: string}
        The static values to be placed on the path, as a key the type property that has the value.
    @return: tuple(string, list[TypeProperty])
        Returns the gateway pattern and the property types that the pattern has capturing groups for.
    '''
    assert isinstance(path, Path), 'Invalid path %s' % path
    assert isinstance(invoker, Invoker), 'Invalid invoker %s' % invoker
    assert isinstance(encoder, IEncoderPath), 'Invalid path encoder %s' % encoder
    
    replaceMarkers, types = [], []
    for propertyType in propertyTypesOf(path, invoker):
        assert isinstance(propertyType, TypeProperty), 'Invalid property type %s' % propertyType
        
        if values:
            assert isinstance(values, dict), 'Invalid values %s' % values
            value = values.get(propertyType)
            if value is not None:
                assert isinstance(value, str), 'Invalid value %s' % value
                replaceMarkers.append(re.escape(value))
                continue
            
        if propertyType.isOf(int): replaceMarkers.append('([0-9\\-]+)')
        elif propertyType.isOf(str): replaceMarkers.append('([^\\/]+)')
        else: raise Exception('Unusable type \'%s\'' % propertyType)
        types.append(propertyType)
    
    pattern = encoder.encodePattern(path, invalid=ReplacerWithMarkers().register(replaceMarkers))
    return '%s[\\/]?(?:\\.|$)' % pattern, types
Example #11
0
 def alternates(self):
     '''
     Provides the alternates.
     
     @return: dictionary{tuple(Node, Invoker): list[tuple(Node, Invoker, set(TypeProperty))]}
         The alternates dictionary, as a key a tuple with the node and invoker and as a value a set of the same tuples
         with the required property types and contains the possible alternates for the key.
     '''
     if self._alternates is None:
         self._alternates = {}
         alternatesRepository = {(typeService, call): set(alternates)
                                 for typeService, call, alternates in self.alternate.iterate()}            
         # First we process the node and invoker keys
         keys = []
         for node in iterateNodes(self.resourcesRoot):
             for _method, attr in METHOD_NODE_ATTRIBUTE.items():
                 invoker = getattr(node, attr)
                 if not invoker: continue
                 
                 keys.append((node, invoker))
         
         # Then we need to find the alternates
         pathTypesByKey, modelTypesByKey = {}, {}
         for key in keys:
             node, invoker = key
             assert isinstance(node, Node), 'Invalid node %s' % node
             assert isinstance(invoker, Invoker), 'Invalid invoker %s' % invoker
             
             for keyAlt in keys:
                 nodeAlt, invokerAlt = keyAlt
                 assert isinstance(nodeAlt, Node), 'Invalid node %s' % nodeAlt
                 assert isinstance(invokerAlt, Invoker), 'Invalid invoker %s' % invokerAlt
                 
                 if node == nodeAlt: continue  # Same node, no need to process
                 if invoker != invokerAlt:
                     if invoker.method != invokerAlt.method: continue  # Not the same method, no need to process
                     if invoker.output != invokerAlt.output: continue  # Not the same return, no need to process
                  
                 modelTypes = modelTypesByKey.get(key)
                 if modelTypes is None:
                     modelTypes = [inp.type for inp in invoker.inputs if isinstance(inp.type, TypeModel)]
                     modelTypesByKey[key] = modelTypes
 
                 modelTypesAlt = modelTypesByKey.get(keyAlt)
                 if modelTypesAlt is None:
                     modelTypesAlt = [inp.type for inp in invokerAlt.inputs if isinstance(inp.type, TypeModel)]
                     modelTypesByKey[keyAlt] = modelTypesAlt
                     
                 if modelTypes != modelTypesAlt: continue  # The model types don't match, no need to process
                
                 pathTypes = pathTypesByKey.get(key)
                 if pathTypes is None: pathTypes = pathTypesByKey[key] = propertyTypesOf(node, invoker)
                 pathTypesAlt = pathTypesByKey.get(keyAlt)
                 if pathTypesAlt is None: pathTypesAlt = pathTypesByKey[keyAlt] = propertyTypesOf(nodeAlt, invokerAlt)
                 
                 required = set(pathTypes)
                 for pathType in pathTypesAlt:
                     try: required.remove(pathType)
                     except KeyError:  # If a type is not found it means that they are not compatible
                         required.clear()
                         break  
                 if not required: continue  # There must be at least one type required
                 
                 # Now we check with the alternates repository configurations
                 if self.processWithRepository(alternatesRepository, invoker, invokerAlt):
                     alternates = self._alternates.get(key)
                     if alternates is None: alternates = self._alternates[key] = []
                     alternates.append(keyAlt + (required,))
                     assert log.debug('Added alternate on %s for %s', invoker, invokerAlt) or True
                     
         for serviceCall, alternates in alternatesRepository.items():
             if alternates:
                 alternates = ('\t%s for %s' % serviceCallAlt for serviceCallAlt in alternates)
                 service, call = serviceCall
                 log.error('Invalid alternate configuration on %s for %s with:\n%s\n', service, call, '\n'.join(alternates))
         
     return self._alternates
Example #12
0
    def alternates(self):
        '''
        Provides the alternates.
        
        @return: dictionary{tuple(Node, Invoker): list[tuple(Node, Invoker, set(TypeProperty))]}
            The alternates dictionary, as a key a tuple with the node and invoker and as a value a set of the same tuples
            with the required property types and contains the possible alternates for the key.
        '''
        if self._alternates is None:
            self._alternates = {}
            alternatesRepository = {
                (typeService, call): set(alternates)
                for typeService, call, alternates in self.alternate.iterate()
            }
            # First we process the node and invoker keys
            keys = []
            for node in iterateNodes(self.resourcesRoot):
                for _method, attr in METHOD_NODE_ATTRIBUTE.items():
                    invoker = getattr(node, attr)
                    if not invoker: continue

                    keys.append((node, invoker))

            # Then we need to find the alternates
            pathTypesByKey, modelTypesByKey = {}, {}
            for key in keys:
                node, invoker = key
                assert isinstance(node, Node), 'Invalid node %s' % node
                assert isinstance(invoker,
                                  Invoker), 'Invalid invoker %s' % invoker

                for keyAlt in keys:
                    nodeAlt, invokerAlt = keyAlt
                    assert isinstance(nodeAlt,
                                      Node), 'Invalid node %s' % nodeAlt
                    assert isinstance(
                        invokerAlt, Invoker), 'Invalid invoker %s' % invokerAlt

                    if node == nodeAlt:
                        continue  # Same node, no need to process
                    if invoker != invokerAlt:
                        if invoker.method != invokerAlt.method:
                            continue  # Not the same method, no need to process
                        if invoker.output != invokerAlt.output:
                            continue  # Not the same return, no need to process

                    modelTypes = modelTypesByKey.get(key)
                    if modelTypes is None:
                        modelTypes = [
                            inp.type for inp in invoker.inputs
                            if isinstance(inp.type, TypeModel)
                        ]
                        modelTypesByKey[key] = modelTypes

                    modelTypesAlt = modelTypesByKey.get(keyAlt)
                    if modelTypesAlt is None:
                        modelTypesAlt = [
                            inp.type for inp in invokerAlt.inputs
                            if isinstance(inp.type, TypeModel)
                        ]
                        modelTypesByKey[keyAlt] = modelTypesAlt

                    if modelTypes != modelTypesAlt:
                        continue  # The model types don't match, no need to process

                    pathTypes = pathTypesByKey.get(key)
                    if pathTypes is None:
                        pathTypes = pathTypesByKey[key] = propertyTypesOf(
                            node, invoker)
                    pathTypesAlt = pathTypesByKey.get(keyAlt)
                    if pathTypesAlt is None:
                        pathTypesAlt = pathTypesByKey[
                            keyAlt] = propertyTypesOf(nodeAlt, invokerAlt)

                    required = set(pathTypes)
                    for pathType in pathTypesAlt:
                        try:
                            required.remove(pathType)
                        except KeyError:  # If a type is not found it means that they are not compatible
                            required.clear()
                            break
                    if not required:
                        continue  # There must be at least one type required

                    # Now we check with the alternates repository configurations
                    if self.processWithRepository(alternatesRepository,
                                                  invoker, invokerAlt):
                        alternates = self._alternates.get(key)
                        if alternates is None:
                            alternates = self._alternates[key] = []
                        alternates.append(keyAlt + (required, ))
                        assert log.debug('Added alternate on %s for %s',
                                         invoker, invokerAlt) or True

            for serviceCall, alternates in alternatesRepository.items():
                if alternates:
                    alternates = ('\t%s for %s' % serviceCallAlt
                                  for serviceCallAlt in alternates)
                    service, call = serviceCall
                    log.error(
                        'Invalid alternate configuration on %s for %s with:\n%s\n',
                        service, call, '\n'.join(alternates))

        return self._alternates
Example #13
0
    def processFilter(self, rfilter, provider, marker, encoder):
        '''
        Process the provided filter.
        
        @param rfilter: Filter
            The resource filter to process.
        @param provider: callable|None
            The callable used in solving the authenticated values.
        @param marker: string
            The resource marker to place in the filter path, this marker is used to identify the group in the gateway pattern.
        @param encoder: IEncoderPath
            The encoder path to be used for the gateways resource paths and patterns.
        @return: string|None
            The marked filter path, None if the filter is invalid.
        '''
        assert isinstance(rfilter, Filter), 'Invalid filter %s' % rfilter
        assert isinstance(
            rfilter.filter,
            IAclFilter), 'Invalid filter %s of %s' % (rfilter.filter, rfilter)
        typeService = typeFor(rfilter.filter)
        assert isinstance(
            typeService, TypeService
        ), 'Invalid filter %s, is not a REST service' % rfilter.filter
        assert isinstance(marker, str), 'Invalid marker %s' % marker
        assert isinstance(encoder,
                          IEncoderPath), 'Invalid encoder path %s' % encoder

        path = self._cacheFilters.get(typeService)
        if not path:
            nodes = findNodesFor(self.resourcesRoot, typeService, 'isAllowed')
            if not nodes:
                log.error(
                    'The filter service %s cannot be located in the resources tree',
                    typeService)
                return
            if len(nodes) > 1:
                log.error(
                    'To many nodes for service %s in the resources tree, don\'t know which one to use',
                    typeService)
                return

            node = nodes[0]
            assert isinstance(node, Node)
            path = pathForNode(node)

            if __debug__:
                # Just checking that the properties are ok
                propertyTypes = propertyTypesOf(path, node.get)
                assert len(
                    propertyTypes) == 2, 'Invalid path %s for filter' % path
                indexAuth = propertyTypes.index(rfilter.authenticated)
                assert indexAuth >= 0, 'Invalid authenticated %s for path %s' % (
                    rfilter.authenticated, path)
                indexRsc = propertyTypes.index(rfilter.resource)
                assert indexRsc >= 0, 'Invalid resource %s for path %s' % (
                    rfilter.resource, path)
                assert indexAuth < indexRsc, 'Invalid path %s, improper order for types' % path

        assert isinstance(path, Path), 'Invalid path %s' % path
        if provider:
            assert callable(
                provider), 'Invalid authenticated provider %s' % provider
            valueAuth = provider(rfilter.authenticated)
        else:
            valueAuth = None
        if valueAuth is None:
            log.error(
                'The filter service %s has not authenticated value for %s',
                typeService, rfilter.authenticated)
            return

        return encoder.encode(path,
                              invalid=ReplacerWithMarkers().register(
                                  (valueAuth, marker)),
                              quoted=False)