Example #1
0
    def _login(self, username=None, store_password=False,
               reenter_password=False):
        """
        Login to the ESO User Portal.

        Parameters
        ----------
        username : str, optional
            Username to the ESO Public Portal. If not given, it should be
            specified in the config file.
        store_password : bool, optional
            Stores the password securely in your keyring. Default is False.
        reenter_password : bool, optional
            Asks for the password even if it is already stored in the
            keyring. This is the way to overwrite an already stored passwork
            on the keyring. Default is False.
        """
        if username is None:
            if self.USERNAME != "":
                username = self.USERNAME
            elif self.username is not None:
                username = self.username
            else:
                raise LoginError("If you do not pass a username to login(), "
                                 "you should configure a default one!")
        else:
            # store username as we may need it to re-authenticate
            self.username = username

        # Get password from keyring or prompt
        password, password_from_keyring = self._get_password(
            "astroquery:www.eso.org", username, reenter=reenter_password)

        # Authenticate
        log.info("Authenticating {0} on www.eso.org...".format(username))

        # Do not cache pieces of the login process
        login_response = self._request("GET", "https://www.eso.org/sso/login",
                                       cache=False)
        root = BeautifulSoup(login_response.content, 'html5lib')
        login_input = root.find(name='input', attrs={'name': 'execution'})
        if login_input is None:
            raise ValueError("ESO login page did not have the correct attributes.")
        execution = login_input.get('value')

        login_result_response = self._request("POST", "https://www.eso.org/sso/login",
                                              data={'username': username,
                                                    'password': password,
                                                    'execution': execution,
                                                    '_eventId': 'submit',
                                                    'geolocation': '',
                                                    })
        login_result_response.raise_for_status()
        root = BeautifulSoup(login_result_response.content, 'html5lib')
        authenticated = root.find('h4').text == 'Login successful'

        if authenticated:
            log.info("Authentication successful!")
        else:
            log.exception("Authentication failed!")

        # When authenticated, save password in keyring if needed
        if authenticated and password_from_keyring is None and store_password:
            keyring.set_password("astroquery:www.eso.org", username, password)
        return authenticated
Example #2
0
    def download_file(self, uri, *, local_path=None, base_url=None, cache=True, cloud_only=False):
        """
        Downloads a single file based on the data URI

        Parameters
        ----------
        uri : str
            The product dataURI, e.g. mast:JWST/product/jw00736-o039_t001_miri_ch1-long_x1d.fits
        local_path : str
            Directory in which the files will be downloaded.  Defaults to current working directory.
        base_url: str
            A base url to use when downloading.  Default is the MAST Portal API
        cache : bool
            Default is True. If file is found on disk it will not be downloaded again.
        cloud_only : bool, optional
            Default False. If set to True and cloud data access is enabled (see `enable_cloud_dataset`)
            files that are not found in the cloud will be skipped rather than downloaded from MAST
            as is the default behavior. If cloud access is not enables this argument as no affect.

        Returns
        -------
        status: str
            download status message.  Either COMPLETE, SKIPPED, or ERROR.
        msg : str
            An error status message, if any.
        url : str
            The full url download path
        """

        # create the full data URL
        base_url = base_url if base_url else self._portal_api_connection.MAST_DOWNLOAD_URL
        data_url = base_url + "?uri=" + uri

        # create a local file path if none is input.  Use current directory as default.
        if not local_path:
            filename = os.path.basename(uri)
            local_path = os.path.join(os.path.abspath('.'), filename)

        # recreate the data_product key for cloud connection check
        data_product = {'dataURI': uri}

        status = "COMPLETE"
        msg = None
        url = None

        try:
            if self._cloud_connection is not None and self._cloud_connection.is_supported(data_product):
                try:
                    self._cloud_connection.download_file(data_product, local_path, cache)
                except Exception as ex:
                    log.exception("Error pulling from S3 bucket: {}".format(ex))
                    if cloud_only:
                        log.warn("Skipping file...")
                        local_path = ""
                        status = "SKIPPED"
                    else:
                        log.warn("Falling back to mast download...")
                        self._download_file(data_url, local_path,
                                            cache=cache, head_safe=True, continuation=False)
            else:
                self._download_file(data_url, local_path,
                                    cache=cache, head_safe=True, continuation=False)

            # check if file exists also this is where would perform md5,
            # and also check the filesize if the database reliably reported file sizes
            if (not os.path.isfile(local_path)) and (status != "SKIPPED"):
                status = "ERROR"
                msg = "File was not downloaded"
                url = data_url

        except HTTPError as err:
            status = "ERROR"
            msg = "HTTPError: {0}".format(err)
            url = data_url

        return status, msg, url
