TeamRestEndpoint.java
/*
* The coLAB project
* Copyright (C) 2021-2024 AlbaSim, MEI, HEIG-VD, HES-SO
*
* Licensed under the MIT License
*/
package ch.colabproject.colab.api.rest.team;
import ch.colabproject.colab.api.controller.team.AssignmentManager;
import ch.colabproject.colab.api.controller.team.TeamManager;
import ch.colabproject.colab.api.exceptions.ColabMergeException;
import ch.colabproject.colab.api.model.team.TeamMember;
import ch.colabproject.colab.api.model.team.TeamRole;
import ch.colabproject.colab.api.model.team.acl.Assignment;
import ch.colabproject.colab.api.model.team.acl.HierarchicalPosition;
import ch.colabproject.colab.api.model.team.acl.InvolvementLevel;
import ch.colabproject.colab.api.persistence.jpa.team.TeamMemberDao;
import ch.colabproject.colab.api.persistence.jpa.team.TeamRoleDao;
import ch.colabproject.colab.api.rest.utils.SerializationStringWrapper;
import ch.colabproject.colab.generator.model.annotations.AuthenticationRequired;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.util.List;
/**
* REST Teams controller. Allow to manage roles and teams members
*
* @author maxence
* @author sandra
*/
@Path("teams")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@AuthenticationRequired
public class TeamRestEndpoint {
/** logger */
private static final Logger logger = LoggerFactory.getLogger(TeamRestEndpoint.class);
/** Team specific logic */
@Inject
private TeamManager teamManager;
/** Assignment specific logic */
@Inject
private AssignmentManager assignmentManager;
/** Team member persistence handling */
@Inject
private TeamMemberDao teamMemberDao;
/** Team role persistence handling */
@Inject
private TeamRoleDao teamRoleDao;
// *********************************************************************************************
// TeamMembers
// *********************************************************************************************
/**
* Get the members of the project team
*
* @param projectId id of the project
*
* @return list of team members
*/
@GET
@Path("members/byproject/{projectId: [0-9]+}")
public List<TeamMember> getTeamMembersForProject(@PathParam("projectId") Long projectId) {
logger.debug("Get project #{} members", projectId);
return teamManager.getTeamMembersForProject(projectId);
}
/**
* Get a TeamMember
*
* @param memberId id of the team member
*
* @return the team member
*/
@GET
@Path("member/{memberId: [0-9]+}")
public TeamMember getTeamMember(@PathParam("memberId") Long memberId) {
logger.debug("Get member #{}", memberId);
return teamMemberDao.findTeamMember(memberId);
}
/**
* Update a TeamMember. Only fields which are editable by users will be impacted.
*
* @param member new value
*
* @throws ColabMergeException if update failed
*/
@PUT
@Path("member")
public void updateTeamMember(TeamMember member) throws ColabMergeException {
logger.debug("Update member {}", member);
teamMemberDao.updateTeamMember(member);
}
/**
* Update hierarchical position of a member
*
* @param memberId id of the member
* @param position new hierarchical position
*/
@PUT
@Path("member/{memberId: [0-9]+}/{position}")
public void changeMemberPosition(
@PathParam("memberId") Long memberId,
@PathParam("position") HierarchicalPosition position
) {
teamManager.updatePosition(memberId, position);
}
/**
* Delete a team member
*
* @param memberId id of the member
*/
@DELETE
@Path("member/{memberId: [0-9]+}")
public void deleteTeamMember(@PathParam("memberId") Long memberId) {
logger.debug("Delete team member #{}", memberId);
teamManager.deleteTeamMember(memberId);
}
// *********************************************************************************************
// Invitations and sharing
// *********************************************************************************************
/**
* Send invitation to someone.
*
* @param projectId id of the project
* @param email recipient address
*
* @return the pending team member
*/
@POST
@Path("Invite/{projectId: [0-9]+}/{email}")
public TeamMember inviteSomeone(@PathParam("projectId") Long projectId,
@PathParam("email") String email) {
logger.debug("Invite {} to joint project #{}", email, projectId);
return teamManager.invite(projectId, email);
}
/**
* Create a token to share the project.
*
* @param projectId The id of the project that will become visible (mandatory)
* @param cardId The id of the card that will become editable (optional)
*
* @return the URL to use to consume the token
*/
@POST
@Path("sharingLink/generate/{projectId: [0-9]+}/{cardId: [0-9]+}")
public SerializationStringWrapper generateSharingLinkToken(@PathParam("projectId") Long projectId,
@PathParam("cardId") Long cardId) {
String url = teamManager.generateSharingLinkToken(projectId, cardId);
return SerializationStringWrapper.build(url);
}
/**
* Delete all sharing link tokens for the given project.
*
* @param projectId the id of the project
*/
@DELETE
@Path("sharingLink/deleteByProject/{projectId: [0-9]+}")
public void deleteSharingLinkTokensByProject(@PathParam("projectId") Long projectId) {
teamManager.deleteSharingLinkTokensByProject(projectId);
}
/**
* Delete all sharing link tokens for the given card.
*
* @param cardId the id of the card
*/
@DELETE
@Path("sharingLink/deleteByCard/{cardId: [0-9]+}")
public void deleteSharingLinkTokensByCard(@PathParam("cardId") Long cardId) {
teamManager.deleteSharingLinkTokensByCard(cardId);
}
// *********************************************************************************************
// Roles
// *********************************************************************************************
/**
* Get the team roles defined in the given project
*
* @param projectId the id of the project
*
* @return list of team roles
*/
@GET
@Path("roles/byproject/{projectId: [0-9]+}")
public List<TeamRole> getTeamRolesForProject(@PathParam("projectId") Long projectId) {
logger.debug("Get project #{} roles", projectId);
return teamManager.getTeamRolesForProject(projectId);
}
/**
* Create a role. The role must have a projectId set.
*
* @param role the role to create
*
* @return id of the new role
*/
@POST
@Path("role")
public Long createRole(TeamRole role) {
logger.debug("Create role {}", role);
teamManager.createRole(role);
return role.getId();
}
/**
* Get a role
*
* @param roleId id of the role
*
* @return the role
*/
@GET
@Path("role/{roleId: [0-9]+}")
public TeamRole getRole(@PathParam("roleId") Long roleId) {
logger.debug("Get Role #{}", roleId);
return teamRoleDao.findRole(roleId);
}
/**
* Update a role. Only fields which are editable by users will be impacted.
*
* @param role the role to update
*
* @throws ColabMergeException if update failed
*/
@PUT
@Path("role")
public void updateRole(TeamRole role) throws ColabMergeException {
logger.debug("Update role {}", role);
teamRoleDao.updateRole(role);
}
/**
* Delete a role
* <p>
* TODO: shall we allow to delete non-empty roles?
*
* @param roleId id of the role to delete id of the role to delete
*/
@DELETE
@Path("role/{roleId: [0-9]+}")
public void deleteRole(@PathParam("roleId") Long roleId) {
logger.debug("Delete role #{}", roleId);
teamManager.deleteRole(roleId);
}
/**
* Give a role to a member. Member and role must belong to the same project. CurrentUser must
* have the right to edit the role
*
* @param roleId id of the role
* @param memberId id of the team member
*/
@PUT
@Path("role/{roleId: [0-9]+}/giveto/{memberId: [0-9]+}")
public void giveRoleTo(
@PathParam("roleId") Long roleId,
@PathParam("memberId") Long memberId
) {
logger.debug("Give role #{} to member#{}", roleId, memberId);
teamManager.giveRole(roleId, memberId);
}
/**
* Remove a role from some team member. CurrentUser must have the right to edit the role.
*
* @param roleId id of the role
* @param memberId id of the team member
*/
@PUT
@Path("role/{roleId: [0-9]+}/removeto/{memberId : [0-9]+}")
public void removeRoleFrom(
@PathParam("roleId") Long roleId,
@PathParam("memberId") Long memberId
) {
logger.debug("Remove role #{} to member#{}", roleId, memberId);
teamManager.removeRole(roleId, memberId);
}
// *********************************************************************************************
// Assignments
// *********************************************************************************************
/**
* Get Assignments related to the given project
*
* @param projectId the id of the project
*
* @return assignments list
*/
@GET
@Path("assignments/byproject/{projectId: [0-9]+}")
public List<Assignment> getAssignmentsForProject(@PathParam("projectId") Long projectId) {
logger.debug("Get all assignments related to project #{}", projectId);
return assignmentManager.getAssignmentsForProject(projectId);
}
/**
* Get assignments related to the given card
*
* @param cardId id of the card
*
* @return assignments list
*/
@GET
@Path("assignments/bycard/{cardId: [0-9]+}")
public List<Assignment> getAssignmentsForCard(@PathParam("cardId") Long cardId) {
return assignmentManager.getAssignmentsForCard(cardId);
}
/**
* Add an assignment for a card and a member without involvement level
*
* @param cardId id of the card
* @param memberId id of the team member
*/
@PUT
@Path("assignment/card/{cardId: [0-9]+}/member/{memberId: [0-9]+}")
public void createEmptyAssignment(
@PathParam("cardId") Long cardId,
@PathParam("memberId") Long memberId
) {
assignmentManager.setAssignment(cardId, memberId, null);
}
/**
* Set an assignment for a card and a member
*
* @param cardId id of the card
* @param memberId id of the team member
* @param level involvement level
*/
@POST
@Path("assignment/card/{cardId: [0-9]+}/member/{memberId: [0-9]+}/{level}")
public void setAssignment(
@PathParam("cardId") Long cardId,
@PathParam("memberId") Long memberId,
@PathParam("level") InvolvementLevel level
) {
assignmentManager.setAssignment(cardId, memberId, level);
}
/**
* Remove the level of an assignment level for a card and a member
*
* @param cardId id of the card
* @param memberId id of the team member
*/
@POST
@Path("assignment/card/{cardId: [0-9]+}/member/{memberId: [0-9]+}")
public void removeAssignmentLevel(
@PathParam("cardId") Long cardId,
@PathParam("memberId") Long memberId
) {
assignmentManager.setAssignment(cardId, memberId, null);
}
/**
* Delete all assignments for a card and a member
*
* @param cardId id of the card
* @param memberId id of the team member
*/
@DELETE
@Path("assignment/card/{cardId: [0-9]+}/member/{memberId: [0-9]+}")
public void deleteAssignments(
@PathParam("cardId") Long cardId,
@PathParam("memberId") Long memberId
) {
assignmentManager.deleteAssignment(cardId, memberId);
}
// *********************************************************************************************
//
// *********************************************************************************************
}