1
Fork 0
mirror of https://github.com/pds-nest/nest.git synced 2024-11-25 14:34:19 +00:00

Add error codes for localization purposes

This commit is contained in:
Lorenzo Balugani 2021-05-17 16:19:32 +02:00
parent c13e5fff40
commit 38ad3673a4
13 changed files with 103 additions and 62 deletions

View file

@ -21,6 +21,7 @@ class InputLoginSchema(Schema):
class ErrorSchema(Schema):
result = fields.String(description="Contains a string that informs if the procedure was successful.")
msg = fields.String(description="Contains a description of the error.")
code = fields.String(description="Error code")
class SuccesSchema(Schema):

27
nest_backend/errors.py Normal file
View file

@ -0,0 +1,27 @@
# User errors
USER_NOT_FOUND = "errorUserNotFound" # Could not find user
USER_WRONG_CREDENTIALS = "errorUserWrongCredentials" # User has given incorrect pair of credentials
USER_NOT_AUTHORIZED = "errorUserNotAuthorized" # User is not authorized to proceed
USER_NOT_ADMIN = "errorUserNotAdmin" # User is not an admin
USER_PREVENT_SEPPUKU = "errorUserPreventSeppuku" # User cannot delete himself
USER_DELETION_ERROR = "errorDeletionError" # Something is preventing the deletion of the user
# Generic
GENERIC_NOT_FOUND = "errorNotFound" # Generic 404
GENERIC_MISSING_FIELDS = "errorMissingFields" # Generic 400
GENERIC_ALREADY_EXISTS = "errorAlreadyExists" # Generic primary key error
GENERIC_ENUM_INVALID = "errorEnumInvalid" # The given integer is not a valid one
GENERIC_UFO = "errorUnknownError" # The classic 'the hell is this' error
GENERIC_NO_JSON = "errorNoJson" # No JSON was given
# Repository
REPOSITORY_NOT_FOUND = "errorRepositoryNotFound" # Repository not found
REPOSITORY_NOT_OWNER = "errorRepositoryNotOwner" # The user is not the repository owner
REPOSITORY_DEPENDENCY_FAILURE = "errorRepositoryDepencencyFailure" # Something is preventing the repo to go away
# Conditions
CONDITION_NOT_FOUND = "errorConditionNotFound" # Condition not found.
# Alerts
ALERT_NOT_FOUND = "errorAlertNotFound" # Alert not found
ALERT_NO_NAME = "errorAlertNoName" # Missing name entry
ALERT_NO_LIMIT = "errorAlertNoLimit" # Missing limit entry
ALERT_NO_WINDOW = "errorAlertNoWindow" # Missing window entry
ALERT_NO_EVALUATION = "errorAlertNoEvaluation" # Missing evalmode entry
ALERT_DELETION_FAILURE = "errorAlertDeletionFailure" # Error while deleting alerts

View file

