Issue #22: Make public route execution validation more strict
Fixes: #22
This commit is contained in:
parent
b9e2655336
commit
3bbe877b88
|
@ -18,6 +18,7 @@ from aioservice.http import controller
|
||||||
from aioservice.http import requests
|
from aioservice.http import requests
|
||||||
|
|
||||||
from ...common import config
|
from ...common import config
|
||||||
|
from ...models import app as app_model
|
||||||
|
|
||||||
|
|
||||||
class RunnableMixin(object):
|
class RunnableMixin(object):
|
||||||
|
@ -88,9 +89,29 @@ class PublicRunnableV1Controller(controller.ServiceController,
|
||||||
description: successful operation. Return "runnable" JSON
|
description: successful operation. Return "runnable" JSON
|
||||||
"404":
|
"404":
|
||||||
description: App does not exist
|
description: App does not exist
|
||||||
"404":
|
"403":
|
||||||
description: App route does not exist
|
description: Unable to execute private route
|
||||||
"""
|
"""
|
||||||
|
app = request.match_info.get('app')
|
||||||
|
path = request.match_info.get('route')
|
||||||
|
routes = await app_model.Routes.find_by(app_name=app, path=path)
|
||||||
|
|
||||||
|
if not routes:
|
||||||
|
return web.json_response(data={
|
||||||
|
"error": {
|
||||||
|
"message": "Route {0} not found".format(app),
|
||||||
|
}
|
||||||
|
}, status=404)
|
||||||
|
route = routes.pop()
|
||||||
|
|
||||||
|
if not route.public:
|
||||||
|
return web.json_response(data={
|
||||||
|
"error": {
|
||||||
|
"message": "Unable to execute private "
|
||||||
|
"route {0}".format(path)
|
||||||
|
}
|
||||||
|
}, status=403)
|
||||||
|
|
||||||
return await super(PublicRunnableV1Controller,
|
return await super(PublicRunnableV1Controller,
|
||||||
self).run(request, **kwargs)
|
self).run(request, **kwargs)
|
||||||
|
|
||||||
|
|
|
@ -17,14 +17,19 @@ import json as jsonlib
|
||||||
|
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def setup_execute(self, app_name):
|
def setup_execute(self, app_name, create_public_route=False):
|
||||||
app, _ = self.testloop.run_until_complete(
|
app, _ = self.testloop.run_until_complete(
|
||||||
self.test_client.apps.create(app_name)
|
self.test_client.apps.create(app_name)
|
||||||
)
|
)
|
||||||
new_app_name = app["app"]["name"]
|
new_app_name = app["app"]["name"]
|
||||||
|
route_data = self.route_data
|
||||||
|
|
||||||
|
if create_public_route:
|
||||||
|
route_data.update(is_public="true")
|
||||||
|
|
||||||
route, _ = self.testloop.run_until_complete(
|
route, _ = self.testloop.run_until_complete(
|
||||||
self.test_client.routes.create(
|
self.test_client.routes.create(
|
||||||
new_app_name, **self.route_data)
|
new_app_name, **route_data)
|
||||||
)
|
)
|
||||||
self.testloop.run_until_complete(
|
self.testloop.run_until_complete(
|
||||||
self.test_client.routes.update(
|
self.test_client.routes.update(
|
||||||
|
@ -199,7 +204,8 @@ class AppRoutesTestSuite(object):
|
||||||
self.assertEqual(200, status)
|
self.assertEqual(200, status)
|
||||||
|
|
||||||
def execute_public(self):
|
def execute_public(self):
|
||||||
with setup_execute(self, "execute_public") as app_name:
|
with setup_execute(self, "execute_public",
|
||||||
|
create_public_route=True) as app_name:
|
||||||
result, status = self.testloop.run_until_complete(
|
result, status = self.testloop.run_until_complete(
|
||||||
self.test_client.routes.execute_public(
|
self.test_client.routes.execute_public(
|
||||||
app_name, self.route_data["path"]
|
app_name, self.route_data["path"]
|
||||||
|
@ -207,3 +213,13 @@ class AppRoutesTestSuite(object):
|
||||||
)
|
)
|
||||||
self.assertIsNotNone(result)
|
self.assertIsNotNone(result)
|
||||||
self.assertEqual(200, status)
|
self.assertEqual(200, status)
|
||||||
|
|
||||||
|
def fail_to_execute_private_as_public(self):
|
||||||
|
with setup_execute(self, "fail_to_execute_"
|
||||||
|
"private_as_public") as app_name:
|
||||||
|
_, status = self.testloop.run_until_complete(
|
||||||
|
self.test_client.routes.execute_public(
|
||||||
|
app_name, self.route_data["path"]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.assertEqual(403, status)
|
||||||
|
|
|
@ -49,3 +49,6 @@ class TestAppRoutes(base.FunctionalTestsBase,
|
||||||
|
|
||||||
def test_public_execution(self):
|
def test_public_execution(self):
|
||||||
super(TestAppRoutes, self).execute_private()
|
super(TestAppRoutes, self).execute_private()
|
||||||
|
|
||||||
|
def test_fail_to_execute_private_route(self):
|
||||||
|
super(TestAppRoutes, self).fail_to_execute_private_as_public()
|
||||||
|
|
|
@ -55,3 +55,7 @@ class TestIntegrationAppRoutes(base.FunctionalTestsBase,
|
||||||
|
|
||||||
def test_public_execution(self):
|
def test_public_execution(self):
|
||||||
super(TestIntegrationAppRoutes, self).execute_private()
|
super(TestIntegrationAppRoutes, self).execute_private()
|
||||||
|
|
||||||
|
def test_fail_to_execute_private_route(self):
|
||||||
|
super(TestIntegrationAppRoutes,
|
||||||
|
self).fail_to_execute_private_as_public()
|
||||||
|
|
4
tox.ini
4
tox.ini
|
@ -32,10 +32,10 @@ commands = flake8
|
||||||
commands = {posargs}
|
commands = {posargs}
|
||||||
|
|
||||||
[testenv:py35-integration]
|
[testenv:py35-integration]
|
||||||
commands = pytest --tb=long --capture=sys --cov=picasso --capture=fd {toxinidir}/picasso/tests/integration
|
commands = pytest -v --tb=long --capture=sys --cov=picasso --capture=fd {toxinidir}/picasso/tests/integration
|
||||||
|
|
||||||
[testenv:py35-functional]
|
[testenv:py35-functional]
|
||||||
commands = pytest --tb=long --capture=sys --cov=picasso --capture=fd {toxinidir}/picasso/tests/functional
|
commands = pytest -v --tb=long --capture=sys --cov=picasso --capture=fd {toxinidir}/picasso/tests/functional
|
||||||
|
|
||||||
[testenv:py35-functional-regression]
|
[testenv:py35-functional-regression]
|
||||||
commands = {toxinidir}/scripts/test_regression.sh functional {posargs}
|
commands = {toxinidir}/scripts/test_regression.sh functional {posargs}
|
||||||
|
|
Loading…
Reference in New Issue