diff --git a/moto/apigateway/exceptions.py b/moto/apigateway/exceptions.py index 52c26fa46..434ebc467 100644 --- a/moto/apigateway/exceptions.py +++ b/moto/apigateway/exceptions.py @@ -101,3 +101,12 @@ class ApiKeyNotFoundException(RESTError): super(ApiKeyNotFoundException, self).__init__( "NotFoundException", "Invalid API Key identifier specified" ) + + +class ApiKeyAlreadyExists(RESTError): + code = 409 + + def __init__(self): + super(ApiKeyAlreadyExists, self).__init__( + "ConflictException", "API Key already exists" + ) diff --git a/moto/apigateway/models.py b/moto/apigateway/models.py index 6f1d01c4f..8b5fb787f 100644 --- a/moto/apigateway/models.py +++ b/moto/apigateway/models.py @@ -32,6 +32,7 @@ from .exceptions import ( RoleNotSpecified, NoIntegrationDefined, NoMethodDefined, + ApiKeyAlreadyExists, ) STAGE_URL = "https://{api_id}.execute-api.{region_name}.amazonaws.com/{stage_name}" @@ -759,6 +760,10 @@ class APIGatewayBackend(BaseBackend): return api.delete_deployment(deployment_id) def create_apikey(self, payload): + if payload.get("value") is not None: + for api_key in self.get_apikeys(): + if api_key.get("value") == payload["value"]: + raise ApiKeyAlreadyExists() key = ApiKey(**payload) self.keys[key["id"]] = key return key diff --git a/moto/apigateway/responses.py b/moto/apigateway/responses.py index 1089de211..c4c7b403e 100644 --- a/moto/apigateway/responses.py +++ b/moto/apigateway/responses.py @@ -9,6 +9,7 @@ from .exceptions import ( BadRequestException, CrossAccountNotAllowed, StageNotFoundException, + ApiKeyAlreadyExists, ) @@ -302,7 +303,17 @@ class APIGatewayResponse(BaseResponse): self.setup_class(request, full_url, headers) if self.method == "POST": - apikey_response = self.backend.create_apikey(json.loads(self.body)) + try: + apikey_response = self.backend.create_apikey(json.loads(self.body)) + except ApiKeyAlreadyExists as error: + return ( + error.code, + self.headers, + '{{"message":"{0}","code":"{1}"}}'.format( + error.message, error.error_type + ), + ) + elif self.method == "GET": apikeys_response = self.backend.get_apikeys() return 200, {}, json.dumps({"item": apikeys_response}) diff --git a/tests/test_apigateway/test_apigateway.py b/tests/test_apigateway/test_apigateway.py index 8da5efa39..af0695940 100644 --- a/tests/test_apigateway/test_apigateway.py +++ b/tests/test_apigateway/test_apigateway.py @@ -1130,6 +1130,23 @@ def test_http_proxying_integration(): requests.get(deploy_url).content.should.equal(b"a fake response") +@mock_apigateway +def test_create_api_key(): + region_name = "us-west-2" + client = boto3.client("apigateway", region_name=region_name) + + apikey_value = "12345" + apikey_name = "TESTKEY1" + payload = {"value": apikey_value, "name": apikey_name} + + client.create_api_key(**payload) + + response = client.get_api_keys() + len(response["items"]).should.equal(1) + + client.create_api_key.when.called_with(**payload).should.throw(ClientError) + + @mock_apigateway def test_api_keys(): region_name = "us-west-2" @@ -1139,26 +1156,18 @@ def test_api_keys(): apikey_value = "12345" apikey_name = "TESTKEY1" - payload = {"value": apikey_value, "name": apikey_name} + payload = { + "value": apikey_value, + "name": apikey_name, + "tags": {"tag1": "test_tag1", "tag2": "1"}, + } response = client.create_api_key(**payload) + apikey_id = response["id"] apikey = client.get_api_key(apiKey=response["id"]) apikey["name"].should.equal(apikey_name) apikey["value"].should.equal(apikey_value) - - apikey_name = "TESTKEY2" - payload = {"name": apikey_name, "tags": {"tag1": "test_tag1", "tag2": "1"}} - response = client.create_api_key(**payload) - apikey_id = response["id"] - apikey = client.get_api_key(apiKey=apikey_id) - apikey["name"].should.equal(apikey_name) apikey["tags"]["tag1"].should.equal("test_tag1") apikey["tags"]["tag2"].should.equal("1") - len(apikey["value"]).should.equal(40) - - apikey_name = "TESTKEY3" - payload = {"name": apikey_name} - response = client.create_api_key(**payload) - apikey_id = response["id"] patch_operations = [ {"op": "replace", "path": "/name", "value": "TESTKEY3_CHANGE"}, @@ -1172,13 +1181,25 @@ def test_api_keys(): response["description"].should.equal("APIKEY UPDATE TEST") response["enabled"].should.equal(False) + updated_api_key = client.get_api_key(apiKey=apikey_id) + updated_api_key["name"].should.equal("TESTKEY3_CHANGE") + updated_api_key["customerId"].should.equal("12345") + updated_api_key["description"].should.equal("APIKEY UPDATE TEST") + updated_api_key["enabled"].should.equal(False) + response = client.get_api_keys() - len(response["items"]).should.equal(3) + len(response["items"]).should.equal(1) + + payload = {"name": apikey_name} + client.create_api_key(**payload) + + response = client.get_api_keys() + len(response["items"]).should.equal(2) client.delete_api_key(apiKey=apikey_id) response = client.get_api_keys() - len(response["items"]).should.equal(2) + len(response["items"]).should.equal(1) @mock_apigateway