diff --git a/backend/__init__.py b/backend/__init__.py
index 1cbbb40d2b..1279b45312 100644
--- a/backend/__init__.py
+++ b/backend/__init__.py
@@ -41,18 +41,18 @@ def create_app(env=None):
)
# Load configuration options from environment
- app.config.from_object(f"backend.config.EnvironmentConfig")
+ app.config.from_object("backend.config.EnvironmentConfig")
# Enable logging to files
initialise_logger(app)
- app.logger.info(f"Starting up a new Tasking Manager application")
+ app.logger.info("Starting up a new Tasking Manager application")
# Connect to database
- app.logger.debug(f"Connecting to the database")
+ app.logger.debug("Connecting to the database")
db.init_app(app)
migrate.init_app(app, db)
- app.logger.debug(f"Initialising frontend routes")
+ app.logger.debug("Initialising frontend routes")
# Main route to frontend
@app.route("/")
diff --git a/backend/api/annotations/resources.py b/backend/api/annotations/resources.py
index 8262905dcd..c4f6be8b13 100644
--- a/backend/api/annotations/resources.py
+++ b/backend/api/annotations/resources.py
@@ -127,10 +127,10 @@ def post(self, project_id: int, annotation_type: str):
application_token
)
except NotFound:
- current_app.logger.error(f"Invalid token")
+ current_app.logger.error("Invalid token")
return {"Error": "Invalid token"}, 500
else:
- current_app.logger.error(f"No token supplied")
+ current_app.logger.error("No token supplied")
return {"Error": "No token supplied"}, 500
try:
diff --git a/backend/api/campaigns/resources.py b/backend/api/campaigns/resources.py
index 075657233a..3a22c17caa 100644
--- a/backend/api/campaigns/resources.py
+++ b/backend/api/campaigns/resources.py
@@ -5,7 +5,7 @@
from backend.services.campaign_service import CampaignService
from backend.services.organisation_service import OrganisationService
from backend.models.postgis.utils import NotFound
-from backend.services.users.authentication_service import token_auth, tm
+from backend.services.users.authentication_service import token_auth
class CampaignsRestAPI(Resource):
@@ -44,9 +44,10 @@ def get(self, campaign_id):
description: Internal Server Error
"""
try:
- if tm.authenticated_user_id:
+ authenticated_user_id = token_auth.current_user()
+ if authenticated_user_id:
campaign = CampaignService.get_campaign_as_dto(
- campaign_id, tm.authenticated_user_id
+ campaign_id, authenticated_user_id
)
else:
campaign = CampaignService.get_campaign_as_dto(campaign_id, 0)
@@ -120,7 +121,7 @@ def patch(self, campaign_id):
"""
try:
orgs_dto = OrganisationService.get_organisations_managed_by_user_as_dto(
- tm.authenticated_user_id
+ token_auth.current_user()
)
if len(orgs_dto.organisations) < 1:
raise ValueError("User not a Org Manager")
@@ -185,7 +186,7 @@ def delete(self, campaign_id):
"""
try:
orgs_dto = OrganisationService.get_organisations_managed_by_user_as_dto(
- tm.authenticated_user_id
+ token_auth.current_user()
)
if len(orgs_dto.organisations) < 1:
raise ValueError("User not a Org Manager")
@@ -284,7 +285,7 @@ def post(self):
"""
try:
orgs_dto = OrganisationService.get_organisations_managed_by_user_as_dto(
- tm.authenticated_user_id
+ token_auth.current_user()
)
if len(orgs_dto.organisations) < 1:
raise ValueError("User not a Org Manager")
diff --git a/backend/api/comments/resources.py b/backend/api/comments/resources.py
index 6e4bf7c89a..9ad3e5ba81 100644
--- a/backend/api/comments/resources.py
+++ b/backend/api/comments/resources.py
@@ -52,13 +52,13 @@ def post(self, project_id):
500:
description: Internal Server Error
"""
-
- if UserService.is_user_blocked(tm.authenticated_user_id):
+ authenticated_user_id = token_auth.current_user()
+ if UserService.is_user_blocked(authenticated_user_id):
return "User is on read only mode", 403
try:
chat_dto = ChatMessageDTO(request.get_json())
- chat_dto.user_id = tm.authenticated_user_id
+ chat_dto.user_id = authenticated_user_id
chat_dto.project_id = project_id
chat_dto.validate()
except DataError as e:
@@ -67,7 +67,7 @@ def post(self, project_id):
try:
project_messages = ChatService.post_message(
- chat_dto, project_id, tm.authenticated_user_id
+ chat_dto, project_id, authenticated_user_id
)
return project_messages.to_primitive(), 201
except ValueError as e:
@@ -188,7 +188,7 @@ def post(self, project_id, task_id):
"""
try:
task_comment = TaskCommentDTO(request.get_json())
- task_comment.user_id = tm.authenticated_user_id
+ task_comment.user_id = token_auth.current_user()
task_comment.task_id = task_id
task_comment.project_id = project_id
task_comment.validate()
@@ -263,7 +263,7 @@ def get(self, project_id, task_id):
"""
try:
task_comment = TaskCommentDTO(request.get_json())
- task_comment.user_id = tm.authenticated_user_id
+ task_comment.user_id = token_auth.current_user()
task_comment.task_id = task_id
task_comment.project_id = project_id
task_comment.validate()
diff --git a/backend/api/interests/resources.py b/backend/api/interests/resources.py
index 955b0e44bf..4cd7c6efb4 100644
--- a/backend/api/interests/resources.py
+++ b/backend/api/interests/resources.py
@@ -5,7 +5,7 @@
from backend.models.postgis.utils import NotFound
from backend.services.interests_service import InterestService
from backend.services.organisation_service import OrganisationService
-from backend.services.users.authentication_service import token_auth, tm
+from backend.services.users.authentication_service import token_auth
from sqlalchemy.exc import IntegrityError
@@ -50,7 +50,7 @@ def post(self):
"""
try:
orgs_dto = OrganisationService.get_organisations_managed_by_user_as_dto(
- tm.authenticated_user_id
+ token_auth.current_user()
)
if len(orgs_dto.organisations) < 1:
raise ValueError("User not a Org Manager")
@@ -145,7 +145,7 @@ def get(self, interest_id):
"""
try:
orgs_dto = OrganisationService.get_organisations_managed_by_user_as_dto(
- tm.authenticated_user_id
+ token_auth.current_user()
)
if len(orgs_dto.organisations) < 1:
raise ValueError("User not a Org Manager")
@@ -206,7 +206,7 @@ def patch(self, interest_id):
"""
try:
orgs_dto = OrganisationService.get_organisations_managed_by_user_as_dto(
- tm.authenticated_user_id
+ token_auth.current_user()
)
if len(orgs_dto.organisations) < 1:
raise ValueError("User not a Org Manager")
@@ -265,7 +265,7 @@ def delete(self, interest_id):
"""
try:
orgs_dto = OrganisationService.get_organisations_managed_by_user_as_dto(
- tm.authenticated_user_id
+ token_auth.current_user()
)
if len(orgs_dto.organisations) < 1:
raise ValueError("User not a Org Manager")
diff --git a/backend/api/licenses/actions.py b/backend/api/licenses/actions.py
index bc9de69fd7..d8c0f18772 100644
--- a/backend/api/licenses/actions.py
+++ b/backend/api/licenses/actions.py
@@ -1,6 +1,6 @@
from flask_restful import Resource, current_app
-from backend.services.users.authentication_service import token_auth, tm
+from backend.services.users.authentication_service import token_auth
from backend.services.users.user_service import UserService, NotFound
@@ -38,7 +38,7 @@ def post(self, license_id):
description: Internal Server Error
"""
try:
- UserService.accept_license_terms(tm.authenticated_user_id, license_id)
+ UserService.accept_license_terms(token_auth.current_user(), license_id)
return {"Success": "Terms Accepted"}, 200
except NotFound:
return {"Error": "User or mapping not found"}, 404
diff --git a/backend/api/notifications/actions.py b/backend/api/notifications/actions.py
index c89dfa52c3..17f18d9001 100644
--- a/backend/api/notifications/actions.py
+++ b/backend/api/notifications/actions.py
@@ -42,7 +42,7 @@ def delete(self):
message_ids = request.get_json()["messageIds"]
if message_ids:
MessageService.delete_multiple_messages(
- message_ids, tm.authenticated_user_id
+ message_ids, token_auth.current_user()
)
return {"Success": "Messages deleted"}, 200
diff --git a/backend/api/notifications/resources.py b/backend/api/notifications/resources.py
index 884b3e512b..ac29a18669 100644
--- a/backend/api/notifications/resources.py
+++ b/backend/api/notifications/resources.py
@@ -43,7 +43,7 @@ def get(self, message_id):
"""
try:
user_message = MessageService.get_message_as_dto(
- message_id, tm.authenticated_user_id
+ message_id, token_auth.current_user()
)
return user_message.to_primitive(), 200
except MessageServiceError:
@@ -89,7 +89,7 @@ def delete(self, message_id):
description: Internal Server Error
"""
try:
- MessageService.delete_message(message_id, tm.authenticated_user_id)
+ MessageService.delete_message(message_id, token_auth.current_user())
return {"Success": "Message deleted"}, 200
except MessageServiceError:
return {"Error": "Unable to delete message"}, 403
@@ -171,7 +171,7 @@ def get(self):
project = request.args.get("project", None, int)
task_id = request.args.get("taskId", None, int)
user_messages = MessageService.get_all_messages(
- tm.authenticated_user_id,
+ token_auth.current_user(),
preferred_locale,
page,
page_size,
@@ -215,7 +215,7 @@ def get(self):
"""
try:
unread_count = MessageService.has_user_new_messages(
- tm.authenticated_user_id
+ token_auth.current_user()
)
return unread_count, 200
except Exception as e:
diff --git a/backend/api/organisations/campaigns.py b/backend/api/organisations/campaigns.py
index 34333e7ab0..c14db621d9 100644
--- a/backend/api/organisations/campaigns.py
+++ b/backend/api/organisations/campaigns.py
@@ -4,7 +4,7 @@
from backend.services.organisation_service import OrganisationService
from backend.models.postgis.utils import NotFound
from backend.models.postgis.campaign import Campaign
-from backend.services.users.authentication_service import token_auth, tm
+from backend.services.users.authentication_service import token_auth
class OrganisationsCampaignsAPI(Resource):
@@ -50,7 +50,7 @@ def post(self, organisation_id, campaign_id):
"""
try:
if OrganisationService.can_user_manage_organisation(
- organisation_id, tm.authenticated_user_id
+ organisation_id, token_auth.current_user()
):
if Campaign.campaign_organisation_exists(campaign_id, organisation_id):
message = "Campaign {} is already assigned to organisation {}.".format(
@@ -155,7 +155,7 @@ def delete(self, organisation_id, campaign_id):
"""
try:
if OrganisationService.can_user_manage_organisation(
- organisation_id, tm.authenticated_user_id
+ organisation_id, token_auth.current_user()
):
CampaignService.delete_organisation_campaign(
organisation_id, campaign_id
diff --git a/backend/api/organisations/resources.py b/backend/api/organisations/resources.py
index b2a532eef0..1d6276968f 100644
--- a/backend/api/organisations/resources.py
+++ b/backend/api/organisations/resources.py
@@ -13,7 +13,7 @@
)
from backend.services.users.user_service import UserService
-from backend.services.users.authentication_service import token_auth, tm, verify_token
+from backend.services.users.authentication_service import token_auth
class OrganisationsRestAPI(Resource):
@@ -70,7 +70,7 @@ def post(self):
500:
description: Internal Server Error
"""
- request_user = User.get_by_id(tm.authenticated_user_id)
+ request_user = User.get_by_id(token_auth.current_user())
if request_user.role != 1:
return {"Error": "Only admin users can create organisations."}, 403
@@ -128,7 +128,7 @@ def delete(self, organisation_id):
description: Internal Server Error
"""
if not OrganisationService.can_user_manage_organisation(
- organisation_id, tm.authenticated_user_id
+ organisation_id, token_auth.current_user()
):
return {"Error": "User is not an admin for the org"}, 403
try:
@@ -174,10 +174,11 @@ def get(self, organisation_id):
description: Internal Server Error
"""
try:
- if tm.authenticated_user_id is None:
+ authenticated_user_id = token_auth.current_user()
+ if authenticated_user_id is None:
user_id = 0
else:
- user_id = tm.authenticated_user_id
+ user_id = authenticated_user_id
organisation_dto = OrganisationService.get_organisation_by_id_as_dto(
organisation_id, user_id
)
@@ -247,7 +248,7 @@ def patch(self, organisation_id):
description: Internal Server Error
"""
if not OrganisationService.can_user_manage_organisation(
- organisation_id, tm.authenticated_user_id
+ organisation_id, token_auth.current_user()
):
return {"Error": "User is not an admin for the org"}, 403
try:
@@ -272,6 +273,7 @@ def patch(self, organisation_id):
class OrganisationsAllAPI(Resource):
+ @token_auth.login_required(optional=True)
def get(self):
"""
List all organisations
@@ -307,6 +309,7 @@ def get(self):
"""
# Restrict some of the parameters to some permissions
+ authenticated_user_id = token_auth.current_user()
try:
manager_user_id = int(request.args.get("manager_user_id"))
except Exception:
@@ -314,15 +317,10 @@ def get(self):
if manager_user_id is not None:
try:
- # Verify login
- verify_token(
- request.environ.get("HTTP_AUTHORIZATION").split(None, 1)[1]
- )
-
# Check whether user is admin (can do any query) or user is checking for own projects
if (
- not UserService.is_user_an_admin(tm.authenticated_user_id)
- and tm.authenticated_user_id != manager_user_id
+ not UserService.is_user_an_admin(authenticated_user_id)
+ and authenticated_user_id != manager_user_id
):
raise ValueError
@@ -332,7 +330,7 @@ def get(self):
# Obtain organisations
try:
results_dto = OrganisationService.get_organisations_as_dto(
- manager_user_id, tm.authenticated_user_id
+ manager_user_id, authenticated_user_id
)
return results_dto.to_primitive(), 200
except NotFound:
diff --git a/backend/api/projects/actions.py b/backend/api/projects/actions.py
index 3964d932d6..e2da0f9163 100644
--- a/backend/api/projects/actions.py
+++ b/backend/api/projects/actions.py
@@ -7,7 +7,7 @@
from backend.services.project_service import ProjectService, NotFound
from backend.services.project_admin_service import ProjectAdminService
from backend.services.messaging.message_service import MessageService
-from backend.services.users.authentication_service import token_auth, tm
+from backend.services.users.authentication_service import token_auth
from backend.services.interests_service import InterestService
@@ -54,8 +54,9 @@ def post(self, project_id):
"""
try:
username = request.get_json()["username"]
+ authenticated_user_id = token_auth.current_user()
ProjectAdminService.transfer_project_to(
- project_id, tm.authenticated_user_id, username
+ project_id, authenticated_user_id, username
)
return {"Success": "Project Transfered"}, 200
except ValueError as e:
@@ -114,8 +115,9 @@ def post(self, project_id):
description: Internal Server Error
"""
try:
+ authenticated_user_id = token_auth.current_user()
message_dto = MessageDTO(request.get_json())
- message_dto.from_user_id = tm.authenticated_user_id
+ message_dto.from_user_id = authenticated_user_id
message_dto.validate()
except DataError as e:
current_app.logger.error(f"Error validating request: {str(e)}")
@@ -123,7 +125,7 @@ def post(self, project_id):
try:
ProjectAdminService.is_user_action_permitted_on_project(
- tm.authenticated_user_id, project_id
+ authenticated_user_id, project_id
)
threading.Thread(
target=MessageService.send_message_to_all_contributors,
@@ -175,15 +177,16 @@ def post(self, project_id):
description: Internal Server Error
"""
try:
+ authenticated_user_id = token_auth.current_user()
ProjectAdminService.is_user_action_permitted_on_project(
- tm.authenticated_user_id, project_id
+ authenticated_user_id, project_id
)
except ValueError as e:
error_msg = f"FeaturedProjects POST: {str(e)}"
return {"Error": error_msg}, 403
try:
- ProjectService.set_project_as_featured(project_id, tm.authenticated_user_id)
+ ProjectService.set_project_as_featured(project_id, authenticated_user_id)
return {"Success": True}, 200
except NotFound:
return {"Error": "Project Not Found"}, 404
@@ -233,7 +236,7 @@ def post(self, project_id):
"""
try:
ProjectAdminService.is_user_action_permitted_on_project(
- tm.authenticated_user_id, project_id
+ token_auth.current_user(), project_id
)
except ValueError as e:
error_msg = f"FeaturedProjects POST: {str(e)}"
@@ -300,7 +303,7 @@ def post(self, project_id):
"""
try:
ProjectAdminService.is_user_action_permitted_on_project(
- tm.authenticated_user_id, project_id
+ token_auth.current_user(), project_id
)
except ValueError as e:
error_msg = f"ProjectsActionsSetInterestsAPI POST: {str(e)}"
diff --git a/backend/api/projects/campaigns.py b/backend/api/projects/campaigns.py
index 98c8d12de0..1dd69bcde0 100644
--- a/backend/api/projects/campaigns.py
+++ b/backend/api/projects/campaigns.py
@@ -5,7 +5,7 @@
from backend.services.campaign_service import CampaignService
from backend.services.project_admin_service import ProjectAdminService
from backend.models.postgis.utils import NotFound
-from backend.services.users.authentication_service import token_auth, tm
+from backend.services.users.authentication_service import token_auth
class ProjectsCampaignsAPI(Resource):
@@ -51,7 +51,7 @@ def post(self, project_id, campaign_id):
"""
try:
ProjectAdminService.is_user_action_permitted_on_project(
- tm.authenticated_user_id, project_id
+ token_auth.current_user(), project_id
)
except ValueError as e:
error_msg = f"ProjectsCampaignsAPI POST: {str(e)}"
@@ -154,7 +154,7 @@ def delete(self, project_id, campaign_id):
"""
try:
ProjectAdminService.is_user_action_permitted_on_project(
- tm.authenticated_user_id, project_id
+ token_auth.current_user(), project_id
)
except ValueError as e:
error_msg = f"ProjectsCampaignsAPI DELETE: {str(e)}"
diff --git a/backend/api/projects/favorites.py b/backend/api/projects/favorites.py
index 6a71df0021..6c0334de9f 100644
--- a/backend/api/projects/favorites.py
+++ b/backend/api/projects/favorites.py
@@ -4,7 +4,7 @@
from backend.models.postgis.utils import NotFound
from backend.models.dtos.project_dto import ProjectFavoriteDTO
from backend.services.project_service import ProjectService
-from backend.services.users.authentication_service import token_auth, tm
+from backend.services.users.authentication_service import token_auth
class ProjectsFavoritesAPI(Resource):
@@ -40,7 +40,7 @@ def get(self, project_id: int):
description: Internal Server Error
"""
try:
- user_id = tm.authenticated_user_id
+ user_id = token_auth.current_user()
favorited = ProjectService.is_favorited(project_id, user_id)
if favorited is True:
return {"favorited": True}, 200
@@ -85,15 +85,16 @@ def post(self, project_id: int):
description: Internal Server Error
"""
try:
+ authenticated_user_id = token_auth.current_user()
favorite_dto = ProjectFavoriteDTO()
favorite_dto.project_id = project_id
- favorite_dto.user_id = tm.authenticated_user_id
+ favorite_dto.user_id = authenticated_user_id
favorite_dto.validate()
except DataError as e:
current_app.logger.error(f"Error validating request: {str(e)}")
return str(e), 400
try:
- ProjectService.favorite(project_id, tm.authenticated_user_id)
+ ProjectService.favorite(project_id, authenticated_user_id)
except NotFound:
return {"Error": "Project Not Found"}, 404
except ValueError as e:
@@ -137,7 +138,7 @@ def delete(self, project_id: int):
description: Internal Server Error
"""
try:
- ProjectService.unfavorite(project_id, tm.authenticated_user_id)
+ ProjectService.unfavorite(project_id, token_auth.current_user())
except NotFound:
return {"Error": "Project Not Found"}, 404
except ValueError as e:
diff --git a/backend/api/projects/resources.py b/backend/api/projects/resources.py
index e06d9842e9..a97c3a1e00 100644
--- a/backend/api/projects/resources.py
+++ b/backend/api/projects/resources.py
@@ -22,7 +22,7 @@
)
from backend.services.users.user_service import UserService
from backend.services.organisation_service import OrganisationService
-from backend.services.users.authentication_service import token_auth, tm, verify_token
+from backend.services.users.authentication_service import token_auth
from backend.services.project_admin_service import (
ProjectAdminService,
ProjectAdminServiceError,
@@ -42,6 +42,12 @@ def get(self, project_id):
produces:
- application/json
parameters:
+ - in: header
+ name: Authorization
+ description: Base64 encoded session token
+ required: false
+ type: string
+ default: Token sessionTokenHere==
- in: header
name: Accept-Language
description: Language user is requesting
@@ -75,6 +81,7 @@ def get(self, project_id):
description: Internal Server Error
"""
try:
+ authenticated_user_id = token_auth.current_user()
as_file = (
strtobool(request.args.get("as_file"))
if request.args.get("as_file")
@@ -88,7 +95,7 @@ def get(self, project_id):
project_dto = ProjectService.get_project_dto_for_mapper(
project_id,
- tm.authenticated_user_id,
+ authenticated_user_id,
request.environ.get("HTTP_ACCEPT_LANGUAGE"),
abbreviated,
)
@@ -189,7 +196,7 @@ def post(self):
"""
try:
draft_project_dto = DraftProjectDTO(request.get_json())
- draft_project_dto.user_id = tm.authenticated_user_id
+ draft_project_dto.user_id = token_auth.current_user()
draft_project_dto.validate()
except DataError as e:
current_app.logger.error(f"error validating request: {str(e)}")
@@ -245,7 +252,7 @@ def head(self, project_id):
"""
try:
ProjectAdminService.is_user_action_permitted_on_project(
- tm.authenticated_user_id, project_id
+ token_auth.current_user(), project_id
)
except ValueError as e:
error_msg = f"ProjectsRestAPI HEAD: {str(e)}"
@@ -387,9 +394,10 @@ def patch(self, project_id):
500:
description: Internal Server Error
"""
+ authenticated_user_id = token_auth.current_user()
try:
ProjectAdminService.is_user_action_permitted_on_project(
- tm.authenticated_user_id, project_id
+ authenticated_user_id, project_id
)
except ValueError as e:
error_msg = f"ProjectsRestAPI PATCH: {str(e)}"
@@ -404,7 +412,7 @@ def patch(self, project_id):
return {"Error": "Unable to update project"}, 400
try:
- ProjectAdminService.update_project(project_dto, tm.authenticated_user_id)
+ ProjectAdminService.update_project(project_dto, authenticated_user_id)
return {"Status": "Updated"}, 200
except InvalidGeoJson as e:
return {"Invalid GeoJson": str(e)}, 400
@@ -450,15 +458,16 @@ def delete(self, project_id):
description: Internal Server Error
"""
try:
+ authenticated_user_id = token_auth.current_user()
ProjectAdminService.is_user_action_permitted_on_project(
- tm.authenticated_user_id, project_id
+ authenticated_user_id, project_id
)
except ValueError as e:
error_msg = f"ProjectsRestAPI DELETE: {str(e)}"
return {"Error": error_msg}, 403
try:
- ProjectAdminService.delete_project(project_id, tm.authenticated_user_id)
+ ProjectAdminService.delete_project(project_id, authenticated_user_id)
return {"Success": "Project deleted"}, 200
except ProjectAdminServiceError:
return {"Error": "Project has some mapping"}, 403
@@ -471,6 +480,7 @@ def delete(self, project_id):
class ProjectSearchBase(Resource):
+ @token_auth.login_required(optional=True)
def setup_search_dto(self):
search_dto = ProjectSearchDTO()
search_dto.preferred_locale = request.environ.get("HTTP_ACCEPT_LANGUAGE")
@@ -489,19 +499,18 @@ def setup_search_dto(self):
# See https://github.com/hotosm/tasking-manager/pull/922 for more info
try:
- verify_token(request.environ.get("HTTP_AUTHORIZATION").split(None, 1)[1])
-
+ authenticated_user_id = token_auth.current_user()
if request.args.get("createdByMe") == "true":
- search_dto.created_by = tm.authenticated_user_id
+ search_dto.created_by = authenticated_user_id
if request.args.get("mappedByMe") == "true":
- search_dto.mapped_by = tm.authenticated_user_id
+ search_dto.mapped_by = authenticated_user_id
if request.args.get("favoritedByMe") == "true":
- search_dto.favorited_by = tm.authenticated_user_id
+ search_dto.favorited_by = authenticated_user_id
if request.args.get("managedByMe") == "true":
- search_dto.managed_by = tm.authenticated_user_id
+ search_dto.managed_by = authenticated_user_id
except Exception:
pass
@@ -691,8 +700,9 @@ def get(self):
description: Internal Server Error
"""
try:
+ authenticated_user_id = token_auth.current_user()
orgs_dto = OrganisationService.get_organisations_managed_by_user_as_dto(
- tm.authenticated_user_id
+ authenticated_user_id
)
if len(orgs_dto.organisations) < 1:
raise ValueError("User not a project manager")
@@ -711,7 +721,7 @@ def get(self):
else False
)
if createdByMe:
- search_dto.project_author = tm.authenticated_user_id
+ search_dto.project_author = authenticated_user_id
search_dto.validate()
except Exception as e:
current_app.logger.error(f"Error validating request: {str(e)}")
@@ -765,8 +775,9 @@ def get(self):
description: Internal Server Error
"""
try:
+ authenticated_user_id = token_auth.current_user()
orgs_dto = OrganisationService.get_organisations_managed_by_user_as_dto(
- tm.authenticated_user_id
+ authenticated_user_id
)
if len(orgs_dto.organisations) < 1:
raise ValueError("User not a project manager")
@@ -777,7 +788,7 @@ def get(self):
try:
search_dto = self.setup_search_dto()
admin_projects = ProjectAdminService.get_projects_for_admin(
- tm.authenticated_user_id,
+ authenticated_user_id,
request.environ.get("HTTP_ACCEPT_LANGUAGE"),
search_dto,
)
@@ -988,7 +999,7 @@ def get(self, project_id):
"""
try:
ProjectAdminService.is_user_action_permitted_on_project(
- tm.authenticated_user_id, project_id
+ token_auth.current_user(), project_id
)
except ValueError as e:
error_msg = f"ProjectsQueriesNoTasksAPI GET: {str(e)}"
diff --git a/backend/api/projects/teams.py b/backend/api/projects/teams.py
index 353fde58d0..ea728013f1 100644
--- a/backend/api/projects/teams.py
+++ b/backend/api/projects/teams.py
@@ -2,7 +2,7 @@
from schematics.exceptions import DataError
from backend.services.team_service import TeamService, TeamServiceError, NotFound
-from backend.services.users.authentication_service import token_auth, tm
+from backend.services.users.authentication_service import token_auth
class ProjectsTeamsAPI(Resource):
@@ -92,7 +92,7 @@ def post(self, team_id, project_id):
500:
description: Internal Server Error
"""
- if not TeamService.user_is_manager(team_id, tm.authenticated_user_id):
+ if not TeamService.user_is_manager(team_id, token_auth.current_user()):
return {"Error": "User is not an admin or a manager for the team"}, 401
try:
@@ -163,7 +163,7 @@ def patch(self, team_id, project_id):
500:
description: Internal Server Error
"""
- if not TeamService.user_is_manager(team_id, tm.authenticated_user_id):
+ if not TeamService.user_is_manager(team_id, token_auth.current_user()):
return {"Error": "User is not an admin or a manager for the team"}, 401
try:
role = request.get_json(force=True)["role"]
@@ -217,7 +217,7 @@ def delete(self, team_id, project_id):
500:
description: Internal Server Error
"""
- if not TeamService.user_is_manager(team_id, tm.authenticated_user_id):
+ if not TeamService.user_is_manager(team_id, token_auth.current_user()):
return {"Error": "User is not an admin or a manager for the team"}, 401
try:
TeamService.delete_team_project(team_id, project_id)
diff --git a/backend/api/system/applications.py b/backend/api/system/applications.py
index e15a18da22..f2ad6e6a8b 100644
--- a/backend/api/system/applications.py
+++ b/backend/api/system/applications.py
@@ -1,7 +1,7 @@
from flask_restful import Resource, current_app
from backend.services.application_service import ApplicationService, NotFound
-from backend.services.users.authentication_service import token_auth, tm
+from backend.services.users.authentication_service import token_auth
class SystemApplicationsRestAPI(Resource):
@@ -31,7 +31,7 @@ def get(self):
"""
try:
tokens = ApplicationService.get_all_tokens_for_logged_in_user(
- tm.authenticated_user_id
+ token_auth.current_user()
)
if len(tokens) == 0:
return 400
@@ -66,7 +66,7 @@ def post(self):
description: A problem occurred
"""
try:
- token = ApplicationService.create_token(tm.authenticated_user_id)
+ token = ApplicationService.create_token(token_auth.current_user())
return token.to_primitive(), 200
except Exception as e:
error_msg = f"Application POST API - unhandled error: {str(e)}"
@@ -141,7 +141,7 @@ def delete(self, application_key):
"""
try:
token = ApplicationService.get_token(application_key)
- if token.user == tm.authenticated_user_id:
+ if token.user == token_auth.current_user():
token.delete()
return 200
else:
diff --git a/backend/api/system/image_upload.py b/backend/api/system/image_upload.py
index 69438be448..44efec5a17 100644
--- a/backend/api/system/image_upload.py
+++ b/backend/api/system/image_upload.py
@@ -4,7 +4,7 @@
from flask_restful import Resource, request, current_app
from backend.services.organisation_service import OrganisationService
-from backend.services.users.authentication_service import token_auth, tm
+from backend.services.users.authentication_service import token_auth
class SystemImageUploadRestAPI(Resource):
@@ -59,7 +59,7 @@ def post(self):
is_org_manager = (
len(
OrganisationService.get_organisations_managed_by_user(
- tm.authenticated_user_id
+ token_auth.current_user()
)
)
> 0
diff --git a/backend/api/tasks/actions.py b/backend/api/tasks/actions.py
index 3823336c0a..73b688d069 100644
--- a/backend/api/tasks/actions.py
+++ b/backend/api/tasks/actions.py
@@ -78,7 +78,7 @@ def post(self, project_id, task_id):
"""
try:
lock_task_dto = LockTaskDTO()
- lock_task_dto.user_id = tm.authenticated_user_id
+ lock_task_dto.user_id = token_auth.current_user()
lock_task_dto.project_id = project_id
lock_task_dto.task_id = task_id
lock_task_dto.preferred_locale = request.environ.get("HTTP_ACCEPT_LANGUAGE")
@@ -164,7 +164,7 @@ def post(self, project_id, task_id):
"""
try:
stop_task = StopMappingTaskDTO(request.get_json())
- stop_task.user_id = tm.authenticated_user_id
+ stop_task.user_id = token_auth.current_user()
stop_task.task_id = task_id
stop_task.project_id = project_id
stop_task.preferred_locale = request.environ.get("HTTP_ACCEPT_LANGUAGE")
@@ -247,8 +247,9 @@ def post(self, project_id, task_id):
description: Internal Server Error
"""
try:
+ authenticated_user_id = token_auth.current_user()
mapped_task = MappedTaskDTO(request.get_json())
- mapped_task.user_id = tm.authenticated_user_id
+ mapped_task.user_id = authenticated_user_id
mapped_task.task_id = task_id
mapped_task.project_id = project_id
mapped_task.validate()
@@ -269,7 +270,7 @@ def post(self, project_id, task_id):
return {"Error": "Task unlock failed"}, 500
finally:
# Refresh mapper level after mapping
- UserService.check_and_update_mapper_level(tm.authenticated_user_id)
+ UserService.check_and_update_mapper_level(authenticated_user_id)
class TasksActionsMappingUndoAPI(Resource):
@@ -320,7 +321,7 @@ def post(self, project_id, task_id):
try:
preferred_locale = request.environ.get("HTTP_ACCEPT_LANGUAGE")
task = MappingService.undo_mapping(
- project_id, task_id, tm.authenticated_user_id, preferred_locale
+ project_id, task_id, token_auth.current_user(), preferred_locale
)
return task.to_primitive(), 200
except NotFound:
@@ -393,7 +394,7 @@ def post(self, project_id):
try:
validator_dto = LockForValidationDTO(request.get_json())
validator_dto.project_id = project_id
- validator_dto.user_id = tm.authenticated_user_id
+ validator_dto.user_id = token_auth.current_user()
validator_dto.preferred_locale = request.environ.get("HTTP_ACCEPT_LANGUAGE")
validator_dto.validate()
except DataError as e:
@@ -474,7 +475,7 @@ def post(self, project_id):
try:
validated_dto = StopValidationDTO(request.get_json())
validated_dto.project_id = project_id
- validated_dto.user_id = tm.authenticated_user_id
+ validated_dto.user_id = token_auth.current_user()
validated_dto.preferred_locale = request.environ.get("HTTP_ACCEPT_LANGUAGE")
validated_dto.validate()
except DataError as e:
@@ -551,7 +552,7 @@ def post(self, project_id):
try:
validated_dto = UnlockAfterValidationDTO(request.get_json())
validated_dto.project_id = project_id
- validated_dto.user_id = tm.authenticated_user_id
+ validated_dto.user_id = token_auth.current_user()
validated_dto.preferred_locale = request.environ.get("HTTP_ACCEPT_LANGUAGE")
validated_dto.validate()
except DataError as e:
@@ -605,15 +606,16 @@ def post(self, project_id):
description: Internal Server Error
"""
try:
+ authenticated_user_id = token_auth.current_user()
ProjectAdminService.is_user_action_permitted_on_project(
- tm.authenticated_user_id, project_id
+ authenticated_user_id, project_id
)
except ValueError as e:
error_msg = f"TasksActionsMapAllAPI POST: {str(e)}"
return {"Error": error_msg}, 403
try:
- MappingService.map_all_tasks(project_id, tm.authenticated_user_id)
+ MappingService.map_all_tasks(project_id, authenticated_user_id)
return {"Success": "All tasks mapped"}, 200
except Exception as e:
error_msg = f"TasksActionsMapAllAPI POST - unhandled error: {str(e)}"
@@ -655,15 +657,16 @@ def post(self, project_id):
description: Internal Server Error
"""
try:
+ authenticated_user_id = token_auth.current_user()
ProjectAdminService.is_user_action_permitted_on_project(
- tm.authenticated_user_id, project_id
+ authenticated_user_id, project_id
)
except ValueError as e:
error_msg = f"TasksActionsValidateAllAPI POST: {str(e)}"
return {"Error": error_msg}, 403
try:
- ValidatorService.validate_all_tasks(project_id, tm.authenticated_user_id)
+ ValidatorService.validate_all_tasks(project_id, authenticated_user_id)
return {"Success": "All tasks validated"}, 200
except Exception as e:
error_msg = f"TasksActionsValidateAllAPI POST - unhandled error: {str(e)}"
@@ -705,15 +708,16 @@ def post(self, project_id):
description: Internal Server Error
"""
try:
+ authenticated_user_id = token_auth.current_user()
ProjectAdminService.is_user_action_permitted_on_project(
- tm.authenticated_user_id, project_id
+ authenticated_user_id, project_id
)
except ValueError as e:
error_msg = f"TasksActionsInvalidateAllAPI POST: {str(e)}"
return {"Error": error_msg}, 403
try:
- ValidatorService.invalidate_all_tasks(project_id, tm.authenticated_user_id)
+ ValidatorService.invalidate_all_tasks(project_id, authenticated_user_id)
return {"Success": "All tasks invalidated"}, 200
except Exception as e:
error_msg = f"TasksActionsInvalidateAllAPI POST - unhandled error: {str(e)}"
@@ -755,15 +759,16 @@ def post(self, project_id):
description: Internal Server Error
"""
try:
+ authenticated_user_id = token_auth.current_user()
ProjectAdminService.is_user_action_permitted_on_project(
- tm.authenticated_user_id, project_id
+ authenticated_user_id, project_id
)
except ValueError as e:
error_msg = f"TasksActionsResetBadImageryAllAPI POST: {str(e)}"
return {"Error": error_msg}, 403
try:
- MappingService.reset_all_badimagery(project_id, tm.authenticated_user_id)
+ MappingService.reset_all_badimagery(project_id, authenticated_user_id)
return {"Success": "All bad imagery tasks marked ready for mapping"}, 200
except Exception as e:
error_msg = (
@@ -807,15 +812,16 @@ def post(self, project_id):
description: Internal Server Error
"""
try:
+ authenticated_user_id = token_auth.current_user()
ProjectAdminService.is_user_action_permitted_on_project(
- tm.authenticated_user_id, project_id
+ authenticated_user_id, project_id
)
except ValueError as e:
error_msg = f"TasksActionsResetAllAPI POST: {str(e)}"
return {"Error": error_msg}, 403
try:
- ProjectAdminService.reset_all_tasks(project_id, tm.authenticated_user_id)
+ ProjectAdminService.reset_all_tasks(project_id, authenticated_user_id)
return {"Success": "All tasks reset"}, 200
except Exception as e:
error_msg = f"TasksActionsResetAllAPI POST - unhandled error: {str(e)}"
@@ -874,7 +880,7 @@ def post(self, project_id, task_id):
"""
try:
split_task_dto = SplitTaskDTO()
- split_task_dto.user_id = tm.authenticated_user_id
+ split_task_dto.user_id = token_auth.current_user()
split_task_dto.project_id = project_id
split_task_dto.task_id = task_id
split_task_dto.preferred_locale = request.environ.get(
diff --git a/backend/api/tasks/resources.py b/backend/api/tasks/resources.py
index 093f7d1b5c..38238631bd 100644
--- a/backend/api/tasks/resources.py
+++ b/backend/api/tasks/resources.py
@@ -8,7 +8,7 @@
from backend.services.mapping_service import MappingService, NotFound
from backend.models.dtos.grid_dto import GridDTO
-from backend.services.users.authentication_service import token_auth, tm, verify_token
+from backend.services.users.authentication_service import token_auth, tm
from backend.services.validator_service import ValidatorService
from backend.services.project_service import ProjectService, ProjectServiceError
@@ -26,12 +26,6 @@ def get(self, project_id, task_id):
produces:
- application/json
parameters:
- - in: header
- name: Authorization
- description: Base64 encoded session token
- required: false
- type: string
- default: Token sessionTokenHere==
- in: header
name: Accept-Language
description: Language user is requesting
@@ -60,17 +54,8 @@ def get(self, project_id, task_id):
"""
try:
preferred_locale = request.environ.get("HTTP_ACCEPT_LANGUAGE")
- token = request.environ.get("HTTP_AUTHORIZATION")
-
- # Login isn't required here, but if we have a token we can find out if the user can undo the task
- if token:
- verify_token(token[6:])
- user_id = tm.authenticated_user_id
-
- task = MappingService.get_task_as_dto(
- task_id, project_id, preferred_locale, user_id
- )
+ task = MappingService.get_task_as_dto(task_id, project_id, preferred_locale)
return task.to_primitive(), 200
except NotFound:
return {"Error": "Task Not Found"}, 404
diff --git a/backend/api/teams/actions.py b/backend/api/teams/actions.py
index df6c989db0..a0a83ee91c 100644
--- a/backend/api/teams/actions.py
+++ b/backend/api/teams/actions.py
@@ -61,8 +61,9 @@ def post(self, team_id):
return str(e), 400
try:
- TeamService.join_team(team_id, tm.authenticated_user_id, username, role)
- if TeamService.user_is_manager(team_id, tm.authenticated_user_id):
+ authenticated_user_id = token_auth.current_user()
+ TeamService.join_team(team_id, authenticated_user_id, username, role)
+ if TeamService.user_is_manager(team_id, authenticated_user_id):
return {"Success": "User added to the team"}, 200
else:
return {"Success": "Request to join the team sent successfully."}, 200
@@ -138,10 +139,11 @@ def patch(self, team_id):
return str(e), 400
try:
+ authenticated_user_id = token_auth.current_user()
if request_type == "join-response":
- if TeamService.user_is_manager(team_id, tm.authenticated_user_id):
+ if TeamService.user_is_manager(team_id, authenticated_user_id):
TeamService.accept_reject_join_request(
- team_id, tm.authenticated_user_id, username, role, action
+ team_id, authenticated_user_id, username, role, action
)
return {"Success": "True"}, 200
else:
@@ -153,7 +155,7 @@ def patch(self, team_id):
)
elif request_type == "invite-response":
TeamService.accept_reject_invitation_request(
- team_id, tm.authenticated_user_id, username, role, action
+ team_id, authenticated_user_id, username, role, action
)
return {"Success": "True"}, 200
except Exception as e:
@@ -208,10 +210,11 @@ def post(self, team_id):
description: Internal Server Error
"""
try:
+ authenticated_user_id = token_auth.current_user()
username = request.get_json(force=True)["username"]
- request_user = User.get_by_id(tm.authenticated_user_id)
+ request_user = User.get_by_id(authenticated_user_id)
if (
- TeamService.user_is_manager(team_id, tm.authenticated_user_id)
+ TeamService.user_is_manager(team_id, authenticated_user_id)
or request_user.username == username
):
TeamService.leave_team(team_id, username)
diff --git a/backend/api/teams/resources.py b/backend/api/teams/resources.py
index 7e8ad3719f..73ae0c8177 100644
--- a/backend/api/teams/resources.py
+++ b/backend/api/teams/resources.py
@@ -3,7 +3,7 @@
from backend.models.dtos.team_dto import TeamDTO, NewTeamDTO, UpdateTeamDTO
from backend.services.team_service import TeamService, TeamServiceError, NotFound
-from backend.services.users.authentication_service import token_auth, tm
+from backend.services.users.authentication_service import token_auth
from backend.services.organisation_service import OrganisationService
from backend.services.users.user_service import UserService
@@ -72,17 +72,18 @@ def post(self, team_id):
team_dto.team_id = team_id
team_dto.validate()
+ authenticated_user_id = token_auth.current_user()
team_details_dto = TeamService.get_team_as_dto(
- team_id, tm.authenticated_user_id
+ team_id, authenticated_user_id
)
org = TeamService.assert_validate_organisation(team_dto.organisation_id)
TeamService.assert_validate_members(team_details_dto)
if not TeamService.user_is_manager(
- team_id, tm.authenticated_user_id
+ team_id, authenticated_user_id
) and not OrganisationService.can_user_manage_organisation(
- org.id, tm.authenticated_user_id
+ org.id, authenticated_user_id
):
return {"Error": "User is not a admin or a manager for the team"}, 401
except DataError as e:
@@ -165,10 +166,11 @@ def patch(self, team_id):
team_dto.team_id = team_id
team_dto.validate()
+ authenticated_user_id = token_auth.current_user()
if not TeamService.user_is_manager(
- team_id, tm.authenticated_user_id
+ team_id, authenticated_user_id
) and not OrganisationService.can_user_manage_organisation(
- team.organisation_id, tm.authenticated_user_id
+ team.organisation_id, authenticated_user_id
):
return {"Error": "User is not a admin or a manager for the team"}, 401
except DataError as e:
@@ -213,10 +215,11 @@ def get(self, team_id):
description: Internal Server Error
"""
try:
- if tm.authenticated_user_id is None:
+ authenticated_user_id = token_auth.current_user()
+ if authenticated_user_id is None:
user_id = 0
else:
- user_id = tm.authenticated_user_id
+ user_id = authenticated_user_id
team_dto = TeamService.get_team_as_dto(team_id, user_id)
return team_dto.to_primitive(), 200
except NotFound:
@@ -262,7 +265,7 @@ def delete(self, team_id):
500:
description: Internal Server Error
"""
- if not TeamService.user_is_manager(team_id, tm.authenticated_user_id):
+ if not TeamService.user_is_manager(team_id, token_auth.current_user()):
return {"Error": "User is not a manager for the team"}, 401
try:
TeamService.delete_team(team_id)
@@ -333,7 +336,7 @@ def get(self):
description: Internal Server Error
"""
try:
- user_id = tm.authenticated_user_id
+ user_id = token_auth.current_user()
except Exception as e:
error_msg = f"Teams GET - unhandled error: {str(e)}"
current_app.logger.critical(error_msg)
@@ -418,7 +421,7 @@ def post(self):
500:
description: Internal Server Error
"""
- user_id = tm.authenticated_user_id
+ user_id = token_auth.current_user()
try:
team_dto = NewTeamDTO(request.get_json())
diff --git a/backend/api/users/actions.py b/backend/api/users/actions.py
index 7c3b6b7202..5b4303c178 100644
--- a/backend/api/users/actions.py
+++ b/backend/api/users/actions.py
@@ -77,8 +77,8 @@ def patch(self):
)
user_dto.validate()
-
- if tm.authenticated_user_id != user_dto.id:
+ authenticated_user_id = token_auth.current_user()
+ if authenticated_user_id != user_dto.id:
return {"Error": "Unable to authenticate"}, 401
except ValueError as e:
return {"Error": str(e)}, 400
@@ -88,7 +88,7 @@ def patch(self):
try:
verification_sent = UserService.update_user_details(
- tm.authenticated_user_id, user_dto
+ authenticated_user_id, user_dto
)
return verification_sent, 200
except NotFound:
@@ -197,7 +197,7 @@ def patch(self, username, role):
description: Internal Server Error
"""
try:
- UserService.add_role_to_user(tm.authenticated_user_id, username, role)
+ UserService.add_role_to_user(token_auth.current_user(), username, role)
return {"Success": "Role Added"}, 200
except UserServiceError:
return {"Error": "Not allowed"}, 403
@@ -246,7 +246,7 @@ def patch(self, is_expert):
"""
try:
UserService.set_user_is_expert(
- tm.authenticated_user_id, is_expert == "true"
+ token_auth.current_user(), is_expert == "true"
)
return {"Success": "Expert mode updated"}, 200
except UserServiceError:
@@ -284,7 +284,7 @@ def patch(self):
description: Internal Server Error
"""
try:
- MessageService.resend_email_validation(tm.authenticated_user_id)
+ MessageService.resend_email_validation(token_auth.current_user())
return {"Success": "Verification email resent"}, 200
except Exception as e:
error_msg = f"User GET - unhandled error: {str(e)}"
@@ -341,7 +341,7 @@ def post(self):
user_dto = UserRegisterEmailDTO(dict(email=user_dto.email, details=str(e)))
return user_dto.to_primitive(), 400
except Exception as e:
- details_msg = f"User POST - unhandled error: Unknown error"
+ details_msg = "User POST - unhandled error: Unknown error"
current_app.logger.critical(str(e))
user_dto = UserRegisterEmailDTO(
dict(email=user_dto.email, details=details_msg)
@@ -389,7 +389,7 @@ def post(self):
try:
data = request.get_json()
user_interests = InterestService.create_or_update_user_interests(
- tm.authenticated_user_id, data["interests"]
+ token_auth.current_user(), data["interests"]
)
return user_interests.to_primitive(), 200
except ValueError as e:
diff --git a/backend/api/users/resources.py b/backend/api/users/resources.py
index 2b0a38f120..7aacdde9e6 100644
--- a/backend/api/users/resources.py
+++ b/backend/api/users/resources.py
@@ -2,7 +2,7 @@
from schematics.exceptions import DataError
from backend.models.dtos.user_dto import UserSearchQuery
-from backend.services.users.authentication_service import token_auth, tm
+from backend.services.users.authentication_service import token_auth
from backend.services.users.user_service import UserService, NotFound
from backend.services.project_service import ProjectService
@@ -149,7 +149,7 @@ def get(self, username):
"""
try:
user_dto = UserService.get_user_dto_by_username(
- username, tm.authenticated_user_id
+ username, token_auth.current_user()
)
return user_dto.to_primitive(), 200
except NotFound:
@@ -242,7 +242,7 @@ def get(self):
"""
try:
locked_tasks = ProjectService.get_task_for_logged_in_user(
- tm.authenticated_user_id
+ token_auth.current_user()
)
return locked_tasks.to_primitive(), 200
except Exception as e:
@@ -287,7 +287,7 @@ def get(self):
try:
preferred_locale = request.environ.get("HTTP_ACCEPT_LANGUAGE")
locked_tasks = ProjectService.get_task_details_for_logged_in_user(
- tm.authenticated_user_id, preferred_locale
+ token_auth.current_user(), preferred_locale
)
return locked_tasks.to_primitive(), 200
except NotFound:
@@ -324,7 +324,7 @@ def get(self):
description: Internal Server Error
"""
try:
- favs_dto = UserService.get_projects_favorited(tm.authenticated_user_id)
+ favs_dto = UserService.get_projects_favorited(token_auth.current_user())
return favs_dto.to_primitive(), 200
except NotFound:
return {"Error": "User not found"}, 404
diff --git a/backend/models/dtos/mapping_dto.py b/backend/models/dtos/mapping_dto.py
index b581a33515..70a6893b8b 100644
--- a/backend/models/dtos/mapping_dto.py
+++ b/backend/models/dtos/mapping_dto.py
@@ -1,6 +1,6 @@
from schematics import Model
from schematics.exceptions import ValidationError
-from schematics.types import StringType, IntType, BooleanType, UTCDateTimeType
+from schematics.types import StringType, IntType, UTCDateTimeType
from schematics.types.compound import ListType, ModelType
from backend.models.postgis.statuses import TaskStatus
from backend.models.dtos.mapping_issues_dto import TaskMappingIssueDTO
@@ -86,7 +86,6 @@ class TaskDTO(Model):
per_task_instructions = StringType(
serialized_name="perTaskInstructions", serialize_when_none=False
)
- is_undoable = BooleanType(serialized_name="isUndoable", default=False)
auto_unlock_seconds = IntType(serialized_name="autoUnlockSeconds")
last_updated = UTCDateTimeType(
serialized_name="lastUpdated", serialize_when_none=False
diff --git a/backend/models/postgis/project.py b/backend/models/postgis/project.py
index 667b7d55d0..bd3441b2e9 100644
--- a/backend/models/postgis/project.py
+++ b/backend/models/postgis/project.py
@@ -438,7 +438,7 @@ def update(self, project_dto: ProjectDTO):
team = Team.get(team_dto.team_id)
if team is None:
- raise NotFound(f"Team not found")
+ raise NotFound("Team not found")
role = TeamRoles[team_dto.role].value
ProjectTeams(project=self, team=team, role=role)
@@ -1023,6 +1023,7 @@ def as_dto_for_mapping(
is_allowed_user = False
if authenticated_user_id:
user = User.get_by_id(authenticated_user_id)
+
if (
UserRole(user.role) == UserRole.ADMIN
or authenticated_user_id == self.author_id
diff --git a/backend/models/postgis/task.py b/backend/models/postgis/task.py
index bc553c368b..06f6531dd8 100644
--- a/backend/models/postgis/task.py
+++ b/backend/models/postgis/task.py
@@ -189,7 +189,10 @@ class TaskHistory(db.Model):
action_text = db.Column(db.String)
action_date = db.Column(db.DateTime, nullable=False, default=timestamp)
user_id = db.Column(
- db.BigInteger, db.ForeignKey("users.id", name="fk_users"), nullable=False
+ db.BigInteger,
+ db.ForeignKey("users.id", name="fk_users"),
+ index=True,
+ nullable=False,
)
invalidation_history = db.relationship(
TaskInvalidationHistory, lazy="dynamic", cascade="all"
@@ -203,6 +206,7 @@ class TaskHistory(db.Model):
[task_id, project_id], ["tasks.id", "tasks.project_id"], name="fk_tasks"
),
db.Index("idx_task_history_composite", "task_id", "project_id"),
+ db.Index("idx_task_history_project_id_user_id", "user_id", "project_id"),
{},
)
@@ -494,13 +498,13 @@ class Task(db.Model):
geometry = db.Column(Geometry("MULTIPOLYGON", srid=4326))
task_status = db.Column(db.Integer, default=TaskStatus.READY.value)
locked_by = db.Column(
- db.BigInteger, db.ForeignKey("users.id", name="fk_users_locked")
+ db.BigInteger, db.ForeignKey("users.id", name="fk_users_locked"), index=True
)
mapped_by = db.Column(
- db.BigInteger, db.ForeignKey("users.id", name="fk_users_mapper")
+ db.BigInteger, db.ForeignKey("users.id", name="fk_users_mapper"), index=True
)
validated_by = db.Column(
- db.BigInteger, db.ForeignKey("users.id", name="fk_users_validator")
+ db.BigInteger, db.ForeignKey("users.id", name="fk_users_validator"), index=True
)
# Mapped objects
diff --git a/backend/services/mapping_service.py b/backend/services/mapping_service.py
index 77b299dd1a..9fa73a6573 100644
--- a/backend/services/mapping_service.py
+++ b/backend/services/mapping_service.py
@@ -44,15 +44,11 @@ def get_task(task_id: int, project_id: int) -> Task:
@staticmethod
def get_task_as_dto(
- task_id: int,
- project_id: int,
- preferred_local: str = "en",
- logged_in_user_id: int = None,
+ task_id: int, project_id: int, preferred_local: str = "en",
) -> TaskDTO:
""" Get task as DTO for transmission over API """
task = MappingService.get_task(task_id, project_id)
task_dto = task.as_dto_with_instructions(preferred_local)
- task_dto.is_undoable = MappingService._is_task_undoable(logged_in_user_id, task)
return task_dto
@staticmethod
diff --git a/backend/services/messaging/message_service.py b/backend/services/messaging/message_service.py
index 15d7ecf59a..6fab829242 100644
--- a/backend/services/messaging/message_service.py
+++ b/backend/services/messaging/message_service.py
@@ -61,6 +61,8 @@ def send_message_after_validation(
user = UserService.get_user_by_id(mapped_by)
if user.validation_message is False:
return # No need to send validation message
+ if user.projects_notifications is False:
+ return
text_template = get_template(
"invalidation_message_en.txt"
@@ -160,6 +162,10 @@ def send_message_after_comment(
except NotFound:
continue # If we can't find the user, keep going no need to fail
+ # Validate mention_notification.
+ if user.mentions_notifications is False:
+ continue
+
message = Message()
message.message_type = MessageType.MENTION_NOTIFICATION.value
message.project_id = project_id
@@ -197,6 +203,9 @@ def send_message_after_comment(
except NotFound:
continue # If we can't find the user, keep going no need to fail
+ if user.comments_notifications is False:
+ continue
+
message = Message()
message.message_type = MessageType.TASK_COMMENT_NOTIFICATION.value
message.project_id = project_id
@@ -291,6 +300,10 @@ def send_message_after_chat(chat_from: int, chat: str, project_id: int):
current_app.logger.error(f"Username {username} not found")
continue # If we can't find the user, keep going no need to fail
+ # Validate mention_notification.
+ if user.mentions_notifications is False:
+ continue
+
message = Message()
message.message_type = MessageType.MENTION_NOTIFICATION.value
message.project_id = project_id
@@ -319,6 +332,9 @@ def send_message_after_chat(chat_from: int, chat: str, project_id: int):
except NotFound:
continue # If we can't find the user, keep going no need to fail
+ if user.comments_notifications is False:
+ continue
+
message = Message()
message.message_type = MessageType.PROJECT_CHAT_NOTIFICATION.value
message.project_id = project_id
@@ -353,6 +369,8 @@ def send_favorite_project_activities(user_id: int):
)
)
user = UserService.get_user_dto_by_id(user_id)
+ if user.projects_notifications is False:
+ return
messages = []
for project in recently_updated_projects:
activity_message = []
diff --git a/backend/services/project_admin_service.py b/backend/services/project_admin_service.py
index 21b5c19f38..e84b63614d 100644
--- a/backend/services/project_admin_service.py
+++ b/backend/services/project_admin_service.py
@@ -130,7 +130,10 @@ def update_project(project_dto: ProjectDTO, authenticated_user_id: int):
project = ProjectAdminService._get_project_by_id(project_id)
project.update(project_dto)
else:
- raise ValueError("Project can only be updated by admins or by the owner")
+ raise ValueError(
+ str(project_id)
+ + " :Project can only be updated by admins or by the owner"
+ )
return project
@@ -298,31 +301,32 @@ def is_user_action_permitted_on_project(
authenticated_user_id, author_id
)
is_org_manager = False
- if hasattr(project, "organisation_id") and project.organisation_id:
- org_id = project.organisation_id
- org = OrganisationService.get_organisation_by_id_as_dto(
- org_id, authenticated_user_id
- )
- if org.is_manager:
- is_org_manager = True
-
- is_manager_team = None
- if hasattr(project, "project_teams") and project.project_teams:
- teams_dto = TeamService.get_project_teams_as_dto(project_id)
- if teams_dto.teams:
- teams_allowed = [
- team_dto
- for team_dto in teams_dto.teams
- if team_dto.role in allowed_roles
- ]
- user_membership = [
- team_dto.team_id
- for team_dto in teams_allowed
- if TeamService.is_user_member_of_team(
- team_dto.team_id, authenticated_user_id
- )
- ]
- if user_membership:
- is_manager_team = True
+ is_manager_team = False
+ if not (is_admin or is_author):
+ if hasattr(project, "organisation_id") and project.organisation_id:
+ org_id = project.organisation_id
+ org = OrganisationService.get_organisation_by_id_as_dto(
+ org_id, authenticated_user_id
+ )
+ if org.is_manager:
+ is_org_manager = True
+ else:
+ if hasattr(project, "project_teams") and project.project_teams:
+ teams_dto = TeamService.get_project_teams_as_dto(project_id)
+ if teams_dto.teams:
+ teams_allowed = [
+ team_dto
+ for team_dto in teams_dto.teams
+ if team_dto.role in allowed_roles
+ ]
+ user_membership = [
+ team_dto.team_id
+ for team_dto in teams_allowed
+ if TeamService.is_user_member_of_team(
+ team_dto.team_id, authenticated_user_id
+ )
+ ]
+ if user_membership:
+ is_manager_team = True
return is_admin or is_author or is_org_manager or is_manager_team
diff --git a/backend/services/users/authentication_service.py b/backend/services/users/authentication_service.py
index e7a8fff1a7..aaf5c16027 100644
--- a/backend/services/users/authentication_service.py
+++ b/backend/services/users/authentication_service.py
@@ -20,7 +20,6 @@ def verify_token(token):
""" Verify the supplied token and check user role is correct for the requested resource"""
tm.authenticated_user_id = None
if not token:
- current_app.logger.debug(f"Token not supplied {request.base_url}")
return False
try:
@@ -37,7 +36,7 @@ def verify_token(token):
tm.authenticated_user_id = (
user_id # Set the user ID on the decorator as a convenience
)
- return True # All tests passed token is good for the requested resource
+ return user_id # All tests passed token is good for the requested resource
class AuthServiceError(Exception):
diff --git a/backend/services/users/user_service.py b/backend/services/users/user_service.py
index 9b1045b984..479bf9341a 100644
--- a/backend/services/users/user_service.py
+++ b/backend/services/users/user_service.py
@@ -564,7 +564,7 @@ def add_role_to_user(admin_user_id: int, username: str, role: str):
admin_role = UserRole(admin.role)
if admin_role != UserRole.ADMIN and requested_role == UserRole.ADMIN:
- raise UserServiceError(f"You must be an Admin to assign Admin role")
+ raise UserServiceError("You must be an Admin to assign Admin role")
user = UserService.get_user_by_username(username)
user.set_user_role(requested_role)
diff --git a/backend/services/validator_service.py b/backend/services/validator_service.py
index 0b0963b4d1..e37b73d866 100644
--- a/backend/services/validator_service.py
+++ b/backend/services/validator_service.py
@@ -63,7 +63,7 @@ def lock_tasks_for_validation(validation_dto: LockForValidationDTO) -> TaskDTOs:
)
if not user_can_validate:
raise ValidatorServiceError(
- f"Tasks cannot be validated by the same user who marked task as mapped or badimagery"
+ "Tasks cannot be validated by the same user who marked task as mapped or badimagery"
)
tasks_to_lock.append(task)
diff --git a/frontend/src/components/projectDetail/index.js b/frontend/src/components/projectDetail/index.js
index 7ef9169bd0..2379622320 100644
--- a/frontend/src/components/projectDetail/index.js
+++ b/frontend/src/components/projectDetail/index.js
@@ -41,7 +41,7 @@ const ProjectDetailTypeBar = (props) => {