import io
import json
import sys
from datetime import datetime

import minio
import pytest
import requests
from minio import Minio

from minio.helpers import get_target_url, get_sha256_hexdigest, get_md5_base64digest

# Note the sign_v4 function needs a patch
#from minio.signer import sign_v4

from urllib.parse import urlencode
# Note this is not actually compatible with version from urllib.parse
#from minio.compat import urlencode

from .miniopatch import sign_v4, parse_assume_role, assume_role

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):
        endpoint = 'minio:9000'
        
        restricted_mc_client = minio.Minio(
            endpoint,
            'newuser',
            'newuser123',
            region='us-east-1',
            secure=False
        )

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

        bucket_name = "uploads"

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

        temp_creds = assume_role(restricted_mc_client, Policy=restricted_upload_policy)

        newly_restricted_mc_client = Minio(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)