Example #3
0
    def _login(self,
               username=None,
               store_password=False,
               reenter_password=False):
        """
        Login to the NRAO archive

        Parameters
        ----------
        username : str, optional
            Username to the NRAO archive. If not given, it should be specified
            in the config file.
        store_password : bool, optional
            Stores the password securely in your keyring. Default is False.
        reenter_password : bool, optional
            Asks for the password even if it is already stored in the
            keyring. This is the way to overwrite an already stored passwork
            on the keyring. Default is False.
        """

        # Developer notes:
        # Login via https://my.nrao.edu/cas/login
        # # this can be added to auto-redirect back to the query tool:
        # ?service=https://archive.nrao.edu/archive/advquery.jsp

        if username is None:
            if not self.USERNAME:
                raise LoginError("If you do not pass a username to login(), "
                                 "you should configure a default one!")
            else:
                username = self.USERNAME

        # Check if already logged in
        loginpage = self._request("GET",
                                  "https://my.nrao.edu/cas/login",
                                  cache=False)
        root = BeautifulSoup(loginpage.content, 'html5lib')
        if root.find('div', class_='success'):
            log.info("Already logged in.")
            return True

        # Get password from keyring or prompt
        password, password_from_keyring = self._get_password(
            "astroquery:my.nrao.edu", username, reenter=reenter_password)

        # Authenticate
        log.info("Authenticating {0} on my.nrao.edu ...".format(username))
        # Do not cache pieces of the login process
        data = {
            kw: root.find('input', {'name': kw})['value']
            for kw in ('lt', '_eventId', 'execution')
        }
        data['username'] = username
        data['password'] = password
        data['execution'] = 'e1s1'  # not sure if needed
        data['_eventId'] = 'submit'
        data['submit'] = 'LOGIN'

        login_response = self._request("POST",
                                       "https://my.nrao.edu/cas/login",
                                       data=data,
                                       cache=False)

        authenticated = ('You have successfully logged in'
                         in login_response.text)

        if authenticated:
            log.info("Authentication successful!")
            self.USERNAME = username
        else:
            log.exception("Authentication failed!")
        # When authenticated, save password in keyring if needed
        if authenticated and password_from_keyring is None and store_password:
            keyring.set_password("astroquery:my.nrao.edu", username, password)

        return authenticated
Example #4
0
    def _login(self, username=None, store_password=False,
               reenter_password=False, auth_urls=auth_urls):
        """
        Login to the ALMA Science Portal.

        Parameters
        ----------
        username : str, optional
            Username to the ALMA Science Portal. If not given, it should be
            specified in the config file.
        store_password : bool, optional
            Stores the password securely in your keyring. Default is False.
        reenter_password : bool, optional
            Asks for the password even if it is already stored in the
            keyring. This is the way to overwrite an already stored passwork
            on the keyring. Default is False.
        """

        success = False
        for auth_url in auth_urls:
            # set session cookies (they do not get set otherwise)
            cookiesetpage = self._request("GET",
                                          urljoin(self._get_dataarchive_url(),
                                                  'rh/forceAuthentication'),
                                          cache=False)
            self._login_cookiepage = cookiesetpage
            cookiesetpage.raise_for_status()

            if (auth_url+'/cas/login' in cookiesetpage.request.url):
                # we've hit a target, we're good
                success = True
                break
        if not success:
            raise LoginError("Could not log in to any of the known ALMA "
                             "authorization portals: {0}".format(auth_urls))

        # Check if already logged in
        loginpage = self._request("GET", "https://{auth_url}/cas/login".format(auth_url=auth_url),
                                  cache=False)
        root = BeautifulSoup(loginpage.content, 'html5lib')
        if root.find('div', class_='success'):
            log.info("Already logged in.")
            return True

        self._auth_url = auth_url

        username, password = self._get_auth_info(username=username,
                                                 store_password=store_password,
                                                 reenter_password=reenter_password)

        # Authenticate
        log.info("Authenticating {0} on {1} ...".format(username, auth_url))
        # Do not cache pieces of the login process
        data = {kw: root.find('input', {'name': kw})['value']
                for kw in ('execution', '_eventId')}
        data['username'] = username
        data['password'] = password
        data['submit'] = 'LOGIN'

        login_response = self._request("POST", "https://{0}/cas/login".format(auth_url),
                                       params={'service': self._get_dataarchive_url()},
                                       data=data,
                                       cache=False)

        # save the login response for debugging purposes
        self._login_response = login_response
        # do not expose password back to user
        del data['password']
        # but save the parameters for debug purposes
        self._login_parameters = data

        authenticated = ('You have successfully logged in' in
                         login_response.text)

        if authenticated:
            log.info("Authentication successful!")
            self.USERNAME = username
        else:
            log.exception("Authentication failed!")

        return authenticated