Ejemplo n.º 1
0
    def get_acl(self):
        self.expand_acl(self.service, self.request.user)
        elems = self.request.path.split("/")

        if "fileServer" in elems:
            first_idx = elems.index("fileServer")
        elif "dodsC" in elems:
            first_idx = elems.index("dodsC")
            elems[-1] = elems[-1].replace(".html", "")
        elif "catalog" in elems:
            first_idx = elems.index("catalog")
        elif elems[-1] == "catalog.html":
            first_idx = elems.index(self.service.resource_name) - 1
        else:
            return self.acl

        elems = elems[first_idx + 1::]
        new_child = self.service
        while new_child and elems:
            elem_name = elems.pop(0)
            if ".nc" in elem_name:
                elem_name = elem_name.split(".nc")[0] + ".nc"  # in case there is more extension to discard such as .dds
            parent_id = new_child.resource_id
            new_child = models.find_children_by_name(elem_name, parent_id=parent_id, db_session=self.request.db)
            self.expand_acl(new_child, self.request.user)

        return self.acl
Ejemplo n.º 2
0
    def get_acl(self, sub_api_route=None):
        self.expand_acl(self.service, self.request.user)

        match_index = 0
        route_parts = self.request.path.split("/")
        route_api_base = self.service.resource_name if sub_api_route is None else sub_api_route

        if self.service.resource_name in route_parts and route_api_base in route_parts:
            api_idx = route_parts.index(route_api_base)
            # keep only parts after api base route to process it
            if len(route_parts) - 1 > api_idx:
                route_parts = route_parts[api_idx + 1::]
                route_child = self.service

                # process read/write inheritance permission access
                while route_child and route_parts:
                    part_name = route_parts.pop(0)
                    route_res_id = route_child.resource_id
                    route_child = models.find_children_by_name(part_name, parent_id=route_res_id,
                                                               db_session=self.request.db)
                    match_index = len(self.acl)
                    self.expand_acl(route_child, self.request.user)

        # process read/write-match specific permission access
        # (convert exact route 'match' to read/write counterparts only if matching last item's permissions)
        for i in range(match_index, len(self.acl)):
            if Permission.get(self.acl[i][2]) == Permission.READ_MATCH:
                self.acl[i] = (self.acl[i][0], self.acl[i][1], Permission.READ.value)
            if Permission.get(self.acl[i][2]) == Permission.WRITE_MATCH:
                self.acl[i] = (self.acl[i][0], self.acl[i][1], Permission.WRITE.value)
        return self.acl
Ejemplo n.º 3
0
    def get_acl(self):
        self.expand_acl(self.service, self.request.user)

        # localhost:8087/geoserver/WATERSHED/wms?layers=WATERSHED:BV_1NS&request=getmap
        # localhost:8087/geoserver/wms?layers=WATERERSHED:BV1_NS&request=getmap
        # those two request lead to the same thing so, here we need to check the workspace in the layer

        # localhost:8087/geoserver/wms?request=getcapabilities (dangerous, get all workspace)
        # localhost:8087/geoserver/WATERSHED/wms?request=getcapabilities (only for the workspace in the path)
        # here we need to check the workspace in the path

        request_type = self.permission_requested()
        if request_type == Permission.GET_CAPABILITIES:
            path_elem = self.request.path.split("/")
            wms_idx = path_elem.index("wms")
            if path_elem[wms_idx - 1] != "geoserver":
                workspace_name = path_elem[wms_idx - 1]
            else:
                workspace_name = ""
        else:
            layer_name = self.parser.params["layers"]
            workspace_name = layer_name.split(":")[0]

        # load workspace resource from the database
        workspace = models.find_children_by_name(child_name=workspace_name,
                                                 parent_id=self.service.resource_id,
                                                 db_session=self.request.db)
        if workspace:
            self.expand_acl(workspace, self.request.user)
        return self.acl
