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 88130f2c7e9b86bbdc7ac7659730e96972829a6b Author: Yannick Martel <martel@©odelutin.com> Date: Wed Dec 10 18:38:58 2014 +0100 manage some restriction on question content --- .../fr/ifremer/coselmar/beans/QuestionBean.java | 10 ++ .../coselmar/converter/BeanEntityConverter.java | 41 ++++++++ .../coselmar/services/v1/QuestionsWebService.java | 103 ++++++++++++++++++--- 3 files changed, 143 insertions(+), 11 deletions(-) diff --git a/coselmar-rest/src/main/java/fr/ifremer/coselmar/beans/QuestionBean.java b/coselmar-rest/src/main/java/fr/ifremer/coselmar/beans/QuestionBean.java index 3cab9f2..ff9e9d2 100644 --- a/coselmar-rest/src/main/java/fr/ifremer/coselmar/beans/QuestionBean.java +++ b/coselmar-rest/src/main/java/fr/ifremer/coselmar/beans/QuestionBean.java @@ -42,6 +42,9 @@ public class QuestionBean implements Serializable { protected Set<String> externalExperts; + protected Boolean isRestricted; + + public String getId() { return id; } @@ -235,4 +238,11 @@ public class QuestionBean implements Serializable { this.externalExperts = externalExperts; } + public Boolean getIsRestricted() { + return isRestricted; + } + + public void setRestricted(boolean isRestricted) { + this.isRestricted = isRestricted; + } } //Question diff --git a/coselmar-rest/src/main/java/fr/ifremer/coselmar/converter/BeanEntityConverter.java b/coselmar-rest/src/main/java/fr/ifremer/coselmar/converter/BeanEntityConverter.java index 5f20852..1875092 100644 --- a/coselmar-rest/src/main/java/fr/ifremer/coselmar/converter/BeanEntityConverter.java +++ b/coselmar-rest/src/main/java/fr/ifremer/coselmar/converter/BeanEntityConverter.java @@ -191,4 +191,45 @@ public class BeanEntityConverter { return result; } + public static QuestionBean toLightBean(TopiaIdFactory idFactory, Question question) { + QuestionBean result = new QuestionBean(); + result.setId(idFactory.getRandomPart(question.getTopiaId())); + + result.setTitle(question.getTitle()); + result.setSummary(question.getSummary()); + result.setType(question.getType()); + result.setPrivacy(question.getPrivacy().name()); + result.setStatus(question.getStatus().name()); + + Collection<String> theme = question.getTheme(); + if (theme != null && !theme.isEmpty()) { + result.setThemes(new HashSet(theme)); + } + + Date submissionDate = question.getSubmissionDate(); + if (submissionDate != null){ + result.setSubmissionDate(new Date(submissionDate.getTime())); + } + + Date deadline = question.getDeadline(); + if (deadline != null){ + result.setDeadline(new Date(deadline.getTime())); + } + + Date closingDate = question.getClosingDate(); + if (closingDate != null){ + result.setClosingDate(new Date(closingDate.getTime())); + } + + Collection<Question> parents = question.getParents(); + if (parents != null && !parents.isEmpty()) { + for (Question parent : parents) { + QuestionBean questionBean = toBean(idFactory, parent); + result.addParent(questionBean); + } + } + + return result; + } + } 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 d2c900b..f10b8a3 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 @@ -38,6 +38,8 @@ public class QuestionsWebService extends CoselmarWebServiceSupport { private static final Log log = LogFactory.getLog(QuestionsWebService.class); + protected static final List<String> RESTRICTED_ACCESS_USERS = Lists.newArrayList(CoselmarUserRole.CLIENT.name(), CoselmarUserRole.MEMBER.name()); + public void addQuestion(QuestionBean question) throws InvalidCredentialException, UnauthorizedException { // Check authentication @@ -194,6 +196,10 @@ public class QuestionsWebService extends CoselmarWebServiceSupport { } else if (StringUtils.equalsIgnoreCase(CoselmarUserRole.MEMBER.name(), currentUserRole)) { questionList = getQuestionDao().forPrivacyEquals(Privacy.PUBLIC).findAll(); + } else if (StringUtils.equalsIgnoreCase(CoselmarUserRole.EXPERT.name(), currentUserRole)) { + questionList = getQuestionDao().findAll(); + //TODO ymartel : manage privacy for experts + } else if (StringUtils.equalsIgnoreCase(CoselmarUserRole.CLIENT.name(), currentUserRole)) { questionList = getQuestionDao().forClientsContains(currentUser).findAll(); } else { @@ -208,7 +214,15 @@ public class QuestionsWebService extends CoselmarWebServiceSupport { for (Question question : questionList) { TopiaIdFactory topiaIdFactory = getPersistenceContext().getTopiaIdFactory(); - QuestionBean questionBean = BeanEntityConverter.toBean(topiaIdFactory, question); + + QuestionBean questionBean; + if (RESTRICTED_ACCESS_USERS.contains(currentUserRole)) { + questionBean = BeanEntityConverter.toLightBean(topiaIdFactory, question); + + } else { + questionBean = BeanEntityConverter.toBean(topiaIdFactory, question); + } + result.add(questionBean); } @@ -221,7 +235,7 @@ public class QuestionsWebService extends CoselmarWebServiceSupport { String authorization = getContext().getHeader("Authorization"); UserWebToken userWebToken = checkAuthentication(authorization); - // Only Supervisor can add question + // Only Supervisor can delete question String userRole = userWebToken.getRole(); if (!StringUtils.equalsIgnoreCase(CoselmarUserRole.SUPERVISOR.name(), userRole) @@ -271,12 +285,14 @@ public class QuestionsWebService extends CoselmarWebServiceSupport { String authorization = getContext().getHeader("Authorization"); UserWebToken userWebToken = checkAuthentication(authorization); - // Only Supervisor can add question + // Supervisor can get all the question elements + // Expert can get all the question elements if public or if he is participant of the question + // Client can get the question (not the documents) if he is client of the question. String userRole = userWebToken.getRole(); if (!StringUtils.equalsIgnoreCase(CoselmarUserRole.SUPERVISOR.name(), userRole) && StringUtils.equalsIgnoreCase(CoselmarUserRole.ADMIN.name(), userRole)) { - String message = String.format("User %s %s ('%s') is not allowed to delete question", + String message = String.format("User %s %s ('%s') is not allowed to view question", userWebToken.getFirstName(), userWebToken.getLastName(), userWebToken.getUserId()); if (log.isWarnEnabled()) { log.warn(message); @@ -287,8 +303,9 @@ public class QuestionsWebService extends CoselmarWebServiceSupport { String fullUserId = getFullIdFromShort(CoselmarUser.class, userWebToken.getUserId()); + CoselmarUser currentUser; try { - getCoselmarUserDao().forTopiaIdEquals(fullUserId).findUnique(); + currentUser = getCoselmarUserDao().forTopiaIdEquals(fullUserId).findUnique(); } catch (TopiaNoResultException tnre) { // Should not happened, cause user are not really deleted String message = String.format("Logged user ('%s') does not exist.", fullUserId); @@ -302,7 +319,30 @@ public class QuestionsWebService extends CoselmarWebServiceSupport { String fullQuestionId = getFullIdFromShort(Question.class, questionId); Question question = getQuestionDao().forTopiaIdEquals(fullQuestionId).findUnique(); - QuestionBean result = BeanEntityConverter.toBean(getPersistenceContext().getTopiaIdFactory(), question); + // Check client authorization on the document + checkIsClient(question, currentUser); + + QuestionBean result = BeanEntityConverter.toBean(getPersistenceContext().getTopiaIdFactory(), question);; + + // Client is not allowed to see documents + if (CoselmarUserRole.CLIENT == currentUser.getRole()) { + result.setRelatedDocuments(null); + + // If document is private, only participants could check it + } else if (CoselmarUserRole.EXPERT == currentUser.getRole() && question.getPrivacy() == Privacy.PRIVATE) { + CoselmarUserGroup participants = question.getParticipants(); + if (participants == null || !participants.getMembers().contains(currentUser)) { + result = new QuestionBean(); + result.setTitle(question.getTitle()); + result.setPrivacy(question.getPrivacy().name()); + result.setRestricted(true); + for (Question parent : question.getParents()) { + result.addParent(BeanEntityConverter.toLightBean(getPersistenceContext().getTopiaIdFactory(), parent)); + } + //TODO ymartel : manager children + } + } + return result; } @@ -312,12 +352,14 @@ public class QuestionsWebService extends CoselmarWebServiceSupport { String authorization = getContext().getHeader("Authorization"); UserWebToken userWebToken = checkAuthentication(authorization); - // Only Supervisor can add question + // Only Supervisor can add documents String userRole = userWebToken.getRole(); if (!StringUtils.equalsIgnoreCase(CoselmarUserRole.SUPERVISOR.name(), userRole) - && StringUtils.equalsIgnoreCase(CoselmarUserRole.ADMIN.name(), userRole)) { - String message = String.format("User %s %s ('%s') is not allowed to delete question", + && !StringUtils.equalsIgnoreCase(CoselmarUserRole.ADMIN.name(), userRole) + && !StringUtils.equalsIgnoreCase(CoselmarUserRole.EXPERT.name(), userRole)) { + + String message = String.format("User %s %s ('%s') is not allowed to add document", userWebToken.getFirstName(), userWebToken.getLastName(), userWebToken.getUserId()); if (log.isWarnEnabled()) { log.warn(message); @@ -328,8 +370,9 @@ public class QuestionsWebService extends CoselmarWebServiceSupport { String fullUserId = getFullIdFromShort(CoselmarUser.class, userWebToken.getUserId()); + CoselmarUser currentUser; try { - getCoselmarUserDao().forTopiaIdEquals(fullUserId).findUnique(); + currentUser = getCoselmarUserDao().forTopiaIdEquals(fullUserId).findUnique(); } catch (TopiaNoResultException tnre) { // Should not happened, cause user are not really deleted String message = String.format("Logged user ('%s') does not exist.", fullUserId); @@ -343,6 +386,10 @@ public class QuestionsWebService extends CoselmarWebServiceSupport { String fullQuestionId = getFullIdFromShort(Question.class, questionId); Question question = getQuestionDao().forTopiaIdEquals(fullQuestionId).findUnique(); + // Check expert authorization on the document + checkIsParticipant(question, currentUser); + + // Retrieve all documents Collection<Document> questionDocuments = question.getRelatedDocuments(); if (documents != null && documents.length > 0) { @@ -372,7 +419,7 @@ public class QuestionsWebService extends CoselmarWebServiceSupport { String authorization = getContext().getHeader("Authorization"); UserWebToken userWebToken = checkAuthentication(authorization); - // Only Supervisor can add question + // Only Supervisor can save question String userRole = userWebToken.getRole(); if (!StringUtils.equalsIgnoreCase(CoselmarUserRole.SUPERVISOR.name(), userRole)) { @@ -566,6 +613,40 @@ public class QuestionsWebService extends CoselmarWebServiceSupport { //////////////////////////////////////////////////////////////////////////// + protected void checkIsParticipant(Question question, CoselmarUser currentUser) throws UnauthorizedException { + String userRole = currentUser.getRole().name(); + Set<CoselmarUser> questionsParticipants = question.getParticipants().getMembers(); + + if (StringUtils.equalsIgnoreCase(CoselmarUserRole.EXPERT.name(), userRole) + && !questionsParticipants.contains(currentUser)) { + + String message = String.format("Expert %s %s ('%s') is not allowed to add document", + currentUser.getFirstname(), currentUser.getName(), currentUser.getTopiaId()); + if (log.isWarnEnabled()) { + log.warn(message); + } + throw new UnauthorizedException(message); + + } + } + + protected void checkIsClient(Question question, CoselmarUser currentUser) throws UnauthorizedException { + String userRole = currentUser.getRole().name(); + Set<CoselmarUser> questionsClients = question.getClients(); + + if (StringUtils.equalsIgnoreCase(CoselmarUserRole.CLIENT.name(), userRole) + && !questionsClients.contains(currentUser)) { + + String message = String.format("Client %s %s ('%s') is not allowed to access question %s", + currentUser.getFirstname(), currentUser.getName(), currentUser.getTopiaId(), question.getTopiaId()); + if (log.isWarnEnabled()) { + log.warn(message); + } + throw new UnauthorizedException(message); + + } + } + protected Set<CoselmarUser> retrieveUsers(Collection<UserBean> userBeans) { Function<UserBean, String> getIds = new Function<UserBean, String>() { @Override -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.