diff --git a/confluent/auth.py b/confluent/auth.py index 6e3699c5..d027889a 100644 --- a/confluent/auth.py +++ b/confluent/auth.py @@ -2,23 +2,34 @@ import confluent.config as config -def authorize(name, element): +def authorize(name, element, tenant=None, access='rw'): #TODO: actually use the element to ascertain if this user is good enough - try: - if '/' in name: - tenant, user = name.split('/', 1) - tenant = config.get_tenant_id(tenant) - user = config.get_user(user, tenant) - elif name in config.get_tenant_names(): - tenant = config.get_tenant_id(name) - user = config.get_user(name, tenant) - else: - user = config.get_user(name, 0) - tenant = 0 - return (tenant, user) - except: - print "uh oh" + """Determine whether the given authenticated name is authorized. + + :param name: The shortname authenticated by the authentication scheme + :param element: The path being examined. + :param tenant: The tenant under which the account exists (defaults to + detect from name) + :param access: Defaults to 'rw', can check 'ro' access + + returns None if authorization fails or a tuple of the user object + and the relevant ConfigManager object for the context of the + request. + """ + if tenant is not None: + user = name + elif '/' in name: + tenant, user = name.split('/', 1) + elif config.is_tenant(name): + user = name + tenant = name + else: + user = name + tenant = 0 + if not config.is_tenant(tenant): return None - - - + configmanager = config.ConfigManager(tenant) + userobj = configmanager.get_user(user) + if userobj: #returning + return (userobj, configmanager) + return None diff --git a/confluent/config.py b/confluent/config.py index 8ea1f1f8..b871618e 100644 --- a/confluent/config.py +++ b/confluent/config.py @@ -49,8 +49,12 @@ import string import threading -_cfgstore = None +def is_tenant(tenant): + try: + return tenant in _cfgstore['tenant'] + except: + return False def get_global(globalname): """Get a global variable @@ -197,16 +201,13 @@ class ConfigManager(object): def __init__(self, tenant, decrypt=False): global _cfgstore - if _cfgstore is None: - try: - self._read_from_file() - except IOError: - _cfgstore = {} self.decrypt = decrypt if 'tenant' not in _cfgstore: - _cfgstore['tenant'] = {} - if tenant not in _cfgstore['tenant']: + _cfgstore['tenant'] = {tenant: {'id': tenant}} + self._bg_sync_to_file() + elif tenant not in _cfgstore['tenant']: _cfgstore['tenant'][tenant] = {'id': tenant} + self._bg_sync_to_file() self.tenant = tenant self._cfgstore = _cfgstore['tenant'][tenant] @@ -407,3 +408,10 @@ class ConfigManager(object): # recurse for nested structures, with some hint tha # it might indeed be a nested structure _recalculate_expressions(cfgobj[key], formatter) + + +try: + ConfigManager._read_from_file() +except IOError: + _cfgstore = {} + diff --git a/confluent/httpapi.py b/confluent/httpapi.py index f4b738f1..43573074 100644 --- a/confluent/httpapi.py +++ b/confluent/httpapi.py @@ -42,8 +42,8 @@ def _authorize_request(env): return {'code': 401} else: return {'code': 200, - 'tenant': authdata[0], - 'user': authdata[1]} + 'cfgmgr': authdata[1], + 'userdata': authdata[0]} # TODO(jbjohnso): actually evaluate the request for authorization # In theory, the x509 or http auth stuff will get translated and then @@ -103,7 +103,7 @@ def resourcehandler(env, start_response): return 'authorization failed' if authorized['code'] != 200: raise Exception("Unrecognized code from auth engine") - cfgmgr = config.ConfigManager(authorized['tenant']) + cfgmgr = authorized['cfgmgr'] querydict = _get_query_dict(env['QUERY_STRING'], reqbody, reqtype) if '/console/session' in env['PATH_INFO']: #hard bake JSON into this path, do not support other incarnations