Ejemplo n.º 4
0
    def resource_requested(self):
        # According to the permission, the resource we want to authorize is not formatted the same way
        permission_requested = self.permission_requested()
        netcdf_file = None
        if permission_requested == Permission.GET_CAPABILITIES:
            # https://colibri.crim.ca/twitcher/ows/proxy/ncWMS2/wms?SERVICE=WMS&REQUEST=GetCapabilities&
            #   VERSION=1.3.0&DATASET=outputs/ouranos/subdaily/aet/pcp/aet_pcp_1961.nc
            if "dataset" in self.parser.params:
                netcdf_file = self.parser.params["dataset"]

        elif permission_requested == Permission.GET_MAP:
            # https://colibri.crim.ca/ncWMS2/wms?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&FORMAT=image%2Fpng&
            #   TRANSPARENT=TRUE&ABOVEMAXCOLOR=extend&STYLES=default-scalar%2Fseq-Blues&
            #   LAYERS=outputs/ouranos/subdaily/aet/pcp/aet_pcp_1961.nc/PCP&EPSG=4326
            netcdf_file = self.parser.params["layers"]
            if netcdf_file:
                netcdf_file = netcdf_file.rsplit("/", 1)[0]

        elif permission_requested == Permission.GET_METADATA:
            # https://colibri.crim.ca/ncWMS2/wms?request=GetMetadata&item=layerDetails&
            #   layerName=outputs/ouranos/subdaily/aet/pcp/aet_pcp_1961.nc/PCP
            netcdf_file = self.parser.params["layername"]
            if netcdf_file:
                netcdf_file = netcdf_file.rsplit("/", 1)[0]

        else:
            return self.service, False

        found_child = self.service
        target = False
        if netcdf_file:
            if "output/" not in netcdf_file:
                return self.service, False
            # FIXME: this is probably too specific to birdhouse... leave as is for bw-compat, adjust as needed
            netcdf_file = netcdf_file.replace("outputs/", "birdhouse/")

            db_session = self.request.db
            file_parts = netcdf_file.split("/")
            while found_child and file_parts:
                part = file_parts.pop(0)
                res_id = found_child.resource_id
                found_child = models.find_children_by_name(
                    part, parent_id=res_id, db_session=db_session)
            # target resource reached if no more parts to process, otherwise we have some parent (minimally the service)
            target = not len(file_parts)
        return found_child, target
Ejemplo n.º 5
0
 def resource_requested(self):
     wps_request = self.permission_requested()
     if wps_request == Permission.GET_CAPABILITIES:
         return self.service, True
     if wps_request in [Permission.DESCRIBE_PROCESS, Permission.EXECUTE]:
         wps_id = self.service.resource_id
         proc_id = self.parser.params["identifier"]
         if not proc_id:
             return self.service, False
         proc = models.find_children_by_name(proc_id,
                                             parent_id=wps_id,
                                             db_session=self.request.db)
         if proc:
             return proc, True
         return self.service, False
     raise NotImplementedError(
         "Unknown WPS operation for permission: {}".format(wps_request))
Ejemplo n.º 6
0
    def get_acl(self):
        self.expand_acl(self.service, self.request.user)

        # According to the permission, the resource we want to authorize is not formatted the same way
        permission_requested = self.permission_requested()
        netcdf_file = None
        if permission_requested == Permission.GET_CAPABILITIES:
            # https://colibri.crim.ca/twitcher/ows/proxy/ncWMS2/wms?SERVICE=WMS&REQUEST=GetCapabilities&
            #   VERSION=1.3.0&DATASET=outputs/ouranos/subdaily/aet/pcp/aet_pcp_1961.nc
            if "dataset" in self.parser.params.keys():
                netcdf_file = self.parser.params["dataset"]

        elif permission_requested == Permission.GET_MAP:
            # https://colibri.crim.ca/ncWMS2/wms?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&FORMAT=image%2Fpng&
            #   TRANSPARENT=TRUE&ABOVEMAXCOLOR=extend&STYLES=default-scalar%2Fseq-Blues&
            #   LAYERS=outputs/ouranos/subdaily/aet/pcp/aet_pcp_1961.nc/PCP&EPSG=4326
            netcdf_file = self.parser.params["layers"]
            if netcdf_file:
                netcdf_file = netcdf_file.rsplit("/", 1)[0]

        elif permission_requested == Permission.GET_METADATA:
            # https://colibri.crim.ca/ncWMS2/wms?request=GetMetadata&item=layerDetails&
            #   layerName=outputs/ouranos/subdaily/aet/pcp/aet_pcp_1961.nc/PCP
            netcdf_file = self.parser.params["layername"]
            if netcdf_file:
                netcdf_file = netcdf_file.rsplit("/", 1)[0]

        else:
            return [(ALLOW, EVERYONE, permission_requested.value,)]

        if netcdf_file:
            ax.verify_param("outputs/", paramCompare=netcdf_file, httpError=HTTPNotFound,
                            msgOnFail="'outputs/' is not in path", notIn=True)
            netcdf_file = netcdf_file.replace("outputs/", "birdhouse/")

            db_session = self.request.db
            path_elems = netcdf_file.split("/")
            new_child = self.service
            while new_child and path_elems:
                elem_name = path_elems.pop(0)
                new_child = models.find_children_by_name(
                    elem_name, parent_id=new_child.resource_id, db_session=db_session
                )
                self.expand_acl(new_child, self.request.user)

        return self.acl
