Пример #1
0
class TestCloudfrontSigner(BaseSignerTest):
    def setUp(self):
        super(TestCloudfrontSigner, self).setUp()
        self.signer = CloudFrontSigner("MY_KEY_ID", lambda message: b'signed')
        # It helps but the long string diff will still be slightly different on
        # Python 2.6/2.7/3.x. We won't soly rely on that anyway, so it's fine.
        self.maxDiff = None

    def test_build_canned_policy(self):
        policy = self.signer.build_policy('foo', datetime.datetime(2016, 1, 1))
        expected = (
            '{"Statement":[{"Resource":"foo",'
            '"Condition":{"DateLessThan":{"AWS:EpochTime":1451606400}}}]}')
        self.assertEqual(json.loads(policy), json.loads(expected))
        self.assertEqual(policy, expected)  # This is to ensure the right order

    def test_build_custom_policy(self):
        policy = self.signer.build_policy(
            'foo', datetime.datetime(2016, 1, 1),
            date_greater_than=datetime.datetime(2015, 12, 1),
            ip_address='12.34.56.78/9')
        expected = {
            "Statement": [{
                "Resource": "foo",
                "Condition": {
                    "DateGreaterThan": {"AWS:EpochTime": 1448928000},
                    "DateLessThan": {"AWS:EpochTime": 1451606400},
                    "IpAddress": {"AWS:SourceIp": "12.34.56.78/9"}
                },
            }]
        }
        self.assertEqual(json.loads(policy), expected)

    def test_generate_presign_url_with_expire_time(self):
        signed_url = self.signer.generate_presigned_url(
            'http://test.com/foo.txt',
            date_less_than=datetime.datetime(2016, 1, 1))
        expected = (
            'http://test.com/foo.txt?Expires=1451606400&Signature=c2lnbmVk'
            '&Key-Pair-Id=MY_KEY_ID')
        self.assert_url_equal(signed_url, expected)

    def test_generate_presign_url_with_custom_policy(self):
        policy = self.signer.build_policy(
            'foo', datetime.datetime(2016, 1, 1),
            date_greater_than=datetime.datetime(2015, 12, 1),
            ip_address='12.34.56.78/9')
        signed_url = self.signer.generate_presigned_url(
            'http://test.com/index.html?foo=bar', policy=policy)
        expected = (
            'http://test.com/index.html?foo=bar'
            '&Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiZm9vIiwiQ29uZ'
            'Gl0aW9uIjp7IkRhdGVMZXNzVGhhbiI6eyJBV1M6RXBvY2hUaW1lIj'
            'oxNDUxNjA2NDAwfSwiSXBBZGRyZXNzIjp7IkFXUzpTb3VyY2VJcCI'
            '6IjEyLjM0LjU2Ljc4LzkifSwiRGF0ZUdyZWF0ZXJUaGFuIjp7IkFX'
            'UzpFcG9jaFRpbWUiOjE0NDg5MjgwMDB9fX1dfQ__'
            '&Signature=c2lnbmVk&Key-Pair-Id=MY_KEY_ID')
        self.assert_url_equal(signed_url, expected)
