コード例 #1
0
    def return_response(self, method, path, data, headers, response):
        # fix backend issue (missing support for API documentation)
        if re.match(r'/restapis/[^/]+/documentation/versions', path):
            if response.status_code == 404:
                return requests_response({'position': '1', 'items': []})

        # add missing implementations
        if response.status_code == 404:
            data = data and json.loads(to_str(data))
            result = None
            if path == '/account':
                result = handle_accounts(method, path, data, headers)
            if re.match(PATH_REGEX_PATH_MAPPINGS, path):
                result = hande_base_path_mappings(method, path, data, headers)
            if result is not None:
                response.status_code = 200
                aws_responses.set_response_content(response, result)

        # publish event
        if method == 'POST' and path == '/restapis':
            content = json.loads(to_str(response.content))
            event_publisher.fire_event(event_publisher.EVENT_APIGW_CREATE_API,
                payload={'a': event_publisher.get_hash(content['id'])})
        api_regex = r'^/restapis/([a-zA-Z0-9\-]+)$'
        if method == 'DELETE' and re.match(api_regex, path):
            api_id = re.sub(api_regex, r'\1', path)
            event_publisher.fire_event(event_publisher.EVENT_APIGW_DELETE_API,
                payload={'a': event_publisher.get_hash(api_id)})
コード例 #2
0
ファイル: kms_listener.py プロジェクト: pinzon/localstack
def search_key_pair(data, response):
    key_pairs = KMSBackend.get().key_pairs
    key = key_pairs.get(data.get("KeyId"))
    if not key:
        return response

    key_object = Key(key["Policy"], key["KeyUsage"], key["KeySpec"],
                     key["Description"], key["Region"])
    key_object.id = key["KeyId"]

    response.status_code = 200
    set_response_content(response, json.dumps(key_object.to_dict()))
    return response
コード例 #3
0
ファイル: kms_listener.py プロジェクト: pinzon/localstack
def add_key_pairs(response):
    key_pairs = KMSBackend.get().key_pairs
    response.status_code = 200
    content = json.loads(to_str(response.content))
    prev_keys = content["Keys"]

    for id in key_pairs:
        prev_keys.append({
            "KeyId": key_pairs[id]["KeyId"],
            "KeyArn": key_pairs[id]["Arn"],
        })

    content["Keys"] = prev_keys
    set_response_content(response, json.dumps(content))
    return response
コード例 #4
0
def handle_get_public_key(data, response):
    key_pairs = _get_key_pairs()
    result = key_pairs.get(data.get("KeyId", ""))
    if not result:
        return 404
    attrs = [
        "KeyId",
        "PublicKey",
        "KeySpec",
        "KeyUsage",
        "EncryptionAlgorithms",
        "SigningAlgorithms",
    ]
    result = select_attributes(result, attrs)
    set_response_content(response, result)
    response.status_code = 200
    return response
コード例 #5
0
    def return_response(self, method, path, data, headers, response):
        # fix backend issue (missing support for API documentation)
        if re.match(r"/restapis/[^/]+/documentation/versions", path):
            if response.status_code == 404:
                return requests_response({"position": "1", "items": []})

        # add missing implementations
        if response.status_code == 404:
            data = data and json.loads(to_str(data))
            result = None
            if path == "/account":
                result = handle_accounts(method, path, data, headers)
            elif path.startswith("/vpclinks"):
                result = handle_vpc_links(method, path, data, headers)
            elif re.match(PATH_REGEX_PATH_MAPPINGS, path):
                result = handle_base_path_mappings(method, path, data, headers)
            elif re.match(PATH_REGEX_CLIENT_CERTS, path):
                result = handle_client_certificates(method, path, data,
                                                    headers)

            if result is not None:
                response.status_code = 200
                aws_responses.set_response_content(
                    response, result, getattr(result, "headers", {}))

        # keep track of API regions for faster lookup later on
        if method == "POST" and path == "/restapis":
            content = json.loads(to_str(response.content))
            api_id = content["id"]
            region = aws_stack.extract_region_from_auth_header(headers)
            API_REGIONS[api_id] = region

        # publish event
        if method == "POST" and path == "/restapis":
            content = json.loads(to_str(response.content))
            event_publisher.fire_event(
                event_publisher.EVENT_APIGW_CREATE_API,
                payload={"a": event_publisher.get_hash(content["id"])},
            )
        api_regex = r"^/restapis/([a-zA-Z0-9\-]+)$"
        if method == "DELETE" and re.match(api_regex, path):
            api_id = re.sub(api_regex, r"\1", path)
            event_publisher.fire_event(
                event_publisher.EVENT_APIGW_DELETE_API,
                payload={"a": event_publisher.get_hash(api_id)},
            )
