def post(self, namespace=None, key_name=None, key=None): if not namespace: return api_base.error(400, 'no namespace specified') with db.get_lock('namespace', None, 'all', op='Namespace update'): rec = db.get_namespace(namespace) if not rec: rec = {'name': namespace, 'keys': {}} # Allow shortcut of creating key at same time as the namespace if key_name: if not key: return api_base.error(400, 'no key specified') if not isinstance(key, str): # Must be a string to encode() return api_base.error(400, 'key is not a string') if key_name == 'service_key': return api_base.error(403, 'illegal key name') encoded = str( base64.b64encode( bcrypt.hashpw(key.encode('utf-8'), bcrypt.gensalt())), 'utf-8') rec['keys'][key_name] = encoded # Initialise metadata db.persist_metadata('namespace', namespace, {}) db.persist_namespace(namespace, rec) return namespace
def get_api_token(base_url, namespace='system'): with db.get_lock('namespace', None, namespace): auth_url = base_url + '/auth' logutil.info(None, 'Fetching %s auth token from %s' % (namespace, auth_url)) ns = db.get_namespace(namespace) if 'service_key' in ns: key = ns['service_key'] else: key = ''.join( random.choice(string.ascii_lowercase) for i in range(50)) ns['service_key'] = key db.persist_namespace(namespace, ns) r = requests.request('POST', auth_url, data=json.dumps({ 'namespace': namespace, 'key': key }), headers={ 'Content-Type': 'application/json', 'User-Agent': get_user_agent() }) if r.status_code != 200: raise Exception('Unauthorized') return 'Bearer %s' % r.json()['access_token']
def post(self, namespace=None, key=None): if not namespace: return api_base.error(400, 'missing namespace in request') if not key: return api_base.error(400, 'missing key in request') if not isinstance(key, str): # Must be a string to encode() return api_base.error(400, 'key is not a string') ns = db.get_namespace(namespace) if not ns: return api_base.error(401, 'unauthorized') service_key = ns.get('service_key') if service_key and key == service_key: return { 'access_token': create_access_token(identity=[namespace, '_service_key']) } for key_name in ns.get('keys', {}): possible_key = base64.b64decode(ns['keys'][key_name]) if bcrypt.checkpw(key.encode('utf-8'), possible_key): return { 'access_token': create_access_token(identity=[namespace, key_name]) } return api_base.error(401, 'unauthorized')
def put(self, namespace=None, key_name=None, key=None): rec = db.get_namespace(namespace) if not rec: return error(404, 'namespace does not exist') if key_name not in rec['keys']: return error(404, 'key does not exist') return _namespace_keys_putpost(namespace, key_name, key)
def wrapper(*args, **kwargs): if kwargs.get('namespace'): if not db.get_namespace(kwargs['namespace']): LOG.with_field('namespace', kwargs['namespace']).warning( 'Attempt to use non-existent namespace') return error(404, 'namespace not found') return func(*args, **kwargs)
def get(self, namespace=None): rec = db.get_namespace(namespace) if not rec: return error(404, 'namespace does not exist') out = [] for keyname in rec['keys']: out.append(keyname) return out
def _get_keys(self, namespace): rec = db.get_namespace(namespace) if not rec: return (None, []) keys = [] for key_name in rec.get('keys', {}): keys.append(base64.b64decode(rec['keys'][key_name])) return (rec.get('service_key'), keys)
def delete(self, namespace, key_name): if not namespace: return error(400, 'no namespace specified') if not key_name: return error(400, 'no key name specified') with db.get_lock('namespace', None, namespace): ns = db.get_namespace(namespace) if ns.get('keys') and key_name in ns['keys']: del ns['keys'][key_name] else: return error(404, 'key name not found in namespace') db.persist_namespace(namespace, ns)
def _namespace_keys_putpost(namespace=None, key_name=None, key=None): if not namespace: return api_base.error(400, 'no namespace specified') if not key_name: return api_base.error(400, 'no key name specified') if not key: return api_base.error(400, 'no key specified') if key_name == 'service_key': return api_base.error(403, 'illegal key name') with db.get_lock('namespace', None, 'all', op='Namespace key update'): rec = db.get_namespace(namespace) if not rec: return api_base.error(404, 'namespace does not exist') encoded = str( base64.b64encode( bcrypt.hashpw(key.encode('utf-8'), bcrypt.gensalt())), 'utf-8') rec['keys'][key_name] = encoded db.persist_namespace(namespace, rec) return key_name
def get(self, namespace=None): out = [] rec = db.get_namespace(namespace) for keyname in rec['keys']: out.append(keyname) return out