Пример #2
0
class TestCloudfrontSigner(BaseSignerTest):
    def setUp(self):
        super(TestCloudfrontSigner, self).setUp()
        self.signer = CloudFrontSigner("MY_KEY_ID", lambda message: b'signed')
        # It helps but the long string diff will still be slightly different on
        # Python 2.6/2.7/3.x. We won't soly rely on that anyway, so it's fine.
        self.maxDiff = None

    def test_build_canned_policy(self):
        policy = self.signer.build_policy('foo', datetime.datetime(2016, 1, 1))
        expected = (
            '{"Statement":[{"Resource":"foo",'
            '"Condition":{"DateLessThan":{"AWS:EpochTime":1451606400}}}]}')
        self.assertEqual(json.loads(policy), json.loads(expected))
        self.assertEqual(policy, expected)  # This is to ensure the right order

    def test_build_custom_policy(self):
        policy = self.signer.build_policy(
            'foo', datetime.datetime(2016, 1, 1),
            date_greater_than=datetime.datetime(2015, 12, 1),
            ip_address='12.34.56.78/9')
        expected = {
            "Statement": [{
                "Resource": "foo",
                "Condition": {
                    "DateGreaterThan": {"AWS:EpochTime": 1448928000},
                    "DateLessThan": {"AWS:EpochTime": 1451606400},
                    "IpAddress": {"AWS:SourceIp": "12.34.56.78/9"}
                },
            }]
        }
        self.assertEqual(json.loads(policy), expected)

    def test_generate_presign_url_with_expire_time(self):
        signed_url = self.signer.generate_presigned_url(
            'http://test.com/foo.txt',
            date_less_than=datetime.datetime(2016, 1, 1))
        expected = (
            'http://test.com/foo.txt?Expires=1451606400&Signature=c2lnbmVk'
            '&Key-Pair-Id=MY_KEY_ID')
        assert_url_equal(signed_url, expected)

    def test_generate_presign_url_with_custom_policy(self):
        policy = self.signer.build_policy(
            'foo', datetime.datetime(2016, 1, 1),
            date_greater_than=datetime.datetime(2015, 12, 1),
            ip_address='12.34.56.78/9')
        signed_url = self.signer.generate_presigned_url(
            'http://test.com/index.html?foo=bar', policy=policy)
        expected = (
            'http://test.com/index.html?foo=bar'
            '&Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiZm9vIiwiQ29uZ'
            'Gl0aW9uIjp7IkRhdGVMZXNzVGhhbiI6eyJBV1M6RXBvY2hUaW1lIj'
            'oxNDUxNjA2NDAwfSwiSXBBZGRyZXNzIjp7IkFXUzpTb3VyY2VJcCI'
            '6IjEyLjM0LjU2Ljc4LzkifSwiRGF0ZUdyZWF0ZXJUaGFuIjp7IkFX'
            'UzpFcG9jaFRpbWUiOjE0NDg5MjgwMDB9fX1dfQ__'
            '&Signature=c2lnbmVk&Key-Pair-Id=MY_KEY_ID')
        assert_url_equal(signed_url, expected)
    def create_signed_cookies(self, resource, expire_minutes=3):
        """
        generate the Cloudfront download distirbution signed cookies
        @resource   path to the file, path, or wildcard pattern to generate policy for
        @expire_minutes  number of minutes until expiration
        return      tuple with domain used within policy (so it matches 
                    cookie domain), and dict of cloudfront cookies you
                    should set in request header
        """
        http_resource = self.get_http_resource_url(
            resource, secure=True
        )  #per-file access #NOTE secure should match security settings of cloudfront distribution

        cloudfront_signer = CloudFrontSigner(
            settings.CLOUDFRONT_SIGNED_COOKIES_KEY_PAIR_ID, rsa_signer)
        expires = SignedCookiedCloudfrontDistribution.get_expires(
            expire_minutes)
        policy = cloudfront_signer.build_policy(
            http_resource, datetime.fromtimestamp(expires))
        encoded_policy = cloudfront_signer._url_b64encode(
            policy.encode('utf-8')).decode('utf-8')

        #assemble the 3 Cloudfront cookies
        signature = rsa_signer(policy.encode('utf-8'))
        encoded_signature = cloudfront_signer._url_b64encode(signature).decode(
            'utf-8')
        cookies = {
            "CloudFront-Policy":
            encoded_policy,
            "CloudFront-Signature":
            encoded_signature,
            "CloudFront-Key-Pair-Id":
            settings.CLOUDFRONT_SIGNED_COOKIES_KEY_PAIR_ID,
        }
        return cookies
Пример #4
0
def get_presigned_url() -> str:
    """
    Two query parameters are required:
    * url: Base URL for the file
    * resource: URL or stream name of the file

    This code uses botocore.signers.CloudFrontSigner to generate presigned URLs
    using a custom policy.

    See Amazon CloudFront documentation for more details on the signing process:
    https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-creating-signed-url-custom-policy.html

    Example using cURL:
    curl 'http://localhost:8000/presigned-url?url=https://www.example.com/images/image.jpg&resource=https://www.example.com/images/*'

    :return str: The signed URL
    """
    config_file_path = os.path.join(os.path.dirname(__file__), 'config.json')
    with open(config_file_path) as config_file:
        config = json.load(config_file)
    private_key_id = config['private_key_id']

    request = app.current_request
    url = request.query_params['url']
    resource = request.query_params['resource']

    expire_date = datetime.now() + timedelta(minutes=+5)

    cf_signer = CloudFrontSigner(private_key_id, rsa_signer)
    cf_policy = cf_signer.build_policy(resource=resource,
                                       date_less_than=expire_date)
    presigned_url = cf_signer.generate_presigned_url(url, policy=cf_policy)

    return presigned_url
