def ver_cb(ver): def new_remote_key_cb(remote_keys): logging.debug("IndxSync link_remote_box, new_remote_key_cb, remote_keys: {0}".format(remote_keys)) # NB: no "private" in remote_keys, that never leaves the remote box. remote_keys = remote_keys['data'] # remove the Indx HTTP response padding remote_encpk = remote_keys['encpk2'] if type(remote_encpk) != type(""): remote_encpk = json.dumps(remote_encpk) remote_serverid = remote_keys['serverid'] link_uid = uuid.uuid1() local_key_uid = uuid.uuid1() remote_key_uid = uuid.uuid1() status1_uid = uuid.uuid1() status2_uid = uuid.uuid1() link_uri = "link-{0}".format(link_uid) status1_uri = "status-{0}".format(status1_uid) status2_uri = "status-{0}".format(status2_uid) # objects get updated to local box, and then synced across to the other boxes once the syncing starts new_objs = [ { "@id": link_uri, "type": [ {"@value": NS_ROOT_BOX + "link"} ], "boxes": [ {"@id": "box-{0}".format(local_key_uid)}, # links to the objs below {"@id": "box-{0}".format(remote_key_uid)}, # links to the objs below ], "statuses": [ {"@id": status1_uri}, {"@id": status2_uri} ], }, { "@id": status1_uri, "type": [ {"@value": NS_ROOT_BOX + "status"} ], "src-boxid": [ {"@value": remote_box} ], "src-server-url": [ {"@value": remote_address} ], "dst-boxid": [ {"@value": self.root_store.boxid} ], "dst-server-url": [ {"@value": self.url} ], "last-version-seen": [ {"@value": ver + 1} ], #we save this because we will push our whole box to it in a sec - it is incremented because the version is before we put this in }, { "@id": status2_uri, "type": [ {"@value": NS_ROOT_BOX + "status"} ], "dst-boxid": [ {"@value": remote_box} ], "dst-server-url": [ {"@value": remote_address} ], "src-boxid": [ {"@value": self.root_store.boxid} ], "src-server-url": [ {"@value": self.url} ], }, { "@id": "box-{0}".format(local_key_uid), "type": [ {"@value": NS_ROOT_BOX + "box"} ], "server-url": [ {"@value": self.url } ], "server-id": [ {"@value": server_id } ], "box": [ {"@value": self.root_store.boxid} ], "key": [ {"@id": local_keys['public-hash']}], # links to the key objs below }, { "@id": "box-{0}".format(remote_key_uid), "type": [ {"@value": NS_ROOT_BOX + "box"} ], "server-url": [ {"@value": remote_address } ], "server-id": [ {"@value": remote_serverid } ], "box": [ {"@value": remote_box} ], "key": [ {"@id": remote_keys['public-hash']}], # links to the key objs below }, { "@id": local_keys['public-hash'], "type": [ {"@value": NS_ROOT_BOX + "key"} ], "public-key": [ {"@value": local_keys['public']} ], # share the full public keys everywhere (private keys only in respective server's keystores) "public-hash": [ {"@value": local_keys['public-hash']} ], # share the full public keys everywhere (private keys only in respective server's keystores) }, { "@id": remote_keys['public-hash'], "type": [ {"@value": NS_ROOT_BOX + "key"} ], "public-key": [ {"@value": remote_keys['public']} ], # share the full public keys everywhere "public-hash": [ {"@value": remote_keys['public-hash']} ], # share the full public keys everywhere }, ] def update_cb(empty): def diff_cb(diff): def applied_cb(empty): def encpk_cb(empty): def remote_added_cb(empty): def local_added_cb(empty): logging.debug("IndxSync link_remote_box, local_added_cb") def added_indx_cb(empty): # start syncing/connecting using the new key self.sync_boxes([link_uri], include_push_all = True).addCallbacks(lambda empty: return_d.callback(remote_keys['public']), return_d.errback) self.database.save_linked_box(self.root_store.boxid).addCallbacks(added_indx_cb, return_d.errback) # add the local key to the local store self.keystore.put(local_keys, local_user, self.root_store.boxid).addCallbacks(local_added_cb, return_d.errback) # store in the local keystore self.keystore.put({"public": remote_keys['public'], "private": "", "public-hash": remote_keys['public-hash']}, local_user, self.root_store.boxid).addCallbacks(remote_added_cb, return_d.errback) # don't save the local encpk2 here, only give it to the remote server. # save the remote encpk2 self.database.save_encpk2(sha512_hash(remote_encpk), remote_encpk, remote_serverid).addCallbacks(encpk_cb, return_d.errback) client.apply_diff(diff).addCallbacks(applied_cb, return_d.errback) self.root_store.diff(0, None, "diff").addCallbacks(diff_cb, return_d.errback) self.root_store.update(new_objs, ver, propagate = True).addCallbacks(update_cb, return_d.errback) client = IndxClient(remote_address, remote_box, self.APPID, token = remote_token) client.generate_new_key(local_keys, local_encpk, server_id).addCallbacks(new_remote_key_cb, return_d.errback)
class CLIClient: def __init__(self, appid = "INDX CLIClient"): """ Associate command-line actions with functions, and enforce required variables. """ self.actions = {'create_box': {'f': self.create_box, 'args': ['box']}, 'delete_box': {'f': self.delete_box, 'args': ['box']}, 'list_boxes': {'f': self.list_boxes, 'args': []}, 'get_object_ids': {'f': self.get_object_ids, 'args': ['box']}, 'create_user': {'f': self.create_user, 'args': ['target_username','target_password']}, 'update': {'f': self.update, 'args': ['box','data','version']}, 'delete': {'f': self.delete, 'args': ['box','id','version']}, 'get_latest': {'f': self.get_latest, 'args': ['box']}, 'get_by_ids': {'f': self.get_by_ids, 'args': ['box','id']}, 'query': {'f': self.query, 'args': ['box','query']}, 'diff': {'f': self.diff, 'args': ['box','from','return_objs']}, #'listen': {'f': self.listen, 'args': ['box']}, 'add_file': {'f': self.add_file, 'args': ['box','data','id','version','contenttype']}, 'delete_file': {'f': self.delete_file, 'args': ['box','id','version']}, 'get_file': {'f': self.get_file, 'args': ['box','id']}, 'list_files': {'f': self.list_files, 'args': ['box']}, 'set_acl': {'f': self.set_acl, 'args': ['box','acl','target_username']}, 'get_acls': {'f': self.get_acls, 'args': ['box']}, 'generate_new_key': {'f': self.generate_new_key, 'args': ['box']}, 'create_root_box': {'f': self.create_root_box, 'args': ['box']}, 'link_remote_box': {'f': self.link_remote_box, 'args': ['box', 'remote_token', 'remote_box', 'remote_address']}, 'generate_token': {'f': self.generate_token, 'args': ['box']}, } self.token = None self.appid = appid self.indx = None def set_args(self, args): """ Move relevant command-line arguments into local variable. """ logging.debug("Set args: {0}".format(args)) self.args = args """ Flatten single value lists into flat key/value pair. """ for key in args: if type(args[key]) == type([]) and len(args[key]) == 1: args[key] = args[key][0] """ Ensure self.server always ends in a / """ if self.args['server'][-1:] != "/": self.args['server'] += "/" def check_args(self, required): not_set = [] for key in required: if key not in self.args or self.args[key] is None or self.args[key] == "": not_set.append(key) if not self.args['allowempty'] and len(not_set) > 0: raise Exception("The following values cannot be empty for this action: {0}".format(", ".join(not_set))) def auth_and_get_token(self, get_token): """ Authenticate, get a token and call it back to the deferred. """ return_d = Deferred() def authed_cb(): def token_cb(token): if token is not None: self.token = token return_d.callback(token) else: return_d.callback(None) if get_token: authclient.get_token(self.args['box']).addCallbacks(token_cb, return_d.errback) else: token_cb(None) authclient = IndxClientAuth(self.args['server'], self.appid) self.client = authclient.client authclient.auth_plain(self.args['username'], self.args['password']).addCallbacks(lambda response: authed_cb(), return_d.errback) return return_d def call_action(self, name, *args, **kwargs): """ Calls an action by name. """ return_d = Deferred() action = self.actions[name] f = action['f'] self.check_args(action['args']) def do_call(): f(*args, **kwargs).addCallbacks(lambda status: return_d.callback(self.parse_status(name, status)), return_d.errback) if not self.token: def token_cb(token): if not self.indx: self.indx = IndxClient(self.args['server'], self.args['box'], self.appid, token = token, client = self.client) do_call() self.auth_and_get_token(IndxClient.requires_token(f)).addCallbacks(token_cb, return_d.errback) else: do_call() return return_d def parse_status(self, source, status): """ Parse the status returned from the server, and raise an Exception if necessary. """ if status is not None: # status is None when a file has been printed raw if status['code'] < 200 or status['code'] > 299: raise Exception("{0} in box {1} failed. Response is {2} with code {3}".format(source, self.args['box'], status['message'], status['code'])) else: if "data" in status and self.args['jsondata']: return json.dumps(status['data'], indent = 2) else: pretty = pprint.pformat(status, indent=2, width=80) logging.info("{0} in box {1} successful, return is: {2}".format(source, self.args['box'], pretty)) return None """ Test functions.""" def create_box(self): """ Test to create a box. """ logging.debug("Creating box: '{0}' on server '{1}'".format(self.args['box'], self.args['server'])) return self.indx.create_box() def delete_box(self): """ Test to delete a box. """ logging.debug("Deleting box: '{0}' on server '{1}'".format(self.args['box'], self.args['server'])) return self.indx.delete_box() def list_boxes(self): """ List the boxes on the INDX server. """ logging.debug("Listing boxes on server '{0}'".format(self.args['server'])) return self.indx.list_boxes() def get_object_ids(self): """ Get the IDs of every object in this box. """ logging.debug("Getting a list of object IDs on server '{0}' in box '{1}'".format(self.args['server'], self.args['box'])) return self.indx.get_object_ids() def update(self): """ Test to update objects in a box. """ logging.debug("Updating data to box: '{0}' on server '{1}'".format(self.args['box'], self.args['server'])) #return self.indx.update(self.args['version'], cjson.decode(self.args['data'].read()), all_unicode=True) return self.indx.update(self.args['version'], json.loads(self.args['data'].read())) def delete(self): """ Test to delete objects from a box. 'id' argument should be a list of ids e.g., --id=id1 --id=id2 """ logging.debug("Deleting data to box: '{0}' on server '{1}'".format(self.args['box'], self.args['server'])) return self.indx.delete(self.args['version'], self.args['id']) def get_latest(self): """ Get the latest version of every object in this box. """ logging.debug("Getting latest objects on server '{0}' in box '{1}'".format(self.args['server'], self.args['box'])) return self.indx.get_latest() def get_by_ids(self): """ Get the latest version of specific objects in this box. """ logging.debug("Getting latest objects on server '{0}' in box '{1}'".format(self.args['server'], self.args['box'])) ids = self.args['id'] if type(ids) != type([]): ids = [ids] # put a single id into an array return self.indx.get_by_ids(ids) def query(self): """ Query this box. e.g., query="{ '@id': 2983 }" or query="{ 'firstname': 'dan' }" """ logging.debug("Querying server '{0}' in box '{1}' with depth '{2}'".format(self.args['server'], self.args['box'], self.args['depth'])) return self.indx.query(self.args['query'], depth = int(self.args['depth'])) def diff(self): """ Run a diff of two version of this box. """ logging.debug("Calling diff on server '{0}' in box '{1}'".format(self.args['server'], self.args['box'])) to_version = None if "to" in self.args and self.args['to'] is not None: to_version = self.args['to'] return self.indx.diff(self.args['return_objs'], self.args['from'], to_version = to_version) # def listen(self): # """ Listen to updates to the database (locally, not with HTTP) and print out the diff in realtime. """ # self.check_args(['box', 'username', 'password']) # # def observer(notify): # print "Version updated to: {0}".format(notify.payload) # # def err_cb(failure): # logging.error("Error in test listen: {0}".format(failure)) # reactor.stop() # # def connected_cb(conn): # print "Listening..." # conns = {"conn": conn} # store = ObjectStoreAsync(conns, self.args['username'], self.appid, "127.0.0.1") # TODO get the IP a better way? does it matter here? # store.listen(observer) # # d = database.connect_box_raw(self.args['box'], self.args['username'], self.args['password']) # d.addCallbacks(connected_cb, err_cb) # reactor.run() def add_file(self): """ Add a file to the database. """ logging.debug("Adding a file to server '{0}' in box '{1}', with id: {2}".format(self.args['server'], self.args['box'], self.args['id'])) return self.indx.add_file(self.args['version'], self.args['id'], self.args['data'].read(), self.args['contenttype']) def delete_file(self): """ Delete a file from the database. """ logging.debug("Deleting a file from server '{0}' in box '{1}', with id: {2}".format(self.args['server'], self.args['box'], self.args['id'])) return self.indx.delete_file(self.args['version'], self.args['id']) def get_file(self): """ Get a file from the database. """ logging.debug("Calling get_file on server '{0}' in box '{1}'".format(self.args['server'], self.args['box'])) # returns the file to stdout so it can be piped to a file print self.indx.get_file(self.args['id']) def list_files(self): """ Get a list of the files from the database. """ logging.debug("Calling list_files on server '{0}' in box '{1}'".format(self.args['server'], self.args['box'])) return self.indx.list_files() def set_acl(self): """ Set an ACL for a target user for a database. """ logging.debug("Calling set_acl on server '{0}' in box '{1}'".format(self.args['server'], self.args['box'])) return self.indx.set_acl(self.args['acl'], self.args['target_username']) def get_acls(self): """ Get ACLs for a database. """ logging.debug("Calling get_acls on server '{0}' in box '{1}'".format(self.args['server'], self.args['box'])) return self.indx.get_acls() def generate_new_key(self): """ Generate and store a new key, returning the public and public-hash parts of the key. """ logging.debug("Calling generate_new_key on server '{0}' in box '{1}'".format(self.args['server'], self.args['box'])) return self.indx.generate_new_key() def create_root_box(self): """ Create root box for a user. """ logging.debug("Calling create_root_box on server '{0}' for box '{1}'".format(self.args['server'], self.args['box'])) return self.indx.create_root_box(self.args['box']) def create_user(self): """ Create a new user. """ logging.debug("Calling create_user on server '{0}' with target username '{1}'".format(self.args['server'], self.args['target_username'])) return self.indx.create_user(self.args['target_username'], self.args['target_password']) def link_remote_box(self): """ Link a remote box with a local box. """ logging.debug("Calling link_remote_box on remote_address '{0}', remote_box '{1}', remote_token '{2}'".format(self.args['remote_address'], self.args['remote_box'], self.args['remote_token'])) return self.indx.link_remote_box(self.args['remote_address'], self.args['remote_box'], self.args['remote_token']) def generate_token(self): """ Generate a token for this box, and print it. """ logging.debug("Calling generate_token on box {0}.".format(self.args['box'])) return_d = Deferred() def token_cb(token): return_d.callback({"code": 200, "data": token}) self.auth_and_get_token(True).addCallbacks(token_cb, return_d.errback) return return_d
class CLIClient: def __init__(self, appid="INDX CLIClient"): """ Associate command-line actions with functions, and enforce required variables. """ self.actions = { 'create_box': { 'f': self.create_box, 'args': ['box'] }, 'delete_box': { 'f': self.delete_box, 'args': ['box'] }, 'list_boxes': { 'f': self.list_boxes, 'args': [] }, 'get_object_ids': { 'f': self.get_object_ids, 'args': ['box'] }, 'create_user': { 'f': self.create_user, 'args': ['target_username', 'target_password'] }, 'update': { 'f': self.update, 'args': ['box', 'data', 'version'] }, 'update_json': { 'f': self.update_json, 'args': ['box', 'data', 'version'] }, 'update_raw': { 'f': self.update_raw, 'args': ['box', 'data', 'version'] }, 'delete': { 'f': self.delete, 'args': ['box', 'id', 'version'] }, 'get_latest': { 'f': self.get_latest, 'args': ['box'] }, 'get_by_ids': { 'f': self.get_by_ids, 'args': ['box', 'id'] }, 'query': { 'f': self.query, 'args': ['box', 'query'] }, 'diff': { 'f': self.diff, 'args': ['box', 'from', 'return_objs'] }, #'listen': {'f': self.listen, 'args': ['box']}, 'add_file': { 'f': self.add_file, 'args': ['box', 'data', 'id', 'version', 'contenttype'] }, 'delete_file': { 'f': self.delete_file, 'args': ['box', 'id', 'version'] }, 'get_file': { 'f': self.get_file, 'args': ['box', 'id'] }, 'list_files': { 'f': self.list_files, 'args': ['box'] }, 'set_acl': { 'f': self.set_acl, 'args': ['box', 'acl', 'target_username'] }, 'set_acl_public': { 'f': self.set_acl_public, 'args': ['box', 'acl'] }, 'get_acls': { 'f': self.get_acls, 'args': ['box'] }, 'generate_new_key': { 'f': self.generate_new_key, 'args': ['box'] }, 'create_root_box': { 'f': self.create_root_box, 'args': ['box'] }, 'link_remote_box': { 'f': self.link_remote_box, 'args': ['box', 'remote_token', 'remote_box', 'remote_address'] }, 'generate_token': { 'f': self.generate_token, 'args': ['box'] }, } self.token = None self.appid = appid self.indx = None def set_args(self, args): """ Move relevant command-line arguments into local variable. """ logging.debug("Set args: {0}".format(args)) self.args = args """ Flatten single value lists into flat key/value pair. """ for key in args: if type(args[key]) == type([]) and len(args[key]) == 1: args[key] = args[key][0] """ Ensure self.server always ends in a / """ if self.args['server'][-1:] != "/": self.args['server'] += "/" def check_args(self, required): not_set = [] for key in required: if key not in self.args or self.args[key] is None or self.args[ key] == "": not_set.append(key) if not self.args['allowempty'] and len(not_set) > 0: raise Exception( "The following values cannot be empty for this action: {0}". format(", ".join(not_set))) def auth_and_get_token(self, get_token): """ Authenticate, get a token and call it back to the deferred. """ return_d = Deferred() def authed_cb(): def token_cb(token): if token is not None: self.token = token return_d.callback(token) else: return_d.callback(None) if get_token: authclient.get_token(self.args['box']).addCallbacks( token_cb, return_d.errback) else: token_cb(None) authclient = IndxClientAuth(self.args['server'], self.appid) self.client = authclient.client authclient.auth_plain(self.args['username'], self.args['password']).addCallbacks( lambda response: authed_cb(), return_d.errback) return return_d def call_action(self, name, *args, **kwargs): """ Calls an action by name. """ return_d = Deferred() action = self.actions[name] f = action['f'] self.check_args(action['args']) def do_call(): f(*args, **kwargs).addCallbacks( lambda status: return_d.callback( self.parse_status(name, status)), return_d.errback) if not self.token: def token_cb(token): if not self.indx: self.indx = IndxClient(self.args['server'], self.args['box'], self.appid, token=token, client=self.client) do_call() self.auth_and_get_token(IndxClient.requires_token(f)).addCallbacks( token_cb, return_d.errback) else: do_call() return return_d def parse_status(self, source, status): """ Parse the status returned from the server, and raise an Exception if necessary. """ if status is not None: # status is None when a file has been printed raw if status['code'] < 200 or status['code'] > 299: raise Exception( "{0} in box {1} failed. Response is {2} with code {3}". format(source, self.args['box'], status['message'], status['code'])) else: if "data" in status and self.args['jsondata']: return json.dumps(status['data'], indent=2) else: pretty = pprint.pformat(status, indent=2, width=80) logging.info( "{0} in box {1} successful, return is: {2}".format( source, self.args['box'], pretty)) return None """ Test functions.""" def create_box(self): """ Test to create a box. """ logging.debug("Creating box: '{0}' on server '{1}'".format( self.args['box'], self.args['server'])) return self.indx.create_box() def delete_box(self): """ Test to delete a box. """ logging.debug("Deleting box: '{0}' on server '{1}'".format( self.args['box'], self.args['server'])) return self.indx.delete_box() def list_boxes(self): """ List the boxes on the INDX server. """ logging.debug("Listing boxes on server '{0}'".format( self.args['server'])) return self.indx.list_boxes() def get_object_ids(self): """ Get the IDs of every object in this box. """ logging.debug( "Getting a list of object IDs on server '{0}' in box '{1}'".format( self.args['server'], self.args['box'])) return self.indx.get_object_ids() def update(self): """ Test to update objects in a box. """ logging.debug("Updating data to box: '{0}' on server '{1}'".format( self.args['box'], self.args['server'])) #return self.indx.update(self.args['version'], cjson.decode(self.args['data'].read()), all_unicode=True) return self.indx.update(self.args['version'], json.loads(self.args['data'].read())) def update_json(self): """ Test to update json objects in a box. """ logging.debug("Updating data to box: '{0}' on server '{1}'".format( self.args['box'], self.args['server'])) #return self.indx.update(self.args['version'], cjson.decode(self.args['data'].read()), all_unicode=True) return self.indx.update_json(self.args['version'], json.loads(self.args['data'].read())) def update_raw(self): """ Test to update raw objects in a box. """ logging.debug("Updating raw data to box: '{0}' on server '{1}'".format( self.args['box'], self.args['server'])) #return self.indx.update(self.args['version'], cjson.decode(self.args['data'].read()), all_unicode=True) return self.indx.update_raw(self.args['version'], json.loads(self.args['data'].read())) def delete(self): """ Test to delete objects from a box. 'id' argument should be a list of ids e.g., --id=id1 --id=id2 """ logging.debug("Deleting data to box: '{0}' on server '{1}'".format( self.args['box'], self.args['server'])) return self.indx.delete(self.args['version'], self.args['id']) def get_latest(self): """ Get the latest version of every object in this box. """ logging.debug( "Getting latest objects on server '{0}' in box '{1}'".format( self.args['server'], self.args['box'])) return self.indx.get_latest() def get_by_ids(self): """ Get the latest version of specific objects in this box. """ logging.debug( "Getting latest objects on server '{0}' in box '{1}'".format( self.args['server'], self.args['box'])) ids = self.args['id'] if type(ids) != type([]): ids = [ids] # put a single id into an array return self.indx.get_by_ids(ids) def query(self): """ Query this box. e.g., query="{ '@id': 2983 }" or query="{ 'firstname': 'dan' }" """ logging.debug( "Querying server '{0}' in box '{1}' with depth '{2}'".format( self.args['server'], self.args['box'], self.args['depth'])) return self.indx.query(self.args['query'], depth=int(self.args['depth'])) def diff(self): """ Run a diff of two version of this box. """ logging.debug("Calling diff on server '{0}' in box '{1}'".format( self.args['server'], self.args['box'])) to_version = None if "to" in self.args and self.args['to'] is not None: to_version = self.args['to'] return self.indx.diff(self.args['return_objs'], self.args['from'], to_version=to_version) # def listen(self): # """ Listen to updates to the database (locally, not with HTTP) and print out the diff in realtime. """ # self.check_args(['box', 'username', 'password']) # # def observer(notify): # print "Version updated to: {0}".format(notify.payload) # # def err_cb(failure): # logging.error("Error in test listen: {0}".format(failure)) # reactor.stop() # # def connected_cb(conn): # print "Listening..." # conns = {"conn": conn} # store = ObjectStoreAsync(conns, self.args['username'], self.appid, "127.0.0.1") # TODO get the IP a better way? does it matter here? # store.listen(observer) # # d = database.connect_box_raw(self.args['box'], self.args['username'], self.args['password']) # d.addCallbacks(connected_cb, err_cb) # reactor.run() def add_file(self): """ Add a file to the database. """ logging.debug( "Adding a file to server '{0}' in box '{1}', with id: {2}".format( self.args['server'], self.args['box'], self.args['id'])) return self.indx.add_file(self.args['version'], self.args['id'], self.args['data'].read(), self.args['contenttype']) def delete_file(self): """ Delete a file from the database. """ logging.debug( "Deleting a file from server '{0}' in box '{1}', with id: {2}". format(self.args['server'], self.args['box'], self.args['id'])) return self.indx.delete_file(self.args['version'], self.args['id']) def get_file(self): """ Get a file from the database. """ logging.debug("Calling get_file on server '{0}' in box '{1}'".format( self.args['server'], self.args['box'])) # returns the file to stdout so it can be piped to a file print self.indx.get_file(self.args['id']) def list_files(self): """ Get a list of the files from the database. """ logging.debug("Calling list_files on server '{0}' in box '{1}'".format( self.args['server'], self.args['box'])) return self.indx.list_files() def set_acl(self): """ Set an ACL for a target user for a database. """ logging.debug("Calling set_acl on server '{0}' in box '{1}'".format( self.args['server'], self.args['box'])) return self.indx.set_acl(self.args['acl'], self.args['target_username']) def set_acl_public(self): """ Set an ACL for the public uer for a database. """ logging.debug( "Calling set_acl_public on server '{0}' in box '{1}'".format( self.args['server'], self.args['box'])) return self.indx.set_acl_public(self.args['acl']) def get_acls(self): """ Get ACLs for a database. """ logging.debug("Calling get_acls on server '{0}' in box '{1}'".format( self.args['server'], self.args['box'])) return self.indx.get_acls() def generate_new_key(self): """ Generate and store a new key, returning the public and public-hash parts of the key. """ logging.debug( "Calling generate_new_key on server '{0}' in box '{1}'".format( self.args['server'], self.args['box'])) return self.indx.generate_new_key() def create_root_box(self): """ Create root box for a user. """ logging.debug( "Calling create_root_box on server '{0}' for box '{1}'".format( self.args['server'], self.args['box'])) return self.indx.create_root_box(self.args['box']) def create_user(self): """ Create a new user. """ logging.debug( "Calling create_user on server '{0}' with target username '{1}'". format(self.args['server'], self.args['target_username'])) return self.indx.create_user(self.args['target_username'], self.args['target_password']) def link_remote_box(self): """ Link a remote box with a local box. """ logging.debug( "Calling link_remote_box on remote_address '{0}', remote_box '{1}', remote_token '{2}'" .format(self.args['remote_address'], self.args['remote_box'], self.args['remote_token'])) return self.indx.link_remote_box(self.args['remote_address'], self.args['remote_box'], self.args['remote_token']) def generate_token(self): """ Generate a token for this box, and print it. """ logging.debug("Calling generate_token on box {0}.".format( self.args['box'])) return_d = Deferred() def token_cb(token): return_d.callback({"code": 200, "data": token}) self.auth_and_get_token(True).addCallbacks(token_cb, return_d.errback) return return_d