def exec_operations_delete(request_handler): """ Removes a file or folder from the localbox directory structure. called from the routing list :param request_handler: the object which has the file path json-encoded in its body """ request_handler.status = 200 user = request_handler.user pathstring = unquote_plus(request_handler.old_body).replace( "path=/", "", 1) bindpoint = get_bindpoint() filepath = join(bindpoint, user, pathstring) getLogger(__name__).debug('deleting %s' % filepath, extra=request_handler.get_log_dict()) if not exists(filepath): request_handler.status = 404 request_handler.body = "Error: No file exits at path" getLogger('api').error("failed to delete %s" % filepath, extra=request_handler.get_log_dict()) return if isdir(filepath): rmtree(filepath) else: remove(filepath) # remove keys sql = 'delete from keys where user = ? and path = ?' database_execute(sql, (user, get_key_path(user, localbox_path=pathstring))) SymlinkCache().remove(filepath)
def exec_edit_shares(request_handler): """ Edits the list of people who can access a certain share object. A list of json encoded identities is in the body to represent the new list of people with access to said share. Called via the routing list :param request_handler: the object which contains the share id in its path and list of users json-encoded in its body. """ share_start = request_handler.path.replace('/lox_api/shares/', '', 1) shareid = share_start.replace('/edit', '', 1) share = get_share_by_id(shareid) json = get_body_json(request_handler) symlinks = SymlinkCache() path = share.item.path links = symlinks.get(path) bindpoint = get_bindpoint() newlinks = [] for entry in json: to_file = join(bindpoint, entry.title, basename(entry.path)) newlinks.append(to_file) symlink(path, to_file) for link in links: if link not in newlinks: remove(link) symlinks.remove(link)
def exec_operations_create_folder(request_handler): """ Creates a new folder in the localbox directory structure. Called from the routing list :param request_handler: the object which has the path url-encoded in its body """ request_handler.status = 200 path = unquote_plus(request_handler.old_body).replace("path=/", "", 1) getLogger(__name__).info( "creating folder %s" % path, extra=localbox.utils.get_logging_extra(request_handler)) bindpoint = get_bindpoint() filepath = join(bindpoint, request_handler.user, path) if lexists(filepath): getLogger(__name__).error( "%s already exists" % path, extra=localbox.utils.get_logging_extra(request_handler)) request_handler.status = 409 # Http conflict request_handler.body = "Error: Something already exits at path" return makedirs(filepath) getLogger('api').info("created directory " + filepath, extra=request_handler.get_log_dict()) request_handler.body = dumps(stat_reader(filepath, request_handler.user))
def build_cache(self, path=None): """ Build the reverse symlink cache by walking through the filesystem and finding all symlinks and put them into a cache dictionary for reference later. """ working_directory = getcwd() if path is None: bindpoint = get_bindpoint() if bindpoint is None: getLogger('files').error( "No bindpoint found in the filesystem " "section of the configuration file, " "exiting") sysexit(1) else: bindpoint = path for dirname, directories, files in walk(bindpoint): for entry in directories + files: linkpath = abspath(join(dirname, entry)) if islink(linkpath): chdir(dirname) destpath = abspath(readlink(linkpath)) if destpath in self.cache: self.cache[destpath].append(linkpath) else: self.cache[destpath] = [linkpath] chdir(working_directory)
def build_cache(self, path=None): """ Build the reverse symlink cache by walking through the filesystem and finding all symlinks and put them into a cache dictionary for reference later. """ working_directory = getcwd() if path is None: bindpoint = get_bindpoint() if bindpoint is None: getLogger('files').error("No bindpoint found in the filesystem " "section of the configuration file, " "exiting") sysexit(1) else: bindpoint = path for dirname, directories, files in walk(bindpoint): for entry in directories + files: linkpath = abspath(join(dirname, entry)) if islink(linkpath): chdir(dirname) destpath = abspath(readlink(linkpath)) if destpath in self.cache: self.cache[destpath].append(linkpath) else: self.cache[destpath] = [linkpath] chdir(working_directory)
def create_user_home(user): """ Create user home directory (for storing LocalBox files), if necessary. :param user: username :return: """ user_folder = join(get_bindpoint(), user) if not exists(user_folder): mkdir_p(user_folder)
def exec_create_share(request_handler): """ Creates a 'share' within localbox. Comes down to creating a symlink next to a few database records to give the share an identifier. :param request_handler: object with the share filepath encoded in its path """ body = request_handler.old_body json_list = loads(body) getLogger(__name__).debug('request data: %s' % json_list, extra=request_handler.get_log_dict()) path2 = unquote_plus( request_handler.path.replace('/lox_api/share_create/', '', 1)) bindpoint = get_bindpoint() sender = request_handler.user from_file = join(bindpoint, sender, path2) getLogger(__name__).debug('from_file: %s' % from_file, extra=request_handler.get_log_dict()) # TODO: something something something group share = Share(sender, None, ShareItem(path=path2)) share.save_to_database() request_handler.status = 200 for json_object in json_list['identities']: if json_object['type'] == 'user': receiver = json_object['username'] to_file = join(bindpoint, receiver, path2) getLogger(__name__).debug('to_file: %s' % to_file, extra=request_handler.get_log_dict()) if exists(to_file): getLogger(__name__).error("destination " + to_file + " exists.", extra=request_handler.get_log_dict()) request_handler.status = 500 return if not exists(from_file): getLogger(__name__).error("source " + from_file + "does not exist.", extra=request_handler.get_log_dict()) request_handler.status = 500 return try: symlink(from_file, to_file) SymlinkCache().add(from_file, to_file) except OSError: getLogger('api').error("Error making symlink from " + from_file + " to " + to_file, extra=request_handler.get_log_dict()) request_handler.status = 500 invite = Invitation(None, 'pending', share, sender, receiver) invite.save_to_database()
def exec_leave_share(request_handler): """ Handle the leave_share call. Removes the share with the specified path for the current user. Returns 200 if succesful, 404 on failure. Called via the routing list. :param request_handler: object holding the path of the share to leave """ pathstart = request_handler.path.replace('/lox_api/shares/', '', 1) path = pathstart.replace('/leave', '', 1) bindpoint = get_bindpoint() linkpath = join(bindpoint, request_handler.user, path) if islink(linkpath): remove(linkpath) request_handler.status = 200 else: request_handler.status = 404
def get_filesystem_path(localbox_path, user): """ Given a LocalBox path (e.g. '/file_name'), return the corresponding filesystem path (e.g. '/var/localbox/data/user/file_name') :param localbox_path: the path relative to localbox' view :param user: the user for which to translate the path (the username is part of the path and hence cannot be omitted. :returns: a filesystem path to the resource pointed to by the localbox path """ while localbox_path.startswith('/'): localbox_path = localbox_path[1:] if ".." in localbox_path.split('/'): raise ValueError("No relative paths allowed in localbox") bindpoint = get_bindpoint() filepath = join(bindpoint, user, localbox_path) getLogger(__name__).debug('filesystem path: %s' % filepath, extra=get_logging_empty_extra()) return filepath
def exec_operations_move(request_handler): """ Moves a file within the localbox directory structure. Called from the routing list :param request_handler: the object which has the to_path and from_path json-encoded in its body """ json_object = loads(request_handler.old_body) bindpoint = get_bindpoint() move_from = join(bindpoint, request_handler.user, json_object['from_path']) move_to = join(bindpoint, request_handler.user, json_object['to_path']) if not isfile(move_from): request_handler.status = 404 request_handler.body = "Error: No file exits at from_path" return if lexists(move_to): request_handler.status = 404 request_handler.body = "Error: A file already exists at to_path" return move(move_from, move_to)
def exec_operations_copy(request_handler): """ copies a file within the localbox filesystem. Called from the routing list :param request_handler: object with to_path and from_path json-encoded in its body """ json_object = loads(request_handler.old_body) bindpoint = get_bindpoint() copy_from = join(bindpoint, request_handler.user, json_object['from_path']) copy_to = join(bindpoint, request_handler.user, json_object['to_path']) if not exists(copy_from): request_handler.status = 404 request_handler.body = "Error: No file exits at from_path" return if lexists(copy_to): request_handler.status = 404 request_handler.body = "Error: A file already exists at to_path" return copyfile(copy_from, copy_to) request_handler.status = 200
def get_bindpoint_user(user): return abspath(join(get_bindpoint(), user))