def processPermissions(self, permissions, Permission, encoder): ''' Process the permissions alternate navigation. @param encoder: IEncoderPath|None The encoder path to be used for the gateways resource paths and patterns. ''' for permission in permissions: assert isinstance(permission, PermissionResource), 'Invalid permission %s' % permission yield permission if not permission.values: continue # No values to work with assert isinstance(permission.path, Path), 'Invalid path %s' % permission.path alternates = self.alternates().get((permission.path.node, permission.invoker)) if not alternates: continue # No alternates to work with for node, invoker, required in alternates: assert isinstance(required, set) if required.issubset(permission.values): permissionAlt = Permission() assert isinstance(permissionAlt, PermissionResource) permissionAlt.method = permission.method permissionAlt.path = pathForNode(node) permissionAlt.invoker = invoker permissionAlt.filters = permission.filters permissionAlt.values = permission.values if PermissionResource.navigate in permissionAlt: assert isinstance(encoder, IEncoderPath), 'Invalid encoder path %s' % encoder path, _types = processPath(permission.path, permission.invoker, encoder, permission.values) permissionAlt.navigate = path yield permissionAlt
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)
def iterPermissions(self, indexed, Permission): ''' Iterates the permissions for the provided indexed structure. ''' for indexedMethod, indexedServices in indexed.items(): for indexedCalls in indexedServices.values(): for indexInvokers, filters in indexedCalls.values(): for node, invoker in indexInvokers.items(): yield Permission(method=indexedMethod, path=pathForNode(node), invoker=invoker, filters=list(filters.values()))
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
def processPermissions(self, permissions, Permission, encoder): ''' Process the permissions alternate navigation. @param encoder: IEncoderPath|None The encoder path to be used for the gateways resource paths and patterns. ''' for permission in permissions: assert isinstance( permission, PermissionResource), 'Invalid permission %s' % permission yield permission if not permission.values: continue # No values to work with assert isinstance(permission.path, Path), 'Invalid path %s' % permission.path alternates = self.alternates().get( (permission.path.node, permission.invoker)) if not alternates: continue # No alternates to work with for node, invoker, required in alternates: assert isinstance(required, set) if required.issubset(permission.values): permissionAlt = Permission() assert isinstance(permissionAlt, PermissionResource) permissionAlt.method = permission.method permissionAlt.path = pathForNode(node) permissionAlt.invoker = invoker permissionAlt.filters = permission.filters permissionAlt.values = permission.values if PermissionResource.navigate in permissionAlt: assert isinstance( encoder, IEncoderPath), 'Invalid encoder path %s' % encoder path, _types = processPath(permission.path, permission.invoker, encoder, permission.values) permissionAlt.navigate = path yield permissionAlt
def iterPermissions(cls, node, rights, method=None): ''' @see: RightBase.iterPermissions ''' assert isinstance(rights, Iterable), 'Invalid rights %s' % rights indexed = {} for right in rights: assert isinstance(right, RightService), 'Invalid right %s' % right cacheNode = right._process(node) assert isinstance(cacheNode, CacheNode) for structCall, cacheCall in cacheNode.calls.items(): assert isinstance(structCall, StructCall) assert isinstance(cacheCall, CacheCall) if method: assert isinstance(method, int), 'Invalid method %s' % method if not method & structCall.call.method: continue assert isinstance(structCall.call, Call) # Processing invokers indexedServices = indexed.get(structCall.call.method) if indexedServices is None: indexedServices = indexed[structCall.call.method] = {} indexedCalls = indexedServices.get(structCall.serviceType) if indexedCalls is None: indexedCalls = indexedServices[structCall.serviceType] = {} invokersAndFilters = indexedCalls.get(structCall.call.name) if invokersAndFilters is None: invokersAndFilters = indexedCalls[structCall.call.name] = ({}, {}) isFirst = True else: isFirst = False cacheInvokers, filters = invokersAndFilters cacheInvokers.update(cacheCall.invokers) # Processing filters if StructCall.filters in structCall: if isFirst: filters.update(structCall.filters) elif filters: # Means there is something in the filters oldFilters = dict(filters) filters.clear() for resourceType, structFilter in structCall.filters.items(): assert isinstance(structFilter, Filter) resourceFilter = oldFilters.get(resourceType) if not resourceFilter: continue assert isinstance(resourceFilter, Filter) if resourceFilter.priority > structFilter.priority: filters[resourceType] = structFilter else: filters[resourceType] = resourceFilter elif filters: filters.clear() # Clear all the filters since this structure requires no filtering for indexedMethod, indexedServices in indexed.items(): for indexedCalls in indexedServices.values(): for cacheInvokers, filters in indexedCalls.values(): for cacheInvoker in cacheInvokers.values(): assert isinstance(cacheInvoker, CacheInvoker) path = pathForNode(cacheInvoker.node) assert isinstance(path, Path) # We need to check if the returned node has at least one filter in the path. # TODO: check implementation, since this was done in a hurry available = [] for resourceType, filter in filters.items(): for match in path.matches: if isinstance(match, MatchProperty): assert isinstance(match, MatchProperty) assert isinstance(match.node, NodeProperty) if resourceType in match.node.typesProperties: available.append(filter) break yield indexedMethod, path, cacheInvoker.invoker, available
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)