コード例 #6
0
ファイル: route53_listener.py プロジェクト: pinzon/localstack
def add_vpc_info_to_response(path: str, response: Response):
    content = to_str(response.content or "")
    if "<HostedZone>" not in content:
        return
    if "GetHostedZoneResponse" not in content and "CreateHostedZoneResponse" not in content:
        return
    content = clone(xmltodict.parse(content))
    region_details = Route53Backend.get()

    def _insert(obj, **_):
        if not isinstance(obj, dict) or "HostedZone" not in obj or "VPCs" in obj:
            return obj
        zone_id = obj["HostedZone"].get("Id", "").replace("/hostedzone/", "")
        zone_details = region_details.vpc_hosted_zone_associations.get(zone_id) or []
        vpcs = [zone["VPC"] for zone in zone_details if zone.get("VPC")]
        if vpcs:
            obj["VPCs"] = [{"VPC": vpc} for vpc in vpcs]
        return obj

    recurse_object(content, _insert)
    set_response_content(response, xmltodict.unparse(content))
コード例 #7
0
def sign(data, response):
    region_details = KMSBackend.get()
    response.status_code = 200
    algo = data.get("SigningAlgorithm")
    key_id = data.get("KeyId")
    message = base64.b64decode(to_bytes(data.get("Message")))

    key_pair = region_details.key_pairs.get(key_id)
    kwargs = {}
    if algo.startswith("RSA"):
        if "PKCS" in algo:
            kwargs["padding"] = padding.PKCS1v15()
        elif "PSS" in algo:
            kwargs["padding"] = padding.PSS(mgf=padding.MGF1(hashes.SHA256()),
                                            salt_length=padding.PSS.MAX_LENGTH)
        else:
            LOG.warning("Unsupported padding in SigningAlgorithm '%s'", algo)

    if "SHA_256" in algo:
        kwargs["algorithm"] = hashes.SHA256()
    elif "SHA_384" in algo:
        kwargs["algorithm"] = hashes.SHA384()
    elif "SHA_512" in algo:
        kwargs["algorithm"] = hashes.SHA512()
    else:
        LOG.warning("Unsupported hash type in SigningAlgorithm '%s'", algo)
    if algo.startswith("ECDSA"):
        kwargs["signature_algorithm"] = ec.ECDSA(
            algorithm=kwargs.pop("algorithm", None))

    # generate signature
    signature = key_pair["_key_"].sign(data=message, **kwargs)

    result = {
        "KeyId": key_id,
        "Signature": to_str(base64.b64encode(signature)),
        "SigningAlgorithm": algo,
    }
    set_response_content(response, json.dumps(result))
    return response
コード例 #8
0
    def return_response(self, method, path, data, headers, response):
        data = json.loads(to_str(data or "{}"))
        name = data.get("name") or (data.get("stateMachineArn") or "").split(":")[-1]
        target = headers.get("X-Amz-Target", "").split(".")[-1]

        # publish event
        if target == "CreateStateMachine":
            event_publisher.fire_event(
                event_publisher.EVENT_STEPFUNCTIONS_CREATE_SM,
                payload={"m": event_publisher.get_hash(name)},
            )
        elif target == "DeleteStateMachine":
            event_publisher.fire_event(
                event_publisher.EVENT_STEPFUNCTIONS_DELETE_SM,
                payload={"m": event_publisher.get_hash(name)},
            )

        content = to_str(response.content or "") or "{}"
        replace = r"\1:\7:\3:\8"
        content = re.sub(SM_ARN_REGEX, replace, content)
        content = json.loads(content)

        def fix_name(obj):
            if obj.get("name"):
                obj["name"] = re.sub(r"^([^_]+)_(.*)", r"\2", obj["name"])

        fix_name(content)
        machines = content.get("stateMachines")
        if machines:
            region_part = ":%s:" % aws_stack.get_region()
            machines = [sm for sm in machines if region_part in sm["stateMachineArn"]]
            for machine in machines:
                fix_name(machine)
            content["stateMachines"] = machines

        content = json.dumps(content)
        set_response_content(response, content)
コード例 #9
0
def generate_data_key_pair_without_plaintext(data, response):
    result = _generate_data_key_pair(data)
    result.pop("PrivateKeyPlaintext", None)
    set_response_content(response, result)
    response.status_code = 200
    return response
コード例 #10
0
def generate_data_key_pair(data, response):
    result = _generate_data_key_pair(data)
    set_response_content(response, result)
    response.status_code = 200
    return response
コード例 #11
0
def update_response_content(response, content, status_code=None):
    aws_responses.set_response_content(response, content)
    if status_code:
        response.status_code = status_code
    fix_headers_for_updated_response(response)