Пример #5
0
 def _run_main(self, args, parsed_globals):
     signer = CloudFrontSigner(
         args.key_pair_id, RSASigner(args.private_key).sign)
     date_less_than = parse_to_aware_datetime(args.date_less_than)
     date_greater_than = args.date_greater_than
     if date_greater_than is not None:
         date_greater_than = parse_to_aware_datetime(date_greater_than)
     if date_greater_than is not None or args.ip_address is not None:
         policy = signer.build_policy(
             args.url, date_less_than, date_greater_than=date_greater_than,
             ip_address=args.ip_address)
         sys.stdout.write(signer.generate_presigned_url(
             args.url, policy=policy))
     else:
         sys.stdout.write(signer.generate_presigned_url(
             args.url, date_less_than=date_less_than))
     return 0
Пример #6
0
def generate_cloudfront_urls_signed_parameters(resource, date_less_than):
    """
    Generate all parameters use by a cloudfront signed url.
    Mainly extracted from CloudFrontSigner class.
    """
    cloudfront_signer = CloudFrontSigner(
        settings.CLOUDFRONT_SIGNED_PUBLIC_KEY_ID,
        rsa_signer,
    )
    policy = cloudfront_signer.build_policy(
        resource=resource, date_less_than=date_less_than).encode("utf8")
    signature = cloudfront_signer.rsa_signer(policy)
    return [
        f"Policy={_url_b64encode(policy).decode('utf8')}",
        f"Signature={_url_b64encode(signature).decode('utf8')}",
        f"Key-Pair-Id={cloudfront_signer.key_id}",
    ]
Пример #7
0
class TestCloudfrontSigner(unittest.TestCase):
    def setUp(self):
        self.signer = CloudFrontSigner("MY_KEY_ID", lambda message: b'signed')
        # It helps but the long string diff will still be slightly different on
        # Python 2.6/2.7/3.x. We won't soly rely on that anyway, so it's fine.
        self.maxDiff = None

    def test_build_canned_policy(self):
        policy = self.signer.build_policy('foo', datetime.datetime(2016, 1, 1))
        expected = (
            '{"Statement":[{"Resource":"foo",'
            '"Condition":{"DateLessThan":{"AWS:EpochTime":1451606400}}}]}')
        self.assertEqual(json.loads(policy), json.loads(expected))
        self.assertEqual(policy, expected)  # This is to ensure the right order

    def test_build_custom_policy(self):
        policy = self.signer.build_policy(
            'foo', datetime.datetime(2016, 1, 1),
            date_greater_than=datetime.datetime(2015, 12, 1),
            ip_address='12.34.56.78/9')
        expected = {
            "Statement": [{
                "Resource": "foo",
                "Condition": {
                    "DateGreaterThan": {"AWS:EpochTime": 1448928000},
                    "DateLessThan": {"AWS:EpochTime": 1451606400},
                    "IpAddress": {"AWS:SourceIp": "12.34.56.78/9"}
                },
            }]
        }
        self.assertEqual(json.loads(policy), expected)

    def _urlparse(self, url):
        if isinstance(url, six.binary_type):
            # Not really necessary, but it helps to reduce noise on Python 2.x
            url = url.decode('utf8')
        return dict(urlparse(url)._asdict())  # Needs an unordered dict here

    def assertEqualUrl(self, url1, url2):
        # We compare long urls by their dictionary parts
        parts1 = self._urlparse(url1)
        parts2 = self._urlparse(url2)
        self.assertEqual(
            parse_qs(parts1.pop('query')), parse_qs(parts2.pop('query')))
        self.assertEqual(parts1, parts2)

    def test_generate_presign_url_with_expire_time(self):
        signed_url = self.signer.generate_presigned_url(
            'http://test.com/foo.txt',
            date_less_than=datetime.datetime(2016, 1, 1))
        expected = (
            'http://test.com/foo.txt?Expires=1451606400&Signature=c2lnbmVk'
            '&Key-Pair-Id=MY_KEY_ID')
        self.assertEqualUrl(signed_url, expected)

    def test_generate_presign_url_with_custom_policy(self):
        policy = self.signer.build_policy(
            'foo', datetime.datetime(2016, 1, 1),
            date_greater_than=datetime.datetime(2015, 12, 1),
            ip_address='12.34.56.78/9')
        signed_url = self.signer.generate_presigned_url(
            'http://test.com/index.html?foo=bar', policy=policy)
        expected = (
            'http://test.com/index.html?foo=bar'
            '&Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiZm9vIiwiQ29uZ'
            'Gl0aW9uIjp7IkRhdGVMZXNzVGhhbiI6eyJBV1M6RXBvY2hUaW1lIj'
            'oxNDUxNjA2NDAwfSwiSXBBZGRyZXNzIjp7IkFXUzpTb3VyY2VJcCI'
            '6IjEyLjM0LjU2Ljc4LzkifSwiRGF0ZUdyZWF0ZXJUaGFuIjp7IkFX'
            'UzpFcG9jaFRpbWUiOjE0NDg5MjgwMDB9fX1dfQ__'
            '&Signature=c2lnbmVk&Key-Pair-Id=MY_KEY_ID')
        self.assertEqualUrl(signed_url, expected)
