Merge pull request #2757 from jrbeilke/feature-apigw-authorizers
Feature: add support for API Gateway authorizers
This commit is contained in:
commit
ec3f6bbc6c
@ -85,6 +85,15 @@ class NoMethodDefined(BadRequestException):
|
||||
)
|
||||
|
||||
|
||||
class AuthorizerNotFoundException(RESTError):
|
||||
code = 404
|
||||
|
||||
def __init__(self):
|
||||
super(AuthorizerNotFoundException, self).__init__(
|
||||
"NotFoundException", "Invalid Authorizer identifier specified"
|
||||
)
|
||||
|
||||
|
||||
class StageNotFoundException(RESTError):
|
||||
code = 404
|
||||
|
||||
|
@ -28,6 +28,7 @@ from .exceptions import (
|
||||
InvalidHttpEndpoint,
|
||||
InvalidResourcePathException,
|
||||
InvalidRequestInput,
|
||||
AuthorizerNotFoundException,
|
||||
StageNotFoundException,
|
||||
RoleNotSpecified,
|
||||
NoIntegrationDefined,
|
||||
@ -187,6 +188,54 @@ class Resource(BaseModel):
|
||||
return self.resource_methods[method_type].pop("methodIntegration")
|
||||
|
||||
|
||||
class Authorizer(BaseModel, dict):
|
||||
def __init__(self, id, name, authorizer_type, **kwargs):
|
||||
super(Authorizer, self).__init__()
|
||||
self["id"] = id
|
||||
self["name"] = name
|
||||
self["type"] = authorizer_type
|
||||
if kwargs.get("provider_arns"):
|
||||
self["providerARNs"] = kwargs.get("provider_arns")
|
||||
if kwargs.get("auth_type"):
|
||||
self["authType"] = kwargs.get("auth_type")
|
||||
if kwargs.get("authorizer_uri"):
|
||||
self["authorizerUri"] = kwargs.get("authorizer_uri")
|
||||
if kwargs.get("authorizer_credentials"):
|
||||
self["authorizerCredentials"] = kwargs.get("authorizer_credentials")
|
||||
if kwargs.get("identity_source"):
|
||||
self["identitySource"] = kwargs.get("identity_source")
|
||||
if kwargs.get("identity_validation_expression"):
|
||||
self["identityValidationExpression"] = kwargs.get(
|
||||
"identity_validation_expression"
|
||||
)
|
||||
self["authorizerResultTtlInSeconds"] = kwargs.get("authorizer_result_ttl")
|
||||
|
||||
def apply_operations(self, patch_operations):
|
||||
for op in patch_operations:
|
||||
if "/authorizerUri" in op["path"]:
|
||||
self["authorizerUri"] = op["value"]
|
||||
elif "/authorizerCredentials" in op["path"]:
|
||||
self["authorizerCredentials"] = op["value"]
|
||||
elif "/authorizerResultTtlInSeconds" in op["path"]:
|
||||
self["authorizerResultTtlInSeconds"] = int(op["value"])
|
||||
elif "/authType" in op["path"]:
|
||||
self["authType"] = op["value"]
|
||||
elif "/identitySource" in op["path"]:
|
||||
self["identitySource"] = op["value"]
|
||||
elif "/identityValidationExpression" in op["path"]:
|
||||
self["identityValidationExpression"] = op["value"]
|
||||
elif "/name" in op["path"]:
|
||||
self["name"] = op["value"]
|
||||
elif "/providerARNs" in op["path"]:
|
||||
# TODO: add and remove
|
||||
raise Exception('Patch operation for "%s" not implemented' % op["path"])
|
||||
elif "/type" in op["path"]:
|
||||
self["type"] = op["value"]
|
||||
else:
|
||||
raise Exception('Patch operation "%s" not implemented' % op["op"])
|
||||
return self
|
||||
|
||||
|
||||
class Stage(BaseModel, dict):
|
||||
def __init__(
|
||||
self,
|
||||
@ -412,6 +461,7 @@ class RestAPI(BaseModel):
|
||||
self.tags = kwargs.get("tags") or {}
|
||||
|
||||
self.deployments = {}
|
||||
self.authorizers = {}
|
||||
self.stages = {}
|
||||
|
||||
self.resources = {}
|
||||
@ -479,6 +529,34 @@ class RestAPI(BaseModel):
|
||||
),
|
||||
)
|
||||
|
||||
def create_authorizer(
|
||||
self,
|
||||
id,
|
||||
name,
|
||||
authorizer_type,
|
||||
provider_arns=None,
|
||||
auth_type=None,
|
||||
authorizer_uri=None,
|
||||
authorizer_credentials=None,
|
||||
identity_source=None,
|
||||
identiy_validation_expression=None,
|
||||
authorizer_result_ttl=None,
|
||||
):
|
||||
authorizer = Authorizer(
|
||||
id=id,
|
||||
name=name,
|
||||
authorizer_type=authorizer_type,
|
||||
provider_arns=provider_arns,
|
||||
auth_type=auth_type,
|
||||
authorizer_uri=authorizer_uri,
|
||||
authorizer_credentials=authorizer_credentials,
|
||||
identity_source=identity_source,
|
||||
identiy_validation_expression=identiy_validation_expression,
|
||||
authorizer_result_ttl=authorizer_result_ttl,
|
||||
)
|
||||
self.authorizers[id] = authorizer
|
||||
return authorizer
|
||||
|
||||
def create_stage(
|
||||
self,
|
||||
name,
|
||||
@ -518,6 +596,9 @@ class RestAPI(BaseModel):
|
||||
def get_deployment(self, deployment_id):
|
||||
return self.deployments[deployment_id]
|
||||
|
||||
def get_authorizers(self):
|
||||
return list(self.authorizers.values())
|
||||
|
||||
def get_stages(self):
|
||||
return list(self.stages.values())
|
||||
|
||||
@ -613,6 +694,46 @@ class APIGatewayBackend(BaseBackend):
|
||||
)
|
||||
return method
|
||||
|
||||
def get_authorizer(self, restapi_id, authorizer_id):
|
||||
api = self.get_rest_api(restapi_id)
|
||||
authorizer = api.authorizers.get(authorizer_id)
|
||||
if authorizer is None:
|
||||
raise AuthorizerNotFoundException()
|
||||
else:
|
||||
return authorizer
|
||||
|
||||
def get_authorizers(self, restapi_id):
|
||||
api = self.get_rest_api(restapi_id)
|
||||
return api.get_authorizers()
|
||||
|
||||
def create_authorizer(self, restapi_id, name, authorizer_type, **kwargs):
|
||||
api = self.get_rest_api(restapi_id)
|
||||
authorizer_id = create_id()
|
||||
authorizer = api.create_authorizer(
|
||||
authorizer_id,
|
||||
name,
|
||||
authorizer_type,
|
||||
provider_arns=kwargs.get("provider_arns"),
|
||||
auth_type=kwargs.get("auth_type"),
|
||||
authorizer_uri=kwargs.get("authorizer_uri"),
|
||||
authorizer_credentials=kwargs.get("authorizer_credentials"),
|
||||
identity_source=kwargs.get("identity_source"),
|
||||
identiy_validation_expression=kwargs.get("identiy_validation_expression"),
|
||||
authorizer_result_ttl=kwargs.get("authorizer_result_ttl"),
|
||||
)
|
||||
return api.authorizers.get(authorizer["id"])
|
||||
|
||||
def update_authorizer(self, restapi_id, authorizer_id, patch_operations):
|
||||
authorizer = self.get_authorizer(restapi_id, authorizer_id)
|
||||
if not authorizer:
|
||||
api = self.get_rest_api(restapi_id)
|
||||
authorizer = api.authorizers[authorizer_id] = Authorizer()
|
||||
return authorizer.apply_operations(patch_operations)
|
||||
|
||||
def delete_authorizer(self, restapi_id, authorizer_id):
|
||||
api = self.get_rest_api(restapi_id)
|
||||
del api.authorizers[authorizer_id]
|
||||
|
||||
def get_stage(self, function_id, stage_name):
|
||||
api = self.get_rest_api(function_id)
|
||||
stage = api.stages.get(stage_name)
|
||||
|
@ -8,11 +8,13 @@ from .exceptions import (
|
||||
ApiKeyNotFoundException,
|
||||
BadRequestException,
|
||||
CrossAccountNotAllowed,
|
||||
AuthorizerNotFoundException,
|
||||
StageNotFoundException,
|
||||
ApiKeyAlreadyExists,
|
||||
)
|
||||
|
||||
API_KEY_SOURCES = ["AUTHORIZER", "HEADER"]
|
||||
AUTHORIZER_TYPES = ["TOKEN", "REQUEST", "COGNITO_USER_POOLS"]
|
||||
ENDPOINT_CONFIGURATION_TYPES = ["PRIVATE", "EDGE", "REGIONAL"]
|
||||
|
||||
|
||||
@ -177,6 +179,88 @@ class APIGatewayResponse(BaseResponse):
|
||||
)
|
||||
return 200, {}, json.dumps(method_response)
|
||||
|
||||
def restapis_authorizers(self, request, full_url, headers):
|
||||
self.setup_class(request, full_url, headers)
|
||||
url_path_parts = self.path.split("/")
|
||||
restapi_id = url_path_parts[2]
|
||||
|
||||
if self.method == "POST":
|
||||
name = self._get_param("name")
|
||||
authorizer_type = self._get_param("type")
|
||||
|
||||
provider_arns = self._get_param_with_default_value("providerARNs", None)
|
||||
auth_type = self._get_param_with_default_value("authType", None)
|
||||
authorizer_uri = self._get_param_with_default_value("authorizerUri", None)
|
||||
authorizer_credentials = self._get_param_with_default_value(
|
||||
"authorizerCredentials", None
|
||||
)
|
||||
identity_source = self._get_param_with_default_value("identitySource", None)
|
||||
identiy_validation_expression = self._get_param_with_default_value(
|
||||
"identityValidationExpression", None
|
||||
)
|
||||
authorizer_result_ttl = self._get_param_with_default_value(
|
||||
"authorizerResultTtlInSeconds", 300
|
||||
)
|
||||
|
||||
# Param validation
|
||||
if authorizer_type and authorizer_type not in AUTHORIZER_TYPES:
|
||||
return self.error(
|
||||
"ValidationException",
|
||||
(
|
||||
"1 validation error detected: "
|
||||
"Value '{authorizer_type}' at 'createAuthorizerInput.type' failed "
|
||||
"to satisfy constraint: Member must satisfy enum value set: "
|
||||
"[TOKEN, REQUEST, COGNITO_USER_POOLS]"
|
||||
).format(authorizer_type=authorizer_type),
|
||||
)
|
||||
|
||||
authorizer_response = self.backend.create_authorizer(
|
||||
restapi_id,
|
||||
name,
|
||||
authorizer_type,
|
||||
provider_arns=provider_arns,
|
||||
auth_type=auth_type,
|
||||
authorizer_uri=authorizer_uri,
|
||||
authorizer_credentials=authorizer_credentials,
|
||||
identity_source=identity_source,
|
||||
identiy_validation_expression=identiy_validation_expression,
|
||||
authorizer_result_ttl=authorizer_result_ttl,
|
||||
)
|
||||
elif self.method == "GET":
|
||||
authorizers = self.backend.get_authorizers(restapi_id)
|
||||
return 200, {}, json.dumps({"item": authorizers})
|
||||
|
||||
return 200, {}, json.dumps(authorizer_response)
|
||||
|
||||
def authorizers(self, request, full_url, headers):
|
||||
self.setup_class(request, full_url, headers)
|
||||
url_path_parts = self.path.split("/")
|
||||
restapi_id = url_path_parts[2]
|
||||
authorizer_id = url_path_parts[4]
|
||||
|
||||
if self.method == "GET":
|
||||
try:
|
||||
authorizer_response = self.backend.get_authorizer(
|
||||
restapi_id, authorizer_id
|
||||
)
|
||||
except AuthorizerNotFoundException as error:
|
||||
return (
|
||||
error.code,
|
||||
{},
|
||||
'{{"message":"{0}","code":"{1}"}}'.format(
|
||||
error.message, error.error_type
|
||||
),
|
||||
)
|
||||
elif self.method == "PATCH":
|
||||
patch_operations = self._get_param("patchOperations")
|
||||
authorizer_response = self.backend.update_authorizer(
|
||||
restapi_id, authorizer_id, patch_operations
|
||||
)
|
||||
elif self.method == "DELETE":
|
||||
self.backend.delete_authorizer(restapi_id, authorizer_id)
|
||||
return 202, {}, "{}"
|
||||
return 200, {}, json.dumps(authorizer_response)
|
||||
|
||||
def restapis_stages(self, request, full_url, headers):
|
||||
self.setup_class(request, full_url, headers)
|
||||
url_path_parts = self.path.split("/")
|
||||
|
@ -7,6 +7,8 @@ url_paths = {
|
||||
"{0}/restapis$": APIGatewayResponse().restapis,
|
||||
"{0}/restapis/(?P<function_id>[^/]+)/?$": APIGatewayResponse().restapis_individual,
|
||||
"{0}/restapis/(?P<function_id>[^/]+)/resources$": APIGatewayResponse().resources,
|
||||
"{0}/restapis/(?P<function_id>[^/]+)/authorizers$": APIGatewayResponse().restapis_authorizers,
|
||||
"{0}/restapis/(?P<function_id>[^/]+)/authorizers/(?P<authorizer_id>[^/]+)/?$": APIGatewayResponse().authorizers,
|
||||
"{0}/restapis/(?P<function_id>[^/]+)/stages$": APIGatewayResponse().restapis_stages,
|
||||
"{0}/restapis/(?P<function_id>[^/]+)/stages/(?P<stage_name>[^/]+)/?$": APIGatewayResponse().stages,
|
||||
"{0}/restapis/(?P<function_id>[^/]+)/deployments$": APIGatewayResponse().deployments,
|
||||
|
@ -8,7 +8,7 @@ import sure # noqa
|
||||
from botocore.exceptions import ClientError
|
||||
|
||||
import responses
|
||||
from moto import mock_apigateway, settings
|
||||
from moto import mock_apigateway, mock_cognitoidp, settings
|
||||
from moto.core import ACCOUNT_ID
|
||||
from nose.tools import assert_raises
|
||||
|
||||
@ -576,6 +576,254 @@ def test_integration_response():
|
||||
response["methodIntegration"]["integrationResponses"].should.equal({})
|
||||
|
||||
|
||||
@mock_apigateway
|
||||
@mock_cognitoidp
|
||||
def test_update_authorizer_configuration():
|
||||
client = boto3.client("apigateway", region_name="us-west-2")
|
||||
authorizer_name = "my_authorizer"
|
||||
response = client.create_rest_api(name="my_api", description="this is my api")
|
||||
api_id = response["id"]
|
||||
|
||||
cognito_client = boto3.client("cognito-idp", region_name="us-west-2")
|
||||
user_pool_arn = cognito_client.create_user_pool(PoolName="my_cognito_pool")[
|
||||
"UserPool"
|
||||
]["Arn"]
|
||||
|
||||
response = client.create_authorizer(
|
||||
restApiId=api_id,
|
||||
name=authorizer_name,
|
||||
type="COGNITO_USER_POOLS",
|
||||
providerARNs=[user_pool_arn],
|
||||
identitySource="method.request.header.Authorization",
|
||||
)
|
||||
authorizer_id = response["id"]
|
||||
|
||||
response = client.get_authorizer(restApiId=api_id, authorizerId=authorizer_id)
|
||||
# createdDate is hard to match against, remove it
|
||||
response.pop("createdDate", None)
|
||||
# this is hard to match against, so remove it
|
||||
response["ResponseMetadata"].pop("HTTPHeaders", None)
|
||||
response["ResponseMetadata"].pop("RetryAttempts", None)
|
||||
response.should.equal(
|
||||
{
|
||||
"id": authorizer_id,
|
||||
"name": authorizer_name,
|
||||
"type": "COGNITO_USER_POOLS",
|
||||
"providerARNs": [user_pool_arn],
|
||||
"identitySource": "method.request.header.Authorization",
|
||||
"authorizerResultTtlInSeconds": 300,
|
||||
"ResponseMetadata": {"HTTPStatusCode": 200},
|
||||
}
|
||||
)
|
||||
|
||||
client.update_authorizer(
|
||||
restApiId=api_id,
|
||||
authorizerId=authorizer_id,
|
||||
patchOperations=[{"op": "replace", "path": "/type", "value": "TOKEN"}],
|
||||
)
|
||||
|
||||
authorizer = client.get_authorizer(restApiId=api_id, authorizerId=authorizer_id)
|
||||
|
||||
authorizer.should.have.key("type").which.should.equal("TOKEN")
|
||||
|
||||
client.update_authorizer(
|
||||
restApiId=api_id,
|
||||
authorizerId=authorizer_id,
|
||||
patchOperations=[{"op": "replace", "path": "/type", "value": "REQUEST"}],
|
||||
)
|
||||
|
||||
authorizer = client.get_authorizer(restApiId=api_id, authorizerId=authorizer_id)
|
||||
|
||||
authorizer.should.have.key("type").which.should.equal("REQUEST")
|
||||
|
||||
# TODO: implement mult-update tests
|
||||
|
||||
try:
|
||||
client.update_authorizer(
|
||||
restApiId=api_id,
|
||||
authorizerId=authorizer_id,
|
||||
patchOperations=[
|
||||
{"op": "add", "path": "/notasetting", "value": "eu-west-1"}
|
||||
],
|
||||
)
|
||||
assert False.should.be.ok # Fail, should not be here
|
||||
except Exception:
|
||||
assert True.should.be.ok
|
||||
|
||||
|
||||
@mock_apigateway
|
||||
def test_non_existent_authorizer():
|
||||
client = boto3.client("apigateway", region_name="us-west-2")
|
||||
response = client.create_rest_api(name="my_api", description="this is my api")
|
||||
api_id = response["id"]
|
||||
|
||||
client.get_authorizer.when.called_with(
|
||||
restApiId=api_id, authorizerId="xxx"
|
||||
).should.throw(ClientError)
|
||||
|
||||
|
||||
@mock_apigateway
|
||||
@mock_cognitoidp
|
||||
def test_create_authorizer():
|
||||
client = boto3.client("apigateway", region_name="us-west-2")
|
||||
authorizer_name = "my_authorizer"
|
||||
response = client.create_rest_api(name="my_api", description="this is my api")
|
||||
api_id = response["id"]
|
||||
|
||||
cognito_client = boto3.client("cognito-idp", region_name="us-west-2")
|
||||
user_pool_arn = cognito_client.create_user_pool(PoolName="my_cognito_pool")[
|
||||
"UserPool"
|
||||
]["Arn"]
|
||||
|
||||
response = client.create_authorizer(
|
||||
restApiId=api_id,
|
||||
name=authorizer_name,
|
||||
type="COGNITO_USER_POOLS",
|
||||
providerARNs=[user_pool_arn],
|
||||
identitySource="method.request.header.Authorization",
|
||||
)
|
||||
authorizer_id = response["id"]
|
||||
|
||||
response = client.get_authorizer(restApiId=api_id, authorizerId=authorizer_id)
|
||||
# createdDate is hard to match against, remove it
|
||||
response.pop("createdDate", None)
|
||||
# this is hard to match against, so remove it
|
||||
response["ResponseMetadata"].pop("HTTPHeaders", None)
|
||||
response["ResponseMetadata"].pop("RetryAttempts", None)
|
||||
response.should.equal(
|
||||
{
|
||||
"id": authorizer_id,
|
||||
"name": authorizer_name,
|
||||
"type": "COGNITO_USER_POOLS",
|
||||
"providerARNs": [user_pool_arn],
|
||||
"identitySource": "method.request.header.Authorization",
|
||||
"authorizerResultTtlInSeconds": 300,
|
||||
"ResponseMetadata": {"HTTPStatusCode": 200},
|
||||
}
|
||||
)
|
||||
|
||||
authorizer_name2 = "my_authorizer2"
|
||||
response = client.create_authorizer(
|
||||
restApiId=api_id,
|
||||
name=authorizer_name2,
|
||||
type="COGNITO_USER_POOLS",
|
||||
providerARNs=[user_pool_arn],
|
||||
identitySource="method.request.header.Authorization",
|
||||
)
|
||||
authorizer_id2 = response["id"]
|
||||
|
||||
response = client.get_authorizers(restApiId=api_id)
|
||||
|
||||
# this is hard to match against, so remove it
|
||||
response["ResponseMetadata"].pop("HTTPHeaders", None)
|
||||
response["ResponseMetadata"].pop("RetryAttempts", None)
|
||||
|
||||
response["items"][0]["id"].should.match(
|
||||
r"{0}|{1}".format(authorizer_id2, authorizer_id)
|
||||
)
|
||||
response["items"][1]["id"].should.match(
|
||||
r"{0}|{1}".format(authorizer_id2, authorizer_id)
|
||||
)
|
||||
|
||||
new_authorizer_name_with_vars = "authorizer_with_vars"
|
||||
response = client.create_authorizer(
|
||||
restApiId=api_id,
|
||||
name=new_authorizer_name_with_vars,
|
||||
type="COGNITO_USER_POOLS",
|
||||
providerARNs=[user_pool_arn],
|
||||
identitySource="method.request.header.Authorization",
|
||||
)
|
||||
authorizer_id3 = response["id"]
|
||||
|
||||
# this is hard to match against, so remove it
|
||||
response["ResponseMetadata"].pop("HTTPHeaders", None)
|
||||
response["ResponseMetadata"].pop("RetryAttempts", None)
|
||||
|
||||
response.should.equal(
|
||||
{
|
||||
"name": new_authorizer_name_with_vars,
|
||||
"id": authorizer_id3,
|
||||
"type": "COGNITO_USER_POOLS",
|
||||
"providerARNs": [user_pool_arn],
|
||||
"identitySource": "method.request.header.Authorization",
|
||||
"authorizerResultTtlInSeconds": 300,
|
||||
"ResponseMetadata": {"HTTPStatusCode": 200},
|
||||
}
|
||||
)
|
||||
|
||||
stage = client.get_authorizer(restApiId=api_id, authorizerId=authorizer_id3)
|
||||
stage["name"].should.equal(new_authorizer_name_with_vars)
|
||||
stage["id"].should.equal(authorizer_id3)
|
||||
stage["type"].should.equal("COGNITO_USER_POOLS")
|
||||
stage["providerARNs"].should.equal([user_pool_arn])
|
||||
stage["identitySource"].should.equal("method.request.header.Authorization")
|
||||
stage["authorizerResultTtlInSeconds"].should.equal(300)
|
||||
|
||||
|
||||
@mock_apigateway
|
||||
@mock_cognitoidp
|
||||
def test_delete_authorizer():
|
||||
client = boto3.client("apigateway", region_name="us-west-2")
|
||||
authorizer_name = "my_authorizer"
|
||||
response = client.create_rest_api(name="my_api", description="this is my api")
|
||||
api_id = response["id"]
|
||||
|
||||
cognito_client = boto3.client("cognito-idp", region_name="us-west-2")
|
||||
user_pool_arn = cognito_client.create_user_pool(PoolName="my_cognito_pool")[
|
||||
"UserPool"
|
||||
]["Arn"]
|
||||
|
||||
response = client.create_authorizer(
|
||||
restApiId=api_id,
|
||||
name=authorizer_name,
|
||||
type="COGNITO_USER_POOLS",
|
||||
providerARNs=[user_pool_arn],
|
||||
identitySource="method.request.header.Authorization",
|
||||
)
|
||||
authorizer_id = response["id"]
|
||||
|
||||
response = client.get_authorizer(restApiId=api_id, authorizerId=authorizer_id)
|
||||
# createdDate is hard to match against, remove it
|
||||
response.pop("createdDate", None)
|
||||
# this is hard to match against, so remove it
|
||||
response["ResponseMetadata"].pop("HTTPHeaders", None)
|
||||
response["ResponseMetadata"].pop("RetryAttempts", None)
|
||||
response.should.equal(
|
||||
{
|
||||
"id": authorizer_id,
|
||||
"name": authorizer_name,
|
||||
"type": "COGNITO_USER_POOLS",
|
||||
"providerARNs": [user_pool_arn],
|
||||
"identitySource": "method.request.header.Authorization",
|
||||
"authorizerResultTtlInSeconds": 300,
|
||||
"ResponseMetadata": {"HTTPStatusCode": 200},
|
||||
}
|
||||
)
|
||||
|
||||
authorizer_name2 = "my_authorizer2"
|
||||
response = client.create_authorizer(
|
||||
restApiId=api_id,
|
||||
name=authorizer_name2,
|
||||
type="COGNITO_USER_POOLS",
|
||||
providerARNs=[user_pool_arn],
|
||||
identitySource="method.request.header.Authorization",
|
||||
)
|
||||
authorizer_id2 = response["id"]
|
||||
|
||||
authorizers = client.get_authorizers(restApiId=api_id)["items"]
|
||||
sorted([authorizer["name"] for authorizer in authorizers]).should.equal(
|
||||
sorted([authorizer_name2, authorizer_name])
|
||||
)
|
||||
# delete stage
|
||||
response = client.delete_authorizer(restApiId=api_id, authorizerId=authorizer_id2)
|
||||
response["ResponseMetadata"]["HTTPStatusCode"].should.equal(202)
|
||||
# verify other stage still exists
|
||||
authorizers = client.get_authorizers(restApiId=api_id)["items"]
|
||||
sorted([authorizer["name"] for authorizer in authorizers]).should.equal(
|
||||
sorted([authorizer_name])
|
||||
)
|
||||
|
||||
|
||||
@mock_apigateway
|
||||
def test_update_stage_configuration():
|
||||
client = boto3.client("apigateway", region_name="us-west-2")
|
||||
|
Loading…
Reference in New Issue
Block a user