Skip to content

Commit c97cd88

Browse files
author
Sergio García Prado
authored
Merge pull request #51 from Clariteia/0.0.4
0.0.4
2 parents ef26e8d + 5b5c3cb commit c97cd88

File tree

7 files changed

+196
-49
lines changed

7 files changed

+196
-49
lines changed

HISTORY.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,6 @@
1414
* Handle requests to unavailable microservices.
1515
* Improve request forwarding to microservices.
1616
* Fix bug related with unnecessary `json` casting.
17+
18+
## 0.0.4 (2021-08-54)
19+
* Add support to `CORS`.

minos/api_gateway/rest/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
66
Minos framework can not be copied and/or distributed without the express permission of Clariteia SL.
77
"""
8-
__version__ = "0.0.3"
8+
__version__ = "0.0.4"
99

1010
from .launchers import (
1111
EntrypointLauncher,

minos/api_gateway/rest/service.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
from aiohttp import (
66
web,
77
)
8+
from aiohttp_middlewares import (
9+
cors_middleware,
10+
)
811
from aiomisc.service.aiohttp import (
912
AIOHTTPService,
1013
)
@@ -25,7 +28,12 @@ def __init__(self, address: str, port: int, config: MinosConfig):
2528
super().__init__(address, port)
2629

2730
async def create_application(self) -> web.Application:
28-
app = web.Application()
31+
middlewares = list()
32+
if self.config.cors.enabled:
33+
middlewares = [cors_middleware(allow_all=True)]
34+
35+
app = web.Application(middlewares=middlewares)
36+
2937
app["config"] = self.config
3038

3139
app.router.add_route("*", "/{endpoint:.*}", handler.orchestrate)

poetry.lock

Lines changed: 92 additions & 45 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "minos_apigateway"
3-
version = "0.0.3"
3+
version = "0.0.4"
44
description = "Python Package containing the main API Gateway implementation used in Minos Microservices."
55
readme = "README.md"
66
repository = "https://github.com/clariteia/api_gateway"
@@ -31,9 +31,10 @@ include = [
3131

3232
[tool.poetry.dependencies]
3333
python = "^3.9"
34-
minos-apigateway-common = "^0.0.4"
34+
minos-apigateway-common = "^0.0.5"
3535
typer = "^0.3.2"
3636
cached-property = "^1.5.2"
37+
aiohttp-middlewares = "^1.1.0"
3738

3839
[tool.poetry.dev-dependencies]
3940
black = "^19.10b"

tests/config.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,6 @@ discovery:
1111
host: localhost
1212
port: 6379
1313
password:
14+
cors:
15+
enabled: false
16+

tests/test_api_gateway/test_rest/test_service.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,23 @@
11
"""tests.test_api_gateway.test_rest.service module."""
22

3+
import os
34
import unittest
5+
from unittest import (
6+
mock,
7+
)
48

9+
import attr
510
from aiohttp.test_utils import (
611
AioHTTPTestCase,
712
unittest_run_loop,
813
)
14+
from aiohttp_middlewares.cors import (
15+
ACCESS_CONTROL_ALLOW_HEADERS,
16+
ACCESS_CONTROL_ALLOW_METHODS,
17+
ACCESS_CONTROL_ALLOW_ORIGIN,
18+
DEFAULT_ALLOW_HEADERS,
19+
DEFAULT_ALLOW_METHODS,
20+
)
921

1022
from minos.api_gateway.common import (
1123
MinosConfig,
@@ -200,5 +212,78 @@ async def test_get(self):
200212
self.assertIn("The requested endpoint is not available.", await response.text())
201213

202214

215+
class TestApiGatewayCORS(AioHTTPTestCase):
216+
CONFIG_FILE_PATH = BASE_PATH / "config.yml"
217+
TEST_DENIED_ORIGIN = "https://www.google.com"
218+
TEST_ORIGIN = "http://localhost:3000"
219+
220+
@mock.patch.dict(os.environ, {"API_GATEWAY_CORS_ENABLED": "true"})
221+
def setUp(self) -> None:
222+
self.config = MinosConfig(self.CONFIG_FILE_PATH)
223+
224+
self.discovery = MockServer(
225+
host=self.config.discovery.connection.host, port=self.config.discovery.connection.port,
226+
)
227+
self.discovery.add_json_response(
228+
"/microservices", {"address": "localhost", "port": "5568", "status": True},
229+
)
230+
231+
self.microservice = MockServer(host="localhost", port=5568)
232+
self.microservice.add_json_response(
233+
"/order/5", "Microservice call correct!!!", methods=("GET", "PUT", "PATCH", "DELETE",)
234+
)
235+
self.microservice.add_json_response("/order", "Microservice call correct!!!", methods=("POST",))
236+
237+
self.discovery.start()
238+
self.microservice.start()
239+
super().setUp()
240+
241+
def tearDown(self) -> None:
242+
self.discovery.shutdown_server()
243+
self.microservice.shutdown_server()
244+
super().tearDown()
245+
246+
async def get_application(self):
247+
"""
248+
Override the get_app method to return your application.
249+
"""
250+
rest_service = ApiGatewayRestService(
251+
address=self.config.rest.connection.host, port=self.config.rest.connection.port, config=self.config
252+
)
253+
254+
return await rest_service.create_application()
255+
256+
@staticmethod
257+
def check_allow_origin(
258+
response, origin, *, allow_headers=DEFAULT_ALLOW_HEADERS, allow_methods=DEFAULT_ALLOW_METHODS,
259+
):
260+
assert response.headers[ACCESS_CONTROL_ALLOW_ORIGIN] == origin
261+
if allow_headers:
262+
assert response.headers[ACCESS_CONTROL_ALLOW_HEADERS] == ", ".join(allow_headers)
263+
if allow_methods:
264+
assert response.headers[ACCESS_CONTROL_ALLOW_METHODS] == ", ".join(allow_methods)
265+
266+
@unittest_run_loop
267+
async def test_cors_enabled(self):
268+
method = "GET"
269+
extra_headers = {}
270+
expected_origin = "*"
271+
expected_allow_headers = None
272+
expected_allow_methods = None
273+
url = "/order/5?verb=GET&path=12324"
274+
275+
kwargs = {}
276+
if expected_allow_headers is not attr.NOTHING:
277+
kwargs["allow_headers"] = expected_allow_headers
278+
if expected_allow_methods is not attr.NOTHING:
279+
kwargs["allow_methods"] = expected_allow_methods
280+
281+
self.check_allow_origin(
282+
await self.client.request(method, url, headers={"Origin": self.TEST_ORIGIN, **extra_headers}),
283+
expected_origin,
284+
**kwargs,
285+
)
286+
287+
203288
if __name__ == "__main__":
204289
unittest.main()

0 commit comments

Comments
 (0)