diff options
| author | Simo Sorce <simo@redhat.com> | 2015-04-06 10:46:27 -0400 |
|---|---|---|
| committer | Simo Sorce <simo@redhat.com> | 2015-04-06 17:04:28 -0400 |
| commit | 18f7a10d2bad6e8050fb1d34c82398ad8acf628c (patch) | |
| tree | 2d0e74e4e38413eb4816e7338a6b905a0076b7ef | |
| parent | 2440cbbc6e84235381a2f62050ad8009033588d7 (diff) | |
| download | custodia-18f7a10d2bad6e8050fb1d34c82398ad8acf628c.tar.gz custodia-18f7a10d2bad6e8050fb1d34c82398ad8acf628c.tar.xz custodia-18f7a10d2bad6e8050fb1d34c82398ad8acf628c.zip | |
Improve secrets.py
Require expicit namespace in name for GET, then check the user is
authorized to access it.
Return lists of keys filtering them by explicit namespace or using
the default namespace.
The list is returned as a dict of keys with full key names as arguments.
| -rw-r--r-- | custodia/secrets.py | 53 |
1 files changed, 41 insertions, 12 deletions
diff --git a/custodia/secrets.py b/custodia/secrets.py index 776d2e2..6eb630e 100644 --- a/custodia/secrets.py +++ b/custodia/secrets.py @@ -9,9 +9,25 @@ import os class Secrets(HTTPConsumer): - def _get_key(self, namespace, trail): + def _get_key(self, namespaces, trail): + # Check tht the keys is in one of the authorized namespaces + if len(trail) < 1 or trail[0] not in namespaces: + raise HTTPError(403) # pylint: disable=star-args - return os.path.join(namespace, 'keys', *trail) + return os.path.join('keys', *trail) + + def _get_filter(self, namespaces, trail, userfilter): + f = None + if len(trail) > 0: + for ns in namespaces: + if ns == trail[0]: + f = self._get_key(namespaces, trail) + break + if f is None: + # Consider the first namespace as the default one + t = [namespaces[0]] + trail + f = self._get_key(namespaces, t) + return '%s/%s' % (f, userfilter) def _validate(self, value): try: @@ -27,31 +43,44 @@ class Secrets(HTTPConsumer): if len(msg.keys()) != 2: raise ValueError('Unknown attributes in Message') - def _namespace(self, request): + def _namespaces(self, request): if 'remote_user' not in request: raise HTTPError(403) - return request['remote_user'] + # At the moment we just have one namespace, the user's name + return [request['remote_user']] def GET(self, request, response): trail = request.get('trail', []) - ns = self._namespace(request) - if len(trail) == 0: + ns = self._namespaces(request) + if len(trail) == 0 or trail[-1] == '': try: - self.root.store.list(request.get('query', - dict()).get('filter', '*')) + userfilter = request.get('query', dict()).get('filter', '') + keyfilter = self._get_filter(ns, trail[:-1], userfilter) + keydict = self.root.store.list(keyfilter) + if keydict is None: + raise HTTPError(404) + output = dict() + for k in keydict: + # strip away the internal prefix for storing keys + name = k[len('keys/'):] + output[name] = json.loads(keydict[k]) + response['output'] = json.dumps(output) except CSStoreError: - raise HTTPError(500) + raise HTTPError(404) else: key = self._get_key(ns, trail) try: - response['output'] = self.root.store.get(key) + output = self.root.store.get(key) + if output is None: + raise HTTPError(404) + response['output'] = output except CSStoreError: raise HTTPError(500) def PUT(self, request, response): trail = request.get('trail', []) - ns = self._namespace(request) - if len(trail) == 0: + ns = self._namespaces(request) + if len(trail) == 0 or trail[-1] == '': raise HTTPError(405) else: content_type = request.get('headers', |
