"""
Testing:
 - uploading over existing files
 - using deleted credentials
 - using expired credentials

"""
import io

import minio
from minio import Minio
import pytest
from minio.credentials import AssumeRoleProvider, Credentials

from entityservice.object_store import connect_to_object_store, connect_to_upload_object_store
from entityservice.settings import Config

restricted_upload_policy = """{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "s3:PutObject"
      ],
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::uploads/2020/*"
      ],
      "Sid": "Upload-access-to-specific-bucket-only"
    }
  ]
} 
"""


class TestAssumeRole:

    def test_temp_credentials_minio(self):

        upload_endpoint = Config.UPLOAD_OBJECT_STORE_SERVER
        bucket_name = "uploads"

        root_mc_client = connect_to_object_store()
        upload_restricted_minio_client = connect_to_upload_object_store()
        if not root_mc_client.bucket_exists(bucket_name):
            root_mc_client.make_bucket(bucket_name)

        with pytest.raises(minio.error.AccessDenied):
            upload_restricted_minio_client.list_buckets()

        # Should be able to put an object though
        upload_restricted_minio_client.put_object(bucket_name, 'testobject', io.BytesIO(b'data'), length=4)

        credentials_provider = AssumeRoleProvider(upload_restricted_minio_client,
                                                  Policy=restricted_upload_policy
                                                  )
        temp_creds = Credentials(provider=credentials_provider)

        newly_restricted_mc_client = Minio(upload_endpoint, credentials=temp_creds, region='us-east-1', secure=False)

        with pytest.raises(minio.error.AccessDenied):
            newly_restricted_mc_client.list_buckets()

        # Note this put object worked with the earlier credentials
        # But should fail if we have applied the more restrictive policy
        with pytest.raises(minio.error.AccessDenied):
            newly_restricted_mc_client.put_object(bucket_name, 'testobject2', io.BytesIO(b'data'), length=4)

        # this path is allowed in the policy however
        newly_restricted_mc_client.put_object(bucket_name, '2020/testobject', io.BytesIO(b'data'), length=4)

[((43, 25, 43, 50), 'entityservice.object_store.connect_to_object_store', 'connect_to_object_store', ({}, {}), '()', False, 'from entityservice.object_store import connect_to_object_store, connect_to_upload_object_store\n'), ((44, 41, 44, 73), 'entityservice.object_store.connect_to_upload_object_store', 'connect_to_upload_object_store', ({}, {}), '()', False, 'from entityservice.object_store import connect_to_object_store, connect_to_upload_object_store\n'), ((54, 31, 56, 51), 'minio.credentials.AssumeRoleProvider', 'AssumeRoleProvider', (), '', False, 'from minio.credentials import AssumeRoleProvider, Credentials\n'), ((57, 21, 57, 63), 'minio.credentials.Credentials', 'Credentials', (), '', False, 'from minio.credentials import AssumeRoleProvider, Credentials\n'), ((59, 37, 59, 117), 'minio.Minio', 'Minio', (), '', False, 'from minio import Minio\n'), ((48, 13, 48, 52), 'pytest.raises', 'pytest.raises', ({(48, 27, 48, 51): 'minio.error.AccessDenied'}, {}), '(minio.error.AccessDenied)', False, 'import pytest\n'), ((52, 77, 52, 96), 'io.BytesIO', 'io.BytesIO', ({(52, 88, 52, 95): "b'data'"}, {}), "(b'data')", False, 'import io\n'), ((61, 13, 61, 52), 'pytest.raises', 'pytest.raises', ({(61, 27, 61, 51): 'minio.error.AccessDenied'}, {}), '(minio.error.AccessDenied)', False, 'import pytest\n'), ((66, 13, 66, 52), 'pytest.raises', 'pytest.raises', ({(66, 27, 66, 51): 'minio.error.AccessDenied'}, {}), '(minio.error.AccessDenied)', False, 'import pytest\n'), ((70, 78, 70, 97), 'io.BytesIO', 'io.BytesIO', ({(70, 89, 70, 96): "b'data'"}, {}), "(b'data')", False, 'import io\n'), ((67, 78, 67, 97), 'io.BytesIO', 'io.BytesIO', ({(67, 89, 67, 96): "b'data'"}, {}), "(b'data')", False, 'import io\n')]