Exemple #1
0
    def generate_presigned_url(self, url, date_less_than=None, policy=None):
        """Creates a signed CloudFront URL based on given parameters.

        :type url: str
        :param url: The URL of the protected object

        :type date_less_than: datetime
        :param date_less_than: The URL will expire after that date and time

        :type policy: str
        :param policy: The custom policy, possibly built by self.build_policy()

        :rtype: str
        :return: The signed URL.
        """
        if (date_less_than is not None and policy is not None or
                date_less_than is None and policy is None):
            e = 'Need to provide either date_less_than or policy, but not both'
            raise ValueError(e)
        if date_less_than is not None:
            # We still need to build a canned policy for signing purpose
            policy = self.build_policy(url, date_less_than)
        if isinstance(policy, six.text_type):
            policy = policy.encode('utf8')
        if date_less_than is not None:
            params = ['Expires=%s' % int(datetime2timestamp(date_less_than))]
        else:
            params = ['Policy=%s' % self._url_b64encode(policy).decode('utf8')]
        signature = self.rsa_signer(policy)
        params.extend([
            'Signature=%s' % self._url_b64encode(signature).decode('utf8'),
            'Key-Pair-Id=%s' % self.key_id,
            ])
        return self._build_url(url, params)
Exemple #2
0
    def generate_presigned_url(self, url, date_less_than=None, policy=None):
        """Creates a signed CloudFront URL based on given parameters.

        :type url: str
        :param url: The URL of the protected object

        :type date_less_than: datetime
        :param date_less_than: The URL will expire after that date and time

        :type policy: str
        :param policy: The custom policy, possibly built by self.build_policy()

        :rtype: str
        :return: The signed URL.
        """
        if (date_less_than is not None and policy is not None
                or date_less_than is None and policy is None):
            e = 'Need to provide either date_less_than or policy, but not both'
            raise ValueError(e)
        if date_less_than is not None:
            # We still need to build a canned policy for signing purpose
            policy = self.build_policy(url, date_less_than)
        if isinstance(policy, six.text_type):
            policy = policy.encode('utf8')
        if date_less_than is not None:
            params = ['Expires=%s' % int(datetime2timestamp(date_less_than))]
        else:
            params = ['Policy=%s' % self._url_b64encode(policy).decode('utf8')]
        signature = self.rsa_signer(policy)
        params.extend([
            'Signature=%s' % self._url_b64encode(signature).decode('utf8'),
            'Key-Pair-Id=%s' % self.key_id,
        ])
        return self._build_url(url, params)
Exemple #3
0
 def filter_log_events(
         self,
         log_group_name,  # type: str
         start_time=None,  # type: Optional[datetime]
         next_token=None,  # type: Optional[str]
 ):
     # type: (...) -> LogEventsResponse
     logs = self._client('logs')
     kwargs = {
         'logGroupName': log_group_name,
         'interleaved': True,
     }
     if start_time is not None:
         kwargs['startTime'] = int(datetime2timestamp(start_time) * 1000)
     if next_token is not None:
         kwargs['nextToken'] = next_token
     try:
         response = logs.filter_log_events(**kwargs)
     except logs.exceptions.ResourceNotFoundException:
         # If there's no log messages yet then we'll just return
         # an empty response.
         return {'events': []}
     # We want to convert the individual events that have integer
     # types over to datetime objects so it's easier for us to
     # work with.
     self._convert_types_on_response(response)
     return response
 def to_epoch_millis(self, timestamp):
     re_match = self._RELATIVE_TIMESTAMP_REGEX.match(timestamp)
     if re_match:
         datetime_value = self._relative_timestamp_to_datetime(
             int(re_match.group('amount')), re_match.group('unit'))
     else:
         datetime_value = parse_timestamp(timestamp)
     return int(datetime2timestamp(datetime_value) * 1000)
