@@ -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 {
0 commit comments