From 484905c24a1f429ff1eff1f982c6e666f83e7fde Mon Sep 17 00:00:00 2001 From: dumbmachine Date: Tue, 8 Sep 2020 22:04:23 +0530 Subject: [PATCH 1/5] Added removeUser and removeProject --- backend/routes/projects.py | 30 ++++++++++++++++ backend/routes/users.py | 31 ++++++++++++++++ frontend/src/pages/admin.js | 71 +++++++++++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+) diff --git a/backend/routes/projects.py b/backend/routes/projects.py index f89332a..680a50f 100644 --- a/backend/routes/projects.py +++ b/backend/routes/projects.py @@ -59,6 +59,36 @@ def create_project(): return jsonify(project_id=project.id, message="Project has been created!"), 201 +@api.route("/rmprojects", methods=["POST"]) +@jwt_required +def remove_project(): + identity = get_jwt_identity() + request_user = User.query.filter_by(username=identity["username"]).first() + is_admin = True if request_user.role.role == "admin" else False + + if is_admin == False: + return jsonify(message="Unauthorized access!"), 401 + + if not request.is_json: + return jsonify(message="Missing JSON in request"), 400 + + project_id = request.json.get("projectId", None) + + try: + project = Project.query.filter_by(id=project_id).first() + for data in Data.query.filter_by(project_id=project.id): + for segment in Segmentation.query.filter_by(data_id=data.id): + db.session.delete(segment) + db.session.delete(data) + db.session.delete(project) + db.session.commit() + except Exception as e: + app.logger.error("Error deleting project") + app.logger.error(e) + return jsonify(message="Error deleting project!"), 500 + + return jsonify(project_id=project_id, message="Project has been deleted!"), 201 + @api.route("/projects", methods=["GET"]) @jwt_required diff --git a/backend/routes/users.py b/backend/routes/users.py index 106eb70..9d7fe55 100644 --- a/backend/routes/users.py +++ b/backend/routes/users.py @@ -65,6 +65,37 @@ def create_user(): return jsonify(user_id=user.id, message="User has been created!"), 201 +@api.route("/rmusers", methods=["POST"]) +@jwt_required +def remove_user(): + # TODO: Make jwt user id based to expire user session if permissions are changed + identity = get_jwt_identity() + request_user = User.query.filter_by(username=identity["username"]).first() + is_admin = True if request_user.role.role == "admin" else False + if is_admin == False: + return jsonify(message="Unauthorized access!"), 401 + + if not request.is_json: + return jsonify(message="Missing JSON in request"), 400 + + try: + del_user_id = request.json['rmuserId'] + del_user = User.query.filter_by(id=del_user_id).first() + if del_user.id == request_user.id: + app.logger.error("Cannot delete self") + return jsonify(message="Cannot delete self!"), 500 + + db.session.delete(del_user) + db.session.commit() + except Exception as e: + app.logger.error("Error deleting user") + app.logger.error(e) + return jsonify(message="Error deleting user!"), 500 + + return jsonify(user_id=request_user.id, name=request_user.username, message="User has been deleted!"), 201 + + + @api.route("/users/", methods=["GET"]) @jwt_required def fetch_user(user_id): diff --git a/frontend/src/pages/admin.js b/frontend/src/pages/admin.js index 6d65c13..7c1ceae 100644 --- a/frontend/src/pages/admin.js +++ b/frontend/src/pages/admin.js @@ -9,6 +9,7 @@ import { faUserPlus, faTags, faDownload, + faTrash, } from "@fortawesome/free-solid-svg-icons"; import { IconButton } from "../components/button"; import Loader from "../components/loader"; @@ -86,6 +87,32 @@ class Admin extends React.Component { this.setState({ formType: "EDIT_USER", title: "Edit User", userId }); } + handleRemoveUser(e, rmuserId) { + console.log("We are removing the user: ", rmuserId); + axios({ + method: "post", + url: "/api/rmusers", + data: { + rmuserId + }, + }) + .then((response) => { + if (response.status === 201) { + this.setState({ successMessage: response.data.message }); + } + this.refreshPage(); + }) + .catch((error) => { + console.log(error.response); + this.setState({ + errorMessage: error.response.data.message, + successMessage: "", + isSubmitting: false, + }); + }); + } + + handleAddLabelsToProject(e, projectId) { const { history } = this.props; history.push(`/projects/${projectId}/labels`); @@ -165,6 +192,31 @@ class Admin extends React.Component { }); } + handleDeleteProject(e, projectId) { + console.log("will delete: ", projectId); + axios({ + method: "post", + url: "/api/rmprojects", + data: { + projectId, + }, + }) + .then((response) => { + if (response.status === 201) { + this.setState({ successMessage: response.data.message }); + } + this.refreshPage(); + }) + .catch((error) => { + console.log(error.response); + this.setState({ + errorMessage: error.response.data.message, + successMessage: "", + isSubmitting: false, + }); + }); + } + setModalShow(modalShow) { this.setState({ modalShow }); } @@ -272,6 +324,17 @@ class Admin extends React.Component { ) } /> + + this.handleDeleteProject( + e, + project["project_id"] + ) + } + /> ); @@ -330,6 +393,14 @@ class Admin extends React.Component { this.handleEditUser(e, user["user_id"]) } /> + + this.handleRemoveUser(e, user["user_id"]) + } + /> {/* Date: Wed, 9 Sep 2020 00:08:38 +0530 Subject: [PATCH 2/5] Added removeDatapoint --- backend/routes/data.py | 45 ++++++++++++++++++++++++++++++++++ frontend/src/pages/annotate.js | 40 ++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/backend/routes/data.py b/backend/routes/data.py index ba0c5ec..8a58e2c 100644 --- a/backend/routes/data.py +++ b/backend/routes/data.py @@ -1,3 +1,4 @@ +import os import json import sqlalchemy as sa import uuid @@ -190,3 +191,47 @@ def add_data(): ), 201, ) + + +@api.route("/rmdata", methods=["POST"]) +@jwt_required +def remove_data(): + identity = get_jwt_identity() + request_user = User.query.filter_by(username=identity["username"]).first() + is_admin = True if request_user.role.role == "admin" else False + if is_admin == False: + return jsonify(message="Unauthorized access!"), 401 + + if not request.is_json: + return jsonify(message="Missing JSON in request"), 400 + + data_id = request.json['dataId'] + project_id = request.json['projectId'] + + app.logger.info(f"This is something: {data_id} : {project_id}") + + try: + data = Data.query.filter_by(id=data_id, project_id=project_id).first() + for segment in Segmentation.query.filter_by(data_id=data.id): + db.session.delete(segment) + db.session.delete(data) + + # delete the file of the folder + filename = data.filename + os.remove( + path=Path(app.config["UPLOAD_FOLDER"]).joinpath(filename) + ) + except Exception as e: + app.logger.error("Error deleting datapoint") + app.logger.error(e) + return jsonify(message="Error deleting datapoint!"), 500 + + db.session.commit() + + return ( + jsonify( + message=f"Data deleted", + type="DATA_DELETED", + ), + 201, + ) diff --git a/frontend/src/pages/annotate.js b/frontend/src/pages/annotate.js index b887110..d98d072 100644 --- a/frontend/src/pages/annotate.js +++ b/frontend/src/pages/annotate.js @@ -347,6 +347,39 @@ class Annotate extends React.Component { }); } + handleDeleteData(e) { + const { dataId, projectId } = this.state; + const { history } = this.props; + console.log("Data to be detelted: ", dataId); + axios({ + method: "post", + url: "/api/rmdata", + data: { + dataId, + projectId + }, + }) + .then((response) => { + if (response.status === 201) { + this.setState({ successMessage: response.data.message }); + } + // TODO: Then revert to the index page + console.log("history ", history); + history.replace({ pathname: "/empty" }); + setTimeout(() => { + history.replace({ pathname: `/projects/${projectId}/data` }); + }); + }) + .catch((error) => { + console.log(error.response); + this.setState({ + errorMessage: error.response.data.message, + successMessage: "", + isSubmitting: false, + }); + }); + } + render() { const { zoom, @@ -575,6 +608,13 @@ class Annotate extends React.Component { > Mark for review +