async def invite_user( workspace_name: str, invited_user: str, inviting_user: str = Depends(get_current_user), ) -> Message: """TODO function docstring""" workspace_data = workspace_db.get_workspace_data(workspace_name) if inviting_user["username"] != workspace_data["creator"]: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Only creator of the workspace can invite users", ) if not user_db.does_user_exist(invited_user): return Message(status=MsgStatus.ERROR, detail="Given user doesn't exists") if invited_user == workspace_data["creator"]: return Message(status=MsgStatus.ERROR, detail="Given user is already added to workspace") for element in workspace_data["permissions"]: if element["username"] == invited_user: return Message( status=MsgStatus.ERROR, detail="Given user is already added to workspace", ) workspace_db.change_user_permissions(workspace_name, invited_user, PermissionType.ALL) user_db.add_active_workspace(invited_user, workspace_name) return Message(status=MsgStatus.INFO, detail="User invited successfully")
def add_user(self, username: str, password_hash: str, email: str): """ Adds a new user to a database (only if a username isn't already taken). Parameters: username (str): username of the new user password_hash (str): hashed password of the new user email (str): email of the new user Returns: Message: the result of an attempted user addition (SUCCESS/FAILURE) with additional info """ if not is_non_empty_string((username, password_hash, email)): return Message(status=MsgStatus.ERROR, detail="Invalid parameter type detected") if self.does_user_exist(username): return Message(status=MsgStatus.INFO, detail="Given user already exists") self.database.insert({ "username": username, "password_hash": password_hash, "email": email, "profile_picture": None, "active_workspaces": [], }) return Message(status=MsgStatus.INFO, detail="User added successfully")
def edit_user_data(self, username, edited_field, new_value): """ Removes user from a database (only if user exists). Parameters: username (str): user we are editing edited_field (str): field we want to edit. Possible values: "username", "hashed_password", "email" new_value (str): new value of selected field Returns: Message: the result of an attempted user data edition (SUCCESS/FAILURE) with some additional info """ if not is_non_empty_string((username, new_value)): return Message(status=MsgStatus.ERROR, detail="Invalid parameter type detected") if not self.does_user_exist(username): return Message(status=MsgStatus.INFO, detail="Given user doesn't exists") if edited_field in ("password_hash", "username", "email", "profile_picture"): self.database.update({edited_field: new_value}, where("username") == username) return Message(status=MsgStatus.INFO, detail="User data edited successfully") return Message( status=MsgStatus.INFO, detail=f"Non-existent field type - {edited_field}", )
async def remove_file(path: Path): """ TODO function docstring """ if path.exists(): path.unlink() return Message(status=MsgStatus.INFO, detail="File removed successfuly") return Message(status=MsgStatus.ERROR, detail="No such file at given path")
def remove_active_workspace(self, username: str, workspace: str): """ TODO function docstring """ if not is_non_empty_string(username): return Message(status=MsgStatus.ERROR, detail="Invalid parameter type detected") user = self.database.get(where("username") == username) active_workspaces = user["active_workspaces"] active_workspaces.remove(workspace) self.database.update({"active_workspaces": active_workspaces}, where("username") == username) return Message(status=MsgStatus.INFO, detail="User active workspace updated successfully")
async def save_document_content(workspace_name: str, document_name: str, document_data: list) -> Message: """TODO function docstring""" path = get_document_path(workspace_name, document_name) / DOCUMENT_FILE with open(path, "w") as document_file: json.dump(document_data, document_file, indent=4) return Message(status=MsgStatus.INFO, detail="Document content updated successfully")
async def change_user_authentication_data( new_data: dict, user: dict = Depends(get_current_user)): """TODO function docstring""" for field in new_data: if field == "password": user_db.edit_user_data(user["username"], "password_hash", hash_password(new_data[field])) else: user_db.edit_user_data(user["username"], field, new_data[field]) return Message(status=MsgStatus.INFO, detail="User data updated successfully")
def get_user_data(self, username: str): """ Get user data from a database (only if user exists). Parameters: username (str): the user whose data we are interested in Returns: If extraction of the user data was successful: dict: {"username": x, "password_hash": x, "email": x} Otherwise: Message: information about the cause of failure """ if not is_non_empty_string(username): return Message(status=MsgStatus.ERROR, detail="Invalid parameter type detected") if self.does_user_exist(username): return self.database.get(where("username") == username) return Message(status=MsgStatus.INFO, detail="Given user doesn't exists")
def remove_user(self, username: str): """ Removes user from a database (only if user exists). Parameters: username (str): user to remove Returns: Message: the result of an attempted user deletion (SUCCESS/FAILURE) with some additional info """ if not is_non_empty_string(username): return Message(status=MsgStatus.ERROR, detail="Invalid parameter type detected") if not self.does_user_exist(username): return Message(status=MsgStatus.INFO, detail="Given user doesn't exists") self.database.remove(where("username") == username) return Message(status=MsgStatus.INFO, detail="User removed successfully")
async def remove_user( workspace_name: str, removed_user: str, removing_user: str = Depends(get_current_user), ) -> Message: """TODO function docstring""" workspace_data = workspace_db.get_workspace_data(workspace_name) if removing_user["username"] != workspace_data["creator"]: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Only creator of the workspace can remove users", ) if not user_db.does_user_exist(removed_user): return Message(status=MsgStatus.ERROR, detail="Given user doesn't exists") workspace_db.remove_user_from_workspace(workspace_name, removed_user) user_db.remove_active_workspace(removed_user, workspace_name) return Message(status=MsgStatus.INFO, detail="User removed successfully")
async def upload_file(file: UploadFile, path: Path): """ TODO function docstring """ contents = await file.read() await file.close() with open(path, "w+b") as new_file: new_file.write(contents) return Message( status=MsgStatus.INFO, detail="File uploaded successfuly", values={"upload_path": path}, )
async def remove_document( workspace_name: str, document_name: str, user: str = Depends(get_current_user)) -> Message: """TODO function docstring""" path = get_document_path(workspace_name, document_name) workspace_data = workspace_db.get_workspace_data(workspace_name) if user["username"] != workspace_data["creator"]: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Only creator of the workspace can delete it", ) workspace_db.remove_from_virtual_structure(workspace_name, document_name, "document") await clear_directory(path) return Message(status=MsgStatus.INFO, detail="Document removed successfully")
async def create_new_document( workspace_name: str, document_name: str, virtual_path: str, creator: str = Depends(get_current_user), ) -> Message: """ Create a new document in given workspace Parameters: workspace_name (str): name of the workspace that contains the document document_name (str): name of the new document virtual_path (str): path of the new document creator (str): username of the creator of the new document Returns: Message: details about result of operation Raises: HTTPException (409): if selected name collides with already existing document HTTPException (422): if selected name is incorrect """ if not fullmatch("[A-Za-z0-9-_]+", document_name): raise HTTPException( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail= "Document name must contain only upper and lower case characters, " + "numbers, and symbols - or _ ", ) path = (Path(".") / Directory.DATA.value / Directory.WORKSPACES.value / workspace_name / document_name) if path.exists(): raise HTTPException( status_code=status.HTTP_409_CONFLICT, detail= f"Document <<{document_name}>> already exists in workspace <<{workspace_name}>>", ) path.mkdir() (path / Directory.IMAGES.value).mkdir() (path / Directory.ATTACHMENTS.value).mkdir() empty_document = [{"type": "paragraph", "children": [{"text": " "}]}] with open(path / DOCUMENT_FILE, "w") as document_file: json.dump(empty_document, document_file, indent=4) workspace_db.add_to_virtual_structure(workspace_name, document_name, "document", virtual_path) return Message( status=MsgStatus.INFO, detail="Document created successfully", values={ "document_name": document_name, "creator": creator }, )