@ -8,6 +8,7 @@ import functools
from flask_jwt_extended import get_jwt_identity
from flask import jsonify
from re import sub
from .errors import GENERIC_UFO
__all__ = ["authenticate", "identity", "gen_password", "find_user", "admin_or_403",
"repository_auth", "json_request_authorizer", "json_error",
@ -84,13 +85,14 @@ def repository_auth(f):
return func
def json_error(msg):
def json_error(msg, code=GENERIC_UFO):
"""
Returns an error in json format
:param code: the code of the error according to the spec.
:param msg: the error message.
:return: a json formatted string.
"""
return jsonify({"result": "failure", 'msg': msg})
return jsonify({"result": "failure", 'msg': msg, 'code':code})
def json_success(data):

View file

@ -4,6 +4,7 @@ from flask_jwt_extended import jwt_required, get_jwt_identity
from nest_backend.gestione import *
from flask_cors import cross_origin
import datetime
from nest_backend.errors import *
@cross_origin()
@ -113,16 +114,14 @@ def page_alert(aid):
"""
user = find_user(get_jwt_identity())
alert = Alert.query.filter_by(id=aid).first()
if alert.repository_id not in user.owner_of:
return json_error("The user is not authorized."), 403
if not alert:
return json_error("Could not find alert."), 404
return json_error("Could not find alert.", ALERT_NOT_FOUND), 404
if alert.repository not in [a.repository for a in user.authorizations] + user.owner_of:
return json_error("You are not authorized to proceed."), 403
return json_error("You are not authorized to proceed.", USER_NOT_AUTHORIZED), 403
if request.method == "GET":
return json_success(alert.to_json()), 200
if alert.repository not in user.owner_of:
return json_error("You are not authorized to proceed."), 403
return json_error("You are not authorized to proceed.", REPOSITORY_NOT_OWNER), 403
if request.method == "PATCH":
if 'name' in request.json:
alert.name = request.json['name']
@ -137,11 +136,11 @@ def page_alert(aid):
ext.session.delete(alert)
ext.session.commit()
except Exception:
return json_error("Something went wrong while deleting alert."), 500
return json_error("Something went wrong while deleting alert.", ALERT_DELETION_FAILURE), 500
return json_success("Deletion completed."), 204
elif request.method == "PUT":
if not json_request_authorizer(request.json, alert):
return json_error("Missing one or more parameters in repository json."), 400
return json_error("Missing one or more parameters in repository json.", GENERIC_MISSING_FIELDS), 400
alert.limit = request.json['limit']
alert.name = request.json['name']
alert.window_size = request.json['window_size']
@ -149,14 +148,14 @@ def page_alert(aid):
try:
alert.evaluation_mode = ConditionMode(mode)
except KeyError:
return json_error("Unknown `type` specified."), 400
return json_error("Unknown `type` specified.", GENERIC_ENUM_INVALID), 400
except Exception as e:
return json_error("Unknown error:" + str(e)), 400
return json_error("Unknown error:" + str(e), GENERIC_UFO), 400
if request.json['conditions'] is not None:
# Possibile vulnearabilità! Un utente potrebbe aggiungere conditions non del suo repo!
for c in request.json['conditions']:
if c['id'] not in alert.repository.conditions:
return json_error("Stop! You violated the law!"), 403
return json_error("Stop! You violated the law!", USER_NOT_AUTHORIZED), 403
# Wow very pythonic so much wow
# Obtain list of no longer needed connections
to_be_deleted = [c.cid for c in alert.conditions if

View file

@ -3,6 +3,7 @@ from nest_backend.database import *
from flask_jwt_extended import jwt_required, get_jwt_identity
from nest_backend.gestione import *
from flask_cors import cross_origin
from nest_backend.errors import *
@cross_origin()
@ -69,30 +70,30 @@ def page_repository_alerts(rid):
repository = Repository.query.filter_by(id=rid).first()
if not repository:
return json_error("Could not find repository"), 404
return json_error("Could not find repository", REPOSITORY_NOT_FOUND), 404
user = find_user(get_jwt_identity())
if user.email != repository.owner_id:
return json_error("You are not authorized."), 403
return json_error("You are not authorized.", REPOSITORY_NOT_OWNER), 403
if request.method == "GET":
return json_success([alert.to_json() for alert in repository.alerts])
if request.method == "POST":
if 'name' not in request.json:
return json_error("Missing name."), 400
return json_error("Missing name.", ALERT_NO_NAME), 400
if 'limit' not in request.json:
return json_error('Missing limit'), 400
return json_error('Missing limit', ALERT_NO_LIMIT), 400
if 'window_size' not in request.json:
return json_error('Missing window size'), 400
return json_error('Missing window size', ALERT_NO_WINDOW), 400
if (mode := request.json.get("evaluation_mode")) is not None:
try:
mode = ConditionMode(mode)
except KeyError:
return json_error("Unknown `type` specified."), 400
return json_error("Unknown `type` specified.", GENERIC_ENUM_INVALID), 400
except Exception as e:
return json_error("Unknown error:" + str(e)), 400
return json_error("Unknown error:" + str(e), GENERIC_UFO), 400
else:
return json_error("Evaluation mode was not provided."), 400
return json_error("Evaluation mode was not provided.", ALERT_NO_EVALUATION), 400
alert = Alert(name=request.json['name'], limit=request.json['limit'], window_size=request.json['window_size'],
repository_id=rid, evaluation_mode=mode)
@ -102,7 +103,7 @@ def page_repository_alerts(rid):
for condition in request.json['conditions']:
c = Condition.query.filter_by(id=condition['id']).first()
if not c:
return json_error("Could not locate condition."), 404
return json_error("Could not locate condition.", CONDITION_NOT_FOUND), 404
conn = MadeOf(aid=alert.id, cid=c.id)
ext.session.add(conn)
ext.session.commit()

View file

@ -3,6 +3,7 @@ from nest_backend.database import *
from flask_jwt_extended import jwt_required, get_jwt_identity
from nest_backend.gestione import *
from flask_cors import cross_origin
from nest_backend.errors import *
@cross_origin()
@ -106,25 +107,25 @@ def page_condition(cid):
condition = Condition.query.filter_by(id=cid).first()
user = find_user(get_jwt_identity())
if not condition:
return json_error("Could not find the condition."), 404
return json_error("Could not find the condition.", CONDITION_NOT_FOUND), 404
if condition.repository not in [a.repository for a in user.authorizations] + user.owner_of and not user.isAdmin:
return json_error("You lack the authorization to proceed, pal."), 403
return json_error("You lack the authorization to proceed, pal.", USER_NOT_AUTHORIZED), 403
if request.method == "GET":
return json_success(condition.to_json()), 200
if condition.repository not in user.owner_of and not user.isAdmin:
return json_error("You lack the authorization to proceed, pal."), 403
return json_error("You lack the authorization to proceed, pal.", USER_NOT_AUTHORIZED), 403
if request.method == "PATCH":
if request.json is None:
return json_error("Missing json content."), 400
return json_error("Missing json content.", GENERIC_NO_JSON), 400
if (type_ := request.json.get("type")) is not None:
try:
type_ = ConditionType(type_)
condition.type = type_
except KeyError:
return json_error("Unknown `type` specified."), 400
return json_error("Unknown `type` specified.", GENERIC_ENUM_INVALID), 400
except Exception as e:
return json_error("Unknown error:" + str(e)), 400
return json_error("Unknown error:" + str(e), GENERIC_UFO), 400
if content := request.json.get("content"):
condition.content = content

View file

@ -5,6 +5,7 @@ from nest_backend.gestione import repository_auth, json_error, json_success, Con
from nest_backend.database import ext
from flask_cors import cross_origin
from nest_backend.gestione import hashtag_validator
from nest_backend.errors import *
@cross_origin()
@ -74,34 +75,34 @@ def page_repository_conditions(rid):
repository = Repository.query.filter_by(id=rid).first()
if not repository:
return json_error("Could not find repository"), 404
return json_error("Could not find repository", REPOSITORY_NOT_FOUND), 404
user = find_user(get_jwt_identity())
if user.email != repository.owner_id:
return json_error("You are not authorized."), 403
return json_error("You are not authorized.", REPOSITORY_NOT_OWNER), 403
if request.method == "GET":
try:
return json_success([u.to_json() for u in repository.conditions])
except Exception as e:
return json_error("Unknown error:" + str(e)), 400
return json_error("Unknown error:" + str(e), GENERIC_UFO), 400
if request.method == "POST":
if request.json is None:
return json_error("Missing json content."), 400
return json_error("Missing json content.", GENERIC_NO_JSON), 400
if (type_ := request.json.get("type")) is None:
return json_error("Missing `type` parameter."), 400
return json_error("Missing `type` parameter.", GENERIC_MISSING_FIELDS), 400
try:
type_ = ConditionType(type_)
except KeyError:
return json_error("Unknown `type` specified."), 400
return json_error("Unknown `type` specified.", GENERIC_ENUM_INVALID), 400
except Exception as e:
return json_error("Unknown error: " + str(e)), 400
if not (content := request.json.get("content")):
return json_error("Missing `content` parameter."), 400
return json_error("Missing `content` parameter.", GENERIC_MISSING_FIELDS), 400
if type_ == ConditionType.hashtag:
content = hashtag_validator(content)
condition = Condition(content=content, type=type_, repository_id=rid)

View file

@ -4,6 +4,7 @@ from flask_jwt_extended import jwt_required, get_jwt_identity
from nest_backend.gestione import *
import datetime
from flask_cors import cross_origin
from nest_backend.errors import *
@cross_origin()
@ -75,23 +76,27 @@ def page_repositories():
# Users will be tolerated if they change parameters they're not supposed to touch. We'll ignore them for now.
if not request.json.get("name") or not request.json.get("conditions") or not str(
request.json.get("evaluation_mode")):
return json_error("Missing arguments."), 400
return json_error("Missing arguments.", GENERIC_MISSING_FIELDS), 400
name = request.json.get("name")
try:
evaluation_mode = ConditionMode(request.json['evaluation_mode'])
except: # KeyError
return json_error("Unknown `type` specified."), 400
except KeyError:
return json_error("Unknown `type` specified.", GENERIC_ENUM_INVALID), 400
repository = Repository(name=name, owner_id=user.email, is_active=False, evaluation_mode=evaluation_mode)
ext.session.add(repository)
ext.session.commit()
ids = [c['id'] for c in request.json['conditions'] if c['id']]
conditions = [c for c in repository.conditions if c.id not in [a['id'] for a in request.json['conditions'] if
a['id'] in [b.id for b in repository.conditions]]]
for c in conditions:
ext.session.delete(c)
ext.session.commit()
# Create brand new conditions
for c in request.json['conditions']:
if not c['id']:
try:
type_ = ConditionType(c['type'])
except KeyError:
return json_error("Unknown `type` specified."), 400
return json_error("Unknown `type` specified.", GENERIC_ENUM_INVALID), 400
ext.session.add(Condition(type=type_, content=c['content'], repository_id=repository.id))
ext.session.commit()
repository.is_active = True

View file

@ -4,7 +4,7 @@ from flask_jwt_extended import jwt_required, get_jwt_identity
from nest_backend.gestione import *
from flask_cors import cross_origin
import datetime
from nest_backend.errors import *
@cross_origin()
@ -156,12 +156,12 @@ 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
return json_error("Could not find repository.", REPOSITORY_NOT_FOUND), 404
if request.method == "GET":
return json_success(repository.to_json()), 200
elif request.method == "PATCH":
if repository.owner_id != user.email:
return json_error("You are not the owner of this repository."), 403
return json_error("You are not the owner of this repository.", REPOSITORY_NOT_OWNER), 403
if 'name' in request.json:
repository.name = request.json['name']
if 'close' in request.json and not repository.end and repository.is_active:
@ -173,28 +173,28 @@ def page_repository(rid):
try:
evaluation_mode = ConditionMode(request.json['evaluation_mode'])
except KeyError:
return json_error("Unknown `type` specified."), 400
return json_error("Unknown `type` specified.", GENERIC_ENUM_INVALID), 400
repository.evaluation_mode = evaluation_mode
ext.session.commit()
return json_success(repository.to_json()), 204
elif request.method == "DELETE":
if repository.owner_id != user.email and not user.isAdmin:
return json_error("You are not the owner of this repository."), 403
return json_error("You are not the owner of this repository.", REPOSITORY_NOT_OWNER), 403
try:
ext.session.delete(repository)
ext.session.commit()
except Exception as e:
ext.session.rollback()
return json_error("Cant delete repository because of dependencies."), 500
return json_error("Cant delete repository because of dependencies.", REPOSITORY_DEPENDENCY_FAILURE), 500
return json_success("Success"), 204
elif request.method == "PUT":
if not json_request_authorizer(request.json, repository):
return json_error("Missing one or more parameters in repository json."), 400
return json_error("Missing one or more parameters in repository json.", GENERIC_MISSING_FIELDS), 400
# Users will be tolerated if they change parameters they're not supposed to touch. We'll ignore them for now.
try:
evaluation_mode = ConditionMode(request.json['evaluation_mode'])
except KeyError:
return json_error("Unknown `type` specified."), 400
return json_error("Unknown `type` specified.", GENERIC_ENUM_INVALID), 400
repository.evaluation_mode = evaluation_mode
repository.name = request.json['name']
repository.is_active = request.json['is_active']
@ -210,7 +210,7 @@ def page_repository(rid):
try:
type_ = ConditionType(c['type'])
except KeyError:
return json_error("Unknown `type` specified."), 400
return json_error("Unknown `type` specified.", GENERIC_ENUM_INVALID), 400
content = c['content']
if type_ == ConditionType.hashtag:
content = hashtag_validator(content)

View file

@ -5,6 +5,7 @@ from nest_backend.gestione import repository_auth, json_error, json_success, Con
from nest_backend.database import ext
from flask_cors import cross_origin
from nest_backend.gestione import hashtag_validator
from nest_backend.errors import *
@cross_origin()
@ -44,11 +45,11 @@ def page_repository_tweets(rid):
repository = Repository.query.filter_by(id=rid).first()
if not repository:
return json_error("Could not find repository"), 404
return json_error("Could not find repository", REPOSITORY_NOT_FOUND), 404
user = find_user(get_jwt_identity())
if user.email != repository.owner_id:
return json_error("You are not authorized."), 403
if user.email != repository.owner_id and user.email not in [a.email for a in Repository.authorizations]:
return json_error("You are not authorized.", USER_NOT_AUTHORIZED), 403
if request.method == "GET":
return json_success([t.tweet.to_json() for t in repository.tweets])

View file

@ -4,6 +4,7 @@ from nest_backend.gestione import *
from flask_jwt_extended import create_access_token
from flask_cors import cross_origin
from datetime import timedelta, datetime
from nest_backend.errors import *
@cross_origin()
@ -42,4 +43,4 @@ def page_login():
access_token = create_access_token(identity=email, expires_delta=delta)
user = find_user(email)
return json_success({"access_token": access_token, 'user': user.to_json(), "expiration": expiration}), 201
return json_error("Bad username or password."), 401
return json_error("Bad username or password.", USER_WRONG_CREDENTIALS), 401

View file

@ -3,6 +3,7 @@ from nest_backend.database import *
from flask_jwt_extended import jwt_required, get_jwt_identity
from nest_backend.gestione import *
from flask_cors import cross_origin
from nest_backend.errors import *
@cross_origin()
@ -117,26 +118,26 @@ def page_user(email):
user = find_user(get_jwt_identity())
target = find_user(email)
if not target:
return json_error("Could not locate the user."), 404
return json_error("Could not locate the user.", USER_NOT_FOUND), 404
if request.method == "GET":
if not email == user.email and not user.isAdmin:
return json_error("Thou art not authorized."), 403
return json_error("Thou art not authorized.", USER_NOT_AUTHORIZED), 403
return json_success(target.to_json())
elif request.method == "DELETE":
if not user.isAdmin:
return json_error("User is not admin."), 403
return json_error("User is not admin.", USER_NOT_ADMIN), 403
if user == target:
return json_error("The user cant delete himself. Its a sin."), 406
return json_error("The user cant delete himself. Its a sin.", USER_PREVENT_SEPPUKU), 406
ext.session.delete(target)
try:
ext.session.commit()
except Exception:
ext.session.rollback()
return json_error("Could not delete the user."), 500
return json_error("Could not delete the user.", USER_DELETION_ERROR), 500
return json_success(""), 204 # "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
return json_error("Thou art not authorized.", USER_NOT_AUTHORIZED), 403
target = find_user(email)
if request.json.get("username"):
target.username = request.json.get("username")

View file

@ -3,6 +3,7 @@ from nest_backend.database import *
from flask_jwt_extended import jwt_required, get_jwt_identity
from nest_backend.gestione import *
from flask_cors import cross_origin
from nest_backend.errors import *
@cross_origin()
@ -65,16 +66,16 @@ def page_users():
user = find_user(get_jwt_identity())
if request.method == "GET":
if not user.isAdmin:
return json_error("User is not admin. Thou art not authorized"), 403
return json_error("User is not admin. Thou art not authorized", USER_NOT_ADMIN), 403
users = User.query.all()
return json_success([user.to_json() for user in users]), 200
if request.method == "POST":
if not user.isAdmin:
return json_error("User is not admin. Thou art not authorized."), 403
return json_error("User is not admin. Thou art not authorized.", USER_NOT_ADMIN), 403
if not request.json.get("email") or not request.json.get("password") or not request.json.get("username"):
return json_error("Missing required fields."), 400
return json_error("Missing required fields.", GENERIC_MISSING_FIELDS), 400
if User.query.filter_by(email=request.json.get("email")).first():
return json_error("User already exists."), 406
return json_error("User already exists.", GENERIC_ALREADY_EXISTS), 406
new_user = User(email=request.json.get("email"), password=gen_password(request.json.get("password")),
username=request.json.get("username"))
ext.session.add(new_user)