def test_pretend_to_put_but_list(tmpdir, conn_cnx, db_parameters):
    """[s3] SNOW-6154: Pretends to PUT but LIST."""
    # create a data file
    fname = str(tmpdir.join('test_put_get_with_aws_token.txt'))
    with gzip.open(fname, 'wb') as f:
        f.write("123,test1\n456,test2".encode(UTF8))
    table_name = random_string(5, 'snow6154_list_')

    with conn_cnx() as cnx:
        cnx.cursor().execute(
            "create or replace table {} (a int, b string)".format(table_name))
        ret = cnx.cursor()._execute_helper("put file://{} @%{}".format(
            fname, table_name))
        stage_location = ret['data']['stageInfo']['location']
        stage_credentials = ret['data']['stageInfo']['creds']

        s3location = SnowflakeS3Util.extract_bucket_name_and_path(
            stage_location)

        # listing
        client = boto3.resource(
            's3',
            aws_access_key_id=stage_credentials['AWS_ID'],
            aws_secret_access_key=stage_credentials['AWS_KEY'],
            aws_session_token=stage_credentials['AWS_TOKEN'])
        from botocore.exceptions import ClientError
        with pytest.raises(ClientError):
            _s3bucket_list(client, s3location.bucket_name)
def test_pretend_to_put_but_list(tmpdir, conn_cnx, db_parameters):
    """
    [s3] SNOW-6154: pretend to PUT but LIST
    """
    # create a data file
    fname = str(tmpdir.join('test_put_get_with_aws_token.txt'))
    f = gzip.open(fname, 'wb')
    f.write("123,test1\n456,test2".encode(UTF8))
    f.close()

    with conn_cnx(
            user=db_parameters['s3_user'],
            account=db_parameters['s3_account'],
            password=db_parameters['s3_password']) as cnx:
        cnx.cursor().execute(
            "create or replace table snow6154 (a int, b string)")
        ret = cnx.cursor()._execute_helper(
            "put file://{} @%snow6154".format(fname))
        stage_location = ret['data']['stageInfo']['location']
        stage_credentials = ret['data']['stageInfo']['creds']

        s3location = SnowflakeS3Util.extract_bucket_name_and_path(
            stage_location)

        # listing
        client = boto3.resource(
            's3',
            aws_access_key_id=stage_credentials['AWS_ID'],
            aws_secret_access_key=stage_credentials['AWS_KEY'],
            aws_session_token=stage_credentials['AWS_TOKEN'])
        with pytest.raises(Exception):
            _s3bucket_list(client, s3location.bucket_name)
def test_put_with_invalid_token(tmpdir, conn_cnx, db_parameters):
    """
    [s3] SNOW-6154: Use invalid combination of AWS credential
    """
    # create a data file
    fname = str(tmpdir.join('test_put_get_with_aws_token.txt.gz'))
    f = gzip.open(fname, 'wb')
    f.write("123,test1\n456,test2".encode(UTF8))
    f.close()

    with conn_cnx(
            user=db_parameters['s3_user'],
            account=db_parameters['s3_account'],
            password=db_parameters['s3_password']) as cnx:
        cnx.cursor().execute(
            "create or replace table snow6154 (a int, b string)")
        ret = cnx.cursor()._execute_helper(
            "put file://{} @%snow6154".format(fname))
        stage_location = ret['data']['stageInfo']['location']
        stage_credentials = ret['data']['stageInfo']['creds']

        s3location = SnowflakeS3Util.extract_bucket_name_and_path(
            stage_location)

        s3path = s3location.s3path + os.path.basename(fname) + ".gz"

        # positive case
        client = boto3.resource(
            's3',
            aws_access_key_id=stage_credentials['AWS_ID'],
            aws_secret_access_key=stage_credentials['AWS_KEY'],
            aws_session_token=stage_credentials['AWS_TOKEN'])

        client.meta.client.upload_file(
            fname, s3location.bucket_name, s3path)

        # negative: wrong location, attempting to put the file in the
        # parent path
        parent_s3path = os.path.dirname(os.path.dirname(s3path)) + '/'

        with pytest.raises(Exception):
            client.meta.client.upload_file(
                fname, s3location.bucket_name, parent_s3path)

        # negative: missing AWS_TOKEN
        client = boto3.resource(
            's3',
            aws_access_key_id=stage_credentials['AWS_ID'],
            aws_secret_access_key=stage_credentials['AWS_KEY'])
        with pytest.raises(Exception):
            client.meta.client.upload_file(
                fname, s3location.bucket_name, s3path)
def test_put_with_invalid_token(tmpdir, conn_cnx, db_parameters, from_path):
    """[s3] SNOW-6154: Uses invalid combination of AWS credential."""
    # create a data file
    fname = str(tmpdir.join('test_put_get_with_aws_token.txt.gz'))
    with gzip.open(fname, 'wb') as f:
        f.write("123,test1\n456,test2".encode(UTF8))
    table_name = random_string(5, 'snow6154_')

    with conn_cnx() as cnx:
        try:
            cnx.cursor().execute("create or replace table {} (a int, b string)".format(table_name))
            ret = cnx.cursor()._execute_helper("put file://{} @%{}".format(fname, table_name))
            stage_location = ret['data']['stageInfo']['location']
            stage_credentials = ret['data']['stageInfo']['creds']

            s3location = SnowflakeS3Util.extract_bucket_name_and_path(stage_location)

            s3path = s3location.s3path + os.path.basename(fname) + ".gz"

            # positive case
            client = boto3.resource(
                's3',
                aws_access_key_id=stage_credentials['AWS_ID'],
                aws_secret_access_key=stage_credentials['AWS_KEY'],
                aws_session_token=stage_credentials['AWS_TOKEN'])

            file_stream = None if from_path else open(fname, 'rb')

            if from_path:
                client.meta.client.upload_file(
                    fname, s3location.bucket_name, s3path)
            else:
                client.meta.client.upload_fileobj(
                    file_stream, s3location.bucket_name, s3path)

            # s3 closes stream
            file_stream = None if from_path else open(fname, 'rb')

            # negative: wrong location, attempting to put the file in the
            # parent path
            parent_s3path = os.path.dirname(os.path.dirname(s3path)) + '/'

            with pytest.raises((S3UploadFailedError, ClientError)):
                if from_path:
                    client.meta.client.upload_file(fname, s3location.bucket_name, parent_s3path)
                else:
                    client.meta.client.upload_fileobj(file_stream, s3location.bucket_name, parent_s3path)

            # s3 closes stream
            file_stream = None if from_path else open(fname, 'rb')

            # negative: missing AWS_TOKEN
            client = boto3.resource(
                's3',
                aws_access_key_id=stage_credentials['AWS_ID'],
                aws_secret_access_key=stage_credentials['AWS_KEY'])

            with pytest.raises((S3UploadFailedError, ClientError)):
                if from_path:
                    client.meta.client.upload_file(
                        fname, s3location.bucket_name, s3path)
                else:
                    client.meta.client.upload_fileobj(
                        file_stream, s3location.bucket_name, s3path)
        finally:
            if file_stream:
                file_stream.close()
            cnx.cursor().execute("drop table if exists {}".format(table_name))