Ejemplo n.º 7
0
    def resource_requested(self):
        # type: () -> Optional[Tuple[ServiceOrResourceType, bool]]

        route_parts = self._get_request_path_parts()
        if not route_parts:
            return self.service, True
        route_found = route_child = self.service

        # find deepest possible resource matching sub-route name
        while route_child and route_parts:
            part_name = route_parts.pop(0)
            route_res_id = route_child.resource_id
            route_child = models.find_children_by_name(
                part_name, parent_id=route_res_id, db_session=self.request.db)
            if route_child:
                route_found = route_child

        # target reached if no more parts to process, otherwise we have some parent (minimally the service)
        route_target = not len(route_parts) and route_child is not None
        return route_found, route_target
Ejemplo n.º 8
0
    def get_acl(self):
        self.expand_acl(self.service, self.request.user)
        request_type = self.permission_requested()
        if request_type == Permission.GET_CAPABILITIES:
            path_elem = self.request.path.split("/")
            wms_idx = path_elem.index("wfs")
            if path_elem[wms_idx - 1] != "geoserver":
                workspace_name = path_elem[wms_idx - 1]
            else:
                workspace_name = ""
        else:
            layer_name = self.parser.params["typenames"]
            workspace_name = layer_name.split(":")[0]

        # load workspace resource from the database
        workspace = models.find_children_by_name(child_name=workspace_name,
                                                 parent_id=self.service.resource_id,
                                                 db_session=self.request.db)
        if workspace:
            self.expand_acl(workspace, self.request.user)
        return self.acl
Ejemplo n.º 9
0
    def resource_requested(self):
        path_parts = self.get_path_parts()

        # handle optional prefix as targeting the service directly
        if len(path_parts) < 2:
            return self.service, True
        path_parts = path_parts[1:]
        cfg = self.get_config()

        # find deepest possible resource matching either Directory or File by name
        found_resource = child_resource = self.service
        while child_resource and path_parts:
            part_name = path_parts.pop(0)
            # when reaching the final part, test for possible file pattern, otherwise default to literal value
            #   allows combining different naming formats into a common file resource (eg: extra extensions)
            # if final part is a directory, still works because of literal value
            #   directory name must match exactly, no format naming variants allowed
            # if final part is 'catalog.html' file, lookup would fail and fall back to previous directory part
            #   since that would be the last part extracted, the parent directory will be matched as intended
            if not path_parts:
                for pattern in cfg["file_patterns"]:
                    try:
                        part_name = re.match(pattern, part_name)[0]
                        break
                    except (
                            TypeError, KeyError
                    ):  # fail match or fail to extract (depending on configured pattern)
                        pass
            child_res_id = child_resource.resource_id
            child_resource = models.find_children_by_name(
                part_name, parent_id=child_res_id, db_session=self.request.db)
            if child_resource:
                found_resource = child_resource

        # target resource reached if no more parts to process, otherwise we have some parent (minimally the service)
        target = not len(path_parts) and child_resource is not None
        return found_resource, target
Ejemplo n.º 10
0
 def resource_requested(self):
     permission = self.permission_requested()
     path_parts = self._get_request_path_parts()
     parts_lower = [part.lower() for part in path_parts]
     if parts_lower and parts_lower[0] == "":
         path_parts = path_parts[1:]
         parts_lower = parts_lower[1:]
     if parts_lower and parts_lower[0] == "geoserver":
         path_parts = path_parts[1:]
         parts_lower = parts_lower[1:]
     workspace_name = None
     if len(parts_lower) > 1 and parts_lower[1] == "wms":
         workspace_name = path_parts[0]
     if permission == Permission.GET_CAPABILITIES:
         # here we need to check the workspace in the path
         #   /geoserver/wms?request=getcapabilities (get all workspaces)
         #   /geoserver/WATERSHED/wms?request=getcapabilities (only for the workspace in the path)
         if not path_parts or "wms" not in parts_lower or (
                 len(parts_lower) == 1 and parts_lower[0] == "wms"):
             return self.service, True
     else:
         # those two request lead to the same thing so, here we need to check the workspace in the layer
         #   /geoserver/WATERSHED/wms?layers=WATERSHED:BV_1NS&request=getmap
         #   /geoserver/wms?layers=WATERERSHED:BV1_NS&request=getmap
         if not workspace_name:
             layer_name = self.parser.params["layers"] or ""
             workspace_name = layer_name.split(":")[0]
     if not workspace_name:
         return self.service, False
     workspace = models.find_children_by_name(
         child_name=workspace_name,
         parent_id=self.service.resource_id,
         db_session=self.request.db)
     if workspace:
         return workspace, True
     return self.service, False