def signIn(self, user: str, pwd: str, refresh_token: bool = False) -> bool:
        """
        Checks if the current session is authenticated. If not, a token is retrieved (if not available yet)
        and its value is set in the session X-XSRF-TOKEN header. Finally, the user will be signed in to GeoNetwork.

        :param user:            The basic authentication user name.
        :param pwd:             The basic authentication password.
        :param refresh_token:   If True (default = False), the token will be refreshed.
        :returns:               True if sign in was successful.
        """
        if GeonetworkSession.HEADER_TOKEN in self.headers and self.signedIn and not refresh_token:
            # We are still signed in: no need to do it again
            return True

        if not (user and pwd):
            return False

        auth = {'username': user, 'password': pwd}

        if GeonetworkSession.HEADER_TOKEN not in self.headers or refresh_token:
            # Obtain cookie token if there is none or we want to refresh it
            token = self.getToken()
            if token:
                # Update session headers with an X-XSRF-TOKEN
                self.headers[GeonetworkSession.HEADER_TOKEN] = token

        auth['_csrf'] = self.headers[GeonetworkSession.HEADER_TOKEN]

        headers = {'Accept': 'application/html'}

        feedback.logInfo(f'POST {self._signin_url}')
        # Note: it is **extremely** important to NOT allow redirects here!
        # Disallowing redirects will sign us in successfully and return a 302 (Found).
        # A redirect however will result in a 403 (Access Denied), even with valid credentials.
        result = self.post(self._signin_url,
                           data=auth,
                           headers=headers,
                           allow_redirects=False)

        status = result.status_code
        if status >= 400:
            prefix = f"Failed to sign in to {self._signin_url}"
            if status == 403:
                if not refresh_token:
                    # Retry 1 more time with a refreshed token
                    feedback.logWarning(f"{prefix}: retrying with new token")
                    return self.signIn(user, pwd, True)
                feedback.logError(
                    f"{prefix}: access denied to user '{user}' ({status})")
            elif status == 401:
                feedback.logError(
                    f"{prefix}: user '{user}' not authorized (bad credentials)"
                )
            else:
                feedback.logError(
                    f"{prefix}: server returned {status} (please check server logs)"
                )
            return False

        return True
示例#2
0
def _createMef(uuid, md_filename, mef_filename, thumb_filename):
    feedback.logInfo(f"Creating MEF file {mef_filename}")
    z = zipfile.ZipFile(mef_filename, "w")
    z.write(md_filename, os.path.join(uuid, "metadata", os.path.basename(md_filename)))
    z.write(thumb_filename, os.path.join(uuid, "public", os.path.basename(thumb_filename)))
    info = _getInfoXmlContent(uuid, thumb_filename)
    z.writestr(os.path.join(uuid, "info.xml"), info)
    z.close()
示例#3
0
def loadConfiguredServers() -> bool:
    """ Reads all configured servers from the QGIS settings and initializes them. """

    # Read QGIS Bridge server settings string
    server_config = QSettings().value(SERVERS_SETTING)
    if not server_config:
        feedback.logInfo(f"Could not find existing {meta.getAppName()} setting '{SERVERS_SETTING}'")
        return False

    # Deserialize JSON and initialize servers
    return deserializeServers(server_config)
 def getToken(self):
     """ Requests a session token using POST and reads its value from the cookie. """
     headers = {'Content-Type': 'application/xml'}
     feedback.logInfo(f'POST {self._token_url}')
     # Note: it is expected that this returns a 403
     self.post(self._token_url, headers=headers)
     token = self.cookies.get(GeonetworkSession.COOKIE_TOKEN)
     if not token:
         feedback.logError(
             f'Did not receive a {GeonetworkSession.COOKIE_TOKEN} cookie!')
     return token
 def signedIn(self) -> bool:
     """ Returns True if the session is authenticated (i.e. the user has been signed in). """
     headers = {'Accept': 'application/xml'}
     feedback.logInfo(f'GET {self._token_url}')
     result = self.get(self._token_url, headers=headers)
     if result.status_code < 400:
         return parseMe(result)
     # This should not happen (even unauthenticated responses should return a 200), but we have to handle it
     feedback.logError(
         f'Failed to query {self._token_url}: server returned {result.status_code}'
     )
     return False
