summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2015-04-08 09:00:37 -0400
committerSimo Sorce <simo@redhat.com>2015-04-08 09:19:59 -0400
commit575efc8bd229cfa5ef7d73c4b53c1e27f6f267d5 (patch)
tree27fedbca9f41d5b000f9f1ed619655575ff616d0
parente538bf2ae154588dd45a8f01fe1cc1c08441de03 (diff)
downloadcustodia-575efc8bd229cfa5ef7d73c4b53c1e27f6f267d5.tar.gz
custodia-575efc8bd229cfa5ef7d73c4b53c1e27f6f267d5.tar.xz
custodia-575efc8bd229cfa5ef7d73c4b53c1e27f6f267d5.zip
Return only key/containers names on LIST operation
-rw-r--r--API.md2
-rw-r--r--custodia/secrets.py67
-rw-r--r--custodia/store/sqlite.py36
3 files changed, 45 insertions, 60 deletions
diff --git a/API.md b/API.md
index e250e9f..a2f7cba 100644
--- a/API.md
+++ b/API.md
@@ -108,8 +108,6 @@ provided: GET /secrets/ may return only keys under /<user-default>/*
Returns:
- 200 in case of success and a dictionary containing a list of all keys
in the container and all subcontainers.
- The dictionary key is the key or container name, the value is the empty
- string for containers.
- 401 if authentication is necessary
- 403 if access to the key is forbidden
- 404 if no key was found
diff --git a/custodia/secrets.py b/custodia/secrets.py
index 9e57a49..397754b 100644
--- a/custodia/secrets.py
+++ b/custodia/secrets.py
@@ -75,26 +75,25 @@ class Secrets(HTTPConsumer):
def _parent_exists(self, default, trail):
# check that the containers exist
- exists = True
- l = len(trail)
- n = 0
- for n in range(1, l):
- probe = self._db_key(trail[:n] + [''])
- try:
- check = self.root.store.get(probe)
- if check is None:
- exists = False
- break
- except CSStoreError:
- raise HTTPError(500)
-
- # create if default namespace needs creating
- if not exists and l == 2 and n == 1 and default == trail[0]:
+ basename = self._db_container_key(trail[0], '')
+ try:
+ keylist = self.root.store.list(basename)
+ except CSStoreError:
+ raise HTTPError(500)
+
+ # create default namespace if it is the only missing piece
+ if keylist is None and len(trail) == 2 and default == trail[0]:
container = self._db_container_key(default, '')
self.root.store.set(container, '')
- exists = True
+ return True
- return exists
+ # check if any parent is missing
+ for n in range(1, len(trail)):
+ c = self._db_key(trail[:n] + [''])
+ if c not in keylist:
+ return False
+
+ return True
def GET(self, request, response):
trail = request.get('trail', [])
@@ -131,21 +130,17 @@ class Secrets(HTTPConsumer):
basename = self._db_container_key(default, trail)
userfilter = request.get('query', dict()).get('filter', '')
try:
- keydict = self.root.store.list(basename + userfilter)
- if keydict is None:
+ keylist = self.root.store.list(basename + userfilter)
+ if keylist is None:
raise HTTPError(404)
- output = dict()
- for k in keydict:
- # remove the base container itself
+ # remove the base container itself
+ output = list()
+ for k in keylist:
if k == basename:
continue
# strip away the internal prefix for storing keys
name = k[len('keys/'):]
- # return empty value for containers
- if name.endswith('/'):
- output[name] = ''
- else:
- output[name] = json.loads(keydict[k])
+ output.append(name)
response['output'] = json.dumps(output)
except CSStoreError:
raise HTTPError(500)
@@ -169,16 +164,14 @@ class Secrets(HTTPConsumer):
def _destroy(self, trail, request, response):
basename = self._db_container_key(None, trail)
try:
- keydict = self.root.store.list(basename)
- if keydict is None:
+ keylist = self.root.store.list(basename)
+ if keylist is None:
raise HTTPError(404)
- keys = list(keydict.keys())
- if len(keys) != 1:
- raise HTTPError(409)
- if keys[0] != basename:
+ if basename not in keylist:
# uh ?
raise HTTPError(409)
- print((basename, keys))
+ if len(keylist) != 1:
+ raise HTTPError(409)
ret = self.root.store.cut(basename)
except CSStoreError:
raise HTTPError(500)
@@ -314,8 +307,7 @@ class SecretsTests(unittest.TestCase):
rep = {}
self.GET(req, rep)
self.assertEqual(json.loads(rep['output']),
- json.loads('{"test/key1":'
- '{"type":"simple","value":"1234"}}'))
+ json.loads('["test/key1"]'))
def test_3_LISTKeys_2(self):
req = {'remote_user': 'test',
@@ -324,8 +316,7 @@ class SecretsTests(unittest.TestCase):
rep = {}
self.GET(req, rep)
self.assertEqual(json.loads(rep['output']),
- json.loads('{"test/key1":'
- '{"type":"simple","value":"1234"}}'))
+ json.loads('["test/key1"]'))
def test_4_PUTKey_errors_400_1(self):
req = {'headers': {'Content-Type': 'text/plain'},
diff --git a/custodia/store/sqlite.py b/custodia/store/sqlite.py
index 5308674..e96848f 100644
--- a/custodia/store/sqlite.py
+++ b/custodia/store/sqlite.py
@@ -72,7 +72,7 @@ class SqliteStore(CSStore):
raise CSStoreError('Error occurred while trying to store key')
def list(self, keyfilter='/'):
- search = "SELECT * FROM %s WHERE key LIKE ?" % self.table
+ search = "SELECT key FROM %s WHERE key LIKE ?" % self.table
key = "%s%%" % (keyfilter,)
try:
conn = sqlite3.connect(self.dburi)
@@ -82,10 +82,10 @@ class SqliteStore(CSStore):
log_error("Error listing (filter: %s): [%r]" % (key, repr(err)))
raise CSStoreError('Error occurred while trying to list keys')
if len(rows) > 0:
- value = dict()
+ value = list()
for row in rows:
- value[row[0]] = row[1]
- return value
+ value.append(row[0])
+ return sorted(value)
else:
return None
@@ -135,10 +135,10 @@ class SqliteStoreTests(unittest.TestCase):
def test_3_list_key(self):
value = self.store.list('key')
- self.assertEqual(value, {'key': 'value'})
+ self.assertEqual(value, ['key'])
value = self.store.list('k')
- self.assertEqual(value, {'key': 'value'})
+ self.assertEqual(value, ['key'])
value = self.store.list('none')
self.assertEqual(value, None)
@@ -152,26 +152,22 @@ class SqliteStoreTests(unittest.TestCase):
self.store.set('/oth3/key1', 'value31')
value = self.store.list()
- self.assertEqual(value, {'/sub1/key1': 'value11',
- '/sub1/key2': 'value12',
- '/sub1/key3': 'value13',
- '/sub2/key1': 'value21',
- '/sub2/key2': 'value22',
- '/oth3/key1': 'value31'})
+ self.assertEqual(value,
+ sorted(['/sub1/key1', '/sub1/key2',
+ '/sub1/key3', '/sub2/key1',
+ '/sub2/key2', '/oth3/key1']))
value = self.store.list('/sub')
- self.assertEqual(value, {'/sub1/key1': 'value11',
- '/sub1/key2': 'value12',
- '/sub1/key3': 'value13',
- '/sub2/key1': 'value21',
- '/sub2/key2': 'value22'})
+ self.assertEqual(value,
+ sorted(['/sub1/key1', '/sub1/key2',
+ '/sub1/key3', '/sub2/key1',
+ '/sub2/key2']))
value = self.store.list('/sub2')
- self.assertEqual(value, {'/sub2/key1': 'value21',
- '/sub2/key2': 'value22'})
+ self.assertEqual(value, sorted(['/sub2/key1', '/sub2/key2']))
value = self.store.list('/o')
- self.assertEqual(value, {'/oth3/key1': 'value31'})
+ self.assertEqual(value, ['/oth3/key1'])
value = self.store.list('/x')
self.assertEqual(value, None)