Skip to content

Commit

Permalink
set up way to request lockUser to unlock task
Browse files Browse the repository at this point in the history
  • Loading branch information
jschwarz2030 committed Feb 17, 2025
1 parent e0aeb47 commit f3e5a5b
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 3 deletions.
44 changes: 42 additions & 2 deletions app/org/maproulette/framework/controller/TaskController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ package org.maproulette.framework.controller
import akka.util.ByteString
import javax.inject.Inject
import org.maproulette.data.ActionManager
import org.maproulette.framework.service.{ServiceManager, TaskService, TaskClusterService}
import org.maproulette.framework.service.{
ServiceManager,
TaskService,
TaskClusterService,
NotificationService
}
import org.maproulette.framework.psql.Paging
import org.maproulette.framework.model.User
import org.maproulette.framework.mixins.TaskJSONMixin
Expand All @@ -33,7 +38,8 @@ class TaskController @Inject() (
taskClusterService: TaskClusterService,
components: ControllerComponents,
val taskDAL: TaskDAL,
val serviceManager: ServiceManager
val serviceManager: ServiceManager,
val notificationService: NotificationService
) extends AbstractController(components)
with MapRouletteController
with TaskJSONMixin {
Expand Down Expand Up @@ -240,4 +246,38 @@ class TaskController @Inject() (
}
}
}

/**
* Request that a task be unlocked by sending a notification to the user who has it locked
*
* @param taskId The id of the task that is locked
* @return 200 OK with success message, or error status
*/
def requestTaskUnlock(taskId: Long): Action[AnyContent] = Action.async { implicit request =>
this.sessionManager.authenticatedRequest { implicit user =>
val task = taskDAL.retrieveById(taskId)

task match {
case Some(t) => {
val lockerId = taskDAL.lockItem(user, t)
if (lockerId != user.id) {
this.serviceManager.user.retrieve(lockerId) match {
case Some(lockUser) =>
this.serviceManager.notification
.createTaskUnlockRequestNotification(user, lockUser, t)
Ok(Json.obj("message" -> "Unlock request notification has been sent successfully"))
case None =>
throw new IllegalAccessException(s"Your notification request encountered an error")
}
} else {
throw new IllegalAccessException(s"Your notification request encountered an error")
}
}
case None =>
throw new NotFoundException(
s"Task with $taskId not found, unable to process unlock notification request."
)
}
}
}
}
5 changes: 4 additions & 1 deletion app/org/maproulette/framework/model/UserNotification.scala
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ object UserNotification extends CommonField {
val NOTIFICATION_TYPE_REVISION_COUNT_NAME = "Revision Count"
val NOTIFICATION_TYPE_CHALLENGE_COMMENT = 14
val NOTIFICATION_TYPE_CHALLENGE_COMMENT_NAME = "Challenge Comment"
val NOTIFICATION_TYPE_CHALLENGE_UNLOCK_REQUESTED = 15
val NOTIFICATION_TYPE_CHALLENGE_UNLOCK_REQUESTED_NAME = "Challenge Unlock Requested"

val notificationTypeMap = Map(
NOTIFICATION_TYPE_SYSTEM -> NOTIFICATION_TYPE_SYSTEM_NAME,
Expand All @@ -94,7 +96,8 @@ object UserNotification extends CommonField {
NOTIFICATION_TYPE_TEAM -> NOTIFICATION_TYPE_TEAM_NAME,
NOTIFICATION_TYPE_FOLLOW -> NOTIFICATION_TYPE_FOLLOW_NAME,
NOTIFICATION_TYPE_MAPPER_CHALLENGE_COMPLETED -> NOTIFICATION_TYPE_MAPPER_CHALLENGE_COMPLETED_NAME,
NOTIFICATION_TYPE_CHALLENGE_COMMENT -> NOTIFICATION_TYPE_CHALLENGE_COMMENT_NAME
NOTIFICATION_TYPE_CHALLENGE_COMMENT -> NOTIFICATION_TYPE_CHALLENGE_COMMENT_NAME,
NOTIFICATION_TYPE_CHALLENGE_UNLOCK_REQUESTED -> NOTIFICATION_TYPE_CHALLENGE_UNLOCK_REQUESTED_NAME
)

val NOTIFICATION_IGNORE = 0 // ignore notification
Expand Down
28 changes: 28 additions & 0 deletions app/org/maproulette/framework/service/NotificationService.scala
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,8 @@ class NotificationService @Inject() (
case UserNotification.NOTIFICATION_TYPE_FOLLOW => subscriptions.follow
case UserNotification.NOTIFICATION_TYPE_CHALLENGE_COMMENT =>
UserNotification.NOTIFICATION_EMAIL_IMMEDIATE
case UserNotification.NOTIFICATION_TYPE_CHALLENGE_UNLOCK_REQUESTED =>
UserNotification.NOTIFICATION_EMAIL_IMMEDIATE
case _ => throw new InvalidException("Invalid notification type")
}

Expand Down Expand Up @@ -580,4 +582,30 @@ class NotificationService @Inject() (
permission.hasSuperAccess(user)
this.repository.usersWithTasksToBeReviewed()
}

/**
* Create new notification requesting that a task be unlocked
*
* @param fromUser The user requesting the unlock
* @param lockedByUser The user receiving the request
* @param task The challenge that needs to be unlocked
*/
def createTaskUnlockRequestNotification(
fromUser: User,
lockedByUser: User,
task: Task
): Unit = {
val fromUserName = Some(fromUser.osmProfile.displayName)
this.addNotification(
UserNotification(
-1,
userId = lockedByUser.id,
notificationType = UserNotification.NOTIFICATION_TYPE_CHALLENGE_UNLOCK_REQUESTED,
fromUsername = fromUserName,
taskId = Some(task.id),
description = Some(s"${fromUserName} is requesting you to unlock a task")
),
User.superUser
)
}
}
21 changes: 21 additions & 0 deletions conf/v2_route/task.api
Original file line number Diff line number Diff line change
Expand Up @@ -915,4 +915,25 @@ GET /tasks/box/:left/:bottom/:right/:top @org.maproulette.framework.c
# '200':
# description: Success
###
# tags: [ Task ]
# summary: Request task unlock
# description: Sends a notification to the user who has locked a task requesting them to unlock it
# responses:
# '200':
# description: Ok with a standard message
# content:
# application/json:
# schema:
# $ref: '#/components/schemas/org.maproulette.exception.StatusMessage'
# '401':
# description: The user is not authorized to make this request
# '404':
# description: The task or user was not found
# parameters:
# - name: taskId
# in: path
# description: The id of the task that is locked
###
PUT /task/:taskId/unlock/request @org.maproulette.framework.controller.TaskController.requestTaskUnlock(taskId:Long)
###
GET /taskCluster @org.maproulette.framework.controller.TaskController.getTaskClusters(points:Int ?= 100)

0 comments on commit f3e5a5b

Please sign in to comment.