示例#6
0
def _transformMetadata(filename, uuid, api_url, wms, wfs, layer_name):
    def _ns(n):
        return f"{{http://www.isotc211.org/2005/gmd}}{n}"

    def _addServiceElement(root_element, md_layer, service_url, service_type):
        trans = ET.SubElement(root_element, _ns("transferOptions"))
        dtrans = ET.SubElement(trans, _ns("MD_DigitalTransferOptions"))
        online = ET.SubElement(dtrans, _ns("onLine"))
        cionline = ET.SubElement(online, _ns("CI_OnlineResource"))
        linkage = ET.SubElement(cionline, _ns("linkage"))
        url = ET.SubElement(linkage, _ns("URL"))
        url.text = service_url
        protocol = ET.SubElement(cionline, _ns("protocol"))
        cs = ET.SubElement(
            protocol, "{http://www.isotc211.org/2005/gco}CharacterString")
        cs.text = f"OGC:{service_type.upper()}"
        name = ET.SubElement(cionline, _ns("name"))
        csname = ET.SubElement(
            name, "{http://www.isotc211.org/2005/gco}CharacterString")
        csname.text = md_layer

    iso_filename = tempFileInSubFolder("metadata.xml")
    feedback.logInfo(f"Creating metadata export file {iso_filename}")
    out_dom = _transformDom(filename, QMD_TO_ISO19139_XSLT)

    for ident in out_dom.iter(_ns("fileIdentifier")):
        ident[0].text = uuid
    if wms is not None:
        for root in out_dom.iter(_ns("MD_Distribution")):
            _addServiceElement(root, layer_name, wms, "wms")
    if wfs is not None:
        for root in out_dom.iter(_ns("MD_Distribution")):
            _addServiceElement(root, layer_name, wfs, "wfs")
    for root in out_dom.iter(_ns("MD_DataIdentification")):
        overview = ET.SubElement(root, _ns("graphicOverview"))
        browse_graphic = ET.SubElement(overview, _ns("MD_BrowseGraphic"))
        file = ET.SubElement(browse_graphic, _ns("fileName"))
        cs = ET.SubElement(
            file, "{http://www.isotc211.org/2005/gco}CharacterString")
        thumbnail_url = f"{api_url}/records/{uuid}/attachments/thumbnail.png"
        cs.text = thumbnail_url

    _writeDom(out_dom, iso_filename)
    return iso_filename
示例#7
0
def _loadMetadataFromFgdcXml(layer, filename):
    iso_filename = tempFileInSubFolder("fromfgdc.xml")
    feedback.logInfo(f"Exporting FGDC metadata to {iso_filename}")
    _convertMetadata(filename, iso_filename, FGDC_TO_ISO19115)
    _loadMetadataFromEsriXml(layer, iso_filename)
示例#8
0
def _loadMetadataFromWrappingEsriXml(layer, filename):
    iso_filename = tempFileInSubFolder("fromesri.xml")
    feedback.logInfo(f"Exporting Wrapping-ISO19115 metadata to {iso_filename}")
    _convertMetadata(filename, iso_filename, WRAPPING_ISO19115_TO_ISO19139_XSLT)
    _loadMetadataFromIsoXml(layer, iso_filename)
示例#9
0
def _loadMetadataFromIsoXml(layer, filename):
    qmd_filename = tempFileInSubFolder("fromiso.qmd")
    feedback.logInfo(f"Exporting ISO19193 metadata to {qmd_filename}")
    _convertMetadata(filename, qmd_filename, ISO19139_TO_QMD_XSLT)
    layer.loadNamedMetadata(qmd_filename)