Пример #8
0
class TestCloudfrontSigner(unittest.TestCase):
    def setUp(self):
        self.signer = CloudFrontSigner("MY_KEY_ID", lambda message: b'signed')
        # It helps but the long string diff will still be slightly different on
        # Python 2.6/2.7/3.x. We won't soly rely on that anyway, so it's fine.
        self.maxDiff = None

    def test_build_canned_policy(self):
        policy = self.signer.build_policy('foo', datetime.datetime(2016, 1, 1))
        expected = (
            '{"Statement":[{"Resource":"foo",'
            '"Condition":{"DateLessThan":{"AWS:EpochTime":1451606400}}}]}')
        self.assertEqual(json.loads(policy), json.loads(expected))
        self.assertEqual(policy, expected)  # This is to ensure the right order

    def test_build_custom_policy(self):
        policy = self.signer.build_policy('foo',
                                          datetime.datetime(2016, 1, 1),
                                          date_greater_than=datetime.datetime(
                                              2015, 12, 1),
                                          ip_address='12.34.56.78/9')
        expected = {
            "Statement": [{
                "Resource": "foo",
                "Condition": {
                    "DateGreaterThan": {
                        "AWS:EpochTime": 1448928000
                    },
                    "DateLessThan": {
                        "AWS:EpochTime": 1451606400
                    },
                    "IpAddress": {
                        "AWS:SourceIp": "12.34.56.78/9"
                    }
                },
            }]
        }
        self.assertEqual(json.loads(policy), expected)

    def _urlparse(self, url):
        if isinstance(url, six.binary_type):
            # Not really necessary, but it helps to reduce noise on Python 2.x
            url = url.decode('utf8')
        return dict(urlparse(url)._asdict())  # Needs an unordered dict here

    def assertEqualUrl(self, url1, url2):
        # We compare long urls by their dictionary parts
        parts1 = self._urlparse(url1)
        parts2 = self._urlparse(url2)
        self.assertEqual(parse_qs(parts1.pop('query')),
                         parse_qs(parts2.pop('query')))
        self.assertEqual(parts1, parts2)

    def test_generate_presign_url_with_expire_time(self):
        signed_url = self.signer.generate_presigned_url(
            'http://test.com/foo.txt',
            date_less_than=datetime.datetime(2016, 1, 1))
        expected = (
            'http://test.com/foo.txt?Expires=1451606400&Signature=c2lnbmVk'
            '&Key-Pair-Id=MY_KEY_ID')
        self.assertEqualUrl(signed_url, expected)

    def test_generate_presign_url_with_custom_policy(self):
        policy = self.signer.build_policy('foo',
                                          datetime.datetime(2016, 1, 1),
                                          date_greater_than=datetime.datetime(
                                              2015, 12, 1),
                                          ip_address='12.34.56.78/9')
        signed_url = self.signer.generate_presigned_url(
            'http://test.com/index.html?foo=bar', policy=policy)
        expected = ('http://test.com/index.html?foo=bar'
                    '&Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiZm9vIiwiQ29uZ'
                    'Gl0aW9uIjp7IkRhdGVMZXNzVGhhbiI6eyJBV1M6RXBvY2hUaW1lIj'
                    'oxNDUxNjA2NDAwfSwiSXBBZGRyZXNzIjp7IkFXUzpTb3VyY2VJcCI'
                    '6IjEyLjM0LjU2Ljc4LzkifSwiRGF0ZUdyZWF0ZXJUaGFuIjp7IkFX'
                    'UzpFcG9jaFRpbWUiOjE0NDg5MjgwMDB9fX1dfQ__'
                    '&Signature=c2lnbmVk&Key-Pair-Id=MY_KEY_ID')
        self.assertEqualUrl(signed_url, expected)