def moveRecursive(self, destpath): # INFO - G.M - 2018-12-11 - We only allow renaming if dirname(normpath( destpath)) == self.environ["http_authenticator.realm"]: # FIXME - G.M - 2018-12-11 - For an unknown reason current_workspace # of tracim_context is here invalid. self.tracim_context._current_workspace = self.workspace try: can_modify_workspace.check(self.tracim_context) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN, contextinfo=str(exc)) try: workspace_api = WorkspaceApi(current_user=self.user, session=self.session, config=self.provider.app_config) workspace_api.update_workspace( workspace=self.workspace, label=webdav_convert_file_name_to_bdd( basename(normpath(destpath))), description=self.workspace.description, ) self.session.add(self.workspace) self.session.flush() workspace_api.execute_update_workspace_actions(self.workspace) transaction.commit() except TracimException as exc: raise DAVError(HTTP_FORBIDDEN, contextinfo=str(exc))
def moveRecursive(self, destpath): """As we support recursive move, copymovesingle won't be called, though with copy it'll be called but i have to check if the client ever call that function...""" destpath = normpath(destpath) self.tracim_context.set_destpath(destpath) if normpath(dirname(destpath)) == normpath(dirname(self.path)): # INFO - G.M - 2018-12-12 - renaming case checker = is_contributor else: # INFO - G.M - 2018-12-12 - move case checker = can_move_content try: checker.check(self.tracim_context) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN, contextinfo=str(exc)) invalid_path = False invalid_path = dirname( destpath) == self.environ["http_authenticator.realm"] if not invalid_path: self.move_file(destpath) if invalid_path: raise DAVError(HTTP_FORBIDDEN)
def move_folder(self, destpath): workspace_api = WorkspaceApi( current_user=self.user, session=self.session, config=self.provider.app_config, ) destpath = normpath(destpath) self.tracim_context.set_destpath(destpath) if normpath(dirname(destpath)) == normpath(dirname(self.path)): # INFO - G.M - 2018-12-12 - renaming case checker = is_contributor else: # INFO - G.M - 2018-12-12 - move case checker = can_move_content try: checker.check(self.tracim_context) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN) destination_workspace = self.tracim_context.candidate_workspace try: destination_parent = self.tracim_context.candidate_parent_content except ContentNotFound as e: destination_parent = None try: with new_revision( content=self.content, tm=transaction.manager, session=self.session, ): if basename(destpath) != self.getDisplayName(): self.content_api.update_content( self.content, webdav_convert_file_name_to_bdd(basename(destpath))) self.content_api.save(self.content) else: if destination_workspace.workspace_id == self.content.workspace.workspace_id: self.content_api.move(self.content, destination_parent) else: self.content_api.move_recursively( self.content, destination_parent, destination_workspace) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN) from exc transaction.commit()
def move_folder(self, destpath): workspace_api = WorkspaceApi( current_user=self.user, session=self.session, config=self.provider.app_config, ) destpath = normpath(destpath) self.tracim_context.set_destpath(destpath) if normpath(dirname(destpath)) == normpath(dirname(self.path)): # INFO - G.M - 2018-12-12 - renaming case checker = is_contributor else: # INFO - G.M - 2018-12-12 - move case checker = can_move_content try: checker.check(self.tracim_context) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN) destination_workspace = self.tracim_context.candidate_workspace try: destination_parent = self.tracim_context.candidate_parent_content except ContentNotFound as e: destination_parent = None try: with new_revision( content=self.content, tm=transaction.manager, session=self.session, ): # renaming file if needed if basename(destpath) != self.getDisplayName(): self.content_api.update_content(self.content, webdav_convert_file_name_to_bdd(basename(destpath))) self.content_api.save(self.content) # move file if needed if destination_workspace != self.content.workspace or destination_parent != self.content.parent : self.content_api.move( self.content, new_parent=destination_parent, new_workspace=destination_workspace, must_stay_in_same_workspace=False ) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN) from exc transaction.commit()
def getResourceInst(self, path: str, environ: dict) -> typing.Optional[_DAVResource]: """ Called by wsgidav whenever a request is called to get the _DAVResource corresponding to the path """ path = normpath(path) tracim_context = environ["tracim_context"] tracim_context.set_path(path) current_path_resource_type = tracim_context.processed_path.current_path_resource_type # root if current_path_resource_type == ResourceType.ROOT: return resources.RootResource(path=path, environ=environ, tracim_context=tracim_context) if current_path_resource_type == ResourceType.WORKSPACE: workspace = tracim_context.current_workspace return get_workspace_resource( path=path, environ=environ, workspace=workspace, tracim_context=tracim_context, label=workspace.filemanager_filename, ) if current_path_resource_type == ResourceType.CONTENT: content = tracim_context.current_content return get_content_resource( path=path, environ=environ, workspace=content.workspace, content=content, tracim_context=tracim_context, ) return None
def move_folder(self, destpath: str): destpath = normpath(destpath) self.tracim_context.set_destpath(destpath) if normpath(dirname(destpath)) == normpath(dirname(self.path)): # INFO - G.M - 2018-12-12 - renaming case checker = is_contributor else: # INFO - G.M - 2018-12-12 - move case checker = can_move_content try: checker.check(self.tracim_context) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN, contextinfo=str(exc)) destination_workspace = self.tracim_context.candidate_workspace try: destination_parent = self.tracim_context.candidate_parent_content except ContentNotFound: destination_parent = None try: with new_revision(content=self.content, tm=transaction.manager, session=self.session): # renaming file if needed if basename(destpath) != self.getDisplayName(): self.content_api.update_content( self.content, webdav_convert_file_name_to_bdd(basename(destpath))) self.content_api.save(self.content) # move file if needed if (destination_workspace != self.content.workspace or destination_parent != self.content.parent): self.content_api.move( self.content, new_parent=destination_parent, new_workspace=destination_workspace, must_stay_in_same_workspace=False, ) self.content_api.execute_update_content_actions(self.content) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN, contextinfo=str(exc)) from exc transaction.commit()
def moveRecursive(self, destpath): # INFO - G.M - 2018-12-11 - We only allow renaming if dirname(normpath(destpath)) == self.environ['http_authenticator.realm']: # FIXME - G.M - 2018-12-11 - For an unknown reason current_workspace # of tracim_context is here invalid. self.tracim_context._current_workspace = self.workspace try: can_modify_workspace.check(self.tracim_context) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN) try: self.workspace.label = webdav_convert_file_name_to_bdd(basename(normpath(destpath))) self.session.add(self.workspace) self.session.flush() transaction.commit() except TracimException as exc: raise DAVError(HTTP_FORBIDDEN)
def copyMoveSingle(self, destpath, isMove): if isMove: # INFO - G.M - 12-03-2018 - This case should not happen # As far as moveRecursive method exist, all move should not go # through this method. If such case appear, try replace this to : #### # self.move_file(destpath) # return #### raise NotImplementedError("Feature not available") destpath = normpath(destpath) self.tracim_context.set_destpath(destpath) try: can_move_content.check(self.tracim_context) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN, contextinfo=str(exc)) content_in_context = self.content_api.get_content_in_context( self.content) try: self.content_api.check_upload_size(content_in_context.size or 0, self.content.workspace) except ( FileSizeOverMaxLimitation, FileSizeOverWorkspaceEmptySpace, FileSizeOverOwnerEmptySpace, ) as exc: raise DAVError(HTTP_REQUEST_ENTITY_TOO_LARGE, contextinfo=str(exc)) new_filename = webdav_convert_file_name_to_bdd(basename(destpath)) regex_file_extension = re.compile("(?P<label>.*){}".format( re.escape(self.content.file_extension))) same_extension = regex_file_extension.match(new_filename) if same_extension: new_label = same_extension.group("label") new_file_extension = self.content.file_extension else: new_label, new_file_extension = os.path.splitext(new_filename) self.tracim_context.set_destpath(destpath) destination_workspace = self.tracim_context.candidate_workspace try: destination_parent = self.tracim_context.candidate_parent_content except ContentNotFound: destination_parent = None try: new_content = self.content_api.copy( item=self.content, new_label=new_label, new_file_extension=new_file_extension, new_parent=destination_parent, new_workspace=destination_workspace, ) self.content_api.execute_created_content_actions(new_content) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN, contextinfo=str(exc)) from exc transaction.commit()
def exists(self, path, environ) -> bool: """ Called by wsgidav to check if a certain path is linked to a _DAVResource """ path = normpath(path) tracim_context = environ["tracim_context"] tracim_context.set_path(path) current_path_resource_type = tracim_context.processed_path.current_path_resource_type return current_path_resource_type is not None
def moveRecursive(self, destpath): # INFO - G.M - 2018-12-11 - We only allow renaming if dirname(normpath( destpath)) == self.environ['http_authenticator.realm']: # FIXME - G.M - 2018-12-11 - For an unknown reason current_workspace # of tracim_context is here invalid. self.tracim_context._current_workspace = self.workspace try: can_modify_workspace.check(self.tracim_context) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN) try: self.workspace.label = basename(normpath(destpath)) self.session.add(self.workspace) self.session.flush() transaction.commit() except TracimException as exc: raise DAVError(HTTP_FORBIDDEN)
def exists(self, path, environ) -> bool: """ Called by wsgidav to check if a certain path is linked to a _DAVResource """ tracim_context = environ["tracim_context"] tracim_context.set_path(path) path = normpath(path) working_path = tracim_context.reduce_path(path) root_path = environ["http_authenticator.realm"] parent_path = dirname(working_path) user = tracim_context.current_user session = tracim_context.dbsession if path == root_path: return True try: workspace = tracim_context.current_workspace except WorkspaceNotFound: workspace = None if parent_path == root_path or workspace is None: return workspace is not None # TODO bastien: Arnaud avait mis a True, verif le comportement # lorsque l'on explore les dossiers archive et deleted content_api = ContentApi( current_user=user, session=session, config=self.app_config, show_archived=False, show_deleted=False, namespaces_filter=[ContentNamespaces.CONTENT], ) revision_id = re.search(r"/\.history/[^/]+/\((\d+) - [a-zA-Z]+\) ([^/].+)$", path) is_archived = self.is_path_archive(path) is_deleted = self.is_path_delete(path) if revision_id: revision_id = revision_id.group(1) content = content_api.get_one_revision(revision_id) else: try: content = tracim_context.current_content except ContentNotFound: content = None return ( content is not None and content.is_deleted == is_deleted and content.is_archived == is_archived )
def exists(self, path, environ) -> bool: """ Called by wsgidav to check if a certain path is linked to a _DAVResource """ tracim_context = environ['tracim_context'] tracim_context.set_path(path) path = normpath(path) working_path = tracim_context.reduce_path(path) root_path = environ['http_authenticator.realm'] parent_path = dirname(working_path) user = tracim_context.current_user session = tracim_context.dbsession if path == root_path: return True try: workspace = tracim_context.current_workspace except WorkspaceNotFound: workspace = None if parent_path == root_path or workspace is None: return workspace is not None # TODO bastien: Arnaud avait mis a True, verif le comportement # lorsque l'on explore les dossiers archive et deleted content_api = ContentApi( current_user=user, session=session, config=self.app_config, show_archived=False, show_deleted=False ) revision_id = re.search(r'/\.history/[^/]+/\((\d+) - [a-zA-Z]+\) ([^/].+)$', path) is_archived = self.is_path_archive(path) is_deleted = self.is_path_delete(path) if revision_id: revision_id = revision_id.group(1) content = content_api.get_one_revision(revision_id) else: try: content = tracim_context.current_content except ContentNotFound: content = None return content is not None \ and content.is_deleted == is_deleted \ and content.is_archived == is_archived
def copyMoveSingle(self, destpath, isMove): if isMove: # INFO - G.M - 12-03-2018 - This case should not happen # As far as moveRecursive method exist, all move should not go # through this method. If such case appear, try replace this to : #### # self.move_file(destpath) # return #### raise NotImplemented('Feature not available') destpath = normpath(destpath) self.tracim_context.set_destpath(destpath) try: can_move_content.check(self.tracim_context) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN) new_filename = webdav_convert_file_name_to_bdd(basename(destpath)) regex_file_extension = re.compile( '(?P<label>.*){}'.format(re.escape(self.content.file_extension))) same_extension = regex_file_extension.match(new_filename) if same_extension: new_label = same_extension.group('label') new_file_extension = self.content.file_extension else: new_label, new_file_extension = os.path.splitext(new_filename) self.tracim_context.set_destpath(destpath) destination_workspace = self.tracim_context.candidate_workspace try: destination_parent = self.tracim_context.candidate_parent_content except ContentNotFound as e: destination_parent = None workspace = self.content.workspace parent = self.content.parent try: new_content = self.content_api.copy( item=self.content, new_label=new_label, new_file_extension=new_file_extension, new_parent=destination_parent, new_workspace=destination_workspace ) self.content_api.copy_children(self.content, new_content) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN) from exc transaction.commit()
def copyMoveSingle(self, destpath, isMove): if isMove: # INFO - G.M - 12-03-2018 - This case should not happen # As far as moveRecursive method exist, all move should not go # through this method. If such case appear, try replace this to : #### # self.move_file(destpath) # return #### raise NotImplemented('Feature not available') destpath = normpath(destpath) self.tracim_context.set_destpath(destpath) try: can_move_content.check(self.tracim_context) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN) new_filename = webdav_convert_file_name_to_bdd(basename(destpath)) regex_file_extension = re.compile('(?P<label>.*){}'.format( re.escape(self.content.file_extension))) same_extension = regex_file_extension.match(new_filename) if same_extension: new_label = same_extension.group('label') new_file_extension = self.content.file_extension else: new_label, new_file_extension = os.path.splitext(new_filename) self.tracim_context.set_destpath(destpath) destination_workspace = self.tracim_context.candidate_workspace try: destination_parent = self.tracim_context.candidate_parent_content except ContentNotFound as e: destination_parent = None workspace = self.content.workspace parent = self.content.parent try: new_content = self.content_api.copy( item=self.content, new_label=new_label, new_file_extension=new_file_extension, new_parent=destination_parent, new_workspace=destination_workspace) self.content_api.copy_children(self.content, new_content) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN) from exc transaction.commit()
def move_file(self, destpath: str) -> None: """ Move file mean changing the path to access to a file. This can mean simple renaming(1), moving file from a directory to one another(2) but also renaming + moving file from a directory to one another at the same time (3). (1): move /dir1/file1 -> /dir1/file2 (2): move /dir1/file1 -> /dir2/file1 (3): move /dir1/file1 -> /dir2/file2 :param destpath: destination path of webdav move :return: nothing """ workspace = self.content.workspace parent = self.content.parent destpath = normpath(destpath) self.tracim_context.set_destpath(destpath) if normpath(dirname(destpath)) == normpath(dirname(self.path)): # INFO - G.M - 2018-12-12 - renaming case checker = is_contributor else: # INFO - G.M - 2018-12-12 - move case checker = can_move_content try: checker.check(self.tracim_context) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN) try: with new_revision( content=self.content, tm=transaction.manager, session=self.session, ): # INFO - G.M - 2018-03-09 - First, renaming file if needed if basename(destpath) != self.getDisplayName(): new_filename = webdav_convert_file_name_to_bdd(basename(destpath)) regex_file_extension = re.compile( '(?P<label>.*){}'.format( re.escape(self.content.file_extension))) same_extension = regex_file_extension.match(new_filename) if same_extension: new_label = same_extension.group('label') new_file_extension = self.content.file_extension else: new_label, new_file_extension = os.path.splitext( new_filename) self.content_api.update_content( self.content, new_label=new_label, ) self.content.file_extension = new_file_extension self.content_api.save(self.content) # INFO - G.M - 2018-03-09 - Moving file if needed destination_workspace = self.tracim_context.candidate_workspace try: destination_parent = self.tracim_context.candidate_parent_content except ContentNotFound: destination_parent = None if destination_parent != parent or destination_workspace != workspace: # nopep8 # INFO - G.M - 12-03-2018 - Avoid moving the file "at the same place" # nopep8 # if the request does not result in a real move. self.content_api.move( item=self.content, new_parent=destination_parent, must_stay_in_same_workspace=False, new_workspace=destination_workspace ) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN) from exc transaction.commit()
def getResourceInst(self, path: str, environ: dict): """ Called by wsgidav whenever a request is called to get the _DAVResource corresponding to the path """ tracim_context = environ["tracim_context"] tracim_context.set_path(path) user = tracim_context.current_user session = tracim_context.dbsession if not self.exists(path, environ): return None path = normpath(path) root_path = tracim_context.root_path # If the requested path is the root, then we return a RootResource resource if path == root_path: return resources.RootResource(path=path, environ=environ, tracim_context=tracim_context) try: workspace = tracim_context.current_workspace except WorkspaceNotFound: workspace = None # If the request path is in the form root/name, then we return a WorkspaceResource resource parent_path = dirname(path) if parent_path == root_path: if not workspace: return None return resources.WorkspaceResource( path=path, environ=environ, workspace=workspace, tracim_context=tracim_context, label=workspace.label, ) # And now we'll work on the path to establish which type or resource is requested ContentApi( current_user=user, session=session, config=self.app_config, show_archived=False, # self._show_archive, show_deleted=False, # self._show_delete namespaces_filter=[ContentNamespaces.CONTENT], ) try: content = tracim_context.current_content except ContentNotFound: content = None # And if we're still going, the client is asking for a standard Folder/File/Page/Thread so we check the type7 # and return the corresponding resource if content is None: return None if content.type == content_type_list.Folder.slug: return resources.FolderResource( path=path, environ=environ, workspace=content.workspace, content=content, tracim_context=tracim_context, ) elif content.type == content_type_list.File.slug: return resources.FileResource( path=path, environ=environ, content=content, tracim_context=tracim_context, ) else: return resources.OtherFileResource( path=path, environ=environ, content=content, tracim_context=tracim_context, )
def _get_candidate_parent_content_path(self): return normpath(dirname(self._destpath))
def _get_content_path(self): return normpath(self.path)
def move_file(self, destpath: str) -> None: """ Move file mean changing the path to access to a file. This can mean simple renaming(1), moving file from a directory to one another(2) but also renaming + moving file from a directory to one another at the same time (3). (1): move /dir1/file1 -> /dir1/file2 (2): move /dir1/file1 -> /dir2/file1 (3): move /dir1/file1 -> /dir2/file2 :param destpath: destination path of webdav move :return: nothing """ workspace = self.content.workspace parent = self.content.parent destpath = normpath(destpath) self.tracim_context.set_destpath(destpath) if normpath(dirname(destpath)) == normpath(dirname(self.path)): # INFO - G.M - 2018-12-12 - renaming case checker = is_contributor else: # INFO - G.M - 2018-12-12 - move case checker = can_move_content try: checker.check(self.tracim_context) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN, contextinfo=str(exc)) try: with new_revision(content=self.content, tm=transaction.manager, session=self.session): # INFO - G.M - 2018-03-09 - First, renaming file if needed if basename(destpath) != self.getDisplayName(): new_filename = webdav_convert_file_name_to_bdd( basename(destpath)) regex_file_extension = re.compile("(?P<label>.*){}".format( re.escape(self.content.file_extension))) same_extension = regex_file_extension.match(new_filename) if same_extension: new_label = same_extension.group("label") new_file_extension = self.content.file_extension else: new_label, new_file_extension = os.path.splitext( new_filename) self.content_api.update_content(self.content, new_label=new_label) self.content.file_extension = new_file_extension self.content_api.save(self.content) # INFO - G.M - 2018-03-09 - Moving file if needed destination_workspace = self.tracim_context.candidate_workspace try: destination_parent = self.tracim_context.candidate_parent_content except ContentNotFound: destination_parent = None if destination_parent != parent or destination_workspace != workspace: # INFO - G.M - 12-03-2018 - Avoid moving the file "at the same place" # if the request does not result in a real move. self.content_api.move( item=self.content, new_parent=destination_parent, must_stay_in_same_workspace=False, new_workspace=destination_workspace, ) self.content_api.execute_update_content_actions(self.content) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN, contextinfo=str(exc)) from exc transaction.commit()
def moveRecursive(self, destpath): """As we support recursive move, copymovesingle won't be called, though with copy it'll be called but i have to check if the client ever call that function...""" destpath = normpath(destpath) self.tracim_context.set_destpath(destpath) if normpath(dirname(destpath)) == normpath(dirname(self.path)): # INFO - G.M - 2018-12-12 - renaming case checker = is_contributor else: # INFO - G.M - 2018-12-12 - move case checker = can_move_content try: checker.check(self.tracim_context) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN, contextinfo=str(exc)) invalid_path = False # if content is either deleted or archived, we'll check that we try moving it to the parent # if yes, then we'll unarchive / undelete them, else the action's not allowed if self.content.is_deleted or self.content.is_archived: # we remove all archived and deleted from the path and we check to the destpath # has to be equal or else path not valid # ex: /a/b/.deleted/resource, to be valid destpath has to be = /a/b/resource (no other solution) current_path = re.sub(r"/\.(deleted|archived)", "", self.path) if current_path == destpath: ManageActions( action_type=ActionDescription.UNDELETION if self.content.is_deleted else ActionDescription.UNARCHIVING, api=self.content_api, content=self.content, session=self.session, ).action() else: invalid_path = True # if the content is not deleted / archived, check if we're trying to delete / archive it by # moving it to a .deleted / .archived folder elif basename(dirname(destpath)) in [".deleted", ".archived"]: # same test as above ^ dest_path = re.sub(r"/\.(deleted|archived)", "", destpath) if dest_path == self.path: ManageActions( action_type=ActionDescription.DELETION if ".deleted" in destpath else ActionDescription.ARCHIVING, api=self.content_api, content=self.content, session=self.session, ).action() else: invalid_path = True # else we check if the path is good (not at the root path / not in a deleted/archived path) # and we move the content else: invalid_path = any(x in destpath for x in [".deleted", ".archived"]) invalid_path = invalid_path or any( x in self.path for x in [".deleted", ".archived"]) invalid_path = (invalid_path or dirname(destpath) == self.environ["http_authenticator.realm"]) if not invalid_path: self.move_file(destpath) if invalid_path: raise DAVError(HTTP_FORBIDDEN)
def getResourceInst(self, path: str, environ: dict): """ Called by wsgidav whenever a request is called to get the _DAVResource corresponding to the path """ tracim_context = environ['tracim_context'] tracim_context.set_path(path) user = tracim_context.current_user session = tracim_context.dbsession if not self.exists(path, environ): return None path = normpath(path) root_path = tracim_context.root_path # If the requested path is the root, then we return a RootResource resource if path == root_path: return resources.RootResource( path=path, environ=environ, tracim_context=tracim_context ) try: workspace = tracim_context.current_workspace except WorkspaceNotFound: workspace = None # If the request path is in the form root/name, then we return a WorkspaceResource resource parent_path = dirname(path) if parent_path == root_path: if not workspace: return None return resources.WorkspaceResource( path=path, environ=environ, workspace=workspace, tracim_context=tracim_context ) # And now we'll work on the path to establish which type or resource is requested content_api = ContentApi( current_user=user, session=session, config=self.app_config, show_archived=False, # self._show_archive, show_deleted=False, # self._show_delete ) try: content = tracim_context.current_content except ContentNotFound: content = None # And if we're still going, the client is asking for a standard Folder/File/Page/Thread so we check the type7 # and return the corresponding resource if content is None: return None if content.type == content_type_list.Folder.slug: return resources.FolderResource( path=path, environ=environ, workspace=content.workspace, content=content, tracim_context=tracim_context, ) elif content.type == content_type_list.File.slug: return resources.FileResource( path=path, environ=environ, content=content, tracim_context=tracim_context, ) else: return resources.OtherFileResource( path=path, environ=environ, content=content, tracim_context=tracim_context, )
def moveRecursive(self, destpath): """As we support recursive move, copymovesingle won't be called, though with copy it'll be called but i have to check if the client ever call that function...""" destpath = normpath(destpath) self.tracim_context.set_destpath(destpath) if normpath(dirname(destpath)) == normpath(dirname(self.path)): # INFO - G.M - 2018-12-12 - renaming case checker = is_contributor else: # INFO - G.M - 2018-12-12 - move case checker = can_move_content try: checker.check(self.tracim_context) except TracimException as exc: raise DAVError(HTTP_FORBIDDEN) invalid_path = False # if content is either deleted or archived, we'll check that we try moving it to the parent # if yes, then we'll unarchive / undelete them, else the action's not allowed if self.content.is_deleted or self.content.is_archived: # we remove all archived and deleted from the path and we check to the destpath # has to be equal or else path not valid # ex: /a/b/.deleted/resource, to be valid destpath has to be = /a/b/resource (no other solution) current_path = re.sub(r'/\.(deleted|archived)', '', self.path) if current_path == destpath: ManageActions( action_type=ActionDescription.UNDELETION if self.content.is_deleted else ActionDescription.UNARCHIVING, api=self.content_api, content=self.content, session=self.session, ).action() else: invalid_path = True # if the content is not deleted / archived, check if we're trying to delete / archive it by # moving it to a .deleted / .archived folder elif basename(dirname(destpath)) in ['.deleted', '.archived']: # same test as above ^ dest_path = re.sub(r'/\.(deleted|archived)', '', destpath) if dest_path == self.path: ManageActions( action_type=ActionDescription.DELETION if '.deleted' in destpath else ActionDescription.ARCHIVING, api=self.content_api, content=self.content, session=self.session, ).action() else: invalid_path = True # else we check if the path is good (not at the root path / not in a deleted/archived path) # and we move the content else: invalid_path = any(x in destpath for x in ['.deleted', '.archived']) invalid_path = invalid_path or any(x in self.path for x in ['.deleted', '.archived']) invalid_path = invalid_path or dirname(destpath) == self.environ['http_authenticator.realm'] if not invalid_path: self.move_file(destpath) if invalid_path: raise DAVError(HTTP_FORBIDDEN)