This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository coselmar. See http://git.codelutin.com/coselmar.git commit 0cb0bb641b320eb164e02052d2fa0251b1805f13 Author: Yannick Martel <martel@©odelutin.com> Date: Tue Jan 19 17:55:04 2016 +0100 refs-40 #7927 Add service to get questions relative to an user by its role --- .../coselmar/beans/QuestionSearchExample.java | 11 ++ .../persistence/entity/QuestionTopiaDao.java | 21 +++ .../ifremer/coselmar/beans/QuestionSearchBean.java | 38 +++++ .../ifremer/coselmar/beans/QuestionUserRole.java | 11 ++ .../coselmar/services/v1/QuestionsWebService.java | 72 +++++++++ coselmar-rest/src/main/resources/mapping | 1 + .../coselmar/services/QuestionsWebServiceTest.java | 161 +++++++++++++++++++++ 7 files changed, 315 insertions(+) diff --git a/coselmar-persistence/src/main/java/fr/ifremer/coselmar/beans/QuestionSearchExample.java b/coselmar-persistence/src/main/java/fr/ifremer/coselmar/beans/QuestionSearchExample.java index 3ac3c15..323cfeb 100644 --- a/coselmar-persistence/src/main/java/fr/ifremer/coselmar/beans/QuestionSearchExample.java +++ b/coselmar-persistence/src/main/java/fr/ifremer/coselmar/beans/QuestionSearchExample.java @@ -24,6 +24,7 @@ package fr.ifremer.coselmar.beans; * #L% */ +import fr.ifremer.coselmar.persistence.entity.CoselmarUser; import fr.ifremer.coselmar.persistence.entity.Question; import java.io.Serializable; @@ -58,6 +59,8 @@ public class QuestionSearchExample extends SearchExample<Question> { protected boolean orderDesc; + protected CoselmarUser participant; + public Date getSubmissionAfterDate() { return submissionAfterDate; } @@ -107,4 +110,12 @@ public class QuestionSearchExample extends SearchExample<Question> { public void setOrderDesc(boolean orderDesc) { this.orderDesc = orderDesc; } + + public CoselmarUser getParticipant() { + return participant; + } + + public void setParticipant(CoselmarUser participant) { + this.participant = participant; + } } diff --git a/coselmar-persistence/src/main/java/fr/ifremer/coselmar/persistence/entity/QuestionTopiaDao.java b/coselmar-persistence/src/main/java/fr/ifremer/coselmar/persistence/entity/QuestionTopiaDao.java index 5ce33ab..6973305 100644 --- a/coselmar-persistence/src/main/java/fr/ifremer/coselmar/persistence/entity/QuestionTopiaDao.java +++ b/coselmar-persistence/src/main/java/fr/ifremer/coselmar/persistence/entity/QuestionTopiaDao.java @@ -278,6 +278,27 @@ public class QuestionTopiaDao extends AbstractQuestionTopiaDao<Question> { finerHqlBuilder.append(deadlineDateConditionAfter); } + // Manage wanted users + if (searchExample.getParticipant() != null) { + String participantCondition= DaoUtils.andAttributeContains(alias, Question.PROPERTY_PARTICIPANTS + "." + CoselmarUserGroup.PROPERTY_MEMBERS, args, searchExample.getParticipant()); + finerHqlBuilder.append(participantCondition); + } + + if (example.isSupervisorsNotEmpty()) { + String supervisorsCondition= DaoUtils.andAttributeContains(alias, Question.PROPERTY_SUPERVISORS, args, example.getSupervisors()); + finerHqlBuilder.append(supervisorsCondition); + } + + if (example.isContributorsNotEmpty()) { + String contributorCondition= DaoUtils.andAttributeContains(alias, Question.PROPERTY_CONTRIBUTORS, args, example.getContributors()); + finerHqlBuilder.append(contributorCondition); + } + + if (example.isClientsNotEmpty()) { + String clientCondition= DaoUtils.andAttributeContains(alias, Question.PROPERTY_CLIENTS, args, example.getClients()); + finerHqlBuilder.append(clientCondition); + } + } List<String> keywords = searchExample.getFullTextSearch(); diff --git a/coselmar-rest/src/main/java/fr/ifremer/coselmar/beans/QuestionSearchBean.java b/coselmar-rest/src/main/java/fr/ifremer/coselmar/beans/QuestionSearchBean.java index 3ef65bd..eab6d9a 100644 --- a/coselmar-rest/src/main/java/fr/ifremer/coselmar/beans/QuestionSearchBean.java +++ b/coselmar-rest/src/main/java/fr/ifremer/coselmar/beans/QuestionSearchBean.java @@ -47,6 +47,12 @@ public class QuestionSearchBean extends QuestionBean { protected Date deadlineBeforeDate; + protected String participantId; + protected String supervisorId; + protected String contributorId; + protected String clientId; + + public Integer getLimit() { return limit; } @@ -102,4 +108,36 @@ public class QuestionSearchBean extends QuestionBean { public void setDeadlineBeforeDate(Date deadlineBeforeDate) { this.deadlineBeforeDate = deadlineBeforeDate; } + + public String getParticipantId() { + return participantId; + } + + public void setParticipantId(String participantId) { + this.participantId = participantId; + } + + public String getSupervisorId() { + return supervisorId; + } + + public void setSupervisorId(String supervisorId) { + this.supervisorId = supervisorId; + } + + public String getContributorId() { + return contributorId; + } + + public void setContributorId(String contributorId) { + this.contributorId = contributorId; + } + + public String getClientId() { + return clientId; + } + + public void setClientId(String clientId) { + this.clientId = clientId; + } } diff --git a/coselmar-rest/src/main/java/fr/ifremer/coselmar/beans/QuestionUserRole.java b/coselmar-rest/src/main/java/fr/ifremer/coselmar/beans/QuestionUserRole.java new file mode 100644 index 0000000..7df4e04 --- /dev/null +++ b/coselmar-rest/src/main/java/fr/ifremer/coselmar/beans/QuestionUserRole.java @@ -0,0 +1,11 @@ +package fr.ifremer.coselmar.beans; + +/** + * Created by martel on 19/01/16. + */ +public enum QuestionUserRole { + SUPERVISOR, + PARTICIPANT, + CONTRIBUTOR, + CLIENT; +} diff --git a/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/QuestionsWebService.java b/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/QuestionsWebService.java index ac5df31..4439b3a 100644 --- a/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/QuestionsWebService.java +++ b/coselmar-rest/src/main/java/fr/ifremer/coselmar/services/v1/QuestionsWebService.java @@ -45,6 +45,7 @@ import fr.ifremer.coselmar.beans.QuestionExportModel; import fr.ifremer.coselmar.beans.QuestionSearchBean; import fr.ifremer.coselmar.beans.QuestionSearchExample; import fr.ifremer.coselmar.beans.QuestionTreeNode; +import fr.ifremer.coselmar.beans.QuestionUserRole; import fr.ifremer.coselmar.beans.UserBean; import fr.ifremer.coselmar.beans.UserWebToken; import fr.ifremer.coselmar.converter.BeanEntityConverter; @@ -1003,6 +1004,50 @@ public class QuestionsWebService extends CoselmarWebServiceSupport { return result; } + public List<QuestionBean> getUserQuestions(String userId, QuestionUserRole userRole) throws InvalidCredentialException, UnauthorizedException { + + // Check authentication + String authorization = getContext().getHeader("Authorization"); + CoselmarUser currentUser = checkUserAuthentication(authorization); + + // Member cannot access to list of questions + if (CoselmarUserRole.MEMBER == currentUser.getRole()) { + String message = String.format("User %s %s ('%s') is not allowed to view question", + currentUser.getFirstname(), currentUser.getName(), getShortIdFromFull(currentUser.getTopiaId())); + if (log.isWarnEnabled()) { + log.warn(message); + } + throw new UnauthorizedException(message); + } + + QuestionSearchBean searchBean = new QuestionSearchBean(); + + String userFullId = getFullUserIdFromShort(userId); + switch (userRole) { + case CONTRIBUTOR: + searchBean.setContributorId(userFullId); + break; + case SUPERVISOR: + searchBean.setSupervisorId(userFullId); + break; + case PARTICIPANT: + searchBean.setParticipantId(userFullId); + break; + case CLIENT: + searchBean.setClientId(userFullId); + break; + default: + return Collections.emptyList(); + } + + List<Question> questionList = getAllFilteredQuestions(currentUser, searchBean); + + List<QuestionBean> result = convert(currentUser, questionList); + + return result; + + } + //////////////////////////////////////////////////////////////////////////// /////////////////////// Internal Parts ///////////////////////////// //////////////////////////////////////////////////////////////////////////// @@ -1199,6 +1244,33 @@ public class QuestionsWebService extends CoselmarWebServiceSupport { Date deadlineBeforeDate = DateUtil.getEndOfDay((searchBean.getDeadlineBeforeDate())); searchExample.setDeadlineBeforeDate(deadlineBeforeDate); } + + if (StringUtils.isNotBlank(searchBean.getParticipantId())) { + CoselmarUser user = getCoselmarUserDao().forTopiaIdEquals(searchBean.getParticipantId()).findAnyOrNull(); + if (user != null) { + searchExample.setParticipant(user); + } + } + + if (StringUtils.isNotBlank(searchBean.getContributorId())) { + CoselmarUser user = getCoselmarUserDao().forTopiaIdEquals(searchBean.getContributorId()).findAnyOrNull(); + if (user != null) { + example.addContributors(user); + } + } + if (StringUtils.isNotBlank(searchBean.getSupervisorId())) { + CoselmarUser user = getCoselmarUserDao().forTopiaIdEquals(searchBean.getSupervisorId()).findAnyOrNull(); + if (user != null) { + example.addSupervisors(user); + } + } + if (StringUtils.isNotBlank(searchBean.getClientId())) { + CoselmarUser user = getCoselmarUserDao().forTopiaIdEquals(searchBean.getClientId()).findAnyOrNull(); + if (user != null) { + example.addClients(user); + } + } + } diff --git a/coselmar-rest/src/main/resources/mapping b/coselmar-rest/src/main/resources/mapping index 9352587..c001b21 100644 --- a/coselmar-rest/src/main/resources/mapping +++ b/coselmar-rest/src/main/resources/mapping @@ -51,6 +51,7 @@ POST /v1/users/password UsersWebService.generateNewPassw POST /v1/users/{userId} UsersWebService.modifyUser POST /v1/users UsersWebService.addUser DELETE /v1/users/{userId} UsersWebService.deleteUser +GET /v1/users/{userId}/projects QuestionsWebService.getUserQuestions # Questions Api diff --git a/coselmar-rest/src/test/java/fr/ifremer/coselmar/services/QuestionsWebServiceTest.java b/coselmar-rest/src/test/java/fr/ifremer/coselmar/services/QuestionsWebServiceTest.java index fd56396..52a562d 100644 --- a/coselmar-rest/src/test/java/fr/ifremer/coselmar/services/QuestionsWebServiceTest.java +++ b/coselmar-rest/src/test/java/fr/ifremer/coselmar/services/QuestionsWebServiceTest.java @@ -31,9 +31,12 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import com.auth0.jwt.JWTVerifier; +import com.google.common.collect.Lists; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import fr.ifremer.coselmar.beans.QuestionBean; +import fr.ifremer.coselmar.beans.QuestionUserRole; import fr.ifremer.coselmar.converter.JsonHelper; import org.apache.http.HttpResponse; import org.apache.http.client.fluent.Request; @@ -296,4 +299,162 @@ public class QuestionsWebServiceTest extends AbstractCoselmarWebServiceTest { Assert.assertTrue(shouldNoResult.isEmpty()); } + + @Test + public void testSearchUserQuestions() throws Exception { + + String webSecurityKey = getServiceContext().getCoselmarServicesConfig().getWebSecurityKey(); + JWTVerifier jwtVerifier = new JWTVerifier(webSecurityKey, "audience"); + + //First : login ! + Request loginRequest = createRequest("/v1/users/login") + .addParameter("mail", "lambda.expert@temporary.coselmar") + .addParameter("password", "manager1234") + .Post(); + + Response loginResponse = loginRequest.execute(); + String loginContent = loginResponse.returnContent().asString(); + Assert.assertNotNull(loginContent); + showTestResult(loginContent); + + Gson gson = new Gson(); + Map<String, String> loginJson = gson.fromJson(loginContent, Map.class); + + String expertToken = loginJson.get("jwt"); + Map<String, Object> expertMap = jwtVerifier.verify(expertToken); + String expertId = (String) expertMap.get("userId"); + + //First : login ! + loginRequest = createRequest("/v1/users/login") + .addParameter("mail", "default.supervisor@temporary.coselmar") + .addParameter("password", "manager1234") + .Post(); + + loginResponse = loginRequest.execute(); + loginContent = loginResponse.returnContent().asString(); + Assert.assertNotNull(loginContent); + showTestResult(loginContent); + + loginJson = gson.fromJson(loginContent, Map.class); + + String supervisorToken = loginJson.get("jwt"); + Map<String, Object> supervisorMap = jwtVerifier.verify(supervisorToken); + String supervisorId = (String) supervisorMap.get("userId"); + + + // Create first document + String documentOneTitle = "Ceci est le titre"; + Request addQuestionsRequest = createRequest("/v1/questions") + .addParameter("question", + "{title: '" + documentOneTitle + "', summary: 'ceci est le resume'," + + " submissionDate: '" + (new Date()).getTime() + "'," + + " themes: ['test', 'questionOne'], type: 'question'," + + " participants: [{'id': '" + expertId + "'}]," + + " supervisors: [{'id': '" + supervisorId + "'}]," + + " privacy : 'PUBLIC' }") + .Post() + .addHeader("Authorization", "Bearer " + supervisorToken); + + HttpResponse addQuestionResponse = addQuestionsRequest.execute().returnResponse(); + Assert.assertEquals(200, addQuestionResponse.getStatusLine().getStatusCode()); + + // Create second document + String documentTwoTitle = "There s someone missing. The question s Who?"; + addQuestionsRequest = createRequest("/v1/questions") + .addParameter("question", + "{title: '" + documentTwoTitle + "'," + + " summary: 'Something old, Something new, Something borrowed, Something blue.'," + + " submissionDate: '" + (new Date()).getTime() + "'," + + " themes: ['big bang two', 'Pandorica', 'River', 'Universe'], type: 'question'," + + " participants: [{'id': '" + expertId + "'}, {'id': '" + supervisorId + "'}]," + + " privacy : 'PUBLIC' }") + .Post() + .addHeader("Authorization", "Bearer " + supervisorToken); + + addQuestionResponse = addQuestionsRequest.execute().returnResponse(); + Assert.assertEquals(200, addQuestionResponse.getStatusLine().getStatusCode()); + + // And a third document ! + String documentThreeTitle = "Private things"; + addQuestionsRequest = createRequest("/v1/questions") + .addParameter("question", + "{title: '" + documentThreeTitle + "'," + + " summary: 'This question is private, zero access for others'," + + " submissionDate: '" + (new Date()).getTime() + "'," + + " themes: ['Universe', 'test', 'zero'], type: 'question'," + + " participants: [{'id': '" + supervisorId + "'}]," + + " clients: [{'id': '" + expertId + "'}]," + + " privacy : 'PRIVATE' }") + .Post() + .addHeader("Authorization", "Bearer " + supervisorToken); + + addQuestionResponse = addQuestionsRequest.execute().returnResponse(); + Assert.assertEquals(200, addQuestionResponse.getStatusLine().getStatusCode()); + + // First search : projects where expert is participant : one and two + Request searchRequest = createRequest("/v1/users/" + expertId + "/projects") + .addParameter("userRole", QuestionUserRole.PARTICIPANT.name()) + .Get() + .addHeader("Authorization", "Bearer " + supervisorToken); + + Response searchResponse = searchRequest.execute(); + String searchResultContent = searchResponse.returnContent().asString(); + JsonHelper jsonHelper = new JsonHelper(true); + List<QuestionBean> result = jsonHelper.fromJson(searchResultContent, new TypeToken<ArrayList<QuestionBean>>(){}.getType()); + + Assert.assertEquals(2, result.size()); + Assert.assertNotNull(result.get(0)); + Assert.assertNotNull(result.get(1)); + List<String> expectedTitles = Arrays.asList(documentOneTitle, documentTwoTitle); + Assert.assertTrue(expectedTitles.contains(result.get(0).getTitle())); + Assert.assertTrue(expectedTitles.contains(result.get(1).getTitle())); + + + // Second search : project where supervisor is participant : two and three + searchRequest = createRequest("/v1/users/" + supervisorId + "/projects") + .addParameter("userRole", QuestionUserRole.PARTICIPANT.name()) + .Get() + .addHeader("Authorization", "Bearer " + supervisorToken); + + searchResponse = searchRequest.execute(); + searchResultContent = searchResponse.returnContent().asString(); + result = jsonHelper.fromJson(searchResultContent, new TypeToken<ArrayList<QuestionBean>>(){}.getType()); + + Assert.assertEquals(2, result.size()); + expectedTitles = Arrays.asList(documentThreeTitle, documentTwoTitle); + Assert.assertTrue(expectedTitles.contains(result.get(0).getTitle())); + Assert.assertTrue(expectedTitles.contains(result.get(1).getTitle())); + + + // Second search : project where expert is client : three + searchRequest = createRequest("/v1/users/" + expertId + "/projects") + .addParameter("userRole", QuestionUserRole.CLIENT.name()) + .Get() + .addHeader("Authorization", "Bearer " + supervisorToken); + + searchResponse = searchRequest.execute(); + searchResultContent = searchResponse.returnContent().asString(); + result = jsonHelper.fromJson(searchResultContent, new TypeToken<ArrayList<QuestionBean>>(){}.getType()); + + Assert.assertEquals(1, result.size()); + Assert.assertEquals(documentThreeTitle, result.get(0).getTitle()); + + + // Second search : project where supervisor is supervisor : all (cause he creates them) + searchRequest = createRequest("/v1/users/" + supervisorId + "/projects") + .addParameter("userRole", QuestionUserRole.SUPERVISOR.name()) + .Get() + .addHeader("Authorization", "Bearer " + supervisorToken); + + searchResponse = searchRequest.execute(); + searchResultContent = searchResponse.returnContent().asString(); + result = jsonHelper.fromJson(searchResultContent, new TypeToken<ArrayList<QuestionBean>>(){}.getType()); + + Assert.assertEquals(3, result.size()); + expectedTitles = Arrays.asList(documentOneTitle, documentTwoTitle, documentThreeTitle); + Assert.assertTrue(expectedTitles.contains(result.get(0).getTitle())); + Assert.assertTrue(expectedTitles.contains(result.get(1).getTitle())); + Assert.assertTrue(expectedTitles.contains(result.get(2).getTitle())); + + } } -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.