Exemple #5
0
def to_epoch_millis(timestamp):
    regex = re.compile(r"(?P<amount>\d+)(?P<unit>s|m|h|d|w)$")
    re_match = regex.match(timestamp)
    if re_match:
        datetime_value = _relative_timestamp_to_datetime(
            int(re_match.group('amount')), re_match.group('unit'))
    else:
        datetime_value = parse_timestamp(timestamp)
    return int(datetime2timestamp(datetime_value) * 1000)
Exemple #6
0
    def test_sso_source_profile(self):
        token_cache_key = 'f395038c92f1828cbb3991d2d6152d326b895606'
        cached_token = {
            'accessToken': 'a.token',
            'expiresAt': self.some_future_time(),
        }
        temp_cache = JSONFileCache(self.tempdir)
        temp_cache[token_cache_key] = cached_token

        config = ('[profile A]\n'
                  'role_arn = arn:aws:iam::123456789:role/RoleA\n'
                  'source_profile = B\n'
                  '[profile B]\n'
                  'sso_region = us-east-1\n'
                  'sso_start_url = https://test.url/start\n'
                  'sso_role_name = SSORole\n'
                  'sso_account_id = 1234567890\n')
        self.write_config(config)

        session, sts_stubber = self.create_session(profile='A')
        client_config = Config(
            region_name='us-east-1',
            signature_version=UNSIGNED,
        )
        sso_stubber = session.stub('sso', config=client_config)
        sso_stubber.activate()
        # The expiration needs to be in milliseconds
        expiration = datetime2timestamp(self.some_future_time()) * 1000
        sso_role_creds = self.create_random_credentials()
        sso_role_response = {
            'roleCredentials': {
                'accessKeyId': sso_role_creds.access_key,
                'secretAccessKey': sso_role_creds.secret_key,
                'sessionToken': sso_role_creds.token,
                'expiration': int(expiration),
            }
        }
        sso_stubber.add_response('get_role_credentials', sso_role_response)

        expected_creds = self.create_random_credentials()
        assume_role_response = self.create_assume_role_response(expected_creds)
        sts_stubber.add_response('assume_role', assume_role_response)

        actual_creds = session.get_credentials()
        self.assert_creds_equal(actual_creds, expected_creds)
        sts_stubber.assert_no_pending_responses()
        # Assert that the client was created with the credentials from the
        # SSO get role credentials response
        self.assertEqual(self.mock_client_creator.call_count, 1)
        _, kwargs = self.mock_client_creator.call_args_list[0]
        expected_kwargs = {
            'aws_access_key_id': sso_role_creds.access_key,
            'aws_secret_access_key': sso_role_creds.secret_key,
            'aws_session_token': sso_role_creds.token,
        }
        self.assertEqual(kwargs, expected_kwargs)
Exemple #7
0
    def build_policy(self,
                     resource,
                     date_less_than,
                     date_greater_than=None,
                     ip_address=None):
        """A helper to build policy.

        :type resource: str
        :param resource: The URL or the stream filename of the protected object

        :type date_less_than: datetime
        :param date_less_than: The URL will expire after the time has passed

        :type date_greater_than: datetime
        :param date_greater_than: The URL will not be valid until this time

        :type ip_address: str
        :param ip_address: Use 'x.x.x.x' for an IP, or 'x.x.x.x/x' for a subnet

        :rtype: str
        :return: The policy in a compact string.
        """
        # Note:
        # 1. Order in canned policy is significant. Special care has been taken
        #    to ensure the output will match the order defined by the document.
        #    There is also a test case to ensure that order.
        #    SEE: http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-creating-signed-url-canned-policy.html#private-content-canned-policy-creating-policy-statement
        # 2. Albeit the order in custom policy is not required by CloudFront,
        #    we still use OrderedDict internally to ensure the result is stable
        #    and also matches canned policy requirement.
        #    SEE: http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-creating-signed-url-custom-policy.html
        moment = int(datetime2timestamp(date_less_than))
        condition = OrderedDict({"DateLessThan": {"AWS:EpochTime": moment}})
        if ip_address:
            if '/' not in ip_address:
                ip_address += '/32'
            condition["IpAddress"] = {"AWS:SourceIp": ip_address}
        if date_greater_than:
            moment = int(datetime2timestamp(date_greater_than))
            condition["DateGreaterThan"] = {"AWS:EpochTime": moment}
        ordered_payload = [('Resource', resource), ('Condition', condition)]
        custom_policy = {"Statement": [OrderedDict(ordered_payload)]}
        return json.dumps(custom_policy, separators=(',', ':'))
