def generate_presigned_url(self, request_dict, expires_in=3600, region_name=None): """Generates a presigned url :type request_dict: dict :param request_dict: The prepared request dictionary returned by ``botocore.awsrequest.prepare_request_dict()`` :type expires_in: int :param expires_in: The number of seconds the presigned url is valid for. By default it expires in an hour (3600 seconds) :type region_name: string :param region_name: The region name to sign the presigned url. :returns: The presigned url """ if region_name is None: region_name = self._region_name query_prefix = '-query' signature_version = self._signature_version if not signature_version.endswith(query_prefix): signature_version += query_prefix kwargs = { 'signing_name': self._signing_name, 'region_name': region_name, 'signature_version': signature_version, 'expires': expires_in } signature_type = signature_version.split('-', 1)[0] try: auth = self.get_auth_instance(**kwargs) except UnknownSignatureVersionError: raise UnsupportedSignatureVersionError( signature_version=signature_type) request = create_request_object(request_dict) # Fix s3 host for s3 sigv2 bucket names fix_s3_host(request, signature_type, region_name) auth.add_auth(request) request.prepare() return request.url
def generate_presigned_post(self, request_dict, fields=None, conditions=None, expires_in=3600, region_name=None): """Generates the url and the form fields used for a presigned s3 post :type request_dict: dict :param request_dict: The prepared request dictionary returned by ``botocore.awsrequest.prepare_request_dict()`` :type fields: dict :param fields: A dictionary of prefilled form fields to build on top of. :type conditions: list :param conditions: A list of conditions to include in the policy. Each element can be either a list or a structure. For example: [ {"acl": "public-read"}, {"bucket": "mybucket"}, ["starts-with", "$key", "mykey"] ] :type expires_in: int :param expires_in: The number of seconds the presigned post is valid for. :type region_name: string :param region_name: The region name to sign the presigned post to. :rtype: dict :returns: A dictionary with two elements: ``url`` and ``fields``. Url is the url to post to. Fields is a dictionary filled with the form fields and respective values to use when submitting the post. For example: {'url': 'https://mybucket.s3.amazonaws.com 'fields': {'acl': 'public-read', 'key': 'mykey', 'signature': 'mysignature', 'policy': 'mybase64 encoded policy'} } """ if fields is None: fields = {} if conditions is None: conditions = [] if region_name is None: region_name = self._request_signer.region_name # Create the policy for the post. policy = {} # Create an expiration date for the policy datetime_now = datetime.datetime.utcnow() expire_date = datetime_now + datetime.timedelta(seconds=expires_in) policy['expiration'] = expire_date.strftime(botocore.auth.ISO8601) # Append all of the conditions that the user supplied. policy['conditions'] = [] for condition in conditions: policy['conditions'].append(condition) # Obtain the appropriate signer. query_prefix = '-presign-post' signature_version = self._request_signer.signature_version if not signature_version.endswith(query_prefix): signature_version += query_prefix kwargs = { 'signing_name': self._request_signer.signing_name, 'region_name': region_name, 'signature_version': signature_version } signature_type = signature_version.split('-', 1)[0] try: auth = self._request_signer.get_auth_instance(**kwargs) except UnknownSignatureVersionError: raise UnsupportedSignatureVersionError( signature_version=signature_type) # Store the policy and the fields in the request for signing request = create_request_object(request_dict) request.context['s3-presign-post-fields'] = fields request.context['s3-presign-post-policy'] = policy auth.add_auth(request) # Fix s3 host for s3 sigv2 bucket names fix_s3_host(request, signature_type, region_name) # Return the url and the fields for th form to post. return {'url': request.url, 'fields': fields}
def sign(self, operation_name, request, region_name=None, signing_type='standard', expires_in=None): """Sign a request before it goes out over the wire. :type operation_name: string :param operation_name: The name of the current operation, e.g. ``ListBuckets``. :type request: AWSRequest :param request: The request object to be sent over the wire. :type region_name: str :param region_name: The region to sign the request for. :type signing_type: str :param signing_type: The type of signing to perform. This can be one of three possible values: * 'standard' - This should be used for most requests. * 'presign-url' - This should be used when pre-signing a request. * 'presign-post' - This should be used when pre-signing an S3 post. :type expires_in: int :param expires_in: The number of seconds the presigned url is valid for. This parameter is only valid for signing type 'presign-url'. """ if region_name is None: region_name = self._region_name signature_version = self._choose_signer(operation_name, signing_type) # Allow mutating request before signing self._event_emitter.emit('before-sign.{0}.{1}'.format( self._service_name, operation_name), request=request, signing_name=self._signing_name, region_name=self._region_name, signature_version=signature_version, request_signer=self) if signature_version != botocore.UNSIGNED: kwargs = { 'signing_name': self._signing_name, 'region_name': region_name, 'signature_version': signature_version } if expires_in is not None: kwargs['expires'] = expires_in try: auth = self.get_auth_instance(**kwargs) except UnknownSignatureVersionError as e: if signing_type != 'standard': raise UnsupportedSignatureVersionError( signature_version=signature_version) else: raise e auth.add_auth(request)