From 5df9053e9110849a96310d21f32c297c65eb5f01 Mon Sep 17 00:00:00 2001 From: Lorenzo Balugani Date: Sat, 1 May 2021 14:25:50 +0200 Subject: [PATCH] Several fixes Now all the tests should pass. --- .../nest_backend/database/tables/Alert.py | 4 ++-- .../nest_backend/database/tables/Condition.py | 2 +- .../database/tables/Repository.py | 8 ++++---- .../nest_backend/database/tables/Tweet.py | 4 ++-- .../nest_backend/database/tables/User.py | 4 ++-- code/backend/nest_backend/gestione.py | 16 ++++++++++----- .../routes/repository/repository.py | 12 ++++++++--- .../repository/repository_conditions.py | 2 ++ .../backend/nest_backend/routes/users/user.py | 20 +++++++++---------- 9 files changed, 43 insertions(+), 29 deletions(-) diff --git a/code/backend/nest_backend/database/tables/Alert.py b/code/backend/nest_backend/database/tables/Alert.py index ff9a7a3..b8506f8 100644 --- a/code/backend/nest_backend/database/tables/Alert.py +++ b/code/backend/nest_backend/database/tables/Alert.py @@ -15,5 +15,5 @@ class Alert(Base.Model): repository_id = Base.Column(Base.Integer, Base.ForeignKey("repository.id"), nullable=False) # Relationships repository = Base.relationship("Repository", back_populates="alerts") - notifications = Base.relationship("Notification", back_populates="alert") - operations = Base.relationship("BoolOperation", back_populates="alert") \ No newline at end of file + notifications = Base.relationship("Notification", back_populates="alert", cascade="all, delete") + operations = Base.relationship("BoolOperation", back_populates="alert", cascade="all, delete") \ No newline at end of file diff --git a/code/backend/nest_backend/database/tables/Condition.py b/code/backend/nest_backend/database/tables/Condition.py index cb16d3f..2124534 100644 --- a/code/backend/nest_backend/database/tables/Condition.py +++ b/code/backend/nest_backend/database/tables/Condition.py @@ -12,7 +12,7 @@ class Condition(Base.Model): type = Base.Column(Base.Enum(ConditionType), nullable=False) content = Base.Column(Base.String, nullable=False) # Relationships - used = Base.relationship("Uses", back_populates="condition") + used = Base.relationship("Uses", back_populates="condition", cascade="all, delete") tweets = Base.relationship("Contains", back_populates="condition") operations = Base.relationship("BoolOperation", back_populates="condition") diff --git a/code/backend/nest_backend/database/tables/Repository.py b/code/backend/nest_backend/database/tables/Repository.py index 7e830f3..5fee71e 100644 --- a/code/backend/nest_backend/database/tables/Repository.py +++ b/code/backend/nest_backend/database/tables/Repository.py @@ -20,10 +20,10 @@ class Repository(Base.Model): # Relationships owner = Base.relationship("User", back_populates="owner_of") - authorizations = Base.relationship("Authorization", back_populates="repository") - tweets = Base.relationship("Composed", back_populates="repository") - alerts = Base.relationship("Alert", back_populates="repository") - uses = Base.relationship("Uses", back_populates="repository") + authorizations = Base.relationship("Authorization", back_populates="repository", cascade="all, delete") + tweets = Base.relationship("Composed", back_populates="repository", cascade="all, delete") + alerts = Base.relationship("Alert", back_populates="repository", cascade="all, delete") + uses = Base.relationship("Uses", back_populates="repository", cascade="all, delete") def to_json(self): return { diff --git a/code/backend/nest_backend/database/tables/Tweet.py b/code/backend/nest_backend/database/tables/Tweet.py index e90c25c..333875c 100644 --- a/code/backend/nest_backend/database/tables/Tweet.py +++ b/code/backend/nest_backend/database/tables/Tweet.py @@ -12,5 +12,5 @@ class Tweet(Base.Model): location = Base.Column(Base.String) # Todo: see if a dedicated class for locations is needed. This is likely. poster = Base.Column(Base.String) # Todo: see if a dedicated class for posters is needed. # Relationships - repositories = Base.relationship("Composed", back_populates="tweet") - conditions = Base.relationship("Contains", back_populates="tweet") \ No newline at end of file + repositories = Base.relationship("Composed", back_populates="tweet", cascade="all, delete") + conditions = Base.relationship("Contains", back_populates="tweet", cascade="all, delete") \ No newline at end of file diff --git a/code/backend/nest_backend/database/tables/User.py b/code/backend/nest_backend/database/tables/User.py index b59e2a9..f5695ad 100644 --- a/code/backend/nest_backend/database/tables/User.py +++ b/code/backend/nest_backend/database/tables/User.py @@ -12,8 +12,8 @@ class User(Base.Model): password = Base.Column(Base.LargeBinary, nullable=False) isAdmin = Base.Column(Base.Boolean, default=False) # Relationships - owner_of = Base.relationship("Repository", back_populates="owner") - authorizations = Base.relationship("Authorization", back_populates="user") + owner_of = Base.relationship("Repository", back_populates="owner", cascade="all, delete") + authorizations = Base.relationship("Authorization", back_populates="user", cascade="all, delete") def to_json(self): return {'email': self.email, 'username': self.username, 'isAdmin': self.isAdmin} diff --git a/code/backend/nest_backend/gestione.py b/code/backend/nest_backend/gestione.py index 6be7d5b..7b213a1 100644 --- a/code/backend/nest_backend/gestione.py +++ b/code/backend/nest_backend/gestione.py @@ -68,15 +68,17 @@ def repository_auth(f): @functools.wraps(f) def func(*args, **kwargs): user = find_user(get_jwt_identity()) - repository_id = request.json.get("id") + repository_id = kwargs["rid"] if not repository_id: return json_error("Missing one or more parameters."), 400 - repository = Repository.query.filter_by(id=repository_id) + repository = Repository.query.filter_by(id=repository_id).first() if not repository: return json_error("Cant't find the repository."), 404 - if repository.owner_id != user.email and user.email not in [a.email for a in repository.authorizations]: + if repository.owner_id != user.email and user.email not in [a.email for a in + repository.authorizations] and not user.isAdmin: return json_error("Stop right there, criminal scum! Nobody accesses protected data under MY watch!"), 403 return f(*args, **kwargs) + return func @@ -99,5 +101,9 @@ def json_success(data): def error_handler(e): - print(f"{e.description} - {e.code}") - return json_error(f"{e.description} - {e.code}") + try: + print(f"{e.description} - {e.code}") + return json_error(f"{e.description} - {e.code}"), 500 + except Exception: + print(e) + return json_error(f"{e.__repr__()}"), 500 diff --git a/code/backend/nest_backend/routes/repository/repository.py b/code/backend/nest_backend/routes/repository/repository.py index 861e2b4..e405bc5 100644 --- a/code/backend/nest_backend/routes/repository/repository.py +++ b/code/backend/nest_backend/routes/repository/repository.py @@ -18,6 +18,8 @@ def page_repository(rid): """ user = find_user(get_jwt_identity()) repository = Repository.query.filter_by(id=rid).first() + if not repository: + return json_error("Could not find repository."), 404 if request.method == "GET": return json_success(repository.to_json()), 200 elif request.method == "PATCH": @@ -33,8 +35,12 @@ def page_repository(rid): Base.session.commit() return json_success(repository.to_json()), 200 elif request.method == "DELETE": - if repository.owner_id != user.email: + if repository.owner_id != user.email and not user.isAdmin: return json_error("You are not the owner of this repository."), 403 - Base.session.delete(repository) - Base.session.commit() + try: + Base.session.delete(repository) + Base.session.commit() + except Exception as e: + Base.session.rollback() + return json_error("Cant delete repository because of dependencies.") return json_success("Success"), 200 \ No newline at end of file diff --git a/code/backend/nest_backend/routes/repository/repository_conditions.py b/code/backend/nest_backend/routes/repository/repository_conditions.py index ab553bf..582411f 100644 --- a/code/backend/nest_backend/routes/repository/repository_conditions.py +++ b/code/backend/nest_backend/routes/repository/repository_conditions.py @@ -16,6 +16,8 @@ def page_repository_conditions(rid): """ repository = Repository.query.filter_by(rid=rid).first() + if not repository: + return json_error("Could not find repository"), 404 user = find_user(get_jwt_identity()) if user.email != repository.owner_id: diff --git a/code/backend/nest_backend/routes/users/user.py b/code/backend/nest_backend/routes/users/user.py index 19e65d0..d2317dd 100644 --- a/code/backend/nest_backend/routes/users/user.py +++ b/code/backend/nest_backend/routes/users/user.py @@ -15,32 +15,32 @@ def page_user(email): + DELETE: deletes the specified user. """ user = find_user(get_jwt_identity()) + target = find_user(email) + if not target: + return json_error("Could not locate the user."), 404 if request.method == "GET": if not email == user.email and not user.isAdmin: return json_error("Thou art not authorized."), 403 - target = find_user(email).to_json() - if not target: - return json_error("Could not locate the user."), 404 - return json_success(target) + return json_success(target.to_json()) elif request.method == "DELETE": if not user.isAdmin: return json_error("User is not admin."), 403 - target = find_user(email) - if not target: - return json_error("User not found."), 404 if user == target: return json_error("The user cant delete himself. Its a sin."), 406 Base.session.delete(target) - Base.session.commit() + try: + Base.session.commit() + except Exception: + Base.session.rollback() + return json_error("Could not delete the user."), 500 return json_success("The user has been deleted.") elif request.method == "PATCH": if not email == user.email and not user.isAdmin: return json_error("Thou art not authorized."), 403 target = find_user(email) - if not target: - return json_error("Could not locate the user."), 404 if request.json.get("username"): target.username = request.json.get("username") if request.json.get("password"): target.password = gen_password(request.json.get("password")) Base.session.commit() + return json_success(target.to_json())