summaryrefslogtreecommitdiff
path: root/macaroonbakery/store.py
diff options
context:
space:
mode:
Diffstat (limited to 'macaroonbakery/store.py')
-rw-r--r--macaroonbakery/store.py77
1 files changed, 77 insertions, 0 deletions
diff --git a/macaroonbakery/store.py b/macaroonbakery/store.py
new file mode 100644
index 0000000..ae5f7a7
--- /dev/null
+++ b/macaroonbakery/store.py
@@ -0,0 +1,77 @@
+# Copyright 2017 Canonical Ltd.
+# Licensed under the LGPLv3, see LICENCE file for details.
+import abc
+import os
+
+
+class MemoryOpsStore:
+ ''' A multi-op store that stores the operations in memory.
+ '''
+ def __init__(self):
+ self._store = {}
+
+ def put_ops(self, key, time, ops):
+ ''' Put an ops only if not already there, otherwise it's a no op.
+ '''
+ if self._store.get(key) is None:
+ self._store[key] = ops
+
+ def get_ops(self, key):
+ ''' Returns ops from the key if found otherwise raises a KeyError.
+ '''
+ ops = self._store.get(key)
+ if ops is None:
+ raise KeyError(
+ 'cannot get operations for {}'.format(key))
+ return ops
+
+
+class RootKeyStore(object):
+ ''' Defines a store for macaroon root keys.
+ '''
+ __metaclass__ = abc.ABCMeta
+
+ @abc.abstractmethod
+ def get(self, id):
+ ''' Returns the root key for the given id.
+ If the item is not there, it returns None.
+ @param id: bytes
+ @return: bytes
+ '''
+ raise NotImplementedError('get method must be defined in '
+ 'subclass')
+
+ @abc.abstractmethod
+ def root_key(self):
+ ''' Returns the root key to be used for making a new macaroon, and an
+ id that can be used to look it up later with the get method.
+ Note that the root keys should remain available for as long as the
+ macaroons using them are valid.
+ Note that there is no need for it to return a new root key for every
+ call - keys may be reused, although some key cycling is over time is
+ advisable.
+ @return: bytes
+ '''
+
+
+class MemoryKeyStore(RootKeyStore):
+ ''' MemoryKeyStore returns an implementation of
+ Store that generates a single key and always
+ returns that from root_key. The same id ("0") is always
+ used.
+ '''
+ def __init__(self, key=None):
+ ''' If the key is not specified a random key will be generated.
+ @param key: bytes
+ '''
+ if key is None:
+ key = os.urandom(24)
+ self._key = key
+
+ def get(self, id):
+ if id != b'0':
+ return None
+ return self._key
+
+ def root_key(self):
+ return self._key, b'0'