Skip to content

Commit c8bdd05

Browse files
committed
feat: API for adding a member to a project
(returns an error if the user is already a member)
1 parent 790c87f commit c8bdd05

File tree

2 files changed

+86
-1
lines changed

2 files changed

+86
-1
lines changed

reqbaz/src/main/java/de/rwth/dbis/acis/bazaar/service/resources/ProjectsResource.java

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -944,6 +944,90 @@ public Response createTag(@PathParam("projectId") int projectId,
944944
}
945945
}
946946

947+
/**
948+
* Add a member to the project
949+
*
950+
* @param projectId id of the project to update
951+
* @param projectMember The new project member
952+
* @return
953+
*/
954+
@POST
955+
@Path("/{projectId}/members")
956+
@Consumes(MediaType.APPLICATION_JSON)
957+
@Produces(MediaType.APPLICATION_JSON)
958+
@ApiOperation(value = "This method allows to add a project member.")
959+
@ApiResponses(value = {
960+
@ApiResponse(code = HttpURLConnection.HTTP_CREATED, message = "Member added"),
961+
@ApiResponse(code = HttpURLConnection.HTTP_UNAUTHORIZED, message = "Unauthorized"),
962+
@ApiResponse(code = HttpURLConnection.HTTP_CONFLICT, message = "User is already member"),
963+
@ApiResponse(code = HttpURLConnection.HTTP_INTERNAL_ERROR, message = "Internal server problems")
964+
})
965+
public Response addMember(@PathParam("projectId") int projectId,
966+
@ApiParam(value = "New project member", required = true) ProjectMember projectMember) {
967+
DALFacade dalFacade = null;
968+
try {
969+
String registrarErrors = bazaarService.notifyRegistrars(EnumSet.of(BazaarFunction.VALIDATION, BazaarFunction.USER_FIRST_LOGIN_HANDLING));
970+
if (registrarErrors != null) {
971+
ExceptionHandler.getInstance().throwException(ExceptionLocation.BAZAARSERVICE, ErrorCode.UNKNOWN, registrarErrors);
972+
}
973+
Agent agent = Context.getCurrent().getMainAgent();
974+
String userId = agent.getIdentifier();
975+
976+
// Take Object for generic error handling
977+
Set<ConstraintViolation<Object>> violations = bazaarService.validate(projectMember);
978+
if (violations.size() > 0) {
979+
ExceptionHandler.getInstance().handleViolations(violations);
980+
}
981+
982+
dalFacade = bazaarService.getDBConnection();
983+
Integer internalUserId = dalFacade.getUserIdByLAS2PeerId(userId);
984+
985+
PrivilegeEnum privilege = PrivilegeEnum.Modify_MEMBERS;
986+
// Only Admins should be able to create new admins.
987+
// Differentiate here
988+
if (projectMember.getRole() == ProjectRole.ProjectAdmin) {
989+
privilege = PrivilegeEnum.Modify_ADMIN_MEMBERS;
990+
}
991+
992+
boolean authorized = new AuthorizationManager().isAuthorized(internalUserId, privilege, projectId, dalFacade);
993+
if (!authorized) {
994+
ExceptionHandler.getInstance().throwException(ExceptionLocation.BAZAARSERVICE, ErrorCode.AUTHORIZATION, Localization.getInstance().getResourceBundle().getString("error.authorization.project.modify"));
995+
}
996+
997+
// ensure the given user exists
998+
dalFacade.getUserById(projectMember.getUserId());
999+
1000+
// we want to *add* a member so throw error if user is already member
1001+
if (dalFacade.isUserProjectMember(projectId, projectMember.getUserId())) {
1002+
ExceptionHandler.getInstance().throwException(ExceptionLocation.BAZAARSERVICE, ErrorCode.UNKNOWN, Localization.getInstance().getResourceBundle().getString("error.validation.project_member.already_exists"));
1003+
}
1004+
1005+
dalFacade.addUserToRole(projectMember.getUserId(), projectMember.getRole().name(), projectId);
1006+
1007+
bazaarService.getNotificationDispatcher().dispatchNotification(OffsetDateTime.now(), Activity.ActivityAction.UPDATE, MonitoringEvent.SERVICE_CUSTOM_MESSAGE_6, projectId, Activity.DataType.PROJECT, internalUserId);
1008+
1009+
// TODO Return 'location' header to conform to HTTP specification
1010+
return Response.status(Response.Status.CREATED).build();
1011+
} catch (BazaarException bex) {
1012+
if (bex.getErrorCode() == ErrorCode.AUTHORIZATION) {
1013+
return Response.status(Response.Status.UNAUTHORIZED).entity(ExceptionHandler.getInstance().toJSON(bex)).build();
1014+
} else if (bex.getErrorCode() == ErrorCode.NOT_FOUND) {
1015+
return Response.status(Response.Status.NOT_FOUND).entity(ExceptionHandler.getInstance().toJSON(bex)).build();
1016+
} else {
1017+
logger.warning(bex.getMessage());
1018+
Context.get().monitorEvent(MonitoringEvent.SERVICE_ERROR, "Update project");
1019+
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(ExceptionHandler.getInstance().toJSON(bex)).build();
1020+
}
1021+
} catch (Exception ex) {
1022+
BazaarException bex = ExceptionHandler.getInstance().convert(ex, ExceptionLocation.BAZAARSERVICE, ErrorCode.UNKNOWN, ex.getMessage());
1023+
logger.warning(bex.getMessage());
1024+
Context.get().monitorEvent(MonitoringEvent.SERVICE_ERROR, "Update project");
1025+
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(ExceptionHandler.getInstance().toJSON(bex)).build();
1026+
} finally {
1027+
bazaarService.closeDBConnection(dalFacade);
1028+
}
1029+
}
1030+
9471031
/**
9481032
* Allows to update a certain project.
9491033
*
@@ -962,7 +1046,7 @@ public Response createTag(@PathParam("projectId") int projectId,
9621046
@ApiResponse(code = HttpURLConnection.HTTP_NOT_FOUND, message = "Not found"),
9631047
@ApiResponse(code = HttpURLConnection.HTTP_INTERNAL_ERROR, message = "Internal server problems")
9641048
})
965-
public Response updateMembership(@PathParam("projectId") int projectId,
1049+
public Response updateMember(@PathParam("projectId") int projectId,
9661050
@ApiParam(value = "New or updated project member", required = true) List<ProjectMember> projectMembers) {
9671051
DALFacade dalFacade = null;
9681052
try {

reqbaz/src/main/resources/i18n/Translation_en.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ error.unknown_exception=%s Error in %s\: %s ExceptionCode\: %d.
5151
category.uncategorized.Name=General Requirements
5252
category.uncategorized.Description=Requirements which do not belong to any category.
5353
error.validation=On %s constraint violation has been detected, because you sent %s and the problem is\: %s.
54+
error.validation.project_member.already_exists=The use is already a member of this project.
5455
error.authorization.project.read=You do not have rights to read this project.
5556
error.authorization.project.modify=You do not have rights to modify this project.
5657
error.authorization.requirement.modify=Only the creator can modify requirements.

0 commit comments

Comments
 (0)