Auth: Check token validity + secure bansho/config
Change-Id: I417814a16df582ee636c197bcc7008978e084d3a
This commit is contained in:
parent
8480b4cc8e
commit
57025d4f4b
@ -1,6 +1,10 @@
|
|||||||
{
|
{
|
||||||
"admin_required": "role:admin or is_admin:1",
|
"admin_required": "role:admin or is_admin:1",
|
||||||
|
"surveil_required": "role:surveil",
|
||||||
|
|
||||||
"surveil:admin": "rule:admin_required",
|
"surveil:admin": "rule:admin_required",
|
||||||
|
"surveil:authenticated": "rule:surveil_required",
|
||||||
|
|
||||||
"surveil:break": "!",
|
"surveil:break": "!",
|
||||||
"surveil:pass": "@"
|
"surveil:pass": "@"
|
||||||
}
|
}
|
||||||
|
@ -88,23 +88,23 @@ class AuthProtocol(object):
|
|||||||
"""
|
"""
|
||||||
self._remove_auth_headers(env)
|
self._remove_auth_headers(env)
|
||||||
|
|
||||||
# TODO(aviau): Get token and validate it, then build proper headers
|
token = self._get_header(env, 'X-Auth-Token', None)
|
||||||
if False:
|
|
||||||
self._reject_request(env, start_response)
|
|
||||||
|
|
||||||
user_headers = {
|
# TODO(aviau): Validate token, then build proper headers
|
||||||
'X-Identity-Status': 'Confirmed',
|
if token == "aaaaa-bbbbb-ccccc-dddd":
|
||||||
'X-User-Id': 'surveil-default-user',
|
user_headers = {
|
||||||
'X-Roles': 'admin',
|
'X-Identity-Status': 'Confirmed',
|
||||||
'X-Service-Catalog': 'surveil'
|
'X-User-Id': 'surveil-default-user',
|
||||||
}
|
'X-Roles': 'admin,surveil',
|
||||||
self._add_headers(env, user_headers)
|
'X-Service-Catalog': 'surveil'
|
||||||
|
}
|
||||||
|
self._add_headers(env, user_headers)
|
||||||
|
|
||||||
service_headers = {
|
service_headers = {
|
||||||
'X-Service-Identity-Status': 'Confirmed',
|
'X-Service-Identity-Status': 'Confirmed',
|
||||||
'X-Service-Roles': 'surveil',
|
'X-Service-Roles': 'surveil',
|
||||||
}
|
}
|
||||||
self._add_headers(env, service_headers)
|
self._add_headers(env, service_headers)
|
||||||
|
|
||||||
return self._call_app(env, start_response)
|
return self._call_app(env, start_response)
|
||||||
|
|
||||||
@ -142,6 +142,11 @@ class AuthProtocol(object):
|
|||||||
"""
|
"""
|
||||||
return 'HTTP_%s' % key.replace('-', '_').upper()
|
return 'HTTP_%s' % key.replace('-', '_').upper()
|
||||||
|
|
||||||
|
def _get_header(self, env, key, default=None):
|
||||||
|
"""Get http header from environment."""
|
||||||
|
env_key = self._header_to_env_var(key)
|
||||||
|
return env.get(env_key, default)
|
||||||
|
|
||||||
def _call_app(self, env, start_response):
|
def _call_app(self, env, start_response):
|
||||||
# NOTE(jamielennox): We wrap the given start response so that if an
|
# NOTE(jamielennox): We wrap the given start response so that if an
|
||||||
# application with a 'delay_auth_decision' setting fails, or otherwise
|
# application with a 'delay_auth_decision' setting fails, or otherwise
|
||||||
|
@ -18,10 +18,12 @@ from pecan import rest
|
|||||||
import wsmeext.pecan as wsme_pecan
|
import wsmeext.pecan as wsme_pecan
|
||||||
|
|
||||||
from surveil.api.handlers.bansho import config_handler
|
from surveil.api.handlers.bansho import config_handler
|
||||||
|
from surveil.common import util
|
||||||
|
|
||||||
|
|
||||||
class ConfigController(rest.RestController):
|
class ConfigController(rest.RestController):
|
||||||
|
|
||||||
|
@util.policy_enforce(['authenticated'])
|
||||||
@wsme_pecan.wsexpose(unicode)
|
@wsme_pecan.wsexpose(unicode)
|
||||||
def get(self):
|
def get(self):
|
||||||
"""Retrieve user config, empty dict if no config exists."""
|
"""Retrieve user config, empty dict if no config exists."""
|
||||||
@ -30,6 +32,7 @@ class ConfigController(rest.RestController):
|
|||||||
config = handler.get(user_name)
|
config = handler.get(user_name)
|
||||||
return config
|
return config
|
||||||
|
|
||||||
|
@util.policy_enforce(['authenticated'])
|
||||||
@wsme_pecan.wsexpose(body=unicode)
|
@wsme_pecan.wsexpose(body=unicode)
|
||||||
def post(self, config):
|
def post(self, config):
|
||||||
"""Save user config.
|
"""Save user config.
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
|
||||||
|
import functools
|
||||||
|
|
||||||
import pecan
|
import pecan
|
||||||
from webob import exc
|
from webob import exc
|
||||||
|
|
||||||
@ -22,7 +24,8 @@ from surveil.api import rbac
|
|||||||
# TODO(aviau && Freddrickk): Properly document this decorator
|
# TODO(aviau && Freddrickk): Properly document this decorator
|
||||||
def policy_enforce(actions):
|
def policy_enforce(actions):
|
||||||
def policy_enforce_inner(handler):
|
def policy_enforce_inner(handler):
|
||||||
def handle_stack_method(controller, **kwargs):
|
@functools.wraps(handler)
|
||||||
|
def handle_stack_method(*args, **kwargs):
|
||||||
request = pecan.request
|
request = pecan.request
|
||||||
for action in actions:
|
for action in actions:
|
||||||
allowed = rbac.enforce(action, request)
|
allowed = rbac.enforce(action, request)
|
||||||
@ -30,6 +33,6 @@ def policy_enforce(actions):
|
|||||||
if not allowed:
|
if not allowed:
|
||||||
raise exc.HTTPForbidden()
|
raise exc.HTTPForbidden()
|
||||||
|
|
||||||
return handler(controller, **kwargs)
|
return handler(*args, **kwargs)
|
||||||
return handle_stack_method
|
return handle_stack_method
|
||||||
return policy_enforce_inner
|
return policy_enforce_inner
|
||||||
|
@ -34,15 +34,26 @@ class TestConfigController(functionalTest.FunctionalTest):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def test_get_post_get(self):
|
def test_get_post_get(self):
|
||||||
|
|
||||||
# At first, conf is empty
|
# At first, conf is empty
|
||||||
response = self.app.get('/v2/bansho/config')
|
self.assertIsNone(
|
||||||
|
self.mongoconnection.surveil.bansho.config.find_one(
|
||||||
|
{"user_name": "surveil-default-user"}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
response = self.get('/v2/bansho/config')
|
||||||
self.assertEqual({}, json.loads(response.body.decode()))
|
self.assertEqual({}, json.loads(response.body.decode()))
|
||||||
|
|
||||||
# Now, post config
|
# Now, post config
|
||||||
config = {"key": "val",
|
config = {"key": "val",
|
||||||
"morekey": "moreval"}
|
"morekey": "moreval"}
|
||||||
self.app.post_json('/v2/bansho/config', params=config)
|
self.post_json('/v2/bansho/config', params=config)
|
||||||
|
|
||||||
# Now config is what we gave to the API
|
# Now config is what we gave to the API
|
||||||
response = self.app.get('/v2/bansho/config')
|
response = self.get('/v2/bansho/config')
|
||||||
self.assertEqual(config, json.loads(response.body.decode()))
|
self.assertEqual(config, json.loads(response.body.decode()))
|
||||||
|
self.assertIsNotNone(
|
||||||
|
self.mongoconnection.surveil.bansho.config.find_one(
|
||||||
|
{"user_name": "surveil-default-user"}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
@ -75,10 +75,27 @@ class FunctionalTest(base.BaseTestCase):
|
|||||||
'app': {
|
'app': {
|
||||||
'root': 'surveil.api.controllers.root.RootController',
|
'root': 'surveil.api.controllers.root.RootController',
|
||||||
'modules': ['surveil.api'],
|
'modules': ['surveil.api'],
|
||||||
'debug': False,
|
'debug': True,
|
||||||
'hooks': app_hooks
|
'hooks': app_hooks
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
self.auth_headers = {
|
||||||
|
'X-Identity-Status': 'Confirmed',
|
||||||
|
'X-User-Id': 'surveil-default-user',
|
||||||
|
'X-Roles': 'admin,surveil',
|
||||||
|
'X-Service-Catalog': 'surveil',
|
||||||
|
'X-Service-Identity-Status': 'Confirmed',
|
||||||
|
'X-Service-Roles': 'surveil',
|
||||||
|
}
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
pecan.set_config({}, overwrite=True)
|
pecan.set_config({}, overwrite=True)
|
||||||
|
|
||||||
|
def post_json(self, *args, **kwargs):
|
||||||
|
kwargs.setdefault('headers', self.auth_headers)
|
||||||
|
return self.app.post_json(*args, **kwargs)
|
||||||
|
|
||||||
|
def get(self, *args, **kwargs):
|
||||||
|
kwargs.setdefault('headers', self.auth_headers)
|
||||||
|
return self.app.get(*args, **kwargs)
|
||||||
|
@ -1,4 +1,10 @@
|
|||||||
{
|
{
|
||||||
"surveil:break":"!",
|
"admin_required": "role:admin or is_admin:1",
|
||||||
"surveil:pass":"@"
|
"surveil_required": "role:surveil",
|
||||||
|
|
||||||
|
"surveil:admin": "rule:admin_required",
|
||||||
|
"surveil:authenticated": "rule:surveil_required",
|
||||||
|
|
||||||
|
"surveil:break": "!",
|
||||||
|
"surveil:pass": "@"
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user