Exemple #8
0
    def build_policy(self, resource, date_less_than,
                     date_greater_than=None, ip_address=None):
        """A helper to build policy.

        :type resource: str
        :param resource: The URL or the stream filename of the protected object

        :type date_less_than: datetime
        :param date_less_than: The URL will expire after the time has passed

        :type date_greater_than: datetime
        :param date_greater_than: The URL will not be valid until this time

        :type ip_address: str
        :param ip_address: Use 'x.x.x.x' for an IP, or 'x.x.x.x/x' for a subnet

        :rtype: str
        :return: The policy in a compact string.
        """
        # Note:
        # 1. Order in canned policy is significant. Special care has been taken
        #    to ensure the output will match the order defined by the document.
        #    There is also a test case to ensure that order.
        #    SEE: http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-creating-signed-url-canned-policy.html#private-content-canned-policy-creating-policy-statement
        # 2. Albeit the order in custom policy is not required by CloudFront,
        #    we still use OrderedDict internally to ensure the result is stable
        #    and also matches canned policy requirement.
        #    SEE: http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-creating-signed-url-custom-policy.html
        moment = int(datetime2timestamp(date_less_than))
        condition = OrderedDict({"DateLessThan": {"AWS:EpochTime": moment}})
        if ip_address:
            if '/' not in ip_address:
                ip_address += '/32'
            condition["IpAddress"] = {"AWS:SourceIp": ip_address}
        if date_greater_than:
            moment = int(datetime2timestamp(date_greater_than))
            condition["DateGreaterThan"] = {"AWS:EpochTime": moment}
        ordered_payload = [('Resource', resource), ('Condition', condition)]
        custom_policy = {"Statement": [OrderedDict(ordered_payload)]}
        return json.dumps(custom_policy, separators=(',', ':'))
Exemple #9
0
 def _register_client(self):
     timestamp = datetime2timestamp(self._time_fetcher())
     response = self._client.register_client(
         # NOTE: As far as I know client name will never be returned to the
         # user. For now we'll just use botocore-client with the timestamp.
         clientName='botocore-client-%s' % int(timestamp),
         clientType=self._CLIENT_REGISTRATION_TYPE,
     )
     expires_at = response['clientSecretExpiresAt']
     expires_at = datetime.datetime.fromtimestamp(expires_at, tzutc())
     registration = {
         'clientId': response['clientId'],
         'clientSecret': response['clientSecret'],
         'expiresAt': expires_at,
     }
     return registration
Exemple #10
0
 def test_datetime2timestamp_aware(self):
     tzinfo = tzoffset("BRST", -10800)
     self.assertEqual(
         datetime2timestamp(datetime.datetime(1970, 1, 2, tzinfo=tzinfo)),
         97200)
Exemple #11
0
 def test_datetime2timestamp_naive(self):
     self.assertEqual(
         datetime2timestamp(datetime.datetime(1970, 1, 2)), 86400)
Exemple #12
0
 def test_datetime2timestamp_aware(self):
     tzinfo = tzoffset("BRST", -10800)
     self.assertEqual(
         datetime2timestamp(datetime.datetime(1970, 1, 2, tzinfo=tzinfo)),
         97200)
Exemple #13
0
 def test_datetime2timestamp_naive(self):
     self.assertEqual(datetime2timestamp(datetime.datetime(1970, 1, 2)),
                      86400)