diff --git a/api/endpoints/editsalamander.py b/api/endpoints/editsalamander.py index 7c292f59218aaf26d7ed8e5ac3e6763446ca644c..e059521b8cf83bf6bc87359e1fbbdc98e0d93b83 100644 --- a/api/endpoints/editsalamander.py +++ b/api/endpoints/editsalamander.py @@ -13,20 +13,25 @@ from image_encoder.image_encoder import * from cv2 import cv2 import numpy as np -""" -Endpoint for editing salamanders. -GET: Gets a specific salamanders original and processed image, and all its data. -PUT: Edits a specific salamander with new data like sex, species, location etc. -DELETE: Deletes a specific salamander from the system. -""" - class EditSalamander(Resource): + """ + Endpoint for editing salamanders. + GET: Gets a specific salamanders original and processed image, and all its data. + PUT: Edits a specific salamander with new data like sex, species, location etc. + DELETE: Deletes a specific salamander from the system. + """ + decorators = [limiter.limit("60/minute")] @staticmethod @jwt_required def get(salamander_id, image_id): + """ + :param salamander_id: the id of the salamander + :param image_id: the id of an image + :return: JSON object containing all information about a specific salamander and the specific image + """ user_id = get_jwt_identity() user = db.session.query(User).filter_by(id=user_id).first() if user.admin: @@ -82,6 +87,12 @@ class EditSalamander(Resource): @staticmethod @jwt_required def delete(): + """ + param id: the id of the salamander + param image_id: the id of an image + param location: the location where the salamander is registered + :return: JSON object containing a confirmation message + """ data = request.form if "id" in data and "image_id" in data and "location" in data: user_id = get_jwt_identity() @@ -139,6 +150,17 @@ class EditSalamander(Resource): @staticmethod @jwt_required def put(): + """ + param id: the id of the salamander + param image_id: the id of an image + param weight: the new weight of the salamander + param length: the new length of the salamander + param location: the location where the salamander i registered + param new_location: the new location if the salamander should be moved + param new_sex: the new sex of the salamander if it is changed + param new_species: the new species of the salamander if it is changed + :return: JSON object containing if it was match or not after rematch + """ user_id = get_jwt_identity() user = db.session.query(User).filter_by(id=user_id).first() data = request.form diff --git a/api/endpoints/findsalamanderinfo.py b/api/endpoints/findsalamanderinfo.py index d8e2af7e9de2c15d183782356c8020304a7787f1..793ecfcf7fb8400364997cd6a750d0f64c61c138 100644 --- a/api/endpoints/findsalamanderinfo.py +++ b/api/endpoints/findsalamanderinfo.py @@ -10,18 +10,22 @@ from path_constants import image_type import glob ALLOWED_EXTENSIONS = ['jpg', 'png', 'jpeg'] -""" -Endpoint for processing the salamanders abdominal pattern. -POST: Receives an image of a salamander, processes it, and returns the processed image back to the user. -""" - class FindSalamanderInfo(Resource): + """ + Endpoint for processing the salamanders abdominal pattern. + POST: Receives an image of a salamander, processes it, and returns the processed image back to the user. + """ + decorators = [limiter.limit("5/minute")] @staticmethod @jwt_required def post(): + """ + param image: an image file of a salamander + :return: JSON object containing the processed image or error messages + """ if "image" not in request.files: return jsonify({"message": "no file given", "status": 400}) image = request.files['image'] diff --git a/api/endpoints/location.py b/api/endpoints/location.py index 776d0bcfa3b4e4e37f33d1675c65af01091eab4b..9dcfe09fac1e968f2cb02b19d1efcccaca8d926d 100644 --- a/api/endpoints/location.py +++ b/api/endpoints/location.py @@ -11,21 +11,27 @@ LATITUDE_REGEX = "^(\\+|-)?(?:90(?:(?:\\.0{1,6})?)|(?:[0-9]|[1-8][0-9])(?:(?:\\. LONGITUDE_REGEX = "^(\\+|-)?(?:180(?:(?:\\.0{1,6})?)|(?:[0-9]|[1-9][0-9]|1[0-7][0-9])(?:(?:\\.[0-9]{1,6})?))$" -""" -Endpoint for creating, updating, getting and deleting locations in the system. -GET: Returns all data about all locations to the user. -POST: Creates a new location with radius, name, longitude and latitude. -PUT: For editing a location. Change its name or radius. -DELETE: For deleting a specific location. This can only be done if the location does not contain a salamander. -""" - - class LocationEndpoint(Resource): + """ + Endpoint for creating, updating, getting and deleting locations in the system. + GET: Returns all data about all locations to the user. + POST: Creates a new location with radius, name, longitude and latitude. + PUT: For editing a location. Change its name or radius. + DELETE: For deleting a specific location. This can only be done if the location does not contain a salamander. + """ + decorators = [limiter.limit("60/minute")] @staticmethod @jwt_required def post(): + """ + param name: name of the location + param radius: radius of the location + param latitude: latitude of the location + param longitude: longitude of the location + :return: JSON object containing confirmation message + """ data = request.form if "name" in data and "radius" in data and "latitude" in data and "longitude" in data: with _ACCESS_DATABASE: @@ -46,6 +52,9 @@ class LocationEndpoint(Resource): @staticmethod @jwt_required def get(): + """ + :return: returns all the registered locations in a JSON object + """ locations = db.session.query(Location).all() location_list = [] for location in locations: @@ -57,6 +66,10 @@ class LocationEndpoint(Resource): @staticmethod @jwt_required def delete(): + """ + param id: the id of the location + :return: JSON object containing a confirmation message or an error message + """ user_id = get_jwt_identity() user = db.session.query(User).filter_by(id=user_id).first() data = request.form @@ -96,6 +109,12 @@ class LocationEndpoint(Resource): @staticmethod @jwt_required def put(): + """ + param id: the id for the location + param new_radius: the new radius for the location + param new_name: the new name for the location + :return: JSON object containing a confirmation message or an error message + """ user_id = get_jwt_identity() user = db.session.query(User).filter_by(id=user_id).first() data = request.form @@ -129,6 +148,10 @@ class LocationEndpoint(Resource): # creates the folder structure when a location is registered def create_directory_folders(location): + """ + :param location: the location name + creates the folder hierarchy for storing images + """ dir_smooth_male = "images/" + location + "/smooth_newt/" + "male/" dir_smooth_female = "images/" + location + "/smooth_newt/" + "female/" dir_smooth_juvenile = "images/" + location + "/smooth_newt/" + "juvenile/" diff --git a/api/endpoints/login.py b/api/endpoints/login.py index 2cdcc2fc24467f26ecc7a793041065f63f670bad..7398fbe43cf7b38b460fa53bed3ffadef8036847 100644 --- a/api/endpoints/login.py +++ b/api/endpoints/login.py @@ -5,18 +5,22 @@ from api.models.dbmodels import User from api import bcrypt, db, limiter -""" -Endpoint for logging in to the system. -POST: Checks if the email and password matches. Returns a JSON Web Token to the user that requested the login. -This JWT contains the users ID encrypted in it, so the server knows who sends request to other endpoints. -""" - - class Login(Resource): + """ + Endpoint for logging in to the system. + POST: Checks if the email and password matches. Returns a JSON Web Token to the user that requested the login. + This JWT contains the users ID encrypted in it, so the server knows who sends request to other endpoints. + """ + decorators = [limiter.limit("3/minute")] @staticmethod def post(): + """ + param email: the users email + param password: the users password + :return: JSON object containing user data and an access token(JWT), or an error message + """ data = request.form if data['email'] or data['password']: user = db.session.query(User).filter_by(email=data['email'].lower()).first() diff --git a/api/endpoints/manageuser.py b/api/endpoints/manageuser.py index a1776b456cf9f725486be7f97b5dd3f77c6108a0..9cb12b351c15bf9151b11001e47e434e6425a606 100644 --- a/api/endpoints/manageuser.py +++ b/api/endpoints/manageuser.py @@ -7,21 +7,23 @@ from random import choice from string import ascii_lowercase, digits -""" -Endpoint for administrators to manage users. -GET: Get all users in the system. -POST: Change a users access rights. The admin can update them to admin, remove admin or remove all access rights. -PUT: Is used if a user forgets their password. The admin can reset it, so that the user can login and change it at a -later point. -""" - - class AdminManageUser(Resource): + """ + Endpoint for administrators to manage users. + GET: Get all users in the system. + POST: Change a users access rights. The admin can update them to admin, remove admin or remove all access rights. + PUT: Is used if a user forgets their password. The admin can reset it, so that the user can login and change it at a + later point. + """ + decorators = [limiter.limit("60/minute")] @staticmethod @jwt_required def get(): + """ + :return: JSON object containing all users access rights, email and id + """ user_id = get_jwt_identity() user = db.session.query(User).filter_by(id=user_id).first() if user.admin: @@ -37,6 +39,14 @@ class AdminManageUser(Resource): @staticmethod @jwt_required def post(): + """ + param id: the updated users id + param email: the updated users email + param removeAdmin: removed administrator access + param makeAdmin: grants the user administrator access + param denyAccess: denies a user access to the system + :return: JSON object with a confirmation message + """ data = request.form user_id = get_jwt_identity() user = db.session.query(User).filter_by(id=user_id).first() @@ -67,6 +77,10 @@ class AdminManageUser(Resource): @staticmethod @jwt_required def put(): + """ + param id: the user id to the user that needs a new password + :return: JSON object containing the new password for the user + """ data = request.form user_id = get_jwt_identity() user = db.session.query(User).filter_by(id=user_id).first() @@ -86,6 +100,10 @@ class AdminManageUser(Resource): def get_random_string(length): + """ + :param length: the length of the new password + :return: a random generated password string + """ # choose from all lowercase letter letters = ascii_lowercase return ''.join(choice(letters + digits) for i in range(length)) diff --git a/api/endpoints/matchsalamander.py b/api/endpoints/matchsalamander.py index 298b9162cb746603ca42b264284ea944553ccb2b..c59bec0a11fb43fd0e5a47ade4f737b348e57ad7 100644 --- a/api/endpoints/matchsalamander.py +++ b/api/endpoints/matchsalamander.py @@ -14,20 +14,25 @@ APPROVED_SEX = ["male", "female", "juvenile"] APPROVED_SPECIES = ["smooth_newt", "northern_crested_newt"] -""" -Endpoint for matching a newly registered salamander with the once in the database. -POST: Matched the processed image of the salamander pattern with the once in the database. -It only matches females and males, not juveniles. -""" - - # matchSalamander endpoint class MatchSalamander(Resource): + """ + Endpoint for matching a newly registered salamander with the once in the database. + POST: Matched the processed image of the salamander pattern with the once in the database. + It only matches females and males, not juveniles. + """ + decorators = [limiter.limit("5/minute")] @staticmethod @jwt_required def post(): + """ + param sex: the sex of the salamander + param location: the location name for salamander registration + param species: the species of the salamander + :return: JSON object that contains match, no match or error message + """ data = request.form user_id = get_jwt_identity() approved_locations = get_locations() diff --git a/api/endpoints/pendingusers.py b/api/endpoints/pendingusers.py index 25af0c40e3c4d5e302cb1d2f64c0ea520da18401..07efa5d886b554c4a5f68b4cf0515d43bee3d8df 100644 --- a/api/endpoints/pendingusers.py +++ b/api/endpoints/pendingusers.py @@ -5,19 +5,21 @@ from api import db, limiter from flask_jwt_extended import get_jwt_identity, jwt_required -""" -Endpoint for administrators to accept newly created users. -GET: Gets all pending users in the system. -POST: For either accepting or denying a users access permissions. If the user is not accepted, it will be deleted. -""" - - class AdminPendingUsers(Resource): + """ + Endpoint for administrators to accept newly created users. + GET: Gets all pending users in the system. + POST: For either accepting or denying a users access permissions. If the user is not accepted, it will be deleted. + """ + decorators = [limiter.limit("60/minute")] @staticmethod @jwt_required def get(): + """ + :return: JSON object containing all users that are not approved by an admin + """ user_id = get_jwt_identity() user = db.session.query(User).filter_by(id=user_id).first() if user.admin: @@ -33,6 +35,12 @@ class AdminPendingUsers(Resource): @staticmethod @jwt_required def post(): + """ + param id: the user id for the user that is being approved + param email: the user email for the user that is being approved + param accepted: 1 if the user is accepted, 0 it the user is not accepted + :return: JSON object containing a confirmation message + """ data = request.form user_id = get_jwt_identity() user = db.session.query(User).filter_by(id=user_id).first() diff --git a/api/endpoints/salamander.py b/api/endpoints/salamander.py index abb739733cea808506aacb0ddf92efb8db49c4f5..6fdbf01c019cfaecaf90bb3e9a6529cc9f01eb69 100644 --- a/api/endpoints/salamander.py +++ b/api/endpoints/salamander.py @@ -10,18 +10,22 @@ from cv2 import cv2 from image_encoder.image_encoder import * from path_constants import _ACCESS_DATABASE -""" -Endpoint for getting all original images of a specific salamander. -GET: Gets all the images based on a salamanders ID. -""" - class SalamanderEndpoint(Resource): + """ + Endpoint for getting all original images of a specific salamander. + GET: Gets all the images based on a salamanders ID. + """ + decorators = [limiter.limit("60/minute")] @staticmethod @jwt_required def get(salamander_id): + """ + :param salamander_id: the id of a specific salamander + :return: JSON object containing all original images and data about a specific salamander + """ user_id = get_jwt_identity() user = db.session.query(User).filter_by(id=user_id).first() if user.admin: diff --git a/api/endpoints/salamanders.py b/api/endpoints/salamanders.py index fbb28d62b24697653e08df04376e266d382308bb..d5b98b77e7173cfd41d41ecb4bac2551d99cb205 100644 --- a/api/endpoints/salamanders.py +++ b/api/endpoints/salamanders.py @@ -5,18 +5,22 @@ from api import db, limiter from api.models.dbmodels import Location, User, Salamander, SalamanderGrowth from path_constants import _ACCESS_DATABASE -""" -Endpoint for for getting data about all salamanders in a specific location. -GET: Gets all salamanders and their data based on a specific location. -""" - class SalamandersEndpoint(Resource): + """ + Endpoint for for getting data about all salamanders in a specific location. + GET: Gets all salamanders and their data based on a specific location. + """ + decorators = [limiter.limit("60/minute")] @staticmethod @jwt_required def get(location_name): + """ + :param location_name: name of the location + :return: JSON object containing a list of all salamanders and its data based on a location + """ user_id = get_jwt_identity() user = db.session.query(User).filter_by(id=user_id).first() if user.admin: diff --git a/api/endpoints/user.py b/api/endpoints/user.py index e9d667a0bc2a12b8cbdaeb65a23232a3344b99e2..70a724d894846dbd1015db4409e8ed3112fb97a1 100644 --- a/api/endpoints/user.py +++ b/api/endpoints/user.py @@ -8,19 +8,26 @@ from api.forms.userforms import RegistrationForm, DeleteUserForm EMAIL_REGEX = "^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$" -""" -Endpoint for creating a new user, deleting a user and edit a user. -POST: For creating a new user with email, name, password and confirm password. -PUT: For editing a user. Either edit name, email or password. -DELETE: For deleting a user. An administrator cannot delete their own account. -""" - class UserEndpoint(Resource): + """ + Endpoint for creating a new user, deleting a user and edit a user. + POST: For creating a new user with email, name, password and confirm password. + PUT: For editing a user. Either edit name, email or password. + DELETE: For deleting a user. An administrator cannot delete their own account. + """ + decorators = [limiter.limit("30/minute")] @staticmethod def post(): + """ + param email: the registered users email + param name: the registered users name + param password: the registered users password + param confirmPassword: the registered users password confirmed + :return: JSON object that contains a confirmation message + """ data = RegistrationForm(request.form) if data.validate(): if data.password.data == data.confirmPassword.data: @@ -41,6 +48,10 @@ class UserEndpoint(Resource): @staticmethod @jwt_required def delete(): + """ + param email: the users email + :return: JSON object that contains a confirmation message + """ data = DeleteUserForm(request.form) user_id = get_jwt_identity() if data.validate(): @@ -60,6 +71,13 @@ class UserEndpoint(Resource): @staticmethod @jwt_required def put(): + """ + param newName: the users new name + param newEmail: the users new email + param newPassword: the users new password + param confirmNewPassword: the users new password confirmed + :return: JSON object that contains a confirmation message + """ data = request.form user_id = get_jwt_identity() user = db.session.query(User).filter_by(id=user_id).first() diff --git a/api/endpoints/verifypassword.py b/api/endpoints/verifypassword.py index 94b6f23d8716e97f3f7c4c5155ac34d95ae7cff8..a9c7a6b163b0c822856dd04a9f7fcb3ce9c0588a 100644 --- a/api/endpoints/verifypassword.py +++ b/api/endpoints/verifypassword.py @@ -5,18 +5,21 @@ from flask_jwt_extended import get_jwt_identity, jwt_required from api.models.dbmodels import User -""" -Endpoint to verify a users password. -POST: Checks that the password that the user typed in is correct. -""" - - class VerifyPassword(Resource): + """ + Endpoint to verify a users password. + POST: Checks that the password that the user typed in is correct. + """ + decorators = [limiter.limit("30/minute")] @staticmethod @jwt_required def post(): + """ + param password: the users password + :return: JSON object containing if the user is verified or not + """ data = request.form if "password" in data: user_id = get_jwt_identity()