Pollen-commits
Threads by month
- ----- 2026 -----
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- 3196 discussions
r3496 - trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll
by tchemit@users.chorem.org 16 Jun '12
by tchemit@users.chorem.org 16 Jun '12
16 Jun '12
Author: tchemit
Date: 2012-06-16 23:49:58 +0200 (Sat, 16 Jun 2012)
New Revision: 3496
Url: http://chorem.org/repositories/revision/pollen/3496
Log:
fix Addchoice action when an validation error occurs
Modified:
trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/AddChoice.java
Modified: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/AddChoice.java
===================================================================
--- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/AddChoice.java 2012-06-16 21:49:24 UTC (rev 3495)
+++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/AddChoice.java 2012-06-16 21:49:58 UTC (rev 3496)
@@ -120,6 +120,10 @@
}
}
+ public String prepareVotePage() throws Exception {
+ return prepareVotePage(false);
+ }
+
@InputConfig(methodName = "prepareVotePage")
@Override
public String execute() throws Exception {
1
0
r3495 - trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/decorators
by tchemit@users.chorem.org 16 Jun '12
by tchemit@users.chorem.org 16 Jun '12
16 Jun '12
Author: tchemit
Date: 2012-06-16 23:49:24 +0200 (Sat, 16 Jun 2012)
New Revision: 3495
Url: http://chorem.org/repositories/revision/pollen/3495
Log:
fix css class injection (add them, but do NOT replace the class attribute)
Modified:
trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/decorators/layout-default.jsp
Modified: trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/decorators/layout-default.jsp
===================================================================
--- trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/decorators/layout-default.jsp 2012-06-16 20:36:03 UTC (rev 3494)
+++ trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/decorators/layout-default.jsp 2012-06-16 21:49:24 UTC (rev 3495)
@@ -53,7 +53,7 @@
jQuery(document).ready(function () {
// apply common style
- $('fieldset').attr('class', 'ui-widget-content ui-corner-all');
+ $('fieldset').addClass('ui-widget-content ui-corner-all');
// Popup for lostPassword
$('#lostPasswordLink').click(function() {
1
0
16 Jun '12
Author: tchemit
Date: 2012-06-16 22:36:03 +0200 (Sat, 16 Jun 2012)
New Revision: 3494
Url: http://chorem.org/repositories/revision/pollen/3494
Log:
fixes #608: Cannot access vote results
fixes #599: Can submit a participant with no name, but it is not saved
fixes #600: Cannot have several particpant: all became one, duplicated on each line
fixes #602: In creation, a member of a group can be created without name
fixes #618: Improve poll form url workflow
refs #609: Review security access for administrator
refs #612: Review security access for creator
Added:
trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/ClonePoll.java
trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/CreatePoll.java
trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/EditPoll.java
Removed:
trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/LoadPoll.java
trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/SavePoll.java
trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/resultLink.jsp
Modified:
trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/json/GetCreatedPolls.java
trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/json/GetPollComments.java
trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/AbstractPollForm.java
trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/AbstractVoteAction.java
trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/SummaryPoll.java
trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/VoteForPoll.java
trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/PollResultAccessRequired.java
trunk/pollen-ui-struts2/src/main/resources/config/struts-poll.xml
trunk/pollen-ui-struts2/src/main/resources/i18n/pollen-ui-struts2_en_GB.properties
trunk/pollen-ui-struts2/src/main/resources/i18n/pollen-ui-struts2_fr_FR.properties
trunk/pollen-ui-struts2/src/main/resources/shiro.ini
trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/decorators/layout-default.jsp
trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/home.jsp
trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/create.jsp
trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/createPoll_choices.jsp
trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/result.jsp
trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/summary.jsp
trunk/pollen-ui-struts2/src/test/java/org/chorem/pollen/ui/PollenFixtures.java
trunk/pollen-ui-struts2/src/test/java/org/chorem/pollen/ui/its/CreateFreeTextPollSIT.java
trunk/pollen-ui-struts2/src/test/java/org/chorem/pollen/ui/its/SecurityAccessSIT.java
Modified: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/json/GetCreatedPolls.java
===================================================================
--- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/json/GetCreatedPolls.java 2012-06-16 20:33:49 UTC (rev 3493)
+++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/json/GetCreatedPolls.java 2012-06-16 20:36:03 UTC (rev 3494)
@@ -24,14 +24,12 @@
import com.google.common.collect.Sets;
import org.chorem.pollen.business.persistence.Poll;
-import org.chorem.pollen.common.PollType;
import org.chorem.pollen.entities.PollenBinderHelper;
import org.chorem.pollen.services.impl.PollService;
import org.nuiton.util.beans.Binder;
import java.util.List;
import java.util.Map;
-import java.util.Set;
/**
* Obtain created polls to put in grid for the connected user.
@@ -86,28 +84,12 @@
Map<String, Object> map = pollService.pollToMap(poll, binder);
- map.put("voteId", poll.getPollId());
+// map.put("voteId", poll.getPollId());
map.put("adminId", poll.getAdminId());
- Set<String> functions = getPollFunctions(poll);
- map.put("functions", functions);
+ map.put("functions", Sets.newHashSet("summary"));
polls[index++] = map;
}
return SUCCESS;
}
- protected Set<String> getPollFunctions(Poll poll) {
- Set<String> result = Sets.newHashSet();
- if (PollType.FREE == poll.getPollType()) {
-
- // only free poll could have vote action because creator can't vote
- result.add("vote");
- } else {
- // to be sure a blank image is setted instead of vote picto
- result.add("novote");
- }
- result.add("summary");
- result.add("delete");
- return result;
- }
-
}
Modified: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/json/GetPollComments.java
===================================================================
--- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/json/GetPollComments.java 2012-06-16 20:33:49 UTC (rev 3493)
+++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/json/GetPollComments.java 2012-06-16 20:36:03 UTC (rev 3494)
@@ -111,7 +111,7 @@
UserAccount userAccount) {
Set<String> result = Sets.newHashSet();
//TODO-tchemit-2012-06-03 Should use also pollAccountId (if specified in url)...
- boolean canDelete = getPollCommentService().isCanDeleteComment(
+ boolean canDelete = getSecurityService().isCanDeleteComment(
comment, null, userAccount, false);
if (canDelete) {
result.add("delete");
Modified: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/AbstractPollForm.java
===================================================================
--- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/AbstractPollForm.java 2012-06-16 20:33:49 UTC (rev 3493)
+++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/AbstractPollForm.java 2012-06-16 20:36:03 UTC (rev 3494)
@@ -24,30 +24,57 @@
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.opensymphony.xwork2.Preparable;
+import com.opensymphony.xwork2.interceptor.annotations.InputConfig;
import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.struts2.interceptor.ParameterAware;
+import org.chorem.pollen.bean.PollDateChoice;
import org.chorem.pollen.bean.PollImageChoice;
+import org.chorem.pollen.bean.PollUri;
import org.chorem.pollen.business.persistence.Choice;
+import org.chorem.pollen.business.persistence.ChoiceImpl;
import org.chorem.pollen.business.persistence.PersonToList;
+import org.chorem.pollen.business.persistence.PersonToListImpl;
import org.chorem.pollen.business.persistence.Poll;
import org.chorem.pollen.business.persistence.PollAccount;
+import org.chorem.pollen.business.persistence.PollAccountImpl;
+import org.chorem.pollen.business.persistence.PreventRule;
+import org.chorem.pollen.business.persistence.UserAccount;
import org.chorem.pollen.business.persistence.VotingList;
+import org.chorem.pollen.business.persistence.VotingListImpl;
import org.chorem.pollen.common.ChoiceType;
import org.chorem.pollen.common.I18nAble;
import org.chorem.pollen.common.PollType;
import org.chorem.pollen.common.VoteCountingType;
import org.chorem.pollen.services.PollenServiceFunctions;
+import org.chorem.pollen.services.exceptions.PollNotFoundException;
import org.chorem.pollen.services.impl.PollService;
+import org.chorem.pollen.services.impl.PreventRuleService;
+import org.chorem.pollen.ui.actions.FileUploadAware;
import org.chorem.pollen.ui.actions.PageSkin;
import org.chorem.pollen.ui.actions.PollenActionSupport;
+import org.chorem.pollen.ui.converters.DateConverter;
+import org.nuiton.util.StringUtil;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
* Created: 04/04/12
@@ -55,12 +82,24 @@
* @author fdesbois <desbois(a)codelutin.com>
* $Id$
*/
-public abstract class AbstractPollForm extends PollenActionSupport {
+public abstract class AbstractPollForm extends PollenActionSupport implements Preparable, ParameterAware, FileUploadAware {
private static final long serialVersionUID = 1L;
+ /** Logger. */
+ private static final Log log = LogFactory.getLog(AbstractPollForm.class);
+
public static final String IMAGECHOICES_THUMB_PREFIX = "imagechoicesThumb_";
+ private static final Pattern TEXT_CHOICE_NAME_PATTERN =
+ Pattern.compile("textChoice_(\\d+)\\.name");
+
+ private static final Pattern DATE_CHOICE_NAME_PATTERN =
+ Pattern.compile("dateChoice_(\\d+)\\.name");
+
+ private static final Pattern IMAGE_CHOICE_DESCRIPTION_PATTERN =
+ Pattern.compile("imageChoice_(\\d+)\\.description");
+
protected Poll poll;
private Map<String, String> pollTypes;
@@ -109,23 +148,415 @@
/** To create a new image choice. */
private transient Function<Choice, Choice> imageChoiceCreator;
+ /**
+ * Flag when there is some errors on the information panel.
+ *
+ * @since 1.3
+ */
+ protected boolean informationsError;
+
+ /**
+ * Flag when there is some errors on the options panel.
+ *
+ * @since 1.3
+ */
+ private boolean optionsError;
+
+ /**
+ * All the parameters send by request used to build back choices of the
+ * poll.
+ *
+ * @since 1.3
+ */
+ protected final Map<String, String[]> parameters = Maps.newTreeMap();
+
+ /**
+ * Indexed choices retreive from parameters for the choiceType selected in
+ * form. (Other choices are lost).
+ *
+ * @since 1.3
+ */
+ private Map<Integer, Choice> choices;
+
+ /**
+ * Indexed voting lists retreive from parameters for the pollType selected
+ * in form. (Other voting lists are lost).
+ *
+ * @since 1.3
+ */
+ private Map<Integer, VotingList> votingLists;
+
+ private PollUri pollUri;
+
+ public abstract boolean isClone();
+
+ protected abstract Poll savePoll(Poll poll) throws PollNotFoundException;
+
+ public abstract boolean isEdit();
+
@Override
+ public void prepare() throws Exception {
+
+ prepareFormPage();
+
+ if (parameters.containsKey("poll.title")) {
+
+ if (log.isInfoEnabled()) {
+ log.info("Starts prepare form...");
+ }
+
+ // we are after a submit
+
+ String pollUid = getNonEmptyParameterValue("poll.pollId");
+ String userId = getNonEmptyParameterValue("userId");
+ if (StringUtils.isBlank(userId)) {
+
+ // try to take the one from current user
+ UserAccount userAccount = getPollenUserAccount();
+ if (userAccount != null) {
+ userId = userAccount.getTopiaId();
+ }
+ }
+ UserAccount userAccount = null;
+ if (StringUtils.isNotBlank(userId)) {
+ // load use account to use
+ userAccount = getPollService().getEntityById(
+ UserAccount.class, userId);
+ }
+
+ // get a copy (or a fresh new poll)
+ poll = getPollService().getPollEditable(pollUid, userAccount, false);
+
+ // If vote is started, prepare choices and votingLists is useless
+ // because they can't be updated.
+ if (!isVoteStarted()) {
+
+ // Retrieve choiceType from parameters, the poll object will be updated after prepare
+ String choiceTypeParam = getNonEmptyParameterValue("poll.choiceType");
+ ChoiceType pollChoiceType = ChoiceType.valueOf(choiceTypeParam);
+ poll.setChoiceType(pollChoiceType);
+
+ // build poll choices
+
+ switch (pollChoiceType) {
+
+ case TEXT:
+ choices = buildTextChoices();
+ break;
+ case DATE:
+ choices = buildDateChoices();
+ break;
+ case IMAGE:
+ choices = buildImageChoices();
+ break;
+ }
+ PollType pollType;
+ String pollTypeParam = getNonEmptyParameterValue("poll.pollType");
+ pollType = PollType.valueOf(pollTypeParam);
+ switch (pollType) {
+
+ case FREE:
+
+ // empty voting list
+ votingLists = Maps.newTreeMap();
+ break;
+ case RESTRICTED:
+
+ // restricted voting list
+ votingLists = buildVotingLists(pollType);
+ break;
+ case GROUP:
+
+ // group voting lists
+ votingLists = buildVotingLists(pollType);
+ break;
+ }
+ }
+ }
+ }
+
+ @Override
+ public String input() throws Exception {
+
+ prepareFormPage();
+
+ UserAccount userAccount = getPollenUserAccount();
+ String pollUid = pollUri == null ? null : pollUri.getPollId();
+ PollService service = getPollService();
+
+ poll = service.getPollEditable(pollUid, userAccount, isClone());
+
+ if (poll.isClosed()) {
+ addFlashWarning(_("pollen.warning.poll.is.closed.so.read.only"));
+ }
+ List<Choice> pollChoices = poll.getChoice();
+
+ if (isClone()) {
+
+ if (ChoiceType.IMAGE == poll.getChoiceType()) {
+
+ // recopy images to tmp
+
+ File tmpDir = getConfiguration().getTemporaryDirectory();
+ for (Choice choice : pollChoices) {
+ String choiceName = choice.getName();
+
+ // image from poll to clone
+ File imageChoiceFile = service.getPollChoiceImageFile(
+ pollUid,
+ choiceName
+ );
+
+ // new image
+ File newImageChoiceFile = File.createTempFile(
+ choiceName, null, tmpDir);
+
+ if (log.isInfoEnabled()) {
+ log.info("Copy image from " + imageChoiceFile +
+ " to " + newImageChoiceFile);
+ }
+ FileUtils.copyFile(imageChoiceFile,
+ newImageChoiceFile);
+
+ ((PollImageChoice) choice).setLocation(
+ newImageChoiceFile.getAbsolutePath());
+ }
+ }
+ }
+
+ List<VotingList> pollVotingLists = poll.getVotingList();
+
+ loadChoicesAndvotingLists(poll,
+ pollChoices,
+ pollVotingLists,
+ !isVoteStarted());
+
+ setLimitChoice(poll.getMaxChoiceNb() > 0);
+
+ if (isLimitChoice()) {
+ setMaxChoices(poll.getMaxChoiceNb());
+ } else {
+ // set default max choices
+ setMaxChoices(1);
+ }
+ PreventRule reminder = poll.getPreventRuleByScope(
+ PreventRuleService.SCOPE_REMINDER);
+ if (reminder != null) {
+ setReminder(true);
+ setReminderHourCountdown(reminder.getSensibility());
+ } else {
+ setReminder(false);
+ // set default reminderHourCountdown
+ setReminderHourCountdown(2);
+ }
+
+ PreventRule notification = poll.getPreventRuleByScope(
+ PreventRuleService.SCOPE_VOTE);
+ if (notification != null) {
+ setNotification(true);
+ }
+
+ if (isVoteStarted()) {
+ addFlashMessage(_("pollen.information.poll.form.voteStarted"));
+ }
+
+ return INPUT;
+ }
+
+ public String inputAfterValidationError() throws Exception {
+
+ Collection<Choice> pollChoices =
+ isVoteStarted() ? poll.getChoice() : choices.values();
+ Collection<VotingList> pollVotingLists =
+ isVoteStarted() ? poll.getVotingList() : votingLists.values();
+
+ if (ChoiceType.IMAGE == poll.getChoiceType()) {
+
+ // recopy images for new choices, the one uploaded will be
+ // destroyed, by the upload interceptor
+
+ File tmpDir = getConfiguration().getTemporaryDirectory();
+
+ for (Choice choice : pollChoices) {
+
+ PollImageChoice imageChoice = (PollImageChoice) choice;
+
+ String choiceId = choice.getTopiaId();
+ String location = imageChoice.getLocation();
+
+ if (StringUtils.isBlank(choiceId) &&
+ !isImageUploadEmpty(imageChoice)) {
+
+ // not persisted choice with an upload
+ // let's copy it somewhere safe
+
+ File uploadedImage = new File(location);
+ File copyImage = File.createTempFile(
+ uploadedImage.getName(), null, tmpDir);
+
+ if (log.isInfoEnabled()) {
+ log.info("Copy image from " + uploadedImage +
+ " to " + copyImage);
+ }
+ FileUtils.copyFile(uploadedImage, copyImage);
+
+ imageChoice.setLocation(copyImage.getAbsolutePath());
+ }
+ }
+ }
+
+ loadChoicesAndvotingLists(poll, pollChoices, pollVotingLists, true);
+ return INPUT;
+ }
+
+ @Override
+ @InputConfig(methodName = "inputAfterValidationError")
+ public String execute() throws Exception {
+
+ // Save choices and votingLists only if vote is not started
+ if (!isVoteStarted()) {
+ //TODO-tchemit comment me 2012-06-04 A merge would be nicer but more complex to code
+ // Clear previous collections to save those from the form
+ poll.clearChoice();
+ poll.clearVotingList();
+ for (Integer index : choices.keySet()) {
+ Choice choice = choices.get(index);
+ poll.addChoice(choice);
+ }
+
+ if (!isFreePoll()) {
+
+ for (Integer index : votingLists.keySet()) {
+ VotingList votingList = votingLists.get(index);
+ poll.addVotingList(votingList);
+ }
+ }
+ }
+
+ if (isLimitChoice()) {
+
+ // push back filled value
+ poll.setMaxChoiceNb(getMaxChoices());
+ } else {
+ // reset value
+ poll.setMaxChoiceNb(0);
+ }
+
+ if (!poll.isPublicResults()) {
+
+ // force to not have continous results
+ poll.setContinuousResults(false);
+ }
+
+ if (poll.isAnonymous()) {
+
+ // force to not have choice to vote anonymously
+ poll.setAnonymousVoteAllowed(false);
+ }
+
+ //TODO-tchemit comment me 2012-06-04 A merge would be nicer but more complex to code
+ poll.clearPreventRule();
+
+ PreventRuleService preventRuleService = getPreventRuleService();
+ if (isNotification()) {
+
+ // add a notification rule
+
+ PreventRule rule = preventRuleService.createAddVotePreventRule();
+ poll.addPreventRule(rule);
+ }
+
+ if (isReminder()) {
+
+ // add a reminder rule
+
+ PreventRule rule = preventRuleService.createRemindPreventRule(
+ getReminderHourCountdown()
+ );
+
+ poll.addPreventRule(rule);
+ }
+
+ // do save poll
+ poll = savePoll(poll);
+
+ // compute fresh pollUri
+ pollUri = PollUri.newPollUri(poll.getAdminId());
+
+ // remove all stuff from session
+ getPollenSession().clearDynamicData();
+
+ return SUCCESS;
+ }
+
+ @Override
+ public void validate() {
+
+ validateInformations();
+
+ validateOptions();
+ }
+
+ @Override
+ public void addFile(int index, File file) {
+ parameters.put("imageChoice_" + index + ".newLocation",
+ new String[]{file.getAbsolutePath()});
+ }
+
+ @Override
+ public void addFileContentType(int index, String contentType) {
+ // not used here
+ }
+
+ @Override
+ public void addFileName(int index, String fileName) {
+ parameters.put("imageChoice_" + index + ".newName", new String[]{fileName});
+ }
+
+ @Override
+ public void setParameters(Map<String, String[]> parameters) {
+ this.parameters.putAll(parameters);
+ }
+
+ @Override
public PageSkin getSkin() {
return PageSkin.EDITION;
}
- public Poll getPoll() {
- return poll;
- }
-
public boolean isInformationsError() {
- return false;
+ return informationsError;
}
public boolean isOptionsError() {
- return false;
+ return optionsError;
}
+ public int getSelectedTab() {
+ int result;
+ if (isInformationsError()) {
+ result = 0;
+ } else {
+ if (isOptionsError()) {
+ result = 1;
+ } else {
+ result = 0;
+ }
+ }
+ return result;
+ }
+
+ public PollUri getUriId() {
+ return pollUri;
+ }
+
+ public void setUriId(PollUri pollUri) {
+ this.pollUri = pollUri;
+ }
+
+ public Poll getPoll() {
+ return poll;
+ }
+
public Map<String, String> getPollTypes() {
return pollTypes;
}
@@ -208,11 +639,6 @@
return pollType == PollType.GROUP;
}
- public int getSelectedTab() {
- int result = 0;
- return result;
- }
-
public String getActionLabel() {
return isEdit() ? _("pollen.action.editPoll") :
_("pollen.action.createPoll");
@@ -232,10 +658,6 @@
return creator.getUserAccount() != null;
}
- public boolean isEdit() {
- return StringUtils.isNotBlank(getPoll().getTopiaId());
- }
-
public void prepareFormPage() throws Exception {
getPollenSession().removeDynamicDataWithPrefix(IMAGECHOICES_THUMB_PREFIX);
@@ -295,6 +717,424 @@
return result;
}
+ protected void validateInformations() {
+
+ // -- Title : required -- //
+ if (StringUtils.isBlank(poll.getTitle())) {
+ addInformationsError("poll.title",
+ _("pollen.error.poll.required.title"));
+ }
+
+ if (isVoteStarted()) {
+
+ // no validation on choices if vote is started
+
+ } else {
+
+ // -- Choice -- //
+ if (MapUtils.isEmpty(choices)) {
+
+ // poll must have at least one choice
+ addInformationsError("poll.choices",
+ _("pollen.error.poll.required.one.choice"));
+ } else {
+ switch (poll.getChoiceType()) {
+
+ case TEXT:
+ validateTextChoices();
+ break;
+ case DATE:
+ validateDateChoices();
+ break;
+ case IMAGE:
+ validateImageChoices();
+ break;
+ }
+ }
+ }
+ }
+
+ protected void validateTextChoices() {
+
+ String choicePrefix = getChoiceFieldPrefix(ChoiceType.TEXT);
+
+ Set<String> choiceNames = Sets.newHashSet();
+
+ for (Map.Entry<Integer, Choice> entry : choices.entrySet()) {
+ Integer choiceIndex = entry.getKey();
+ Choice choice = entry.getValue();
+ String choiceErrorField = choicePrefix + choiceIndex + ".name";
+ String choiceName = choice.getName();
+ if (StringUtils.isBlank(choiceName)) {
+ // no name
+ addInformationsError(
+ choiceErrorField,
+ _("pollen.error.poll.choice.name.required"));
+ continue;
+ }
+ if (choiceNames.contains(choiceName)) {
+ // duplicated names
+ addInformationsError(
+ choiceErrorField,
+ _("pollen.error.poll.choice.already.used.name"));
+ continue;
+ }
+ choiceNames.add(choiceName);
+ }
+ }
+
+ protected void validateDateChoices() {
+
+
+ String choicePrefix = getChoiceFieldPrefix(ChoiceType.DATE);
+
+ Set<String> choiceNames = Sets.newHashSet();
+
+ for (Map.Entry<Integer, Choice> entry : choices.entrySet()) {
+ Integer choiceIndex = entry.getKey();
+ PollDateChoice choice = (PollDateChoice) entry.getValue();
+ String choiceErrorField = choicePrefix + choiceIndex + ".name";
+ String choiceName = choice.getName();
+ if (StringUtils.isBlank(choiceName)) {
+ // no name
+ addInformationsError(
+ choiceErrorField,
+ _("pollen.error.poll.dateChoice.required"));
+ continue;
+ }
+ if (choiceNames.contains(choiceName)) {
+ // duplicated names
+ addInformationsError(
+ choiceErrorField,
+ _("pollen.error.poll.dateChoice.already.used"));
+ continue;
+ }
+ if (choice.getDate() == null) {
+
+ // format error
+ addInformationsError(
+ choiceErrorField,
+ _("pollen.error.poll.dateChoice.badDateFormat"));
+
+ }
+ choiceNames.add(choiceName);
+ }
+ }
+
+ protected void validateImageChoices() {
+
+ String choicePrefix = getChoiceFieldPrefix(ChoiceType.IMAGE);
+
+ Set<String> choiceNames = Sets.newHashSet();
+
+ for (Map.Entry<Integer, Choice> entry : choices.entrySet()) {
+ Integer choiceIndex = entry.getKey();
+ Choice choice = entry.getValue();
+ String choiceErrorField = choicePrefix + choiceIndex + ".name";
+ String choiceName = choice.getName();
+ if (StringUtils.isBlank(choiceName)) {
+ // no name
+ addInformationsError(
+ choiceErrorField,
+ _("pollen.error.poll.imageChoice.upload.required"));
+ continue;
+ }
+ if (choiceNames.contains(choiceName)) {
+ // duplicated names
+ addInformationsError(
+ choiceErrorField,
+ _("pollen.error.poll.imageChoice.already.used"));
+ continue;
+ }
+ choiceNames.add(choiceName);
+ }
+
+ }
+
+ protected void validateOptions() {
+
+ if (isVoteStarted()) {
+
+ // no validation on votingLists if vote is started
+
+ } else {
+
+ // -- VotingList -- //
+
+ if (isFreePoll()) {
+
+ // nothing to validate
+
+ } else {
+
+ Set<String> groups = Sets.newHashSet();
+ Set<String> voters = Sets.newHashSet();
+ Set<String> emails = Sets.newHashSet();
+
+ for (Map.Entry<Integer, VotingList> entry : votingLists.entrySet()) {
+ validateVotingList(entry.getKey(),
+ entry.getValue(),
+ groups,
+ voters,
+ emails);
+ }
+ }
+ }
+
+ String creatorEmail = poll.getCreator().getEmail();
+ if (StringUtils.isNotBlank(creatorEmail) &&
+ !StringUtil.isEmail(creatorEmail)) {
+
+ addOptionsError("poll.creator.email",
+ _("pollen.error.email.invalid"));
+ }
+
+ Date currentTime = serviceContext.getCurrentTime();
+
+ if (validateEndDate(poll.getBeginChoiceDate(), poll.getEndChoiceDate())) {
+
+ addOptionsError(
+ "poll.endChoiceDate",
+ _("pollen.error.poll.endChoiceDate.before.beginChoiceDate"));
+ }
+
+ if (validateEndDate(currentTime, poll.getEndChoiceDate())) {
+
+ addOptionsError(
+ "poll.endChoiceDate",
+ _("pollen.error.poll.endChoiceDate.before.now"));
+ }
+
+ if (validateEndDate(poll.getBeginDate(), poll.getEndDate())) {
+
+ addOptionsError("poll.endDate",
+ _("pollen.error.poll.endDate.before.beginDate"));
+ }
+
+
+ if (validateEndDate(currentTime, poll.getEndDate())) {
+
+ addOptionsError(
+ "poll.endDate",
+ _("pollen.error.poll.endDate.before.now"));
+ }
+
+ if (validateEndDate(poll.getEndChoiceDate(), poll.getEndDate())) {
+
+ addOptionsError("poll.endChoiceDate",
+ _("pollen.error.poll.endChoiceDate.after.endDate"));
+ }
+
+ if (isLimitChoice()) {
+
+ // validate maxChoices
+
+ if (getMaxChoices() == null) {
+ // maxChoices == null
+ addOptionsError("maxChoices",
+ _("pollen.error.poll.maxChoice.required"));
+ } else if (getMaxChoices() < 1) {
+ // maxChoices <= 0
+ addOptionsError("maxChoices",
+ _("pollen.error.poll.maxChoice.greater.than.0"));
+ }
+ }
+
+ if (isReminder()) {
+
+ // validate reminderHourCountdown
+
+ if (getReminderHourCountdown() == null) {
+
+ // reminderHourCountdown == null
+ addOptionsError("reminderHourCountdown",
+ _("pollen.error.poll.reminderHourCountdown.required"));
+ } else if (getReminderHourCountdown() < 1) {
+
+ // reminderHourCountdown <= 0
+ addOptionsError("reminderHourCountdown",
+ _("pollen.error.poll.reminderHourCountdown.greater.than.0"));
+ }
+ }
+ }
+
+ protected void validateVotingList(int votingListNumber,
+ VotingList votingList,
+ Set<String> groups,
+ Set<String> voters,
+ Set<String> emails) {
+
+ PollType votingListType = poll.getPollType();
+ String fieldNamePrefix = "votingList" + votingListType + "_" +
+ votingListNumber;
+
+ if (isGroupPoll()) {
+
+ // group poll
+
+ // check there is at least one group
+ // check no doublon on group names
+ // check there is at least one voter on each group
+ // check no doublon on voter names
+ // check no doublon on voter emails
+
+ // validate votingList name
+ String votingListName = votingList.getName();
+
+ if (StringUtils.isEmpty(votingListName)) {
+
+ addOptionsError(
+ fieldNamePrefix,
+ _("pollen.error.poll.required.votingList.name"));
+ } else {
+
+ // check no votingList name doublon
+ boolean add = groups.add(votingListName);
+ if (!add) {
+
+ // name doublon
+ addOptionsError(
+ fieldNamePrefix,
+ _("pollen.error.poll.votingList.name.doublon"));
+ }
+ }
+
+ // validate votingList weight
+
+ if (votingList.getWeight() == 0) {
+
+ // no weight filled (can be a bad conversion)
+ addOptionsError(
+ fieldNamePrefix,
+ _("pollen.error.poll.votingList.weight.not.valid"));
+ }
+
+ }
+
+ // check there is at least one voter
+
+ List<PersonToList> personToLists =
+ votingList.getPollAccountPersonToList();
+
+ if (CollectionUtils.isEmpty(personToLists)) {
+
+ // no personToList found for unique votingList 0
+ addOptionsError(fieldNamePrefix,
+ _("pollen.error.poll.required.one.personToList"));
+ } else {
+
+ // check no doublon on voter names
+
+ for (int i = 0; i < personToLists.size(); i++) {
+
+ validatePersonList(i,
+ fieldNamePrefix,
+ personToLists.get(i),
+ voters,
+ emails);
+ }
+ }
+ }
+
+ protected void validatePersonList(int personToListNumber,
+ String votingListFieldNamePrefix,
+ PersonToList personToList,
+ Set<String> voters,
+ Set<String> emails) {
+
+ String fieldNamePrefix = votingListFieldNamePrefix +
+ "PersonToList_" + personToListNumber;
+
+ PollAccount pollAccount = personToList.getPollAccount();
+
+ // -- validate votingId -- //
+
+ String votingId = pollAccount.getVotingId();
+
+ if (StringUtils.isEmpty(votingId)) {
+
+ // voter name mandatory
+ addOptionsError(
+ fieldNamePrefix,
+ _("pollen.error.poll.personToList.votingId.required"));
+ } else {
+
+ boolean add = voters.add(votingId);
+ if (!add) {
+
+ // voter name already used
+ addOptionsError(
+ fieldNamePrefix,
+ _("pollen.error.poll.personToList.votingId.doublon"));
+ }
+ }
+
+ // -- validate email -- //
+
+ String email = pollAccount.getEmail();
+
+ if (StringUtils.isEmpty(email)) {
+
+ // voter email mandatory
+ addOptionsError(fieldNamePrefix,
+ _("pollen.error.email.required"));
+ } else {
+
+ boolean validEmail = StringUtil.isEmail(email);
+ if (!validEmail) {
+
+ // not a valid email
+ addOptionsError(fieldNamePrefix,
+ _("pollen.error.email.invalid"));
+ } else {
+
+ boolean add = emails.add(email);
+ if (!add) {
+
+ // email already used
+ addOptionsError(
+ fieldNamePrefix,
+ _("pollen.error.poll.personToList.email.doublon"));
+ }
+ }
+ }
+
+ // -- validate weight -- //
+
+ if (personToList.getWeight() == 0) {
+
+ // no weight filled (can be a bad conversion)
+ addOptionsError(
+ fieldNamePrefix,
+ _("pollen.error.poll.personToList.weight.not.valid"));
+ }
+
+ }
+
+ protected boolean validateEndDate(Date begin, Date end) {
+ return begin != null
+ && end != null
+ && end.before(begin);
+ }
+
+ @Override
+ public void addFieldError(String fieldName, String errorMessage) {
+ super.addFieldError(fieldName, errorMessage);
+ if (log.isDebugEnabled()) {
+ log.debug("VALIDATION [" + fieldName + "] : " + errorMessage);
+ }
+ }
+
+ protected void addInformationsError(String fieldName, String errorMessage) {
+ addFieldError(fieldName, errorMessage);
+ informationsError = true;
+ }
+
+ protected void addOptionsError(String fieldName, String errorMessage) {
+ addFieldError(fieldName, errorMessage);
+ optionsError = true;
+ }
+
protected void loadChoicesAndvotingLists(Poll poll,
Collection<Choice> pollChoices,
Collection<VotingList> pollVotinLists,
@@ -324,38 +1164,41 @@
for (Choice choice : pollChoices) {
PollImageChoice imageChoice = (PollImageChoice) choice;
String choiceId = imageChoice.getTopiaId();
- File imageChoiceFile;
+ File imageChoiceFile = null;
PollService service = getPollService();
if (StringUtils.isBlank(choiceId)) {
- // new choice, must create the thumb
- imageChoiceFile =
- new File(imageChoice.getLocation());
+ if (!isImageUploadEmpty(imageChoice)) {
+ // new choice, must create the thumb
+ imageChoiceFile =
+ new File(imageChoice.getLocation());
- if (imageChoiceFile.exists()) {
+ if (imageChoiceFile.exists()) {
- service.generateThumbIfNeeded(imageChoiceFile);
+ service.generateThumbIfNeeded(imageChoiceFile);
+ }
}
+
} else {
// already persisted choice, nothing to do
imageChoiceFile = service.getPollChoiceImageFile(
poll.getPollId(), choice.getName());
-
}
- File thumbFile = service.getImageThumbFile(
- imageChoiceFile);
+ if (imageChoiceFile != null) {
+ File thumbFile = service.getImageThumbFile(
+ imageChoiceFile);
- // keep in session the location of this thumb (do not
- // want to expose the full path location in url)
- getPollenSession().putDynamicData(
- IMAGECHOICES_THUMB_PREFIX + choice.getName(),
- thumbFile);
+ // keep in session the location of this thumb (do not
+ // want to expose the full path location in url)
+ getPollenSession().putDynamicData(
+ IMAGECHOICES_THUMB_PREFIX + choice.getName(),
+ thumbFile);
+ }
}
-
break;
}
}
@@ -419,6 +1262,482 @@
getPersontoListCreator(),
defaultMaxVoting);
}
+ }
+ protected boolean isTextChoiceEmpty(Choice textChoice) {
+ boolean result =
+ StringUtils.isBlank(textChoice.getName()) &&
+ StringUtils.isBlank(textChoice.getDescription());
+ return result;
}
+
+ protected boolean isDateChoiceEmpty(PollDateChoice dateChoice) {
+ boolean result =
+ StringUtils.isBlank(dateChoice.getName()) &&
+ StringUtils.isBlank(dateChoice.getDescription());
+ return result;
+ }
+
+ protected boolean isImageChoiceEmpty(PollImageChoice imageChoice) {
+ boolean result =
+ StringUtils.isBlank(imageChoice.getLocation()) &&
+ StringUtils.isBlank(imageChoice.getDescription());
+ return result;
+ }
+
+ protected boolean isImageUploadEmpty(PollImageChoice imageChoice) {
+ boolean result =
+ StringUtils.isBlank(imageChoice.getLocation());
+ return result;
+ }
+
+ protected boolean isPersonToListEmpty(PersonToList personToList) {
+ PollAccount pollAccount = personToList.getPollAccount();
+ boolean result =
+ StringUtils.isBlank(pollAccount.getVotingId()) &&
+ StringUtils.isBlank(pollAccount.getEmail());
+ return result;
+ }
+
+ protected Map<Integer, Choice> buildTextChoices() {
+ Map<Integer, Choice> result = Maps.newTreeMap();
+
+ String fieldPrefix = getChoiceFieldPrefix(ChoiceType.TEXT);
+
+ int maxNumber = 0;
+
+ for (String paramName : parameters.keySet()) {
+
+ Matcher matcher = TEXT_CHOICE_NAME_PATTERN.matcher(paramName);
+ if (matcher.matches()) {
+
+ // found a text choice name
+
+ String paramValue = getNonEmptyParameterValue(paramName);
+
+ // can keep this none empty text choice name
+
+ Integer choiceNumber = Integer.valueOf(matcher.group(1));
+ if (choiceNumber > maxNumber) {
+ maxNumber = choiceNumber;
+ }
+ Choice choice = createChoice(new ChoiceImpl(),
+ fieldPrefix + choiceNumber,
+ paramValue);
+ if (!isTextChoiceEmpty(choice)) {
+
+ // This is not an empty choice keep it
+ result.put(choiceNumber, choice);
+ }
+ }
+ }
+ result = reindexMap(result, maxNumber);
+
+ int size = result.size();
+ if (log.isInfoEnabled()) {
+ log.info("nbTextChoices (from request) = " + size);
+ }
+ logChoice(result);
+ return result;
+ }
+
+ protected Map<Integer, Choice> buildDateChoices() {
+ Map<Integer, Choice> result = Maps.newTreeMap();
+
+ String fieldPrefix = getChoiceFieldPrefix(ChoiceType.DATE);
+
+ int maxNumber = 0;
+ for (String paramName : parameters.keySet()) {
+
+ Matcher matcher = DATE_CHOICE_NAME_PATTERN.matcher(paramName);
+ if (matcher.matches()) {
+
+ // found a text choice name
+
+ String paramValue = getNonEmptyParameterValue(paramName);
+
+ // can keep this none empty text choice name
+
+ Integer choiceNumber = Integer.valueOf(matcher.group(1));
+ if (choiceNumber > maxNumber) {
+ maxNumber = choiceNumber;
+ }
+ String choiceFieldPrefix = fieldPrefix + choiceNumber;
+
+ PollDateChoice choice = createChoice(new PollDateChoice(),
+ choiceFieldPrefix,
+ paramValue);
+ if (StringUtils.isNotBlank(paramValue)) {
+ Date date = DateConverter.convertFromString(paramValue);
+ choice.setDate(date);
+ }
+
+ if (!isDateChoiceEmpty(choice)) {
+
+ // This is not an empty choice keep it
+ result.put(choiceNumber, choice);
+ }
+ }
+ }
+ result = reindexMap(result, maxNumber);
+
+ int size = result.size();
+ if (log.isInfoEnabled()) {
+ log.info("nbDateChoices (from request) = " + size);
+ }
+ logChoice(result);
+ return result;
+ }
+
+ protected Map<Integer, Choice> buildImageChoices() {
+ Map<Integer, Choice> result = Maps.newTreeMap();
+
+ String fieldPrefix = getChoiceFieldPrefix(ChoiceType.IMAGE);
+
+ int maxNumber = 0;
+
+ Map<String, String> parametersToSwitch = Maps.newTreeMap();
+
+ for (String paramName : parameters.keySet()) {
+
+ Matcher matcher = IMAGE_CHOICE_DESCRIPTION_PATTERN.matcher(paramName);
+ if (matcher.matches()) {
+
+ // found an image choice description
+ // Note: We can not use as for other choices (text and date)
+ // the name since there is no name parameter submitted...
+ // the upload filed will implies a such parameter...
+
+ Integer choiceNumber = Integer.valueOf(matcher.group(1));
+ if (choiceNumber > maxNumber) {
+ maxNumber = choiceNumber;
+ }
+
+ String choiceFieldPrefix = fieldPrefix + choiceNumber;
+
+ PollImageChoice choice = createChoice(new PollImageChoice(),
+ choiceFieldPrefix,
+ null);
+ String location = getNonEmptyParameterValue(
+ choiceFieldPrefix + ".newLocation");
+ if (StringUtils.isNotBlank(location)) {
+
+ // found a real upload file (not jus the location of an
+ // already choice uploaded choice
+ choice.setLocation(location);
+
+ // ok so now use also newName
+ String paramValue = getNonEmptyParameterValue(
+ choiceFieldPrefix + ".newName");
+ choice.setName(paramValue);
+
+ parametersToSwitch.put(choiceFieldPrefix + ".newLocation",
+ choiceFieldPrefix + ".location");
+
+ parametersToSwitch.put(choiceFieldPrefix + ".newName",
+ choiceFieldPrefix + ".name");
+
+ } else {
+
+ // try with old location
+ location = getNonEmptyParameterValue(
+ choiceFieldPrefix + ".location");
+ choice.setLocation(location);
+
+ String paramValue = getNonEmptyParameterValue(
+ choiceFieldPrefix + ".name");
+ choice.setName(paramValue);
+ }
+
+ if (!isImageChoiceEmpty(choice)) {
+
+ // This is not an empty choice keep it
+ result.put(choiceNumber, choice);
+ }
+ }
+ }
+
+ // switch new uploaded values
+ for (Map.Entry<String, String> entry : parametersToSwitch.entrySet()) {
+ String paramNameSource = entry.getKey();
+ String paramNameTarget = entry.getValue();
+ String[] valueToSwitch = parameters.remove(paramNameSource);
+ parameters.put(paramNameTarget, valueToSwitch);
+ }
+ result = reindexMap(result, maxNumber);
+ int size = result.size();
+ if (log.isInfoEnabled()) {
+ log.info("nbImageChoices (from request) = " + size);
+ }
+ logChoice(result);
+ return result;
+ }
+
+ protected Map<Integer, VotingList> buildVotingLists(PollType pollType) {
+ Map<Integer, VotingList> result = Maps.newTreeMap();
+
+ int maxNumber = 0;
+
+ String votingListPrefix = "votingList" + pollType.name();
+
+ // get all votingList_xxx parameters
+ Set<String> votingListParameterNames = Sets.filter(
+ parameters.keySet(),
+ new StringStartWithPredicate(votingListPrefix));
+
+ Pattern votingListPattern = Pattern.compile(
+ "(" + votingListPrefix + ")_(\\d+)\\.name");
+
+ for (String paramName : votingListParameterNames) {
+
+ Matcher matcher = votingListPattern.matcher(paramName);
+
+ if (matcher.matches()) {
+
+ // found a voting list name
+
+ int votingListNumber = Integer.valueOf(matcher.group(2));
+
+ buildVotingList(paramName,
+ votingListPrefix + "_" + votingListNumber,
+ votingListNumber,
+ result
+ );
+ maxNumber = Math.max(maxNumber, votingListNumber);
+ }
+ }
+
+ result = reindexMap(result, maxNumber);
+
+ int size = result.size();
+ if (log.isInfoEnabled()) {
+ log.info("nbVotingList [" + pollType + "] (from request) = " + size);
+ }
+
+ // add personToList maps to session (but just now, since votingList
+ // could have been reindex)
+ for (Map.Entry<Integer, VotingList> entry : result.entrySet()) {
+ VotingList votingList = entry.getValue();
+
+ if (!votingList.isPollAccountPersonToListEmpty()) {
+ List<PersonToList> personToList =
+ votingList.getPollAccountPersonToList();
+
+ Map<Integer, PersonToList> personToListMap = Maps.newTreeMap();
+ int index = 0;
+ for (PersonToList toList : personToList) {
+ personToListMap.put(index++, toList);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private double getDoubleValue(String parameterName) {
+ String parameterValue = getNonEmptyParameterValue(parameterName);
+ double result = 0;
+ if (StringUtils.isNotEmpty(parameterValue)) {
+
+ try {
+ result = Double.valueOf(parameterValue);
+ } catch (NumberFormatException e) {
+ //bad conversion, will be treated later
+ if (log.isDebugEnabled()) {
+ log.debug("Bad double conversion from param [" +
+ parameterName + "] : " + parameterValue);
+ }
+ }
+ }
+ return result;
+ }
+
+ private int buildVotingList(String votingListParameterName,
+ String votingListPrefix,
+ int votingListNumber,
+ Map<Integer, VotingList> result) {
+
+ String paramValue = getNonEmptyParameterValue(votingListParameterName);
+
+ VotingList votingList = new VotingListImpl();
+
+ votingList.setName(paramValue);
+
+ double weight = getDoubleValue(votingListPrefix + ".weight");
+ votingList.setWeight(weight);
+
+ String topiaId = getNonEmptyParameterValue(votingListPrefix + ".topiaId");
+ votingList.setTopiaId(topiaId);
+
+ result.put(votingListNumber, votingList);
+
+ String personToListPrefix = votingListPrefix + "PersonToList_";
+
+ // get all personToList parameters
+ Set<String> votingListParameterNames = Sets.filter(
+ parameters.keySet(),
+ new StringStartWithPredicate(personToListPrefix));
+
+ Pattern personToListNamePattern = Pattern.compile(
+ personToListPrefix + "(\\d+)\\.votingId");
+
+ Map<Integer, PersonToList> personToLists = Maps.newTreeMap();
+
+ int maxPersonToListNumber = 0;
+
+ // let's build personToList list
+ for (String personToListNameParameter : votingListParameterNames) {
+
+ Matcher matcher = personToListNamePattern.matcher(
+ personToListNameParameter);
+
+ if (matcher.matches()) {
+
+ int personToListNumber = buildPersonToList(
+ personToListPrefix,
+ personToListNameParameter,
+ matcher,
+ votingListNumber,
+ personToLists);
+
+ maxPersonToListNumber = Math.max(maxPersonToListNumber,
+ personToListNumber);
+ }
+ }
+
+ personToLists = reindexMap(personToLists, maxPersonToListNumber);
+
+ for (PersonToList personToList : personToLists.values()) {
+ votingList.addPollAccountPersonToList(personToList);
+ }
+
+ return votingListNumber;
+ }
+
+ private int buildPersonToList(String personToListPrefix,
+ String paramName,
+ Matcher personToListMatcher,
+ int votingListNumber,
+ Map<Integer, PersonToList> result) {
+
+ int personToListNumber = Integer.valueOf(personToListMatcher.group(1));
+
+ PersonToList personToList = new PersonToListImpl();
+
+ PollAccount account = new PollAccountImpl();
+ personToList.setPollAccount(account);
+
+ account.setVotingId(getNonEmptyParameterValue(paramName));
+
+ String prefix = personToListPrefix + personToListNumber;
+
+ double weight = getDoubleValue(prefix + ".weight");
+ personToList.setWeight(weight);
+
+ String topiaId = getNonEmptyParameterValue(prefix + ".topiaId");
+ personToList.setTopiaId(topiaId);
+
+ String email = getNonEmptyParameterValue(prefix + ".email");
+ account.setEmail(email);
+
+ String accountId = getNonEmptyParameterValue(prefix + ".accountId");
+ account.setAccountId(accountId);
+
+ if (!isPersonToListEmpty(personToList)) {
+
+ // can keep this not empty personToList
+ result.put(personToListNumber, personToList);
+ }
+ return personToListNumber;
+ }
+
+ private <C extends Choice> C createChoice(C choice,
+ String prefix,
+ String name) {
+ String description = getNonEmptyParameterValue(prefix + ".description");
+ String topiaId = getNonEmptyParameterValue(prefix + ".topiaId");
+ choice.setName(name);
+ choice.setDescription(description);
+ choice.setTopiaId(topiaId);
+ return choice;
+ }
+
+ private void logChoice(Map<Integer, Choice> result) {
+ for (Map.Entry<Integer, Choice> e : result.entrySet()) {
+ Integer choiceId = e.getKey();
+ Choice choice = e.getValue();
+ if (log.isInfoEnabled()) {
+ log.info("Choice [" + choiceId + "] = " +
+ choice.getName() + " -- " +
+ choice.getDescription());
+ }
+ }
+ }
+
+ protected <T> Map<Integer, T> reindexMap(Map<Integer, T> result, int maxNumber) {
+ Map<Integer, T> result2;
+
+ if (maxNumber != result.size() - 1) {
+
+ // means there is a hole inside the result (a empty choice was
+ // submitted)
+
+ // le'ts remove this
+ List<Integer> numbers = Lists.newArrayList(result.keySet());
+
+ Collections.sort(numbers);
+
+ result2 = Maps.newTreeMap();
+ int i = 0;
+ for (Integer number : numbers) {
+ T choice = result.get(number);
+ result2.put(i++, choice);
+ }
+ } else {
+ result2 = result;
+ }
+ return result2;
+ }
+
+ protected String getNonEmptyParameterValue(String paramName) {
+ String[] paramValues = parameters.get(paramName);
+ String result = null;
+ if (paramValues != null && paramValues.length == 1) {
+ String paramValue = paramValues[0];
+ if (StringUtils.isNotEmpty(paramValue)) {
+ result = paramValue;
+ }
+ }
+ return result;
+ }
+
+ private String getChoiceFieldPrefix(ChoiceType choiceType) {
+ String result = null;
+ switch (choiceType) {
+
+ case TEXT:
+ result = "textChoice_";
+ break;
+ case DATE:
+ result = "dateChoice_";
+ break;
+ case IMAGE:
+ result = "imageChoice_";
+ break;
+ }
+ return result;
+ }
+
+ private static class StringStartWithPredicate implements Predicate<String> {
+ private final String prefix;
+
+ public StringStartWithPredicate(String prefix) {
+ this.prefix = prefix;
+ }
+
+ @Override
+ public boolean apply(String input) {
+ return input.startsWith(prefix);
+ }
+ }
}
Modified: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/AbstractVoteAction.java
===================================================================
--- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/AbstractVoteAction.java 2012-06-16 20:33:49 UTC (rev 3493)
+++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/AbstractVoteAction.java 2012-06-16 20:36:03 UTC (rev 3494)
@@ -120,8 +120,6 @@
*/
private String commentAuthor;
-// private String voteSizeMessage;
-
/**
* Results of the poll.
*
@@ -302,8 +300,15 @@
// TODO no pagination for the moment, need to retrieve the correct page depends on current pollAccount
votes = getVoteService().getAllVotes(poll);
- voteAllowed = !moderate && getVoteService().isVoteAllowed(poll, pollAccount);
+ voteAllowed = !moderate && getSecurityService().isVoteAllowed(poll, pollAccount);
+ if (voteAllowed) {
+
+ // can not vote if accountId from the url is the creator one
+ voteAllowed = !poll.getCreator().getAccountId().equals(getUriId().getAccountId());
+
+ }
+
// Current vote
if (voteAllowed) {
vote = getVoteService().getVoteEditable(poll, pollAccount);
@@ -371,7 +376,7 @@
}
public boolean isModifAllowed(Vote vote) {
- return getVoteService().isUpdateAllowed(
+ return getSecurityService().isUpdateAllowed(
getPoll(),
vote.getTopiaId(),
getAccountId(),
@@ -383,7 +388,7 @@
}
public boolean isDeleteCommentAllowed(Comment comment) {
- return getPollCommentService().isCanDeleteComment(
+ return getSecurityService().isCanDeleteComment(
comment,
getPollAccount(),
getPollenUserAccount(),
Added: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/ClonePoll.java
===================================================================
--- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/ClonePoll.java (rev 0)
+++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/ClonePoll.java 2012-06-16 20:36:03 UTC (rev 3494)
@@ -0,0 +1,54 @@
+/*
+ * #%L
+ * Pollen :: UI (struts2)
+ * $Id: SavePoll.java 3467 2012-06-13 15:57:49Z tchemit $
+ * $HeadURL: http://svn.chorem.org/svn/pollen/trunk/pollen-ui-struts2/src/main/java/org/… $
+ * %%
+ * Copyright (C) 2009 - 2012 CodeLutin, Tony Chemit
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * #L%
+ */
+package org.chorem.pollen.ui.actions.poll;
+
+import org.chorem.pollen.business.persistence.Poll;
+
+/**
+ * Clones a poll.
+ *
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 1.4
+ */
+public class ClonePoll extends AbstractPollForm {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public boolean isClone() {
+ return true;
+ }
+
+ @Override
+ public boolean isEdit() {
+ return false;
+ }
+
+ @Override
+ protected Poll savePoll(Poll poll) {
+ poll = getPollService().createPoll(poll);
+ addFlashMessage(_("pollen.information.poll.created", poll.getTitle()));
+ return poll;
+ }
+
+}
Copied: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/CreatePoll.java (from rev 3486, trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/SavePoll.java)
===================================================================
--- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/CreatePoll.java (rev 0)
+++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/CreatePoll.java 2012-06-16 20:36:03 UTC (rev 3494)
@@ -0,0 +1,54 @@
+/*
+ * #%L
+ * Pollen :: UI (struts2)
+ * $Id$
+ * $HeadURL$
+ * %%
+ * Copyright (C) 2009 - 2012 CodeLutin, Tony Chemit
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * #L%
+ */
+package org.chorem.pollen.ui.actions.poll;
+
+import org.chorem.pollen.business.persistence.Poll;
+
+/**
+ * Creates a poll.
+ *
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 1.4
+ */
+public class CreatePoll extends AbstractPollForm {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public boolean isClone() {
+ return false;
+ }
+
+ @Override
+ public boolean isEdit() {
+ return false;
+ }
+
+ @Override
+ protected Poll savePoll(Poll poll) {
+ poll = getPollService().createPoll(poll);
+ addFlashMessage(_("pollen.information.poll.created", poll.getTitle()));
+ return poll;
+ }
+
+}
Added: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/EditPoll.java
===================================================================
--- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/EditPoll.java (rev 0)
+++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/EditPoll.java 2012-06-16 20:36:03 UTC (rev 3494)
@@ -0,0 +1,58 @@
+/*
+ * #%L
+ * Pollen :: UI (struts2)
+ * $Id: SavePoll.java 3467 2012-06-13 15:57:49Z tchemit $
+ * $HeadURL: http://svn.chorem.org/svn/pollen/trunk/pollen-ui-struts2/src/main/java/org/… $
+ * %%
+ * Copyright (C) 2009 - 2012 CodeLutin, Tony Chemit
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * #L%
+ */
+package org.chorem.pollen.ui.actions.poll;
+
+import org.chorem.pollen.business.persistence.Poll;
+import org.chorem.pollen.services.exceptions.PollNotFoundException;
+
+/**
+ * Edit a poll (load it via {@link #input()}), and save it
+ * via {@link #execute()}).
+ *
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 1.3
+ */
+public class EditPoll extends AbstractPollForm {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public boolean isClone() {
+
+ // in edit mode never can be a clone
+ return false;
+ }
+
+ @Override
+ public boolean isEdit() {
+ return true;
+ }
+
+ @Override
+ protected Poll savePoll(Poll poll) throws PollNotFoundException {
+ poll = getPollService().updatePoll(poll);
+ addFlashMessage(_("pollen.information.poll.updated", poll.getTitle()));
+ return poll;
+ }
+
+}
Deleted: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/LoadPoll.java
===================================================================
--- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/LoadPoll.java 2012-06-16 20:33:49 UTC (rev 3493)
+++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/LoadPoll.java 2012-06-16 20:36:03 UTC (rev 3494)
@@ -1,163 +0,0 @@
-/*
- * #%L
- * Pollen :: UI (struts2)
- * $Id$
- * $HeadURL$
- * %%
- * Copyright (C) 2009 - 2012 CodeLutin, Tony Chemit
- * %%
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- * #L%
- */
-package org.chorem.pollen.ui.actions.poll;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.chorem.pollen.bean.PollImageChoice;
-import org.chorem.pollen.bean.PollUri;
-import org.chorem.pollen.business.persistence.Choice;
-import org.chorem.pollen.business.persistence.PreventRule;
-import org.chorem.pollen.business.persistence.UserAccount;
-import org.chorem.pollen.business.persistence.VotingList;
-import org.chorem.pollen.common.ChoiceType;
-import org.chorem.pollen.services.impl.PollService;
-import org.chorem.pollen.services.impl.PreventRuleService;
-
-import java.io.File;
-import java.util.List;
-
-/**
- * Load the poll form for modification (or only read if poll is no more
- * editable).
- * <p/>
- * Created: 04/04/12
- *
- * @author fdesbois <desbois(a)codelutin.com>
- * @author tchemit <chemit(a)codelutin.com>
- * @since 1.3
- */
-public class LoadPoll extends AbstractPollForm {
-
- private static final long serialVersionUID = 1L;
-
- /** Logger. */
- private static final Log log = LogFactory.getLog(LoadPoll.class);
-
- private PollUri pollUri;
-
- private boolean clone;
-
- public PollUri getUriId() {
- return pollUri;
- }
-
- public void setUriId(PollUri pollUri) {
- this.pollUri = pollUri;
- }
-
- public void setClone(boolean clone) {
- this.clone = clone;
- }
-
- @Override
- public String execute() throws Exception {
-
- prepareFormPage();
-
- UserAccount userAccount = getPollenUserAccount();
- String pollUid = pollUri == null ? null : pollUri.getPollId();
- PollService service = getPollService();
-
- poll = service.getPollEditable(pollUid, userAccount, clone);
-
- if (poll.isClosed()) {
- addFlashWarning(_("pollen.warning.poll.is.closed.so.read.only"));
- }
- List<Choice> pollChoices = poll.getChoice();
-
- if (clone) {
-
- if (ChoiceType.IMAGE == poll.getChoiceType()) {
-
- // recopy images to tmp
-
- File tmpDir = getConfiguration().getTemporaryDirectory();
- for (Choice choice : pollChoices) {
- String choiceName = choice.getName();
-
- // image from poll to clone
- File imageChoiceFile = service.getPollChoiceImageFile(
- pollUid,
- choiceName
- );
-
- // new image
- File newImageChoiceFile = File.createTempFile(
- choiceName, null, tmpDir);
-
- if (log.isInfoEnabled()) {
- log.info("Copy image from " + imageChoiceFile +
- " to " + newImageChoiceFile);
- }
- FileUtils.copyFile(imageChoiceFile,
- newImageChoiceFile);
-
- ((PollImageChoice) choice).setLocation(
- newImageChoiceFile.getAbsolutePath());
- }
- }
- }
-
- List<VotingList> pollVotingLists = poll.getVotingList();
-
- loadChoicesAndvotingLists(poll,
- pollChoices,
- pollVotingLists,
- !isVoteStarted());
-
- setLimitChoice(poll.getMaxChoiceNb() > 0);
-
- if (isLimitChoice()) {
- setMaxChoices(poll.getMaxChoiceNb());
- } else {
- // set default max choices
- setMaxChoices(1);
- }
- PreventRule reminder = poll.getPreventRuleByScope(
- PreventRuleService.SCOPE_REMINDER);
- if (reminder != null) {
- setReminder(true);
- setReminderHourCountdown(reminder.getSensibility());
- } else {
- setReminder(false);
- // set default reminderHourCountdown
- setReminderHourCountdown(2);
- }
-
- PreventRule notification = poll.getPreventRuleByScope(
- PreventRuleService.SCOPE_VOTE);
- if (notification != null) {
- setNotification(true);
- }
-
- if (isVoteStarted()) {
- addFlashMessage(_("pollen.information.poll.form.voteStarted"));
- }
-
- return SUCCESS;
- }
-
-
-}
Deleted: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/SavePoll.java
===================================================================
--- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/SavePoll.java 2012-06-16 20:33:49 UTC (rev 3493)
+++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/SavePoll.java 2012-06-16 20:36:03 UTC (rev 3494)
@@ -1,1099 +0,0 @@
-/*
- * #%L
- * Pollen :: UI (struts2)
- * $Id$
- * $HeadURL$
- * %%
- * Copyright (C) 2009 - 2012 CodeLutin, Tony Chemit
- * %%
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- * #L%
- */
-package org.chorem.pollen.ui.actions.poll;
-
-import com.google.common.base.Predicate;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.opensymphony.xwork2.Preparable;
-import com.opensymphony.xwork2.interceptor.annotations.InputConfig;
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.collections.MapUtils;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.struts2.interceptor.ParameterAware;
-import org.chorem.pollen.bean.ChoiceHelper;
-import org.chorem.pollen.bean.PollDateChoice;
-import org.chorem.pollen.bean.PollImageChoice;
-import org.chorem.pollen.bean.PollUri;
-import org.chorem.pollen.business.persistence.Choice;
-import org.chorem.pollen.business.persistence.ChoiceImpl;
-import org.chorem.pollen.business.persistence.PersonToList;
-import org.chorem.pollen.business.persistence.PersonToListImpl;
-import org.chorem.pollen.business.persistence.PollAccount;
-import org.chorem.pollen.business.persistence.PollAccountImpl;
-import org.chorem.pollen.business.persistence.PreventRule;
-import org.chorem.pollen.business.persistence.UserAccount;
-import org.chorem.pollen.business.persistence.VotingList;
-import org.chorem.pollen.business.persistence.VotingListImpl;
-import org.chorem.pollen.common.ChoiceType;
-import org.chorem.pollen.common.PollType;
-import org.chorem.pollen.services.impl.PreventRuleService;
-import org.chorem.pollen.ui.actions.FileUploadAware;
-import org.chorem.pollen.ui.converters.DateConverter;
-import org.nuiton.util.StringUtil;
-
-import java.io.File;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Saves the incoming poll, could be a new poll or just an update.
- *
- * @author tchemit <chemit(a)codelutin.com>
- * @since 1.3
- */
-public class SavePoll extends AbstractPollForm implements Preparable, ParameterAware, FileUploadAware {
-
- private static final long serialVersionUID = 1L;
-
- /** Logger. */
- private static final Log log = LogFactory.getLog(SavePoll.class);
-
- private static final Pattern TEXT_CHOICE_NAME_PATTERN =
- Pattern.compile("textChoice_(\\d+)\\.name");
-
- private static final Pattern DATE_CHOICE_NAME_PATTERN =
- Pattern.compile("dateChoice_(\\d+)\\.name");
-
- private static final Pattern IMAGE_CHOICE_NAME_PATTERN =
- Pattern.compile("imageChoice_(\\d+)\\.name");
-
- /**
- * Flag when there is some errors on the information panel.
- *
- * @since 1.3
- */
- protected boolean informationsError;
-
- /**
- * Flag when there is some errors on the options panel.
- *
- * @since 1.3
- */
- private boolean optionsError;
-
- /**
- * All the parameters send by request used to build back choices of the
- * poll.
- *
- * @since 1.3
- */
- protected final Map<String, String[]> parameters = Maps.newTreeMap();
-
- /**
- * Indexed choices retreive from parameters for the choiceType selected in
- * form. (Other choices are lost).
- *
- * @since 1.3
- */
- private Map<Integer, Choice> choices;
-
- /**
- * Indexed voting lists retreive from parameters for the pollType selected
- * in form. (Other voting lists are lost).
- *
- * @since 1.3
- */
- private Map<Integer, VotingList> votingLists;
-
- @Override
- public void prepare() throws Exception {
-
- prepareFormPage();
-
- String pollUid = getNonEmptyParameterValue("poll.pollId");
- String userId = getNonEmptyParameterValue("userId");
- if (StringUtils.isBlank(userId)) {
-
- // try to take the one from current user
- UserAccount userAccount = getPollenUserAccount();
- if (userAccount != null) {
- userId = userAccount.getTopiaId();
- }
- }
- UserAccount userAccount = null;
- if (StringUtils.isNotBlank(userId)) {
- // load use account to use
- userAccount = getPollService().getEntityById(
- UserAccount.class, userId);
- }
-
- // get a copy (or a fresh new poll)
- poll = getPollService().getPollEditable(pollUid, userAccount, false);
-
- // If vote is started, prepare choices and votingLists is useless
- // because they can't be updated.
- if (!isVoteStarted()) {
-
- // Retrieve choiceType from parameters, the poll object will be updated after prepare
- String choiceTypeParam = getNonEmptyParameterValue("poll.choiceType");
- ChoiceType pollChoiceType = ChoiceType.valueOf(choiceTypeParam);
- poll.setChoiceType(pollChoiceType);
-
- // build poll choices
-
- switch (pollChoiceType) {
-
- case TEXT:
- choices = buildTextChoices();
- break;
- case DATE:
- choices = buildDateChoices();
- break;
- case IMAGE:
- choices = buildImageChoices();
- break;
- }
- PollType pollType;
- String pollTypeParam = getNonEmptyParameterValue("poll.pollType");
- pollType = PollType.valueOf(pollTypeParam);
- switch (pollType) {
-
- case FREE:
-
- // empty voting list
- votingLists = Maps.newTreeMap();
- break;
- case RESTRICTED:
-
- // restricted voting list
- votingLists = buildVotingLists(pollType);
- break;
- case GROUP:
-
- // group voting lists
- votingLists = buildVotingLists(pollType);
- break;
- }
- }
- }
-
- public PollUri getUriId() {
- return PollUri.newPollUri(poll.getAdminId());
- }
-
- @Override
- public String input() throws Exception {
-
- Collection<Choice> pollChoices =
- isVoteStarted() ? poll.getChoice() : choices.values();
- Collection<VotingList> pollVotingLists =
- isVoteStarted() ? poll.getVotingList() : votingLists.values();
-
- if (ChoiceType.IMAGE == poll.getChoiceType()) {
-
- // recopy images for new choices, the one uploaded will be
- // destroyed, by the upload interceptor
-
- File tmpDir = getConfiguration().getTemporaryDirectory();
-
- for (Choice choice : pollChoices) {
-
- String choiceId = choice.getTopiaId();
-
- if (StringUtils.isBlank(choiceId)) {
-
- PollImageChoice imageChoice = (PollImageChoice) choice;
-
- File uploadedImage = new File(imageChoice.getLocation());
- File copyImage = File.createTempFile(
- uploadedImage.getName(), null, tmpDir);
-
- if (log.isInfoEnabled()) {
- log.info("Copy image from " + uploadedImage +
- " to " + copyImage);
- }
- FileUtils.copyFile(uploadedImage, copyImage);
-
- imageChoice.setLocation(copyImage.getAbsolutePath());
- }
- }
- }
-
- loadChoicesAndvotingLists(poll, pollChoices, pollVotingLists, true);
- return INPUT;
- }
-
-
- @Override
- public void validate() {
-
- validateInformations();
-
- validateOptions();
- }
-
- @Override
- @InputConfig(methodName = "input")
- public String execute() throws Exception {
-
- // Save choices and votingLists only if vote is not started
- if (!isVoteStarted()) {
- //TODO-tchemit comment me 2012-06-04 A merge would be nicer but more complex to code
- // Clear previous collections to save those from the form
- poll.clearChoice();
- poll.clearVotingList();
- for (Integer index : choices.keySet()) {
- Choice choice = choices.get(index);
- poll.addChoice(choice);
- }
-
- if (!isFreePoll()) {
-
- for (Integer index : votingLists.keySet()) {
- VotingList votingList = votingLists.get(index);
- poll.addVotingList(votingList);
- }
- }
- }
-
- if (isLimitChoice()) {
-
- // push back filled value
- poll.setMaxChoiceNb(getMaxChoices());
- } else {
- // reset value
- poll.setMaxChoiceNb(0);
- }
-
- if (!poll.isPublicResults()) {
-
- // force to not have continous results
- poll.setContinuousResults(false);
- }
-
- if (poll.isAnonymous()) {
-
- // force to not have choice to vote anonymously
- poll.setAnonymousVoteAllowed(false);
- }
-
- //TODO-tchemit comment me 2012-06-04 A merge would be nicer but more complex to code
- poll.clearPreventRule();
-
- PreventRuleService preventRuleService = getPreventRuleService();
- if (isNotification()) {
-
- // add a notification rule
-
- PreventRule rule = preventRuleService.createAddVotePreventRule();
- poll.addPreventRule(rule);
- }
-
- if (isReminder()) {
-
- // add a reminder rule
-
- PreventRule rule = preventRuleService.createRemindPreventRule(
- getReminderHourCountdown()
- );
-
- poll.addPreventRule(rule);
- }
-
- if (isEdit()) {
- getPollService().updatePoll(poll);
- addFlashMessage(
- _("pollen.information.poll.updated", poll.getTitle()));
-
- } else {
- poll = getPollService().createPoll(poll);
- addFlashMessage(
- _("pollen.information.poll.created", poll.getTitle()));
- }
-
- // remove all stuff from session
- getPollenSession().clearDynamicData();
-
- return SUCCESS;
- }
-
- @Override
- public void addFile(int index, File file) {
- parameters.put("imageChoice_" + index + ".location",
- new String[]{file.getAbsolutePath()});
- }
-
- @Override
- public void addFileContentType(int index, String contentType) {
- // not used here
- }
-
- @Override
- public void addFileName(int index, String fileName) {
- parameters.put("imageChoice_" + index + ".name", new String[]{fileName});
- }
-
- @Override
- public void setParameters(Map<String, String[]> parameters) {
- this.parameters.putAll(parameters);
- }
-
- @Override
- public boolean isInformationsError() {
- return informationsError;
- }
-
- @Override
- public boolean isOptionsError() {
- return optionsError;
- }
-
- @Override
- public int getSelectedTab() {
- int result;
- if (isInformationsError()) {
- result = 0;
- } else {
- if (isOptionsError()) {
- result = 1;
- } else {
- result = 0;
- }
- }
- return result;
- }
-
- protected void validateInformations() {
-
- // -- Title : required -- //
- if (StringUtils.isBlank(poll.getTitle())) {
- addInformationsError("poll.title",
- _("pollen.error.poll.required.title"));
- }
-
- if (isVoteStarted()) {
-
- // no validation on choices if vote is started
-
- } else {
-
- // -- Choice -- //
-
- if (MapUtils.isEmpty(choices)) {
-
- // poll must have at least one choice
- addInformationsError("poll.choices",
- _("pollen.error.poll.required.one.choice"));
- } else {
-
- // get all names from choices
- Set<String> choiceNames =
- Sets.newHashSet(ChoiceHelper.toNames(choices.values()));
-
- if (choices.size() > choiceNames.size()) {
-
- // theire is some duplicated names
- addInformationsError(
- "poll.choices",
- _("pollen.error.poll.detected.duplicate.choice.name"));
- }
- }
- }
- }
-
- protected void validateOptions() {
-
- if (isVoteStarted()) {
-
- // no validation on votingLists if vote is started
-
- } else {
-
- // -- VotingList -- //
-
- if (isFreePoll()) {
-
- // nothing to validate
-
- } else {
-
- Set<String> groups = Sets.newHashSet();
- Set<String> voters = Sets.newHashSet();
- Set<String> emails = Sets.newHashSet();
-
- for (Map.Entry<Integer, VotingList> entry : votingLists.entrySet()) {
- validateVotingList(entry.getKey(),
- entry.getValue(),
- groups,
- voters,
- emails);
- }
- }
- }
-
- String creatorEmail = poll.getCreator().getEmail();
- if (StringUtils.isNotBlank(creatorEmail) &&
- !StringUtil.isEmail(creatorEmail)) {
-
- addOptionsError("poll.creator.email",
- _("pollen.error.email.invalid"));
- }
-
- Date currentTime = serviceContext.getCurrentTime();
-
- if (validateEndDate(poll.getBeginChoiceDate(), poll.getEndChoiceDate())) {
-
- addOptionsError(
- "poll.endChoiceDate",
- _("pollen.error.poll.endChoiceDate.before.beginChoiceDate"));
- }
-
- if (validateEndDate(currentTime, poll.getEndChoiceDate())) {
-
- addOptionsError(
- "poll.endChoiceDate",
- _("pollen.error.poll.endChoiceDate.before.now"));
- }
-
- if (validateEndDate(poll.getBeginDate(), poll.getEndDate())) {
-
- addOptionsError("poll.endDate",
- _("pollen.error.poll.endDate.before.beginDate"));
- }
-
-
- if (validateEndDate(currentTime, poll.getEndDate())) {
-
- addOptionsError(
- "poll.endDate",
- _("pollen.error.poll.endDate.before.now"));
- }
-
- if (validateEndDate(poll.getEndChoiceDate(), poll.getEndDate())) {
-
- addOptionsError("poll.endChoiceDate",
- _("pollen.error.poll.endChoiceDate.after.endDate"));
- }
-
- if (isLimitChoice()) {
-
- // validate maxChoices
-
- if (getMaxChoices() == null) {
- // maxChoices == null
- addOptionsError("maxChoices",
- _("pollen.error.poll.maxChoice.required"));
- } else if (getMaxChoices() < 1) {
- // maxChoices <= 0
- addOptionsError("maxChoices",
- _("pollen.error.poll.maxChoice.greater.than.0"));
- }
- }
-
- if (isReminder()) {
-
- // validate reminderHourCountdown
-
- if (getReminderHourCountdown() == null) {
-
- // reminderHourCountdown == null
- addOptionsError("reminderHourCountdown",
- _("pollen.error.poll.reminderHourCountdown.required"));
- } else if (getReminderHourCountdown() < 1) {
-
- // reminderHourCountdown <= 0
- addOptionsError("reminderHourCountdown",
- _("pollen.error.poll.reminderHourCountdown.greater.than.0"));
- }
- }
- }
-
- protected void validateVotingList(int votingListNumber,
- VotingList votingList,
- Set<String> groups,
- Set<String> voters,
- Set<String> emails) {
-
- PollType votingListType = poll.getPollType();
- String fieldNamePrefix = "votingList" + votingListType + "_" +
- votingListNumber;
-
- if (isGroupPoll()) {
-
- // group poll
-
- // check there is at least one group
- // check no doublon on group names
- // check there is at least one voter on each group
- // check no doublon on voter names
- // check no doublon on voter emails
-
- { // validate votingList name
- String votingListName = votingList.getName();
-
- if (StringUtils.isEmpty(votingListName)) {
-
- addOptionsError(
- fieldNamePrefix,
- _("pollen.error.poll.required.votingList.name"));
- } else {
-
- // check no votingList name doublon
- boolean add = groups.add(votingListName);
- if (!add) {
-
- // name doublon
- addOptionsError(
- fieldNamePrefix,
- _("pollen.error.poll.votingList.name.doublon"));
- }
-
- }
- }
-
- { // validate votingList weight
-
- if (votingList.getWeight() == 0) {
-
- // no weight filled (can be a bad conversion)
- addOptionsError(
- fieldNamePrefix,
- _("pollen.error.poll.votingList.weight.not.valid"));
- }
- }
- }
-
- // check there is at least one voter
-
- List<PersonToList> personToLists =
- votingList.getPollAccountPersonToList();
-
- if (CollectionUtils.isEmpty(personToLists)) {
-
- // no personToList found for unique votingList 0
- addOptionsError(fieldNamePrefix,
- _("pollen.error.poll.required.one.personToList"));
- } else {
-
- // check no doublon on voter names
- // check no doublon on voter emails
-
- for (int i = 0; i < personToLists.size(); i++) {
-
- validatePersonList(i,
- fieldNamePrefix,
- personToLists.get(i),
- voters,
- emails);
- }
- }
- }
-
- protected void validatePersonList(int personToListNumber,
- String votingListFieldNamePrefix,
- PersonToList personToList,
- Set<String> voters,
- Set<String> emails) {
-
- String fieldNamePrefix = votingListFieldNamePrefix +
- "PersonToList_" + personToListNumber;
-
- PollAccount pollAccount = personToList.getPollAccount();
-
- { // validate votingId
-
- String votingId = pollAccount.getVotingId();
- // check voter is not doublon
- boolean add = voters.add(votingId);
- if (!add) {
-
- // voter doublon
- addOptionsError(
- fieldNamePrefix,
- _("pollen.error.poll.personToList.votingId.doublon"));
- }
- }
- { // validate email
- String email = pollAccount.getEmail();
-
- if (StringUtils.isEmpty(email)) {
- addOptionsError(
- fieldNamePrefix,
- _("pollen.error.email.required"));
- } else {
-
-
- boolean validEmail = StringUtil.isEmail(email);
- if (!validEmail) {
-
- // not a valid email
- addOptionsError(
- fieldNamePrefix,
- _("pollen.error.email.invalid"));
- } else {
-
- // check email not doublon
- boolean add = emails.add(email);
- if (!add) {
-
- // email doublon
- addOptionsError(
- fieldNamePrefix,
- _("pollen.error.poll.personToList.email.doublon"));
- }
- }
- }
- }
- { // validate weight
- if (personToList.getWeight() == 0) {
-
- // no weight filled (can be a bad conversion)
- addOptionsError(
- fieldNamePrefix,
- _("pollen.error.poll.personToList.weight.not.valid"));
- }
- }
- }
-
- protected boolean validateEndDate(Date begin, Date end) {
- return begin != null
- && end != null
- && end.before(begin);
- }
-
- @Override
- public void addFieldError(String fieldName, String errorMessage) {
- super.addFieldError(fieldName, errorMessage);
- if (log.isDebugEnabled()) {
- log.debug("VALIDATION [" + fieldName + "] : " + errorMessage);
- }
- }
-
- protected void addInformationsError(String fieldName, String errorMessage) {
- addFieldError(fieldName, errorMessage);
- informationsError = true;
- }
-
- protected void addOptionsError(String fieldName, String errorMessage) {
- addFieldError(fieldName, errorMessage);
- optionsError = true;
- }
-
- protected Map<Integer, Choice> buildTextChoices() {
- Map<Integer, Choice> result = Maps.newTreeMap();
-
- int maxNumber = 0;
-
- for (String paramName : parameters.keySet()) {
-
- Matcher matcher = TEXT_CHOICE_NAME_PATTERN.matcher(paramName);
- if (matcher.matches()) {
-
- // found a text choice name
-
- String paramValue = getNonEmptyParameterValue(paramName);
- if (paramValue != null) {
-
- // can keep this none empty text choice name
-
- Integer choiceNumber = Integer.valueOf(matcher.group(1));
- if (choiceNumber > maxNumber) {
- maxNumber = choiceNumber;
- }
- Choice choice = new ChoiceImpl();
- createChoice(choice, "textChoice_" + choiceNumber,
- paramValue);
- result.put(choiceNumber, choice);
- }
- }
- }
- result = reindexMap(result, maxNumber);
-
- int size = result.size();
- if (log.isInfoEnabled()) {
- log.info("nbTextChoices (from request) = " + size);
- }
- logChoice(result);
- return result;
- }
-
- protected Map<Integer, Choice> buildDateChoices() {
- Map<Integer, Choice> result = Maps.newTreeMap();
-
- int maxNumber = 0;
- for (String paramName : parameters.keySet()) {
-
- Matcher matcher = DATE_CHOICE_NAME_PATTERN.matcher(paramName);
- if (matcher.matches()) {
-
- // found a text choice name
-
- String paramValue = getNonEmptyParameterValue(paramName);
- if (paramValue != null) {
-
- // can keep this none empty text choice name
-
- Integer choiceNumber = Integer.valueOf(matcher.group(1));
- if (choiceNumber > maxNumber) {
- maxNumber = choiceNumber;
- }
- PollDateChoice choice = new PollDateChoice();
- createDateChoice(choice,
- "dateChoice_" + choiceNumber,
- paramValue);
- result.put(choiceNumber, choice);
- }
- }
- }
- result = reindexMap(result, maxNumber);
-
- int size = result.size();
- if (log.isInfoEnabled()) {
- log.info("nbDateChoices (from request) = " + size);
- }
- logChoice(result);
- return result;
- }
-
- protected Map<Integer, Choice> buildImageChoices() {
- Map<Integer, Choice> result = Maps.newTreeMap();
-
- int maxNumber = 0;
- for (String paramName : parameters.keySet()) {
-
- Matcher matcher = IMAGE_CHOICE_NAME_PATTERN.matcher(paramName);
- if (matcher.matches()) {
-
- // found an image choice name
-
- String paramValue = getNonEmptyParameterValue(paramName);
- if (paramValue != null) {
-
- // can keep this none empty text choice name
-
- Integer choiceNumber = Integer.valueOf(matcher.group(1));
- if (choiceNumber > maxNumber) {
- maxNumber = choiceNumber;
- }
- PollImageChoice choice = new PollImageChoice();
- createImageChoice(choice,
- "imageChoice_" + choiceNumber,
- paramValue);
-
- result.put(choiceNumber, choice);
- }
- }
- }
- result = reindexMap(result, maxNumber);
- int size = result.size();
- if (log.isInfoEnabled()) {
- log.info("nbImageChoices (from request) = " + size);
- }
- logChoice(result);
- return result;
- }
-
- protected Map<Integer, VotingList> buildVotingLists(PollType pollType) {
- Map<Integer, VotingList> result = Maps.newTreeMap();
-
- int maxNumber = 0;
-
- String votingListPrefix = "votingList" + pollType.name();
-
- // get all votingList_ parameters
- Set<String> votingListParameterNames = Sets.filter(
- parameters.keySet(),
- new StringStartWithPredicate(votingListPrefix));
-
- Pattern votingListPattern = Pattern.compile(
- "(" + votingListPrefix + ")_(\\d+)\\.name");
-
- for (String paramName : votingListParameterNames) {
-
- Matcher matcher = votingListPattern.matcher(paramName);
-
- if (matcher.matches()) {
-
- // found a voting list name
-
- int votingListNumber = Integer.valueOf(matcher.group(2));
-
- buildVotingList(paramName,
- votingListPrefix+ "_" + votingListNumber,
- votingListNumber,
- result
- );
- maxNumber = Math.max(maxNumber, votingListNumber);
- }
- }
-
- result = reindexMap(result, maxNumber);
-
- int size = result.size();
- if (log.isInfoEnabled()) {
- log.info("nbVotingList [" + pollType + "] (from request) = " + size);
- }
-
- // add personToList maps to session (but just now, since votingList
- // could have been reindex)
- for (Map.Entry<Integer, VotingList> entry : result.entrySet()) {
- VotingList votingList = entry.getValue();
-
- if (!votingList.isPollAccountPersonToListEmpty()) {
- List<PersonToList> personToList =
- votingList.getPollAccountPersonToList();
-
- Map<Integer, PersonToList> personToListMap = Maps.newTreeMap();
- int index = 0;
- for (PersonToList toList : personToList) {
- personToListMap.put(index++, toList);
- }
- }
- }
-
- return result;
- }
-
- private double getDoubleValue(String parameterName) {
- String parameterValue = getNonEmptyParameterValue(parameterName);
- double result = 0;
- if (StringUtils.isNotEmpty(parameterValue)) {
-
- try {
- result = Double.valueOf(parameterValue);
- } catch (NumberFormatException e) {
- //bad conversion, will be treated later
- if (log.isDebugEnabled()) {
- log.debug("Bad double conversion from param [" +
- parameterName + "] : " + parameterValue);
- }
- }
- }
- return result;
- }
-
- private int buildVotingList(String votingListParameterName,
- String votingListPrefix,
- int votingListNumber,
- Map<Integer, VotingList> result) {
-
- String paramValue = getNonEmptyParameterValue(votingListParameterName);
-
- VotingList votingList = new VotingListImpl();
-
- votingList.setName(paramValue);
-
- double weight = getDoubleValue(votingListPrefix + ".weight");
- votingList.setWeight(weight);
-
- String topiaId = getNonEmptyParameterValue(votingListPrefix + ".topiaId");
- votingList.setTopiaId(topiaId);
-
- result.put(votingListNumber, votingList);
-
- String personToListPrefix = votingListPrefix + "PersonToList_";
-
- // get all personToList parameters
- Set<String> votingListParameterNames = Sets.filter(
- parameters.keySet(),
- new StringStartWithPredicate(personToListPrefix));
-
- Pattern personToListNamePattern = Pattern.compile(
- personToListPrefix + "(\\d+)\\.votingId");
-
- Map<Integer, PersonToList> personToLists = Maps.newTreeMap();
-
- int maxPersonToListNumber = 0;
-
- // let's build personToList list
- for (String personToListNameParameter : votingListParameterNames) {
-
- Matcher matcher = personToListNamePattern.matcher(
- personToListNameParameter);
-
- if (matcher.matches()) {
-
- int personToListNumber = buildPersonToList(
- personToListPrefix,
- personToListNameParameter,
- matcher,
- votingListNumber,
- personToLists);
-
- maxPersonToListNumber = Math.max(maxPersonToListNumber,
- personToListNumber);
- }
- }
-
- personToLists = reindexMap(personToLists, maxPersonToListNumber);
-
- for (PersonToList personToList : personToLists.values()) {
- votingList.addPollAccountPersonToList(personToList);
- }
-
- return votingListNumber;
- }
-
- private int buildPersonToList(String personToListPrefix,
- String paramName,
- Matcher personToListMatcher,
- int votingListNumber,
- Map<Integer, PersonToList> result) {
-
- String paramValue = getNonEmptyParameterValue(paramName);
-
- int personToListNumber = 0;
-
- if (paramValue != null) {
-
- // found a PersonToList none empty name, keep it
-
- personToListNumber = Integer.valueOf(personToListMatcher.group(1));
-
- PersonToList personToList = new PersonToListImpl();
-
- PollAccount account = new PollAccountImpl();
- personToList.setPollAccount(account);
-
- account.setVotingId(paramValue);
-
- String prefix = personToListPrefix + personToListNumber;
-
- double weight = getDoubleValue(prefix + ".weight");
- personToList.setWeight(weight);
-
- String topiaId = getNonEmptyParameterValue(prefix + ".topiaId");
- personToList.setTopiaId(topiaId);
-
- String email = getNonEmptyParameterValue(prefix + ".email");
- account.setEmail(email);
-
- String accountId = getNonEmptyParameterValue(prefix + ".accountId");
- account.setAccountId(accountId);
-
- result.put(personToListNumber, personToList);
- }
- return personToListNumber;
- }
-
- private Choice createImageChoice(PollImageChoice choice,
- String prefix,
- String name) {
- createChoice(choice, prefix, name);
- String locationName = prefix + ".location";
- String location = getNonEmptyParameterValue(locationName);
- choice.setLocation(location);
- if (log.isInfoEnabled()) {
- log.info("image location [" + name + "] =" + location);
- }
- return choice;
- }
-
- private Choice createDateChoice(PollDateChoice choice,
- String prefix,
- String name) {
- createChoice(choice, prefix, name);
- if (StringUtils.isNotEmpty(name)) {
- Date date = DateConverter.convertFromString(name);
- if (date == null) {
- addInformationsError(prefix, _("pollen.error.date.format"));
- }
- choice.setDate(date);
- }
- return choice;
- }
-
- private Choice createChoice(Choice choice, String prefix, String name) {
- String descriptionName = prefix + ".description";
- String topiaIdName = prefix + ".topiaId";
- String description = getNonEmptyParameterValue(descriptionName);
- String topiaId = getNonEmptyParameterValue(topiaIdName);
- choice.setName(name);
- choice.setDescription(description);
- choice.setTopiaId(topiaId);
- return choice;
- }
-
- private void logChoice(Map<Integer, Choice> result) {
- for (Map.Entry<Integer, Choice> e : result.entrySet()) {
- Integer choiceId = e.getKey();
- Choice choice = e.getValue();
- if (log.isInfoEnabled()) {
- log.info("Choice [" + choiceId + "] = " +
- choice.getName() + " -- " +
- choice.getDescription());
- }
- }
- }
-
- protected <T> Map<Integer, T> reindexMap(Map<Integer, T> result, int maxNumber) {
- Map<Integer, T> result2;
-
- if (maxNumber != result.size() - 1) {
-
- // means there is a hole inside the result (a empty choice was
- // submitted)
-
- // le'ts remove this
- List<Integer> numbers = Lists.newArrayList(result.keySet());
-
- Collections.sort(numbers);
-
- result2 = Maps.newTreeMap();
- int i = 0;
- for (Integer number : numbers) {
- T choice = result.get(number);
- result2.put(i++, choice);
- }
- } else {
- result2 = result;
- }
- return result2;
- }
-
- protected String getNonEmptyParameterValue(String paramName) {
- String[] paramValues = parameters.get(paramName);
- String result = null;
- if (paramValues != null && paramValues.length == 1) {
- String paramValue = paramValues[0];
- if (StringUtils.isNotEmpty(paramValue)) {
- result = paramValue;
- }
- }
- return result;
- }
-
- private static class StringStartWithPredicate implements Predicate<String> {
- private final String prefix;
-
- public StringStartWithPredicate(String prefix) {
- this.prefix = prefix;
- }
-
- @Override
- public boolean apply(String input) {
- return input.startsWith(prefix);
- }
- }
-}
Modified: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/SummaryPoll.java
===================================================================
--- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/SummaryPoll.java 2012-06-16 20:33:49 UTC (rev 3493)
+++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/SummaryPoll.java 2012-06-16 20:36:03 UTC (rev 3494)
@@ -25,6 +25,7 @@
import com.google.common.base.Preconditions;
import org.chorem.pollen.business.persistence.Poll;
import org.chorem.pollen.common.PollType;
+import org.chorem.pollen.services.impl.SecurityService;
import org.chorem.pollen.ui.actions.PageSkin;
/**
@@ -82,7 +83,9 @@
}
public boolean isCanShowResult() {
- return poll.isPublicResults();
+ String errorMessage = getSecurityService().isCanShowResult(
+ poll, SecurityService.AccountIdRole.CREATOR);
+ return errorMessage == null;
}
public boolean isCanVote() {
Modified: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/VoteForPoll.java
===================================================================
--- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/VoteForPoll.java 2012-06-16 20:33:49 UTC (rev 3493)
+++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/VoteForPoll.java 2012-06-16 20:36:03 UTC (rev 3494)
@@ -61,7 +61,11 @@
} else if (isPollFinished()) {
addFlashMessage(_("pollen.information.pollFinished"));
} else if (isCreatorUser()) {
- addFlashWarning(_("pollen.information.vote.creatorUser"));
+ if (getUriId().isAccountIdNotBlank()) {
+
+ // account Id setted in url, so should not be abel to vote
+ addFlashWarning(_("pollen.information.vote.creatorUser"));
+ }
}
if (isPollChoiceRunning()) {
addFlashMessage(_("pollen.information.pollChoiceRunning"));
Modified: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/PollResultAccessRequired.java
===================================================================
--- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/PollResultAccessRequired.java 2012-06-16 20:33:49 UTC (rev 3493)
+++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/PollResultAccessRequired.java 2012-06-16 20:36:03 UTC (rev 3494)
@@ -24,7 +24,6 @@
import org.chorem.pollen.bean.PollUri;
import org.chorem.pollen.business.persistence.Poll;
-import org.chorem.pollen.common.PollType;
import org.chorem.pollen.services.PollenServiceContext;
import org.chorem.pollen.services.impl.PollService;
import org.chorem.pollen.services.impl.SecurityService;
@@ -114,49 +113,18 @@
// check now poll results can be displayed
- boolean publicResults = poll.isPublicResults();
- boolean continuousResults = poll.isContinuousResults();
+ String errorMessage = securityService.isCanShowResult(
+ poll, accountIdRole);
- if (!continuousResults && !poll.isClosed()) {
+ if (errorMessage != null) {
- // results are not continuous and poll is not closed
+ // can not show results
isAccessAllowed = false;
- registerError(
- request,
- n_("pollen.security.error.poll.not.closed.and.results.not.continuous"));
+ registerError(request, errorMessage);
}
-
- if (isAccessAllowed) {
-
- if (!publicResults &&
- accountIdRole != SecurityService.AccountIdRole.CREATOR) {
-
- // poll results are private, only poll admin can see results
- isAccessAllowed = false;
- registerError(
- request,
- n_("pollen.security.error.poll.result.private.and.access.not.granted"));
- }
- }
-
- if (isAccessAllowed) {
-
- boolean pollIsFree = PollType.FREE == poll.getPollType();
-
- if (publicResults &&
- !pollIsFree &&
- !SecurityService.NONE_FREE_ACCOUNT_ID_ROLES.contains(accountIdRole)) {
-
- // on none free poll, only creator or restricted user can have it
- isAccessAllowed = false;
- registerError(
- request,
- n_("pollen.security.error.poll.not.free.and.access.not.granted"));
- }
- }
}
-
return isAccessAllowed;
}
+
}
\ No newline at end of file
Modified: trunk/pollen-ui-struts2/src/main/resources/config/struts-poll.xml
===================================================================
--- trunk/pollen-ui-struts2/src/main/resources/config/struts-poll.xml 2012-06-16 20:33:49 UTC (rev 3493)
+++ trunk/pollen-ui-struts2/src/main/resources/config/struts-poll.xml 2012-06-16 20:36:03 UTC (rev 3494)
@@ -40,32 +40,27 @@
</result-types>
<!-- create poll -->
- <action name="create" class="org.chorem.pollen.ui.actions.poll.LoadPoll">
- <result>/WEB-INF/jsp/poll/create.jsp</result>
+ <action name="create" class="org.chorem.pollen.ui.actions.poll.CreatePoll">
+ <result name="input">/WEB-INF/jsp/poll/create.jsp</result>
+ <result type="pollenRedirectAction">
+ <param name="namespace">/poll</param>
+ <param name="actionName">summary/${uriId}</param>
+ </result>
</action>
- <!-- display * -->
- <action name="display*"
- class="org.chorem.pollen.ui.actions.poll.Display{1}">
- <result>/WEB-INF/jsp/poll/display{1}.jsp</result>
- </action>
-
<!-- edit poll -->
- <action name="modification/*"
- class="org.chorem.pollen.ui.actions.poll.LoadPoll">
+ <action name="edit/*" class="org.chorem.pollen.ui.actions.poll.EditPoll">
<param name="uriId">{1}</param>
- <result>/WEB-INF/jsp/poll/create.jsp</result>
+ <result name="input">/WEB-INF/jsp/poll/create.jsp</result>
+ <result type="pollenRedirectAction">
+ <param name="namespace">/poll</param>
+ <param name="actionName">summary/${uriId}</param>
+ </result>
</action>
<!-- clone poll -->
- <action name="clone/*" class="org.chorem.pollen.ui.actions.poll.LoadPoll">
+ <action name="clone/*" class="org.chorem.pollen.ui.actions.poll.ClonePoll">
<param name="uriId">{1}</param>
- <param name="clone">true</param>
- <result>/WEB-INF/jsp/poll/create.jsp</result>
- </action>
-
- <!-- save poll -->
- <action name="save" class="org.chorem.pollen.ui.actions.poll.SavePoll">
<result name="input">/WEB-INF/jsp/poll/create.jsp</result>
<result type="pollenRedirectAction">
<param name="namespace">/poll</param>
@@ -73,6 +68,12 @@
</result>
</action>
+ <!-- display * -->
+ <action name="display*"
+ class="org.chorem.pollen.ui.actions.poll.Display{1}">
+ <result>/WEB-INF/jsp/poll/display{1}.jsp</result>
+ </action>
+
<!-- resume poll -->
<action name="summary/*" method="execute"
class="org.chorem.pollen.ui.actions.poll.SummaryPoll">
@@ -108,13 +109,6 @@
<result type="redirect2"/>
</action>
- <!-- display result link -->
- <action name="resultLink/*"
- class="org.chorem.pollen.ui.actions.poll.ResultLink">
- <param name="uriId">{1}</param>
- <result>/WEB-INF/jsp/poll/resultLink.jsp</result>
- </action>
-
<!-- confirm delete poll -->
<action name="confirmDeletePoll/*"
class="org.chorem.pollen.ui.actions.poll.ConfirmPollAction">
Modified: trunk/pollen-ui-struts2/src/main/resources/i18n/pollen-ui-struts2_en_GB.properties
===================================================================
--- trunk/pollen-ui-struts2/src/main/resources/i18n/pollen-ui-struts2_en_GB.properties 2012-06-16 20:33:49 UTC (rev 3493)
+++ trunk/pollen-ui-struts2/src/main/resources/i18n/pollen-ui-struts2_en_GB.properties 2012-06-16 20:36:03 UTC (rev 3494)
@@ -172,17 +172,25 @@
pollen.error.password.required=Your must provide a password
pollen.error.password2.required=You must repeat your password for confirmation
pollen.error.passwords.not.equals=The two password are not the same
+pollen.error.poll.choice.already.used.name=Choice already used.
+pollen.error.poll.choice.name.required=Choice name is mandatory.
+pollen.error.poll.dateChoice.already.used=Date already used.
+pollen.error.poll.dateChoice.badDateFormat=Invalid date format, required format is MM/dd/yyyy [hh\:mm] (example 12/31/2000 12\:59)
+pollen.error.poll.dateChoice.required=Date is required.
pollen.error.poll.detected.duplicate.choice.name=Choices must be unique.
pollen.error.poll.endChoiceDate.after.endDate=The choice end date must be sooner than the poll end date.
pollen.error.poll.endChoiceDate.before.beginChoiceDate=The choice end date must be later than the begin date.
pollen.error.poll.endChoiceDate.before.now=The choice end date must be later than current date.
pollen.error.poll.endDate.before.beginDate=The poll end date must be later than the begin date.
pollen.error.poll.endDate.before.now=The poll end date must be later than current date.
+pollen.error.poll.imageChoice.already.used=Image choice name already used.
+pollen.error.poll.imageChoice.upload.required=Upload an image is mandatory.
pollen.error.poll.maxChoice.greater.than.0=Number of choices must be strictly greater than 0
pollen.error.poll.maxChoice.required=Number of choices mandatory
pollen.error.poll.notfound=No such poll exists. Please make sure that you are using the correct link and copy it completely into your browser's address field.
-pollen.error.poll.personToList.email.doublon=Email must be unique
-pollen.error.poll.personToList.votingId.doublon=The voter's name must be unique
+pollen.error.poll.personToList.email.doublon=Email already used.
+pollen.error.poll.personToList.votingId.doublon=This voter's name is already used.
+pollen.error.poll.personToList.votingId.required=Voter's name mandatory.
pollen.error.poll.personToList.weight.not.valid=The voter's weight is not valid (must be greater than 0).
pollen.error.poll.reminderHourCountdown.greater.than.0=Reminder hour countdown must be strictly greater than 0.
pollen.error.poll.reminderHourCountdown.required=Reminder hour countdown mandatory.
Modified: trunk/pollen-ui-struts2/src/main/resources/i18n/pollen-ui-struts2_fr_FR.properties
===================================================================
--- trunk/pollen-ui-struts2/src/main/resources/i18n/pollen-ui-struts2_fr_FR.properties 2012-06-16 20:33:49 UTC (rev 3493)
+++ trunk/pollen-ui-struts2/src/main/resources/i18n/pollen-ui-struts2_fr_FR.properties 2012-06-16 20:36:03 UTC (rev 3494)
@@ -172,17 +172,25 @@
pollen.error.password.required=Mot de passe obligatoire
pollen.error.password2.required=Mot de passe répété obligatoire
pollen.error.passwords.not.equals=Les deux mots de passe saisis non identiques
+pollen.error.poll.choice.already.used.name=Choix déjà utilisé.
+pollen.error.poll.choice.name.required=Le nom du choix est obligatoire.
+pollen.error.poll.dateChoice.already.used=Date déjà utilisée.
+pollen.error.poll.dateChoice.badDateFormat=Format de date non valide, format jj/MM/aaaa [hh\:mm] (exemple 31/12/2000 23\:59)
+pollen.error.poll.dateChoice.required=La saisie d'une date est obligatoire.
pollen.error.poll.detected.duplicate.choice.name=Les choix doivent être uniques.
pollen.error.poll.endChoiceDate.after.endDate=La date de fin d'ajout de choix doit-être antérieure à la date de fin du sondage.
pollen.error.poll.endChoiceDate.before.beginChoiceDate=La date de fin d'ajout de choix doit-être postérieure à la date de début.
pollen.error.poll.endChoiceDate.before.now=La date de fin d'ajout de choix doit-être postérieure à la date actuelle.
pollen.error.poll.endDate.before.beginDate=La date de fin du sondage doit-être postérieure à la date de début.
pollen.error.poll.endDate.before.now=La date de fin du sondage doit-être postérieure à la date actuelle.
+pollen.error.poll.imageChoice.already.used=Choix d'image déjà utilisé (les noms doivent être tous différents).
+pollen.error.poll.imageChoice.upload.required=Le choix d'une image est obligatoire.
pollen.error.poll.maxChoice.greater.than.0=Nombre de choix maximum doit être strictement supérieur à 0
pollen.error.poll.maxChoice.required=Nombre de choix maximum obligatoire
pollen.error.poll.notfound=Il n'y a pas de sondage à cette adresse. Veuillez verifier que vous utilisez le lien correcte et copiez-le complètement dans le champ d'adresse de votre navigateur.
-pollen.error.poll.personToList.email.doublon=Les emails doivent être uniques.
-pollen.error.poll.personToList.votingId.doublon=Les noms des votants doivent être uniques.
+pollen.error.poll.personToList.email.doublon=Courriel déjà utilisé.
+pollen.error.poll.personToList.votingId.doublon=nom de votant déjà utilisé.
+pollen.error.poll.personToList.votingId.required=Nom de votant obligatoire.
pollen.error.poll.personToList.weight.not.valid=Poids du votant non valide (doit être une nombre supérieur à 0).
pollen.error.poll.reminderHourCountdown.greater.than.0=Le nombre d'heures doit être strictement supérieure à 0.
pollen.error.poll.reminderHourCountdown.required=Le nombre d'heures est obligatoire.
Modified: trunk/pollen-ui-struts2/src/main/resources/shiro.ini
===================================================================
--- trunk/pollen-ui-struts2/src/main/resources/shiro.ini 2012-06-16 20:33:49 UTC (rev 3493)
+++ trunk/pollen-ui-struts2/src/main/resources/shiro.ini 2012-06-16 20:36:03 UTC (rev 3494)
@@ -45,6 +45,7 @@
/user/changeLang=anon
/user/register**=anon
/user/lostPassword**=anon
+/poll/create**=anon
# connected urls
/user/**=connected
@@ -70,9 +71,8 @@
/poll/results/**=pollResultAccess
# is poll exists and user can admin it (his creator or an admin)
-/poll/modification/**=pollCreatorAccess
+/poll/edit/**=pollCreatorAccess
/poll/summary/**=pollCreatorAccess
/poll/moderate/**=pollCreatorAccess
/poll/clone/**=pollCreatorAccess
-/poll/resultLink/**=pollCreatorAccess
/poll/resume/**=pollCreatorAccess
\ No newline at end of file
Modified: trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/decorators/layout-default.jsp
===================================================================
--- trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/decorators/layout-default.jsp 2012-06-16 20:33:49 UTC (rev 3493)
+++ trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/decorators/layout-default.jsp 2012-06-16 20:36:03 UTC (rev 3494)
@@ -190,7 +190,7 @@
<div class="top_left${pageLogo}"></div>
<ul class="top_middle${pageLogo}">
<li>
- <s:a action="create" namespace="/poll">
+ <s:a action="create" namespace="/poll" method="input">
<s:text name="pollen.menu.createPoll"/>
</s:a>
</li>
Modified: trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/home.jsp
===================================================================
--- trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/home.jsp 2012-06-16 20:33:49 UTC (rev 3493)
+++ trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/home.jsp 2012-06-16 20:36:03 UTC (rev 3494)
@@ -31,7 +31,7 @@
</div>
<div class="center">
- <s:a action="create" namespace="/poll">
+ <s:a action="create" namespace="/poll" method="input">
<img src="<s:url value='/img/smallCreation_%{safeLanguage}.png' />" alt="poll creation"/>
</s:a>
<img src="<s:url value='/img/smallVote_%{safeLanguage}.png' />" alt="vote"/>
Modified: trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/create.jsp
===================================================================
--- trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/create.jsp 2012-06-16 20:33:49 UTC (rev 3493)
+++ trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/create.jsp 2012-06-16 20:36:03 UTC (rev 3494)
@@ -61,7 +61,7 @@
confirmCloseTitle:"<s:text name='pollen.title.close.poll'/>",
confirmCloseUrl:'<s:url action="confirmClosePoll/" namespace="/poll"/>'
+ '<s:property value="%{poll.adminId}"/>',
- confirmCloseRedirectUrl:'<s:url action="resultLink/" namespace="/poll"/>'
+ confirmCloseRedirectUrl:'<s:url action="summary/" namespace="/poll"/>'
+ '<s:property value="%{poll.adminId}"/>'
}
);
@@ -91,7 +91,6 @@
<div id="tgeneral">
<fieldset>
- <%--<legend><s:text name="pollen.common.voteCountingType"/></legend>--%>
<s:textfield key="poll.title" label="%{getText('pollen.common.title')}"
required="true" size="80"/>
@@ -171,28 +170,24 @@
disabled="%{voteStarted}"
tooltip="%{getText('pollen.common.pollOption.choiceAddAllowed.help')}"
tooltipIconPath="/img/tooltip.png"/>
- <%--<div id='addChoiceAddAllowedPanel' class="hidden">--%>
- <sj:datepicker key="poll.beginChoiceDate"
- label="%{getText('pollen.common.beginChoiceDate')}"
- displayFormat="%{getText('pollen.common.datePickerPattern')}"
- timepicker="true"
- disabled="%{voteStarted}"/>
- <sj:datepicker key="poll.endChoiceDate"
- label="%{getText('pollen.common.endChoiceDate')}"
- displayFormat="%{getText('pollen.common.datePickerPattern')}"
- timepicker="true"
- disabled="%{voteStarted}"/>
- <%--</div>--%>
+ <sj:datepicker key="poll.beginChoiceDate"
+ label="%{getText('pollen.common.beginChoiceDate')}"
+ displayFormat="%{getText('pollen.common.datePickerPattern')}"
+ timepicker="true"
+ disabled="%{voteStarted}"/>
+ <sj:datepicker key="poll.endChoiceDate"
+ label="%{getText('pollen.common.endChoiceDate')}"
+ displayFormat="%{getText('pollen.common.datePickerPattern')}"
+ timepicker="true"
+ disabled="%{voteStarted}"/>
<s:checkbox key="limitChoice"
label="%{getText('pollen.common.pollOption.limitChoice')}"
disabled="%{voteStarted}"
tooltip="%{getText('pollen.common.pollOption.limitChoice.help')}"
tooltipIconPath="/img/tooltip.png"/>
- <%--<div id='maxChoiceNbPanel' class="hidden">--%>
- <s:textfield key="maxChoices"
- label="%{getText('pollen.common.pollOption.maxChoiceNb')}"
- disabled="%{voteStarted}"/>
- <%--</div>--%>
+ <s:textfield key="maxChoices"
+ label="%{getText('pollen.common.pollOption.maxChoiceNb')}"
+ disabled="%{voteStarted}"/>
</fieldset>
<br/>
@@ -209,13 +204,14 @@
disabled="%{voteStarted}"
tooltip="%{getText('pollen.common.pollOption.anonymous.help')}"
tooltipIconPath="/img/tooltip.png"/>
- <s:checkbox key="poll.anonymousVoteAllowed"
- label="%{getText('pollen.common.pollOption.anonymousVoteAllowed')}"
- disabled="%{voteStarted}"
- tooltip="%{getText('pollen.common.pollOption.anonymousVoteAllowed.help')}"
- tooltipIconPath="/img/tooltip.png"/>
- </fieldset>
- <br/><fieldset>
+ <s:checkbox key="poll.anonymousVoteAllowed"
+ label="%{getText('pollen.common.pollOption.anonymousVoteAllowed')}"
+ disabled="%{voteStarted}"
+ tooltip="%{getText('pollen.common.pollOption.anonymousVoteAllowed.help')}"
+ tooltipIconPath="/img/tooltip.png"/>
+ </fieldset>
+ <br/>
+ <fieldset>
<legend>
<s:text name="pollen.fieldset.result.options"/>
<img src="<s:url value='/img/tooltip.png'/>" class="tooltip"
@@ -227,12 +223,10 @@
label="%{getText('pollen.common.pollOption.publicResults')}"
tooltip="%{getText('pollen.common.pollOption.publicResults.help')}"
tooltipIconPath="/img/tooltip.png"/>
- <%--<div id='publicPanel' class="hidden">--%>
- <s:checkbox key="poll.continuousResults"
- label="%{getText('pollen.common.pollOption.continuousResults')}"
- tooltip="%{getText('pollen.common.pollOption.continuousResults.help')}"
- tooltipIconPath="/img/tooltip.png"/>
- <%--</div>--%>
+ <s:checkbox key="poll.continuousResults"
+ label="%{getText('pollen.common.pollOption.continuousResults')}"
+ tooltip="%{getText('pollen.common.pollOption.continuousResults.help')}"
+ tooltipIconPath="/img/tooltip.png"/>
</fieldset>
<br/>
@@ -251,10 +245,8 @@
label="%{getText('pollen.common.pollOption.reminder')}"
tooltip="%{getText('pollen.common.pollOption.reminder.help')}"
tooltipIconPath="/img/tooltip.png"/>
- <%--<div id='reminderPanel' class="hidden">--%>
- <s:textfield key="reminderHourCountdown"
- label="%{getText('pollen.common.pollOption.reminderHourCountdown')}"/>
- <%--</div>--%>
+ <s:textfield key="reminderHourCountdown"
+ label="%{getText('pollen.common.pollOption.reminderHourCountdown')}"/>
</fieldset>
<br/>
@@ -300,9 +292,8 @@
disabled="%{voteStarted}"/>
<s:if test="userLoggued">
<s:submit key="pollen.action.addVotingListFromPersonList"
- theme="simple"
onclick='return selectPersonListToCreateNewVotingList();'
- disabled="%{voteStarted}"/>
+ theme="simple" disabled="%{voteStarted}"/>
</s:if>
</div>
</div>
@@ -312,14 +303,20 @@
</sj:tabbedpanel>
<br/>
- <s:submit action="save" value="%{actionLabel}" align="center"/>
<s:if test="edit">
+ <s:submit action="edit/%{uriId}" value="%{actionLabel}" align="center"/>
<div align="center" style="margin-top: 10px">
<button onclick="return confirmClose();">
<s:text name="pollen.action.close"/>
</button>
</div>
</s:if>
+ <s:elseif test="clone">
+ <s:submit action="clone/%{uriId}" value="%{actionLabel}" align="center"/>
+ </s:elseif>
+ <s:else>
+ <s:submit action="create" value="%{actionLabel}" align="center"/>
+ </s:else>
</s:form>
<script type="text/javascript">
Modified: trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/createPoll_choices.jsp
===================================================================
--- trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/createPoll_choices.jsp 2012-06-16 20:33:49 UTC (rev 3493)
+++ trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/createPoll_choices.jsp 2012-06-16 20:36:03 UTC (rev 3494)
@@ -45,6 +45,7 @@
<s:hidden key='%{#prefix}.topiaId' value='%{#choice.topiaId}' label=''/>
<sp:fielderror fieldName="%{#prefix}" id="%{#prefix}_error"/>
<div class="fleft choiceName">
+ <sp:fielderror fieldName="%{#prefix}.name" id="%{#prefix}.name_error"/>
<s:label for="%{#prefix}.name" id="choicesTEXT_label_%{#choiceNumber}"
theme="simple" value=''/>
<s:textfield cssClass="nameField" id='%{#prefix}.name'
@@ -99,13 +100,14 @@
value='%{#choice.topiaId}' label='' theme="simple"/>
<sp:fielderror fieldName="%{#prefix}" id="%{#prefix}_error"/>
<div class="fleft choiceName">
+ <sp:fielderror fieldName="%{#prefix}.name" id="%{#prefix}.name_error"/>
<s:label for="%{#prefix}.name" id="choicesDATE_label_%{choiceNumber}"
theme="simple" value=''/>
<sj:datepicker id='%{#prefix}.name' key="%{#prefix}.name"
changeMonth="true"
changeYear="true" labelSeparator="" theme="simple"
label=""
- timepicker="true" value="%{#choice.date}"
+ timepicker="true" value="%{#choice.name}"
displayFormat="%{getText('pollen.common.datePickerPattern')}"
disabled="%{voteStarted}"/>
-
@@ -154,6 +156,7 @@
<s:hidden key='%{#prefix}.topiaId' value='%{#choice.topiaId}' label=''/>
<sp:fielderror fieldName="%{#prefix}" id="%{#prefix}_error"/>
<div class="fleft choiceName">
+ <sp:fielderror fieldName="%{#prefix}.name" id="%{#prefix}.name_error"/>
<s:label for="%{#prefix}.name" id="choicesIMAGE_label_%{choiceNumber}"
theme="simple" value=''/>
<s:if test="#choice.name != null">
@@ -175,8 +178,10 @@
title="<s:property value='name'/>"
src="<s:property value='imageUrl'/>">
- <!--s:label label='' theme="simple" cssClass="nameField"
- value="%{#choice.name}" readonly="true"/-->
+ <s:file key='imageChoice[%{#choiceNumber}]' label=''
+ theme="simple"
+ cssClass="nameField fleft"
+ disabled="%{voteStarted}" cssStyle="margin-left:50px;"/>
</s:if>
<s:else>
<%--New image--%>
Modified: trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/result.jsp
===================================================================
--- trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/result.jsp 2012-06-16 20:33:49 UTC (rev 3493)
+++ trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/result.jsp 2012-06-16 20:36:03 UTC (rev 3494)
@@ -66,7 +66,7 @@
<legend><s:text name="pollen.common.aboutPoll"/></legend>
<div style="float: right">
<s:if test="creatorUser or userAdmin">
- <s:a namespace="/poll" action="modification/%{uriId}">
+ <s:a namespace="/poll" action="summary/%{uriId}">
<img src="<s:url value='/img/editSmall.png'/>"
title="<s:text name='pollen.action.editPoll'/>"
alt="<s:text name='pollen.action.editPoll'/>"/>
Deleted: trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/resultLink.jsp
===================================================================
--- trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/resultLink.jsp 2012-06-16 20:33:49 UTC (rev 3493)
+++ trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/resultLink.jsp 2012-06-16 20:36:03 UTC (rev 3494)
@@ -1,46 +0,0 @@
-<%--
- #%L
- Pollen :: UI (struts2)
- $Id$
- $HeadURL$
- %%
- Copyright (C) 2009 - 2012 CodeLutin, Tony Chemit
- %%
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- #L%
- --%>
-<%@ page language="java" contentType="text/html" pageEncoding="utf-8" %>
-<%@ taglib prefix="s" uri="/struts-tags" %>
-<h1 class="titleCreation"><s:property value="poll.title"/></h1>
-
-<h3><s:property value="poll.title"/> <s:text name="pollen.common.by"/>
- <s:property value="poll.creator.votingId"/></h3>
-
-<div style="margin-top: 10px;">
- <img src="<s:url value='/img/count.png'/>"
- alt="<s:text name='pollen.common.resultAction'/>"
- title="<s:text name='pollen.common.resultAction'/>"
- style="margin-right: 18px;"/>
- <s:text name='pollen.label.pollResultPage'/>
- <br/>
- <s:a href="%{pollResultUrl}" cssStyle="margin-left:50px;">
- <s:property value="%{pollResultUrl}"/>
- </s:a>
-</div>
-<div style="margin-top: 30px;">
- <s:text name="pollen.label.pollRegisterPage"/>
- <s:a namespace="/user" action="createdList">
- <s:text name="pollen.common.myPolls"/>
- </s:a>.
-</div>
Modified: trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/summary.jsp
===================================================================
--- trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/summary.jsp 2012-06-16 20:33:49 UTC (rev 3493)
+++ trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/summary.jsp 2012-06-16 20:36:03 UTC (rev 3494)
@@ -23,17 +23,20 @@
<%@ page language="java" contentType="text/html" pageEncoding="utf-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ taglib prefix="sj" uri="/struts-jquery-tags" %>
-<link rel="stylesheet" type="text/css" href="<s:url value='/css/summary.css'/>"/>
+<link rel="stylesheet" type="text/css"
+ href="<s:url value='/css/summary.css'/>"/>
<script type="text/javascript">
- var redirectUrl = '<s:url namespace="/poll" action="summary/%{uriId}"/>';
function confirmDeletePoll(id) {
$('.ui-dialog-title').html("<s:text name="pollen.title.delete.poll"/>");
var dialog = $("#confirmDialog");
dialog.html('');
var url = "<s:url action='confirmDeletePoll/' namespace='/poll'/>";
- url += id + '?' + $.param({redirectUrl:redirectUrl});
+ url += id + '?' + $.param(
+ {
+ redirectUrl:'<s:url namespace="/poll" action="summary/%{uriId}"/>'
+ });
dialog.load(url);
dialog.dialog('open');
return false;
@@ -44,7 +47,10 @@
var dialog = $("#confirmDialog");
dialog.html('');
var url = "<s:url action='confirmClosePoll/' namespace='/poll'/>";
- url += id + '?' + $.param({redirectUrl:redirectUrl});
+ url += id + '?' + $.param(
+ {
+ redirectUrl:'<s:url namespace="/poll" action="summary/%{uriId}"/>'
+ });
dialog.load(url);
dialog.dialog('open');
return false;
@@ -62,7 +68,7 @@
<br/>
</div>
-<%--Vote action--%>
+<%--Vote--%>
<s:if test="canVote">
<div class="ui-widget-content-green ui-corner-all">
<img src="<s:url value='/img/vote.png'/>" class="imgAction"
@@ -76,10 +82,10 @@
</div>
</s:if>
-<%--Show Results action--%>
+<%--Show Results--%>
<s:if test="canShowResult">
<div class="ui-widget-content-green ui-corner-all">
- <img src="<s:url value='/img/count.png'/>" class="imgAction"
+ <img src="<s:url value='/img/count.png'/>" class="imgAction"
alt="<s:text name='pollen.action.pollResult'/>"
title="<s:text name='pollen.action.pollResult'/>"/>
<s:text name='pollen.label.pollResultPage'/>
@@ -90,7 +96,7 @@
</div>
</s:if>
-<%--Moderate action--%>
+<%--Moderate--%>
<div class="ui-widget-content-yellow ui-corner-all">
<img src="<s:url value='/img/moderate.png'/>" class="imgAction"
alt="<s:text name='pollen.action.pollModerateVote'/>"
@@ -102,7 +108,7 @@
</s:a>
</div>
-<%--Edit action--%>
+<%--Edit--%>
<div class="ui-widget-content-yellow ui-corner-all">
<img src="<s:url value='/img/edit.png'/>" class="imgAction"
alt="<s:text name='pollen.action.editPoll'/>"
@@ -114,7 +120,7 @@
</s:a>
</div>
-<%--Export action--%>
+<%--Export--%>
<div class="ui-widget-content-blue ui-corner-all">
<img src="<s:url value='/img/export.png'/>" class="imgAction"
alt="<s:text name='pollen.action.pollExport'/>"
@@ -124,7 +130,7 @@
</s:a>
</div>
-<%--Clone action--%>
+<%--Clone--%>
<div class="ui-widget-content-blue ui-corner-all">
<img src="<s:url value='/img/copy.png'/>" class="imgAction"
alt="<s:text name='pollen.action.clone'/>"
@@ -134,7 +140,7 @@
</s:a>
</div>
-<%--Close action--%>
+<%--Close--%>
<s:if test="canClose">
<div class="ui-widget-content-red ui-corner-all">
<img src="<s:url value='/img/close.png'/>" class="imgAction"
@@ -147,7 +153,7 @@
</div>
</s:if>
-<%--Delete action--%>
+<%--Delete --%>
<div class="ui-widget-content-red ui-corner-all">
<img src="<s:url value='/img/delete.png'/>" class="imgAction"
alt="<s:text name='pollen.action.deletePoll'/>"
@@ -157,11 +163,4 @@
</s:a>
</div>
-<%--div style="margin-top: 30px;">
- <s:text name="pollen.label.pollRegisterPage"/>
- <s:a namespace="/user" action="createdList">
- <s:text name="pollen.common.myPolls"/>
- </s:a>.
-</div--%>
-
<sj:dialog id="confirmDialog" autoOpen="false" modal="true" width="500"/>
Modified: trunk/pollen-ui-struts2/src/test/java/org/chorem/pollen/ui/PollenFixtures.java
===================================================================
--- trunk/pollen-ui-struts2/src/test/java/org/chorem/pollen/ui/PollenFixtures.java 2012-06-16 20:33:49 UTC (rev 3493)
+++ trunk/pollen-ui-struts2/src/test/java/org/chorem/pollen/ui/PollenFixtures.java 2012-06-16 20:36:03 UTC (rev 3494)
@@ -115,22 +115,6 @@
return baseUrl() + "security/admin_required";
}
- public String voteforURL() {
- return baseUrl() + "poll/votefor/";
- }
-
- public String voteforURL(PollUri pollUri) {
- return voteforURL() + pollUri.toString();
- }
-
- public String modificationURL(PollUri pollUri) {
- return modificationURL() + pollUri.toString();
- }
-
- public String modificationURL() {
- return baseUrl() + "poll/modification/";
- }
-
public String poll_requiredURL() {
return baseUrl() + "security/illegal_access";
}
@@ -143,12 +127,20 @@
return baseUrl() + "security/illegal_access";
}
+ public String voteforURL(PollUri pollUri) {
+ return baseUrl() + "poll/votefor/" + pollUri.toString();
+ }
+
+ public String editURL(PollUri pollUri) {
+ return baseUrl() + "poll/edit/" + pollUri.toString() + "!input";
+ }
+
public String createPollURL() {
return baseUrl() + "poll/create";
}
- public String savePollURL() {
- return baseUrl() + "poll/save";
+ public String editPollURL() {
+ return baseUrl() + "poll/edit";
}
public String summaryURL() {
Modified: trunk/pollen-ui-struts2/src/test/java/org/chorem/pollen/ui/its/CreateFreeTextPollSIT.java
===================================================================
--- trunk/pollen-ui-struts2/src/test/java/org/chorem/pollen/ui/its/CreateFreeTextPollSIT.java 2012-06-16 20:33:49 UTC (rev 3493)
+++ trunk/pollen-ui-struts2/src/test/java/org/chorem/pollen/ui/its/CreateFreeTextPollSIT.java 2012-06-16 20:36:03 UTC (rev 3494)
@@ -471,8 +471,7 @@
submit.click();
// No choices, should stay on create poll page
- //FIXME-tchemit-2012-06-15 (see http://chorem.org/issues/618)
- checkCurrentUrl(fixtures.savePollURL(), false);
+ checkCurrentUrl(fixtures.createPollURL(), false);
}
Modified: trunk/pollen-ui-struts2/src/test/java/org/chorem/pollen/ui/its/SecurityAccessSIT.java
===================================================================
--- trunk/pollen-ui-struts2/src/test/java/org/chorem/pollen/ui/its/SecurityAccessSIT.java 2012-06-16 20:33:49 UTC (rev 3493)
+++ trunk/pollen-ui-struts2/src/test/java/org/chorem/pollen/ui/its/SecurityAccessSIT.java 2012-06-16 20:36:03 UTC (rev 3494)
@@ -243,11 +243,11 @@
gotoUrl(fixtures.voteforURL(PollUri.newPollUri(pollId, badCreatorId)), fixtures.poll_access_requiredURL(), false);
// try to access to poll moderation page, current url should be good one
- String normalPollAdminURL = fixtures.modificationURL(PollUri.newPollUri(pollId, creatorId));
+ String normalPollAdminURL = fixtures.editURL(PollUri.newPollUri(pollId, creatorId));
gotoUrl(normalPollAdminURL);
// try to access to poll page with bad pollId, current url should be the poll_required one
- gotoUrl(fixtures.modificationURL(PollUri.newPollUri(pollId, badCreatorId)), fixtures.poll_creator_requiredURL(), false);
+ gotoUrl(fixtures.editURL(PollUri.newPollUri(pollId, badCreatorId)), fixtures.poll_creator_requiredURL(), false);
}
/**
@@ -295,15 +295,15 @@
gotoUrl(fixtures.voteforURL(PollUri.newPollUri(pollId, badCreatorId)), fixtures.poll_access_requiredURL(), false);
// try to access to poll modification page without creator Id, current url should be good one (admin access)
- String simpleNormalPollAdminURL = fixtures.modificationURL(PollUri.newPollUri(pollId));
+ String simpleNormalPollAdminURL = fixtures.editURL(PollUri.newPollUri(pollId));
gotoUrl(simpleNormalPollAdminURL);
// try to access to poll modification page with creator Id, current url should be good one
- String normalPollAdminURL = fixtures.modificationURL(PollUri.newPollUri(pollId, creatorId));
+ String normalPollAdminURL = fixtures.editURL(PollUri.newPollUri(pollId, creatorId));
gotoUrl(normalPollAdminURL);
// try to access to poll modifcation page with bad creatorId, current url should be the poll_creator_required one, even if we are admin
- gotoUrl(fixtures.modificationURL(PollUri.newPollUri(pollId, badCreatorId)), fixtures.poll_creator_requiredURL(), false);
+ gotoUrl(fixtures.editURL(PollUri.newPollUri(pollId, badCreatorId)), fixtures.poll_creator_requiredURL(), false);
}
/**
@@ -351,15 +351,15 @@
gotoUrl(fixtures.voteforURL(PollUri.newPollUri(pollId, badCreatorId)), fixtures.poll_access_requiredURL(), false);
// try to access to poll modification page without creator Id, current url should be good one (owner access)
- String simpleNormalPollModificationURL = fixtures.modificationURL(PollUri.newPollUri(pollId));
+ String simpleNormalPollModificationURL = fixtures.editURL(PollUri.newPollUri(pollId));
gotoUrl(simpleNormalPollModificationURL);
// try to access to poll modification page with creator Id, current url should be good one
- String normalPollModificationURL = fixtures.modificationURL(PollUri.newPollUri(pollId, creatorId));
+ String normalPollModificationURL = fixtures.editURL(PollUri.newPollUri(pollId, creatorId));
gotoUrl(normalPollModificationURL);
// try to access to poll modifcation page with bad creatorId, current url should be the poll_creator_required one, even if we are owner
- gotoUrl(fixtures.modificationURL(PollUri.newPollUri(pollId, badCreatorId)), fixtures.poll_creator_requiredURL(), false);
+ gotoUrl(fixtures.editURL(PollUri.newPollUri(pollId, badCreatorId)), fixtures.poll_creator_requiredURL(), false);
}
}
1
0
r3493 - in trunk/pollen-services/src/main: java/org/chorem/pollen/services/impl resources/i18n
by tchemit@users.chorem.org 16 Jun '12
by tchemit@users.chorem.org 16 Jun '12
16 Jun '12
Author: tchemit
Date: 2012-06-16 22:33:49 +0200 (Sat, 16 Jun 2012)
New Revision: 3493
Url: http://chorem.org/repositories/revision/pollen/3493
Log:
move security stuff in SecurityService
Modified:
trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollCommentService.java
trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollResultsService.java
trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollService.java
trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/SecurityService.java
trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/VoteService.java
trunk/pollen-services/src/main/resources/i18n/pollen-services_en_GB.properties
trunk/pollen-services/src/main/resources/i18n/pollen-services_fr_FR.properties
Modified: trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollCommentService.java
===================================================================
--- trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollCommentService.java 2012-06-16 12:38:50 UTC (rev 3492)
+++ trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollCommentService.java 2012-06-16 20:33:49 UTC (rev 3493)
@@ -67,7 +67,6 @@
// creates the poll comment
Comment commentCreated = dao.create(
-// Comment.PROPERTY_POLL, pollToUpdate,
Comment.PROPERTY_POST_DATE, comment.getPostDate(),
Comment.PROPERTY_AUTHOR, comment.getAuthor(),
Comment.PROPERTY_TEXT, comment.getText()
@@ -146,37 +145,6 @@
return result;
}
- public boolean isCanDeleteComment(Comment comment,
- PollAccount pollAccount,
- UserAccount userAccount,
- boolean isPollCreator) {
-
- boolean result = false;
-
- PollAccount commentAccount = comment.getPollAccount();
-
- if (isPollCreator) {
-
- // poll creator has admin rights on his poll
- result = true;
- } else if (userAccount != null) {
-
- // loggued
- boolean isAdmin = userAccount.isAdministrator();
-// boolean isCommentAccount = userAccount.equals(commentAccount.getUserAccount());
-
- // pollen admin or comment owner (linked by user account)
- result = isAdmin ||
- userAccount.equals(commentAccount.getUserAccount());
-
- } else if (pollAccount != null) {
-
- // comment owner (linked by poll account)
- result = pollAccount.equals(commentAccount);
- }
- return result;
- }
-
public List<Comment> getComments(TopiaFilterPagerUtil.FilterPagerBean pager,
String pollId) {
Modified: trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollResultsService.java
===================================================================
--- trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollResultsService.java 2012-06-16 12:38:50 UTC (rev 3492)
+++ trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollResultsService.java 2012-06-16 20:33:49 UTC (rev 3493)
@@ -372,114 +372,6 @@
return val;
}
-
-// /**
-// * Retourne la liste des résultats d'un sondage sous forme de DTOs.
-// *
-// * @param poll le sondage (entitée Poll)
-// * @return la liste des DTO Result
-// */
-// protected List<PollResult> createPollResults(Poll poll) {
-// List<PollResult> results = Lists.newArrayList();
-// for (Result res : poll.getResult()) {
-// PollResult dto = new PollResult();
-// dto.setId(res.getTopiaId());
-// dto.setPollId(poll.getPollId());
-// String resName = res.getName();
-// dto.setName(resName);
-// dto.setHidden(resName != null &&
-// resName.startsWith(NumberMethod.HIDDEN_PREFIX));
-// dto.setValue(res.getResultValue());
-// dto.setByGroup(res.isByGroup());
-// dto.setChoiceType(poll.getChoiceType());
-// dto.setVoteCountingType(poll.getVoteCountingType());
-// results.add(dto);
-// }
-// return results;
-// }
-
-// /**
-// * Création des résultats de sondage à partir d'un dto de résultats de
-// * sondage.
-// *
-// * @param ePoll poll à remplir
-// * @param dto le dto des résultats de sondage.
-// */
-// protected void populateResultEntities(Poll ePoll,
-// VoteCountingResultDTO dto) {
-// for (ChoiceDTO choice : dto.getChoices()) {
-//
-// ResultDAO daoResult = getDAO(Result.class);
-// Result eResult = create(daoResult);
-//
-// Choice eChoice = ePoll.getChoiceByTopiaId(choice.getIdChoice());
-//
-// ePoll.addResult(eResult);
-//
-// eResult.setName(eChoice.getName());
-// eResult.setByGroup(dto.isByGroup());
-// eResult.setPoll(ePoll);
-// eResult.setResultValue(String.valueOf(choice.getValue()));
-// eResult.setVoteCountingType(dto.getTypeVoteCounting());
-// }
-// }
-
-// /**
-// * Retourne vrai si le sondage a des résultats.
-// *
-// * @param poll le sondage
-// * @param type type de dépouillement
-// * @return vrai si le sondage a des résultats
-// */
-// protected boolean hasResults(Poll poll, VoteCountingType type) {
-// boolean hasresult = false;
-//
-// if (!poll.isResultEmpty()) {
-//
-// if (type == null) {
-// hasresult = true;
-// } else {
-// for (Result result : poll.getResult()) {
-// if (type.equals(result.getVoteCountingType())) {
-// hasresult = true;
-// break;
-// }
-// }
-// }
-// }
-// return hasresult;
-// }
-
-// public String importPoll(String filePath) {
-// return importPoll(filePath, null);
-// }
-//
-// public String importPoll(String filePath, UserAccount user) {
-// String topiaId = "";
-//
-// // Import du sondage
-// ServiceExport serviceExport = new ServiceExportImpl();
-// PollExportDTO pollExportDTO = serviceExport.executeImport(filePath);
-//
-// // Transformation du sondage
-// // FIXME do not call a Service from an other one
-// PollService servicePoll = newService(PollService.class);
-// org.chorem.pollen.business.dto.PollDTO poll = DataVoteCountingConverter
-// .createPollDTO(pollExportDTO.getPoll());
-//
-// // Enregistrement du sondage
-// if (user != null) {
-// poll.setUserId(user.getId());
-// }
-// topiaId = servicePoll.createPoll(poll);
-//
-// if (log.isInfoEnabled()) {
-// log.info("Poll imported: " + topiaId);
-// }
-//
-// return topiaId;
-// }
-
/**
* Retourne une chaîne contenant les résultats du sondage.
*
Modified: trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollService.java
===================================================================
--- trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollService.java 2012-06-16 12:38:50 UTC (rev 3492)
+++ trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollService.java 2012-06-16 20:33:49 UTC (rev 3493)
@@ -870,20 +870,6 @@
return result;
}
-// public File getPollChoiceImageFile(String pollId,
-// String choiceId,
-// boolean thumb) {
-// File imageDirectory = getConfiguration().getImageDirectory();
-// File pollDirectory = new File(imageDirectory, pollId);
-//
-// if (thumb) {
-// choiceId = THUMB_PREFIX + choiceId;
-// }
-// File result = new File(pollDirectory, choiceId);
-//
-// return result;
-// }
-
/**
* given the location of an image, gets his name as a thumb image.
*
Modified: trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/SecurityService.java
===================================================================
--- trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/SecurityService.java 2012-06-16 12:38:50 UTC (rev 3492)
+++ trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/SecurityService.java 2012-06-16 20:33:49 UTC (rev 3493)
@@ -24,20 +24,29 @@
import com.google.common.base.Preconditions;
import com.google.common.collect.Sets;
+import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.chorem.pollen.PollenTechnicalException;
import org.chorem.pollen.bean.PollUri;
+import org.chorem.pollen.business.persistence.Comment;
+import org.chorem.pollen.business.persistence.PersonToList;
+import org.chorem.pollen.business.persistence.PersonToListDAO;
import org.chorem.pollen.business.persistence.Poll;
import org.chorem.pollen.business.persistence.PollAccount;
import org.chorem.pollen.business.persistence.PollAccountDAO;
+import org.chorem.pollen.business.persistence.UserAccount;
+import org.chorem.pollen.business.persistence.Vote;
import org.chorem.pollen.common.PollType;
import org.chorem.pollen.services.PollenServiceSupport;
import org.chorem.pollen.services.exceptions.PollNotFoundException;
import org.chorem.pollen.services.exceptions.UnauthorizedPollAccessException;
import org.nuiton.topia.TopiaException;
+import java.util.Date;
import java.util.Set;
+import static org.nuiton.i18n.I18n.n_;
+
/**
* Service to manager security.
*
@@ -46,6 +55,22 @@
*/
public class SecurityService extends PollenServiceSupport {
+ public boolean isCreator(Poll poll,
+ PollUri uriId,
+ UserAccount pollenUserAccount) {
+
+ PollAccount creator = poll.getCreator();
+
+ boolean result = creator.getAccountId().equals(uriId.getAccountId());
+ if (!result) {
+
+ // try to match userAccount
+ result = ObjectUtils.equals(pollenUserAccount,
+ creator.getUserAccount());
+ }
+ return result;
+ }
+
/**
* To define meaning of a accountId.
*
@@ -138,7 +163,6 @@
throw new PollenTechnicalException(
"Could not obtain restricted pollAccount", e);
}
-
}
}
@@ -225,4 +249,137 @@
return result;
}
+ public String isCanShowResult(Poll poll,
+ SecurityService.AccountIdRole accountIdRole) {
+
+ // check now poll results can be displayed
+
+ boolean publicResults = poll.isPublicResults();
+ boolean continuousResults = poll.isContinuousResults();
+
+ if (!continuousResults && !poll.isClosed()) {
+
+ // results are not continuous and poll is not closed
+ return n_("pollen.security.error.poll.not.closed.and.results.not.continuous");
+ }
+
+ if (!publicResults &&
+ accountIdRole != SecurityService.AccountIdRole.CREATOR) {
+
+ // poll results are private, only poll admin can see results
+ return n_("pollen.security.error.poll.result.private.and.access.not.granted");
+ }
+
+ boolean pollIsFree = PollType.FREE == poll.getPollType();
+
+ if (publicResults &&
+ !pollIsFree &&
+ !SecurityService.NONE_FREE_ACCOUNT_ID_ROLES.contains(accountIdRole)) {
+
+ // on none free poll, only creator or restricted user can have it
+ return n_("pollen.security.error.poll.not.free.and.access.not.granted");
+ }
+ return null;
+ }
+
+ /**
+ * Vote is allowed if {@code poll} is running and {@code pollAccount} is
+ * defined in the {@code poll} restricted list if it's not a {@link PollType#FREE}
+ * poll. The account must be defined previously using
+ * {@link PollService#getPollAccountEditable(String, UserAccount, Poll)} to
+ * have a proper link between userAccount and pollAccount even if not already
+ * created in dabase. The poll creator can't vote. The token is just use
+ * for moderate purpose.
+ *
+ * @param poll Poll
+ * @param accountEditable Account to check
+ * @return true if vote is allowed, false otherwise
+ */
+ public boolean isVoteAllowed(Poll poll, PollAccount accountEditable) {
+
+ Preconditions.checkNotNull(poll);
+ Preconditions.checkNotNull(accountEditable);
+
+ Date now = serviceContext.getCurrentTime();
+
+ boolean result;
+ if (poll.getCreator().equals(accountEditable)) {
+
+ // The creator user can't vote
+ result = false;
+ } else {
+
+ // The poll must be running and account allowed for restricted poll
+ result = poll.isRunning(now);
+ if (poll.getPollType() != PollType.FREE) {
+
+ PersonToListDAO dao = getDAO(PersonToList.class);
+ PersonToList personToList =
+ dao.findByPollAndAccount(poll, accountEditable);
+
+ result &= personToList != null;
+ }
+ }
+ return result;
+ }
+
+ public boolean isUpdateAllowed(Poll poll, String voteId,
+ String accountId, UserAccount userConnected) {
+
+ Date now = serviceContext.getCurrentTime();
+
+ boolean result = false;
+
+ Vote vote = poll.getVoteByTopiaId(voteId);
+
+ // can only modify a vote if poll is running.
+ if (vote != null && poll.isRunning(now)) {
+ PollAccount votePollAccount = vote.getPollAccount();
+
+ // si le votant du vote correspond au votant actuel (pollAccountId)
+ if (accountId != null
+ && accountId.equals(votePollAccount.getAccountId())) {
+ result = true;
+ }
+
+ // si l'utilisateur du vote correspond à l'utilisateur actuel (user)
+ if (userConnected != null) {
+ UserAccount voteUserAccount = votePollAccount.getUserAccount();
+ result = userConnected.equals(voteUserAccount);
+ }
+ }
+ return result;
+ }
+
+ public boolean isCanDeleteComment(Comment comment,
+ PollAccount pollAccount,
+ UserAccount userAccount,
+ boolean isPollCreator) {
+
+ boolean result = false;
+
+ PollAccount commentAccount = comment.getPollAccount();
+
+ if (isPollCreator) {
+
+ // poll creator has admin rights on his poll
+ result = true;
+ } else if (userAccount != null) {
+
+ // loggued
+ boolean isAdmin = userAccount.isAdministrator();
+// boolean isCommentAccount = userAccount.equals(commentAccount.getUserAccount());
+
+ // pollen admin or comment owner (linked by user account)
+ result = isAdmin ||
+ userAccount.equals(commentAccount.getUserAccount());
+
+ } else if (pollAccount != null) {
+
+ // comment owner (linked by poll account)
+ result = pollAccount.equals(commentAccount);
+ }
+ return result;
+ }
+
}
Modified: trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/VoteService.java
===================================================================
--- trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/VoteService.java 2012-06-16 12:38:50 UTC (rev 3492)
+++ trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/VoteService.java 2012-06-16 20:33:49 UTC (rev 3493)
@@ -49,7 +49,6 @@
import org.nuiton.topia.TopiaException;
import org.nuiton.topia.persistence.TopiaFilterPagerUtil;
-import java.util.Date;
import java.util.List;
import java.util.Map;
@@ -321,7 +320,6 @@
delete(voteToChoiceDao, voteToChoice);
}
-// Poll poll = entityToDelete.getPoll();
PollAccount voteAccount = entityToDelete.getPollAccount();
if (PollType.FREE == poll.getPollType()) {
@@ -378,75 +376,6 @@
}
}
- /**
- * Vote is allowed if {@code poll} is running and {@code pollAccount} is
- * defined in the {@code poll} restricted list if it's not a {@link PollType#FREE}
- * poll. The account must be defined previously using
- * {@link PollService#getPollAccountEditable(String, UserAccount, Poll)} to
- * have a proper link between userAccount and pollAccount even if not already
- * created in dabase. The poll creator can't vote. The token is just use
- * for moderate purpose.
- *
- * @param poll Poll
- * @param accountEditable Account to check
- * @return true if vote is allowed, false otherwise
- */
- public boolean isVoteAllowed(Poll poll, PollAccount accountEditable) {
-
- Preconditions.checkNotNull(poll);
- Preconditions.checkNotNull(accountEditable);
-
- Date now = serviceContext.getCurrentTime();
-
- boolean result;
- if (poll.getCreator().equals(accountEditable)) {
-
- // The creator user can't vote
- result = false;
- } else {
-
- // The poll must be running and account allowed for restricted poll
- result = poll.isRunning(now);
- if (poll.getPollType() != PollType.FREE) {
-
- PersonToListDAO dao = getDAO(PersonToList.class);
- PersonToList personToList =
- dao.findByPollAndAccount(poll, accountEditable);
-
- result &= personToList != null;
- }
- }
- return result;
- }
-
- public boolean isUpdateAllowed(Poll poll, String voteId,
- String accountId, UserAccount userConnected) {
-
- Date now = serviceContext.getCurrentTime();
-
- boolean result = false;
-
- Vote vote = poll.getVoteByTopiaId(voteId);
-
- // can only modify a vote if poll is running.
- if (vote != null && poll.isRunning(now)) {
- PollAccount votePollAccount = vote.getPollAccount();
-
- // si le votant du vote correspond au votant actuel (pollAccountId)
- if (accountId != null
- && accountId.equals(votePollAccount.getAccountId())) {
- result = true;
- }
-
- // si l'utilisateur du vote correspond à l'utilisateur actuel (user)
- if (userConnected != null) {
- UserAccount voteUserAccount = votePollAccount.getUserAccount();
- result = userConnected.equals(voteUserAccount);
- }
- }
- return result;
- }
-
public boolean hasAlreadyVoted(Poll poll, String votingId) {
try {
VoteDAO dao = getDAO(Vote.class);
@@ -510,4 +439,4 @@
pollResultsService.generateResult(poll);
}
-} //voteservice
+}
Modified: trunk/pollen-services/src/main/resources/i18n/pollen-services_en_GB.properties
===================================================================
--- trunk/pollen-services/src/main/resources/i18n/pollen-services_en_GB.properties 2012-06-16 12:38:50 UTC (rev 3492)
+++ trunk/pollen-services/src/main/resources/i18n/pollen-services_en_GB.properties 2012-06-16 20:33:49 UTC (rev 3493)
@@ -44,3 +44,6 @@
pollen.feed.updateVoteTitle=Vote modified for '%s'
pollen.info.admin.created=Super admin was created with login %1$s
pollen.info.admin.exists=Super admin already exists
+pollen.security.error.poll.not.closed.and.results.not.continuous=The poll is not closed and results are not continuous
+pollen.security.error.poll.not.free.and.access.not.granted=You can not access to this non free poll
+pollen.security.error.poll.result.private.and.access.not.granted=Results of the poll are private and you do not have credentials to see them
Modified: trunk/pollen-services/src/main/resources/i18n/pollen-services_fr_FR.properties
===================================================================
--- trunk/pollen-services/src/main/resources/i18n/pollen-services_fr_FR.properties 2012-06-16 12:38:50 UTC (rev 3492)
+++ trunk/pollen-services/src/main/resources/i18n/pollen-services_fr_FR.properties 2012-06-16 20:33:49 UTC (rev 3493)
@@ -44,3 +44,6 @@
pollen.feed.updateVoteTitle=Vote modifié de '%s'
pollen.info.admin.created=Le super admin a été créé avec l'identifiant %1$s.
pollen.info.admin.exists=Le super admin existe déjà
+pollen.security.error.poll.not.closed.and.results.not.continuous=Vous n'avez pas accès aux résultats de ce sondage (résultats non continus et sondage non fermé)
+pollen.security.error.poll.not.free.and.access.not.granted=Vous n'avez pas accès à ce sondage restreint
+pollen.security.error.poll.result.private.and.access.not.granted=Vous n'avez pas accès aux résultats privés de ce sondage
1
0
r3492 - trunk/pollen-persistence/src/main/java/org/chorem/pollen/business/persistence
by tchemit@users.chorem.org 16 Jun '12
by tchemit@users.chorem.org 16 Jun '12
16 Jun '12
Author: tchemit
Date: 2012-06-16 14:38:50 +0200 (Sat, 16 Jun 2012)
New Revision: 3492
Url: http://chorem.org/repositories/revision/pollen/3492
Log:
refs #618: change urls
Modified:
trunk/pollen-persistence/src/main/java/org/chorem/pollen/business/persistence/PollActions.java
Modified: trunk/pollen-persistence/src/main/java/org/chorem/pollen/business/persistence/PollActions.java
===================================================================
--- trunk/pollen-persistence/src/main/java/org/chorem/pollen/business/persistence/PollActions.java 2012-06-16 12:36:30 UTC (rev 3491)
+++ trunk/pollen-persistence/src/main/java/org/chorem/pollen/business/persistence/PollActions.java 2012-06-16 12:38:50 UTC (rev 3492)
@@ -35,7 +35,7 @@
RESULT("poll/results"),
SUMMARY("poll/summary"),
MODERATE("poll/moderate"),
- EDIT("poll/modification"),
+ EDIT("poll/edit"),
CLOSE("poll/close"),
CLONE("poll/clone"),
EXPORT("poll/export"),
1
0
r3491 - trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl
by tchemit@users.chorem.org 16 Jun '12
by tchemit@users.chorem.org 16 Jun '12
16 Jun '12
Author: tchemit
Date: 2012-06-16 14:36:30 +0200 (Sat, 16 Jun 2012)
New Revision: 3491
Url: http://chorem.org/repositories/revision/pollen/3491
Log:
refs #618: change urls
Modified:
trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollUrlService.java
Modified: trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollUrlService.java
===================================================================
--- trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollUrlService.java 2012-06-16 12:01:22 UTC (rev 3490)
+++ trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollUrlService.java 2012-06-16 12:36:30 UTC (rev 3491)
@@ -39,55 +39,56 @@
public class PollUrlService extends PollenServiceSupport {
public PollUrl getPollSummaryUrl(Poll poll) {
-
- PollUrl result = newPollUri(PollActions.SUMMARY, poll, true);
+ PollUrl result = newPollUrl(PollActions.SUMMARY, poll, true);
return result;
}
public PollUrl getPollCloneUrl(Poll poll) {
-
- PollUrl result = newPollUri(PollActions.CLONE, poll, true);
+ PollUrl result = newPollUrl(PollActions.CLONE, poll, true);
+ result.setSuffixUrl("!input");
return result;
}
public PollUrl getPollExportUrl(Poll poll) {
-
- PollUrl result = newPollUri(PollActions.EXPORT, poll, true);
+ PollUrl result = newPollUrl(PollActions.EXPORT, poll, true);
return result;
}
public PollUrl getPollVoteUrl(Poll poll) {
- PollUrl result = newPollUri(PollActions.VOTE, poll, false);
+ PollUrl result = newPollUrl(PollActions.VOTE, poll, false);
return result;
}
public PollUrl getPollVoteUrl(Poll poll, PollAccount pollAccount) {
- PollUrl result = newPollUri(PollActions.VOTE, poll, pollAccount);
+ PollUrl result = newPollUrl(PollActions.VOTE, poll, pollAccount);
return result;
}
public PollUrl getPollModerateUrl(Poll poll) {
- PollUrl result = newPollUri(PollActions.MODERATE, poll, true);
+ PollUrl result = newPollUrl(PollActions.MODERATE, poll, true);
return result;
}
public PollUrl getPollEditUrl(Poll poll) {
- PollUrl result = newPollUri(PollActions.EDIT, poll, true);
+ PollUrl result = newPollUrl(PollActions.EDIT, poll, true);
+ result.setSuffixUrl("!input");
return result;
}
public PollUrl getPollResultUrl(Poll poll) {
- PollUrl result = newPollUri(PollActions.RESULT, poll,
+ PollUrl result = newPollUrl(PollActions.RESULT, poll,
!poll.isPublicResults());
return result;
}
- protected PollUrl newPollUri(PollActions action, Poll poll, boolean admin) {
+ protected PollUrl newPollUrl(PollActions action, Poll poll, boolean admin) {
Preconditions.checkNotNull(poll);
- return newPollUri(action, poll, admin ? poll.getCreator() : null);
+ return newPollUrl(action, poll, admin ? poll.getCreator() : null);
}
- protected PollUrl newPollUri(PollActions action, Poll poll, PollAccount pollAccount) {
+ protected PollUrl newPollUrl(PollActions action,
+ Poll poll,
+ PollAccount pollAccount) {
Preconditions.checkNotNull(poll);
Preconditions.checkNotNull(action);
@@ -104,7 +105,6 @@
// no account id
pollUri = PollUri.newPollUri(poll.getPollId());
-
} else {
// add account id
1
0
r3490 - in trunk: pollen-services/src/main/java/org/chorem/pollen/bean pollen-services/src/main/java/org/chorem/pollen/services pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll
by tchemit@users.chorem.org 16 Jun '12
by tchemit@users.chorem.org 16 Jun '12
16 Jun '12
Author: tchemit
Date: 2012-06-16 14:01:22 +0200 (Sat, 16 Jun 2012)
New Revision: 3490
Url: http://chorem.org/repositories/revision/pollen/3490
Log:
- Nearly remove this dummy ChoiceHelper class (thanks to FD:()
- Add a comment on Addchoice class (validation is so bad :()
Modified:
trunk/pollen-services/src/main/java/org/chorem/pollen/bean/ChoiceHelper.java
trunk/pollen-services/src/main/java/org/chorem/pollen/services/PollenServiceFunctions.java
trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/AddChoice.java
Modified: trunk/pollen-services/src/main/java/org/chorem/pollen/bean/ChoiceHelper.java
===================================================================
--- trunk/pollen-services/src/main/java/org/chorem/pollen/bean/ChoiceHelper.java 2012-06-16 12:00:01 UTC (rev 3489)
+++ trunk/pollen-services/src/main/java/org/chorem/pollen/bean/ChoiceHelper.java 2012-06-16 12:01:22 UTC (rev 3490)
@@ -35,7 +35,9 @@
*
* @author fdesbois <desbois(a)codelutin.com>
* @since 1.3
+ * @deprecated will be removed soon a class form this is not required :(
*/
+@Deprecated
public final class ChoiceHelper {
private ChoiceHelper() {
@@ -85,20 +87,20 @@
PollenServiceFunctions.CHOICE_TO_NAME);
}
- public static String getValuePropertyName(ChoiceType choiceType) {
- String result;
- switch (choiceType) {
- case DATE:
- result = PollDateChoice.PROPERTY_DATE;
- break;
- case IMAGE:
- result = PollImageChoice.PROPERTY_LOCATION;
- break;
- case TEXT:
- default:
- result = Choice.PROPERTY_NAME;
- }
- return result;
- }
+// public static String getValuePropertyName(ChoiceType choiceType) {
+// String result;
+// switch (choiceType) {
+// case DATE:
+// result = PollDateChoice.PROPERTY_DATE;
+// break;
+// case IMAGE:
+// result = PollImageChoice.PROPERTY_LOCATION;
+// break;
+// case TEXT:
+// default:
+// result = Choice.PROPERTY_NAME;
+// }
+// return result;
+// }
}
Modified: trunk/pollen-services/src/main/java/org/chorem/pollen/services/PollenServiceFunctions.java
===================================================================
--- trunk/pollen-services/src/main/java/org/chorem/pollen/services/PollenServiceFunctions.java 2012-06-16 12:00:01 UTC (rev 3489)
+++ trunk/pollen-services/src/main/java/org/chorem/pollen/services/PollenServiceFunctions.java 2012-06-16 12:01:22 UTC (rev 3490)
@@ -80,6 +80,24 @@
}
};
+ public static final Function<ChoiceType, String> CHOICE_TYPE_TO_PROPERTY_NAME = new Function<ChoiceType, String>() {
+ @Override
+ public String apply(ChoiceType choiceType) {
+ String result;
+ switch (choiceType) {
+ case DATE:
+ result = PollDateChoice.PROPERTY_DATE;
+ break;
+ case IMAGE:
+ result = PollImageChoice.PROPERTY_LOCATION;
+ break;
+ case TEXT:
+ default:
+ result = Choice.PROPERTY_NAME;
+ }
+ return result;
+ }
+ };
public static TopiaIdExtractor newTopiaIdExtractor() {
return new TopiaIdExtractor();
}
Modified: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/AddChoice.java
===================================================================
--- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/AddChoice.java 2012-06-16 12:00:01 UTC (rev 3489)
+++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/AddChoice.java 2012-06-16 12:01:22 UTC (rev 3490)
@@ -30,6 +30,7 @@
import org.chorem.pollen.bean.PollImageChoice;
import org.chorem.pollen.business.persistence.Choice;
import org.chorem.pollen.common.ChoiceType;
+import org.chorem.pollen.services.PollenServiceFunctions;
import org.chorem.pollen.services.exceptions.PollNotFoundException;
import org.chorem.pollen.ui.actions.FileUploadAware;
@@ -95,7 +96,7 @@
ChoiceType choiceType = getPoll().getChoiceType();
- String propName = ChoiceHelper.getValuePropertyName(choiceType);
+ String propName = PollenServiceFunctions.CHOICE_TYPE_TO_PROPERTY_NAME.apply(choiceType);
String choiceName = choice.getName();
@@ -106,6 +107,7 @@
_("pollen.error.choice.empty", typeLabel));
} else {
+ //TODO-tchemit-2012-06-16 Remove this code and perfomr a real validation (name not empty, name not duplicated)
// Retrieve existing values to check if the new choice not already exists
Iterable<String> pollChoiceValues = ChoiceHelper.toNames(
getPoll().getChoice());
1
0
r3489 - trunk/pollen-services/src/main/java/org/chorem/pollen/bean
by tchemit@users.chorem.org 16 Jun '12
by tchemit@users.chorem.org 16 Jun '12
16 Jun '12
Author: tchemit
Date: 2012-06-16 14:00:01 +0200 (Sat, 16 Jun 2012)
New Revision: 3489
Url: http://chorem.org/repositories/revision/pollen/3489
Log:
add a suffixUrl on pollUrl
Modified:
trunk/pollen-services/src/main/java/org/chorem/pollen/bean/PollUrl.java
Modified: trunk/pollen-services/src/main/java/org/chorem/pollen/bean/PollUrl.java
===================================================================
--- trunk/pollen-services/src/main/java/org/chorem/pollen/bean/PollUrl.java 2012-06-16 11:59:04 UTC (rev 3488)
+++ trunk/pollen-services/src/main/java/org/chorem/pollen/bean/PollUrl.java 2012-06-16 12:00:01 UTC (rev 3489)
@@ -22,6 +22,8 @@
*/
package org.chorem.pollen.bean;
+import org.apache.commons.lang3.StringUtils;
+
/**
* Created: 12/04/12
*
@@ -31,6 +33,8 @@
private String baseUrl;
+ private String suffixUrl;
+
private PollUri pollUri;
/**
@@ -61,6 +65,7 @@
result.baseUrl = pollUrl.getBaseUrl();
String pollId = pollUrl.getPollUri().getPollId();
result.pollUri = PollUri.newPollUri(pollId, accountId);
+ result.suffixUrl = pollUrl.suffixUrl;
return result;
}
@@ -75,8 +80,20 @@
return pollUri;
}
+ public String getSuffixUrl() {
+ return suffixUrl;
+ }
+
+ public void setSuffixUrl(String suffixUrl) {
+ this.suffixUrl = suffixUrl;
+ }
+
public String getUrl() {
- return getBaseUrl() + getPollUri().getUri();
+ String result = getBaseUrl() + getPollUri().getUri();
+ if (StringUtils.isNotBlank(suffixUrl)) {
+ result += suffixUrl;
+ }
+ return result;
}
@Override
1
0
16 Jun '12
Author: tchemit
Date: 2012-06-16 13:59:04 +0200 (Sat, 16 Jun 2012)
New Revision: 3488
Url: http://chorem.org/repositories/revision/pollen/3488
Log:
remove commented old code
Modified:
trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/pollListHelper.jsp
Modified: trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/pollListHelper.jsp
===================================================================
--- trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/pollListHelper.jsp 2012-06-15 21:26:08 UTC (rev 3487)
+++ trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/pollListHelper.jsp 2012-06-16 11:59:04 UTC (rev 3488)
@@ -39,29 +39,10 @@
<s:url id='summaryImg' value='/img/edit.png'/>
<s:set id='summaryTitle'><s:text name="pollen.action.pollSummary"/></s:set>
-<%--<s:url id='moderateImg' value='/img/moderate.png'/>--%>
-<%--<s:set id='moderateTitle'><s:text name="pollen.action.pollModerateVote"/></s:set>--%>
-
<s:url id="resultUrl" action="results/" namespace="/poll"/>
<s:url id='resultImg' value='/img/count.png'/>
<s:set id='resultTitle'><s:text name="pollen.action.pollResult"/></s:set>
-<%--<s:url id="editUrl" action="modification/" namespace="/poll"/>--%>
-<%--<s:url id='editImg' value='/img/edit.png'/>--%>
-<%--<s:set id='editTitle'><s:text name="pollen.action.pollEdit"/></s:set>--%>
-
-<%--<s:url id="closeUrl" action="confirmClosePoll/" namespace="/poll"/>--%>
-<%--<s:url id='closeImg' value='/img/close.png'/>--%>
-<%--<s:set id='closeTitle'><s:text name="pollen.action.pollClose"/></s:set>--%>
-
-<%--<s:url id="exportUrl" action="export/" namespace="/poll"/>--%>
-<%--<s:url id='exportImg' value='/img/export.png'/>--%>
-<%--<s:set id='exportTitle'><s:text name="pollen.action.pollExport"/></s:set>--%>
-
-<%--<s:url id="cloneUrl" action="clone/" namespace="/poll"/>--%>
-<%--<s:url id='cloneImg' value='/img/copy.png'/>--%>
-<%--<s:set id='cloneTitle'><s:text name="pollen.action.pollClone"/></s:set>--%>
-
<s:url id="deleteUrl" action="confirmDeletePoll/" namespace="/poll"/>
<s:url id='deleteImg' value='/img/delete.png'/>
<s:set id='deleteTitle'><s:text name="pollen.action.pollDelete"/></s:set>
1
0
r3487 - in trunk/pollen-ui-struts2/src: main/java/org/chorem/pollen/ui/security main/resources main/resources/i18n main/webapp/WEB-INF/jsp/security test/java/org/chorem/pollen/ui test/java/org/chorem/pollen/ui/its
by tchemit@users.chorem.org 15 Jun '12
by tchemit@users.chorem.org 15 Jun '12
15 Jun '12
Author: tchemit
Date: 2012-06-15 23:26:08 +0200 (Fri, 15 Jun 2012)
New Revision: 3487
Url: http://chorem.org/repositories/revision/pollen/3487
Log:
- refs #609: Review security access for administrator
- refs #612: Review security access for creator
- add fixme in tests
Added:
trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/PollCreatorAccessRequired.java
trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/PollResultAccessRequired.java
trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/PollVoteAccessRequired.java
trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/security/illegal_access.jsp
Removed:
trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/PollAccessRequired.java
trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/PollCreatorRequired.java
trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/PollRequired.java
trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/ResultAccessRequired.java
trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/security/poll_access_required.jsp
trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/security/poll_creator_required.jsp
trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/security/poll_required.jsp
trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/security/result_access_required.jsp
Modified:
trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/AbstractPollenAuthorization.java
trunk/pollen-ui-struts2/src/main/resources/i18n/pollen-ui-struts2_en_GB.properties
trunk/pollen-ui-struts2/src/main/resources/i18n/pollen-ui-struts2_fr_FR.properties
trunk/pollen-ui-struts2/src/main/resources/shiro.ini
trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/security/admin_required.jsp
trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/security/connected_required.jsp
trunk/pollen-ui-struts2/src/test/java/org/chorem/pollen/ui/PollenFixtures.java
trunk/pollen-ui-struts2/src/test/java/org/chorem/pollen/ui/its/CreateFreeTextPollSIT.java
trunk/pollen-ui-struts2/src/test/java/org/chorem/pollen/ui/its/PollenBaseWebDriverIT.java
trunk/pollen-ui-struts2/src/test/java/org/chorem/pollen/ui/its/SecurityAccessSIT.java
Modified: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/AbstractPollenAuthorization.java
===================================================================
--- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/AbstractPollenAuthorization.java 2012-06-15 21:13:46 UTC (rev 3486)
+++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/AbstractPollenAuthorization.java 2012-06-15 21:26:08 UTC (rev 3487)
@@ -23,18 +23,20 @@
package org.chorem.pollen.ui.security;
import com.google.common.base.Preconditions;
+import com.google.common.collect.Maps;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.shiro.util.StringUtils;
import org.apache.shiro.web.filter.authz.AuthorizationFilter;
import org.apache.shiro.web.util.WebUtils;
+import org.chorem.pollen.PollenApplicationContext;
import org.chorem.pollen.bean.PollUri;
import org.chorem.pollen.business.persistence.UserAccount;
import org.chorem.pollen.services.DefaultPollenServiceContext;
import org.chorem.pollen.services.PollenServiceContext;
import org.chorem.pollen.services.PollenServiceFactory;
+import org.chorem.pollen.services.exceptions.PollNotFoundException;
import org.chorem.pollen.services.impl.SecurityService;
-import org.chorem.pollen.PollenApplicationContext;
import org.chorem.pollen.ui.PollenSession;
import org.chorem.pollen.ui.PollenUIUtils;
import org.nuiton.topia.TopiaContext;
@@ -47,9 +49,12 @@
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Locale;
+import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import static org.nuiton.i18n.I18n.n_;
+
public abstract class AbstractPollenAuthorization extends AuthorizationFilter {
/**
@@ -67,6 +72,9 @@
private static final Log log =
LogFactory.getLog(AbstractPollenAuthorization.class);
+ private static final String ERROR_MESSAGE_PARAMETER =
+ "securityPollenErrorMessage";
+
protected AbstractPollenAuthorization() {
if (log.isInfoEnabled()) {
log.info("Init - " + this);
@@ -137,10 +145,82 @@
String unauthorizedUrl = getUnauthorizedUrl();
//SHIRO-142 - ensure that redirect _or_ error code occurs - both cannot happen due to response commit:
if (StringUtils.hasText(unauthorizedUrl)) {
- WebUtils.issueRedirect(request, response, unauthorizedUrl);
+ String attribute = (String) request.getAttribute(ERROR_MESSAGE_PARAMETER);
+ if (StringUtils.hasText(attribute)) {
+
+ // add a params
+ Map<String, String> params = Maps.newHashMap();
+ params.put("errorMessage", attribute);
+ WebUtils.issueRedirect(request, response, unauthorizedUrl, params);
+// request.removeAttribute(ERROR_MESSAGE_PARAMETER);
+
+ } else {
+
+ WebUtils.issueRedirect(request, response, unauthorizedUrl);
+ }
} else {
WebUtils.toHttp(response).sendError(HttpServletResponse.SC_UNAUTHORIZED);
}
return false;
}
+
+ protected boolean isPollIdSane(PollUri pollUri,
+ SecurityService securityService,
+ ServletRequest request) {
+
+ String errorMessage = null;
+ if (pollUri == null) {
+
+ // no pollUri in url
+ errorMessage = n_("pollen.security.error.no.pollId");
+
+ } else {
+
+ if (!pollUri.isPollIdNotBlank()) {
+
+ // no pollId in uri
+ errorMessage = n_("pollen.security.error.no.pollId");
+ } else {
+
+ // there is a pollId check that it exists
+
+ try {
+ securityService.checkPoll(pollUri);
+
+ if (log.isDebugEnabled()) {
+ log.debug("Can access to this poll " +
+ pollUri.getPollId());
+ }
+
+ } catch (PollNotFoundException e) {
+ if (log.isDebugEnabled()) {
+ log.debug("Poll not found!");
+ }
+ errorMessage = n_("pollen.security.error.poll.not.found");
+ }
+ }
+ }
+ boolean isAccessAllowed;
+
+ if (errorMessage == null) {
+
+ // no error message seems ok
+ isAccessAllowed = true;
+
+ } else {
+
+ // something wrong happens
+ isAccessAllowed = false;
+
+ registerError(request, errorMessage);
+ }
+
+ return isAccessAllowed;
+ }
+
+
+ protected void registerError(ServletRequest request, String errorMessage) {
+ request.setAttribute(ERROR_MESSAGE_PARAMETER, errorMessage);
+ }
+
}
Deleted: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/PollAccessRequired.java
===================================================================
--- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/PollAccessRequired.java 2012-06-15 21:13:46 UTC (rev 3486)
+++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/PollAccessRequired.java 2012-06-15 21:26:08 UTC (rev 3487)
@@ -1,105 +0,0 @@
-/*
- * #%L
- * Pollen :: UI (struts2)
- * $Id$
- * $HeadURL$
- * %%
- * Copyright (C) 2009 - 2012 CodeLutin, Tony Chemit
- * %%
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- * #L%
- */
-package org.chorem.pollen.ui.security;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.chorem.pollen.bean.PollUri;
-import org.chorem.pollen.services.exceptions.PollNotFoundException;
-import org.chorem.pollen.services.exceptions.UnauthorizedPollAccessException;
-import org.chorem.pollen.services.impl.SecurityService;
-
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-
-public class PollAccessRequired extends AbstractPollenAuthorization {
-
- private static final Log log =
- LogFactory.getLog(PollAccessRequired.class);
-
- protected final AdminUserRequired adminFilter;
-
- protected final PollCreatorRequired pollCreatorFilter;
-
- public PollAccessRequired() {
- adminFilter = new AdminUserRequired();
- pollCreatorFilter = new PollCreatorRequired();
- }
-
- @Override
- protected boolean isAccessAllowed(ServletRequest request,
- ServletResponse response,
- Object mappedValue) {
-
- boolean isAccessAllowed;
-
- if (adminFilter.isAccessAllowed(request, response, mappedValue)) {
-
- // user is connected ans admin, so
- isAccessAllowed = true;
-
- } else if (pollCreatorFilter.isAccessAllowed(request, response, mappedValue)) {
-
- // user is connected ans admin, so
- isAccessAllowed = true;
-
- } else {
-
- PollUri pollUri = getPollUri(request);
-
- if (pollUri == null) {
-
- // no uriId given
- isAccessAllowed = false;
-
-
- } else {
-
- SecurityService securityService = getSecurityService(request);
-
- try {
- securityService.checkPollAccount(pollUri);
- isAccessAllowed = true;
-
- if (log.isDebugEnabled()) {
- log.debug("Can access to this poll " + pollUri.getPollId());
- }
- } catch (PollNotFoundException e) {
- if (log.isDebugEnabled()) {
- log.debug("Poll not found!");
- }
- isAccessAllowed = false;
- } catch (UnauthorizedPollAccessException e) {
- if (log.isDebugEnabled()) {
- log.debug("User can not access page");
- }
- isAccessAllowed = false;
- }
-
- }
- }
-
- return isAccessAllowed;
- }
-
-}
Added: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/PollCreatorAccessRequired.java
===================================================================
--- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/PollCreatorAccessRequired.java (rev 0)
+++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/PollCreatorAccessRequired.java 2012-06-15 21:26:08 UTC (rev 3487)
@@ -0,0 +1,135 @@
+/*
+ * #%L
+ * Pollen :: UI (struts2)
+ * $Id$
+ * $HeadURL$
+ * %%
+ * Copyright (C) 2009 - 2012 CodeLutin
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * #L%
+ */
+package org.chorem.pollen.ui.security;
+
+import org.chorem.pollen.bean.PollUri;
+import org.chorem.pollen.business.persistence.Poll;
+import org.chorem.pollen.business.persistence.UserAccount;
+import org.chorem.pollen.services.PollenServiceContext;
+import org.chorem.pollen.services.impl.PollService;
+import org.chorem.pollen.services.impl.SecurityService;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+
+import static org.nuiton.i18n.I18n.n_;
+
+/**
+ * Check that a user can show results of a poll.
+ *
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 1.4
+ */
+public class PollCreatorAccessRequired extends AbstractPollenAuthorization {
+
+ protected final AdminUserRequired adminFilter;
+
+ public PollCreatorAccessRequired() {
+ adminFilter = new AdminUserRequired();
+ }
+
+ @Override
+ protected boolean isAccessAllowed(ServletRequest request,
+ ServletResponse response,
+ Object mappedValue) {
+
+ PollenServiceContext serviceContext = getServiceContext(request);
+
+ PollUri pollUri = getPollUri(request);
+
+ SecurityService securityService =
+ serviceContext.newService(SecurityService.class);
+
+ // test that poll is sane
+ boolean isAccessAllowed = isPollIdSane(pollUri, securityService, request);
+
+ SecurityService.AccountIdRole accountIdRole =
+ SecurityService.AccountIdRole.UNDEFINED;
+
+ if (isAccessAllowed) {
+
+ // pollId is sane (poll exists from it)
+
+ // get it
+ Poll poll = serviceContext.newService(PollService.class).getPollByPollId(
+ pollUri.getPollId());
+
+ // test if user is admin
+ boolean isAdmin = adminFilter.isAccessAllowed(request,
+ response,
+ mappedValue);
+
+ boolean withAccountId = pollUri.isAccountIdNotBlank();
+
+ if (withAccountId) {
+
+ // there is a account id, must validate it
+ accountIdRole = securityService.getAccountIdRole(
+ poll, pollUri.getAccountId());
+
+ if (accountIdRole == SecurityService.AccountIdRole.UNDEFINED) {
+
+ // bad account Id
+ isAccessAllowed = false;
+ registerError(
+ request, n_("pollen.security.error.bad.accountId"));
+ }
+ }
+
+ if (isAdmin) {
+
+ // admin user acts as a poll creator
+ accountIdRole = SecurityService.AccountIdRole.CREATOR;
+ } else {
+
+ UserAccount userAccount = getPollenUserAccount(request);
+ if (userAccount != null &&
+ userAccount.equals(poll.getCreator().getUserAccount())) {
+
+ //conntected user is the creator
+ accountIdRole = SecurityService.AccountIdRole.CREATOR;
+ }
+ }
+ }
+
+ if (isAccessAllowed) {
+
+ // pollId is sane
+ // accountId also
+
+ // check now that account role is a creator
+
+ if (accountIdRole != SecurityService.AccountIdRole.CREATOR) {
+
+ // not a creator, access not granted
+ isAccessAllowed = false;
+ registerError(
+ request,
+ n_("pollen.security.error.creatorId.or.admin.required"));
+ }
+ }
+
+ return isAccessAllowed;
+ }
+
+}
\ No newline at end of file
Property changes on: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/PollCreatorAccessRequired.java
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision HeadURL
Added: svn:eol-style
+ native
Deleted: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/PollCreatorRequired.java
===================================================================
--- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/PollCreatorRequired.java 2012-06-15 21:13:46 UTC (rev 3486)
+++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/PollCreatorRequired.java 2012-06-15 21:26:08 UTC (rev 3487)
@@ -1,96 +0,0 @@
-/*
- * #%L
- * Pollen :: UI (struts2)
- * $Id$
- * $HeadURL$
- * %%
- * Copyright (C) 2009 - 2012 CodeLutin, Tony Chemit
- * %%
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- * #L%
- */
-package org.chorem.pollen.ui.security;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.chorem.pollen.bean.PollUri;
-import org.chorem.pollen.services.exceptions.PollNotFoundException;
-import org.chorem.pollen.services.exceptions.UnauthorizedPollAccessException;
-import org.chorem.pollen.services.impl.SecurityService;
-
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-
-public class PollCreatorRequired extends AbstractPollenAuthorization {
-
- private static final Log log = LogFactory.getLog(PollCreatorRequired.class);
-
- protected final AdminUserRequired adminFilter;
-
- public PollCreatorRequired() {
- adminFilter = new AdminUserRequired();
- }
-
- @Override
- protected boolean isAccessAllowed(ServletRequest request,
- ServletResponse response,
- Object mappedValue) {
-
- boolean isAccessAllowed;
-
- if (adminFilter.isAccessAllowed(request, response, mappedValue)) {
-
- // user is connected and admin, so access granted
- isAccessAllowed = true;
-
- } else {
-
- PollUri pollUri = getPollUri(request);
-
- if (pollUri == null) {
-
- // no uriId given
- isAccessAllowed = false;
-
-
- } else {
- SecurityService securityService = getSecurityService(request);
-
- try {
- securityService.checkPollCreator(pollUri);
- isAccessAllowed = true;
-
- if (log.isDebugEnabled()) {
- log.debug("Can access to this poll " +
- pollUri.getPollId());
- }
- } catch (PollNotFoundException e) {
- if (log.isDebugEnabled()) {
- log.debug("Poll not found!");
- }
- isAccessAllowed = false;
- } catch (UnauthorizedPollAccessException e) {
- if (log.isDebugEnabled()) {
- log.debug("User can not access page");
- }
- isAccessAllowed = false;
- }
-
- }
- }
-
- return isAccessAllowed;
- }
-
-}
Deleted: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/PollRequired.java
===================================================================
--- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/PollRequired.java 2012-06-15 21:13:46 UTC (rev 3486)
+++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/PollRequired.java 2012-06-15 21:26:08 UTC (rev 3487)
@@ -1,75 +0,0 @@
-/*
- * #%L
- * Pollen :: UI (struts2)
- * $Id$
- * $HeadURL$
- * %%
- * Copyright (C) 2009 - 2012 CodeLutin, Tony Chemit
- * %%
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- * #L%
- */
-package org.chorem.pollen.ui.security;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.chorem.pollen.bean.PollUri;
-import org.chorem.pollen.services.exceptions.PollNotFoundException;
-import org.chorem.pollen.services.impl.SecurityService;
-
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-
-public class PollRequired extends AbstractPollenAuthorization {
-
- private static final Log log =
- LogFactory.getLog(PollRequired.class);
-
- @Override
- protected boolean isAccessAllowed(ServletRequest request,
- ServletResponse response,
- Object mappedValue) {
-
- boolean isAccessAllowed;
-
- PollUri pollUri = getPollUri(request);
-
- if (pollUri == null) {
-
- // no uriId given
- isAccessAllowed = false;
-
- } else {
-
- SecurityService securityService = getSecurityService(request);
-
- try {
- securityService.checkPoll(pollUri);
- isAccessAllowed = true;
-
- if (log.isDebugEnabled()) {
- log.debug("Can access to this poll " + pollUri.getPollId());
- }
- } catch (PollNotFoundException e) {
- if (log.isDebugEnabled()) {
- log.debug("Poll not found!");
- }
- isAccessAllowed = false;
- }
- }
-
- return isAccessAllowed;
- }
-
-}
Added: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/PollResultAccessRequired.java
===================================================================
--- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/PollResultAccessRequired.java (rev 0)
+++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/PollResultAccessRequired.java 2012-06-15 21:26:08 UTC (rev 3487)
@@ -0,0 +1,162 @@
+/*
+ * #%L
+ * Pollen :: UI (struts2)
+ * $Id$
+ * $HeadURL$
+ * %%
+ * Copyright (C) 2009 - 2012 CodeLutin
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * #L%
+ */
+package org.chorem.pollen.ui.security;
+
+import org.chorem.pollen.bean.PollUri;
+import org.chorem.pollen.business.persistence.Poll;
+import org.chorem.pollen.common.PollType;
+import org.chorem.pollen.services.PollenServiceContext;
+import org.chorem.pollen.services.impl.PollService;
+import org.chorem.pollen.services.impl.SecurityService;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+
+import static org.nuiton.i18n.I18n.n_;
+
+/**
+ * Check that a user can show results of a poll.
+ *
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 1.4
+ */
+public class PollResultAccessRequired extends AbstractPollenAuthorization {
+
+ protected final AdminUserRequired adminFilter;
+
+ public PollResultAccessRequired() {
+ adminFilter = new AdminUserRequired();
+ }
+
+ @Override
+ protected boolean isAccessAllowed(ServletRequest request,
+ ServletResponse response,
+ Object mappedValue) {
+
+ PollenServiceContext serviceContext = getServiceContext(request);
+
+ PollUri pollUri = getPollUri(request);
+
+ SecurityService securityService =
+ serviceContext.newService(SecurityService.class);
+
+ // test that poll is sane
+ boolean isAccessAllowed = isPollIdSane(pollUri, securityService, request);
+
+ Poll poll = null;
+
+ SecurityService.AccountIdRole accountIdRole = null;
+
+ if (isAccessAllowed) {
+
+ // pollId is sane (poll exists from it)
+
+ // get it
+ poll = serviceContext.newService(PollService.class).getPollByPollId(
+ pollUri.getPollId());
+
+ // test if user is admin
+
+ boolean isAdmin = adminFilter.isAccessAllowed(request,
+ response,
+ mappedValue);
+
+
+ boolean withAccountId = pollUri.isAccountIdNotBlank();
+
+ if (withAccountId) {
+
+ // there is a account id, must validate it
+ accountIdRole = securityService.getAccountIdRole(
+ poll, pollUri.getAccountId());
+
+ if (accountIdRole == SecurityService.AccountIdRole.UNDEFINED) {
+
+ // bad account Id
+ isAccessAllowed = false;
+ registerError(
+ request,
+ n_("pollen.security.error.bad.accountId"));
+ }
+ }
+
+ if (isAdmin) {
+
+ // admin user acts as a poll creator
+ accountIdRole = SecurityService.AccountIdRole.CREATOR;
+ }
+ }
+
+ if (isAccessAllowed) {
+
+ // pollId is sane
+ // accountId also
+
+ // check now poll results can be displayed
+
+ boolean publicResults = poll.isPublicResults();
+ boolean continuousResults = poll.isContinuousResults();
+
+ if (!continuousResults && !poll.isClosed()) {
+
+ // results are not continuous and poll is not closed
+ isAccessAllowed = false;
+ registerError(
+ request,
+ n_("pollen.security.error.poll.not.closed.and.results.not.continuous"));
+ }
+
+ if (isAccessAllowed) {
+
+ if (!publicResults &&
+ accountIdRole != SecurityService.AccountIdRole.CREATOR) {
+
+ // poll results are private, only poll admin can see results
+ isAccessAllowed = false;
+ registerError(
+ request,
+ n_("pollen.security.error.poll.result.private.and.access.not.granted"));
+ }
+ }
+
+ if (isAccessAllowed) {
+
+ boolean pollIsFree = PollType.FREE == poll.getPollType();
+
+ if (publicResults &&
+ !pollIsFree &&
+ !SecurityService.NONE_FREE_ACCOUNT_ID_ROLES.contains(accountIdRole)) {
+
+ // on none free poll, only creator or restricted user can have it
+ isAccessAllowed = false;
+ registerError(
+ request,
+ n_("pollen.security.error.poll.not.free.and.access.not.granted"));
+ }
+ }
+ }
+
+ return isAccessAllowed;
+ }
+
+}
\ No newline at end of file
Property changes on: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/PollResultAccessRequired.java
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision HeadURL
Added: svn:eol-style
+ native
Added: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/PollVoteAccessRequired.java
===================================================================
--- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/PollVoteAccessRequired.java (rev 0)
+++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/PollVoteAccessRequired.java 2012-06-15 21:26:08 UTC (rev 3487)
@@ -0,0 +1,132 @@
+/*
+ * #%L
+ * Pollen :: UI (struts2)
+ * $Id$
+ * $HeadURL$
+ * %%
+ * Copyright (C) 2009 - 2012 CodeLutin
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * #L%
+ */
+package org.chorem.pollen.ui.security;
+
+import org.chorem.pollen.bean.PollUri;
+import org.chorem.pollen.business.persistence.Poll;
+import org.chorem.pollen.common.PollType;
+import org.chorem.pollen.services.PollenServiceContext;
+import org.chorem.pollen.services.impl.PollService;
+import org.chorem.pollen.services.impl.SecurityService;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+
+import static org.nuiton.i18n.I18n.n_;
+
+/**
+ * Check that a user can vote.
+ *
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 1.4
+ */
+public class PollVoteAccessRequired extends AbstractPollenAuthorization {
+
+ protected final AdminUserRequired adminFilter;
+
+ public PollVoteAccessRequired() {
+ adminFilter = new AdminUserRequired();
+ }
+
+ @Override
+ protected boolean isAccessAllowed(ServletRequest request,
+ ServletResponse response,
+ Object mappedValue) {
+
+ PollenServiceContext serviceContext = getServiceContext(request);
+
+ PollUri pollUri = getPollUri(request);
+
+ SecurityService securityService =
+ serviceContext.newService(SecurityService.class);
+
+ // test that poll is sane
+ boolean isAccessAllowed = isPollIdSane(pollUri, securityService,
+ request);
+
+ Poll poll = null;
+
+ SecurityService.AccountIdRole accountIdRole = null;
+
+ if (isAccessAllowed) {
+
+ // pollId is sane (poll exists from it)
+
+ // get it
+ poll = serviceContext.newService(PollService.class).getPollByPollId(
+ pollUri.getPollId());
+
+ // test if user is admin
+ boolean isAdmin = adminFilter.isAccessAllowed(request,
+ response,
+ mappedValue);
+
+ boolean withAccountId = pollUri.isAccountIdNotBlank();
+
+ if (withAccountId) {
+
+ // there is a account id, must validate it
+ accountIdRole = securityService.getAccountIdRole(
+ poll, pollUri.getAccountId());
+
+ if (accountIdRole == SecurityService.AccountIdRole.UNDEFINED) {
+
+ // bad account Id
+ isAccessAllowed = false;
+ registerError(
+ request,
+ n_("pollen.security.error.bad.accountId"));
+ }
+ }
+
+ if (isAdmin) {
+
+ // admin user acts as a poll creator
+ accountIdRole = SecurityService.AccountIdRole.CREATOR;
+ }
+ }
+
+ if (isAccessAllowed) {
+
+ // pollId is sane
+ // accountId also
+
+ // check now poll votes can be displayed
+
+ boolean pollIsFree = PollType.FREE == poll.getPollType();
+
+ if (!pollIsFree &&
+ !SecurityService.NONE_FREE_ACCOUNT_ID_ROLES.contains(accountIdRole)) {
+
+ // on none free poll, only creator or restricted user can have it
+ isAccessAllowed = false;
+ registerError(
+ request,
+ n_("pollen.security.error.poll.not.free.and.access.not.granted"));
+ }
+ }
+
+ return isAccessAllowed;
+ }
+
+}
\ No newline at end of file
Property changes on: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/PollVoteAccessRequired.java
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision HeadURL
Added: svn:eol-style
+ native
Deleted: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/ResultAccessRequired.java
===================================================================
--- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/ResultAccessRequired.java 2012-06-15 21:13:46 UTC (rev 3486)
+++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/ResultAccessRequired.java 2012-06-15 21:26:08 UTC (rev 3487)
@@ -1,102 +0,0 @@
-/*
- * #%L
- * Pollen :: UI (struts2)
- * $Id$
- * $HeadURL$
- * %%
- * Copyright (C) 2009 - 2012 CodeLutin, Tony Chemit
- * %%
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- * #L%
- */
-package org.chorem.pollen.ui.security;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.chorem.pollen.bean.PollUri;
-import org.chorem.pollen.services.exceptions.PollNotFoundException;
-import org.chorem.pollen.services.exceptions.UnauthorizedPollAccessException;
-import org.chorem.pollen.services.impl.SecurityService;
-
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-
-public class ResultAccessRequired extends AbstractPollenAuthorization {
-
- private static final Log log =
- LogFactory.getLog(ResultAccessRequired.class);
-
- protected final AdminUserRequired adminFilter;
-
- protected final PollCreatorRequired pollCreatorFilter;
-
- protected final PollAccessRequired pollAccountFilter;
-
- public ResultAccessRequired() {
- adminFilter = new AdminUserRequired();
- pollCreatorFilter = new PollCreatorRequired();
- pollAccountFilter = new PollAccessRequired();
- }
-
- @Override
- protected boolean isAccessAllowed(ServletRequest request,
- ServletResponse response,
- Object mappedValue) {
-
- boolean isAccessAllowed;
-
- if (adminFilter.isAccessAllowed(request, response, mappedValue)) {
-
- // user is connected ans admin, so
- isAccessAllowed = true;
-
- } else if (pollCreatorFilter.isAccessAllowed(request, response, mappedValue)) {
-
- // account is creator
- isAccessAllowed = true;
-
- } else if (pollAccountFilter.isAccessAllowed(request, response, mappedValue)) {
-
- PollUri pollUri = getPollUri(request);
-
- SecurityService securityService = getSecurityService(request);
-
- try {
- securityService.checkPollResult(pollUri);
- isAccessAllowed = true;
-
- if (log.isDebugEnabled()) {
- log.debug("Can display result for this poll " + pollUri.getPollId());
- }
- } catch (PollNotFoundException e) {
- if (log.isDebugEnabled()) {
- log.debug("Poll not found!");
- }
- isAccessAllowed = false;
- } catch (UnauthorizedPollAccessException e) {
- if (log.isDebugEnabled()) {
- log.debug("User can not access page");
- }
- isAccessAllowed = false;
- }
-
- } else {
-
- isAccessAllowed = false;
- }
-
- return isAccessAllowed;
- }
-
-}
Modified: trunk/pollen-ui-struts2/src/main/resources/i18n/pollen-ui-struts2_en_GB.properties
===================================================================
--- trunk/pollen-ui-struts2/src/main/resources/i18n/pollen-ui-struts2_en_GB.properties 2012-06-15 21:13:46 UTC (rev 3486)
+++ trunk/pollen-ui-struts2/src/main/resources/i18n/pollen-ui-struts2_en_GB.properties 2012-06-15 21:26:08 UTC (rev 3487)
@@ -305,8 +305,16 @@
pollen.menu.register=Register
pollen.menu.userFavoriteLists=Voting lists
pollen.security.error.admin_required=You must be connected as an administrator to access this page.
+pollen.security.error.bad.accountId=Bad account id
pollen.security.error.connected_required=You must be connected to access this page.
+pollen.security.error.creatorId.or.admin.required=Only the poll creator or an administrator can access this page.
pollen.security.error.creator_required=Only the poll creator or an administrator can access this page.
+pollen.security.error.illegal_access=You are not authorise to access this page for following reason\:
+pollen.security.error.no.pollId=No poll id given
+pollen.security.error.poll.not.closed.and.results.not.continuous=The poll is not closed and results are not continuous
+pollen.security.error.poll.not.found=Poll not found with this id
+pollen.security.error.poll.not.free.and.access.not.granted=You can not access to this non free poll
+pollen.security.error.poll.result.private.and.access.not.granted=Results of the poll are private and you do not have credentials to see them
pollen.security.error.poll_access_required=You are not authorise to access this poll page.
pollen.security.error.poll_required=No poll found with the given url.
pollen.security.error.result_access_required=You are not authorise to access this result page.
Modified: trunk/pollen-ui-struts2/src/main/resources/i18n/pollen-ui-struts2_fr_FR.properties
===================================================================
--- trunk/pollen-ui-struts2/src/main/resources/i18n/pollen-ui-struts2_fr_FR.properties 2012-06-15 21:13:46 UTC (rev 3486)
+++ trunk/pollen-ui-struts2/src/main/resources/i18n/pollen-ui-struts2_fr_FR.properties 2012-06-15 21:26:08 UTC (rev 3487)
@@ -305,8 +305,16 @@
pollen.menu.register=Inscrivez-vous
pollen.menu.userFavoriteLists=Listes de votants
pollen.security.error.admin_required=Vous devez être connecté en administrateur pour accéder à cette page.
+pollen.security.error.bad.accountId=L'identifiant de compte n'est pas bon
pollen.security.error.connected_required=Vous devez être connecté pour accéder à cette page.
+pollen.security.error.creatorId.or.admin.required=Seul le créateur du sondage ou un administrateur peut accéder à cette page.
pollen.security.error.creator_required=Seul le créateur du sondage ou un administrateur peut accéder à cette page.
+pollen.security.error.illegal_access=Vous n'êtes pas autorisé à accéder à cette page pour la raison suivante \:
+pollen.security.error.no.pollId=Pas d'identifiant de sondage donné.
+pollen.security.error.poll.not.closed.and.results.not.continuous=
+pollen.security.error.poll.not.found=Sondage non trouvé pour l'identifiant donné
+pollen.security.error.poll.not.free.and.access.not.granted=Vou s n'avez pas accès à ce sondage restreint
+pollen.security.error.poll.result.private.and.access.not.granted=Vous n'avez pas accès aux résultats privés de ce sondage
pollen.security.error.poll_access_required=Vous n'êtes pas autorisé à accéder à cette page de sondage.
pollen.security.error.poll_required=Aucun sondage à l'url donné.
pollen.security.error.result_access_required=Vous n'êtes pas autorisé à accéder à cette page de résultats.
Modified: trunk/pollen-ui-struts2/src/main/resources/shiro.ini
===================================================================
--- trunk/pollen-ui-struts2/src/main/resources/shiro.ini 2012-06-15 21:13:46 UTC (rev 3486)
+++ trunk/pollen-ui-struts2/src/main/resources/shiro.ini 2012-06-15 21:26:08 UTC (rev 3487)
@@ -29,18 +29,15 @@
admin=org.chorem.pollen.ui.security.AdminUserRequired
admin.unauthorizedUrl=/security/admin_required
-poll=org.chorem.pollen.ui.security.PollRequired
-poll.unauthorizedUrl=/security/poll_required
+pollCreatorAccess=org.chorem.pollen.ui.security.PollCreatorAccessRequired
+pollCreatorAccess.unauthorizedUrl=/security/illegal_access
-pollAccess=org.chorem.pollen.ui.security.PollAccessRequired
-pollAccess.unauthorizedUrl=/security/poll_access_required
+pollVoteAccess=org.chorem.pollen.ui.security.PollVoteAccessRequired
+pollVoteAccess.unauthorizedUrl=/security/illegal_access
-pollCreator=org.chorem.pollen.ui.security.PollCreatorRequired
-pollCreator.unauthorizedUrl=/security/poll_creator_required
+pollResultAccess=org.chorem.pollen.ui.security.PollResultAccessRequired
+pollResultAccess.unauthorizedUrl=/security/illegal_access
-resultAccess=org.chorem.pollen.ui.security.ResultAccessRequired
-resultAccess.unauthorizedUrl=/security/result_access_required
-
[urls]
# anon urls
@@ -65,15 +62,17 @@
/json/getUser=connected,admin
/json/getPolls=connected,admin
-# is pollAccount (can vote and see result of a poll)
-/poll/votefor/**=poll,pollAccess
-/poll/VoteFor/**=poll,pollAccess
-/poll/results/**=poll,resultAccess
+# is poll exists and user can vote to it
+/poll/votefor/**=pollVoteAccess
+/poll/VoteFor/**=pollVoteAccess
-# is pollCreator (can admin a poll)
-/poll/modification/**=poll,pollCreator
-/poll/summary/**=poll,pollCreator
-/poll/moderate/**=poll,pollCreator
-/poll/clone/**=poll,pollCreator
-/poll/resultLink/**=poll,pollCreator
-/poll/resume/**=poll,pollCreator
\ No newline at end of file
+# is poll exists and user can access to his result
+/poll/results/**=pollResultAccess
+
+# is poll exists and user can admin it (his creator or an admin)
+/poll/modification/**=pollCreatorAccess
+/poll/summary/**=pollCreatorAccess
+/poll/moderate/**=pollCreatorAccess
+/poll/clone/**=pollCreatorAccess
+/poll/resultLink/**=pollCreatorAccess
+/poll/resume/**=pollCreatorAccess
\ No newline at end of file
Modified: trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/security/admin_required.jsp
===================================================================
--- trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/security/admin_required.jsp 2012-06-15 21:13:46 UTC (rev 3486)
+++ trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/security/admin_required.jsp 2012-06-15 21:26:08 UTC (rev 3487)
@@ -1,24 +1,24 @@
<%--
#%L
-Pollen :: UI (struts2)
-$Id$
-$HeadURL$
-%%
-Copyright (C) 2009 - 2012 CodeLutin, Tony Chemit
-%%
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
-#L%
+ Pollen :: UI (struts2)
+ $Id$
+ $HeadURL$
+ %%
+ Copyright (C) 2009 - 2012 CodeLutin, Tony Chemit
+ %%
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ #L%
--%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Modified: trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/security/connected_required.jsp
===================================================================
--- trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/security/connected_required.jsp 2012-06-15 21:13:46 UTC (rev 3486)
+++ trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/security/connected_required.jsp 2012-06-15 21:26:08 UTC (rev 3487)
@@ -1,24 +1,24 @@
<%--
#%L
-Pollen :: UI (struts2)
-$Id$
-$HeadURL$
-%%
-Copyright (C) 2009 - 2012 CodeLutin, Tony Chemit
-%%
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
-#L%
+ Pollen :: UI (struts2)
+ $Id$
+ $HeadURL$
+ %%
+ Copyright (C) 2009 - 2012 CodeLutin, Tony Chemit
+ %%
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ #L%
--%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Added: trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/security/illegal_access.jsp
===================================================================
--- trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/security/illegal_access.jsp (rev 0)
+++ trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/security/illegal_access.jsp 2012-06-15 21:26:08 UTC (rev 3487)
@@ -0,0 +1,37 @@
+<%--
+#%L
+ Pollen :: UI (struts2)
+ $Id$
+ $HeadURL$
+ %%
+ Copyright (C) 2009 - 2012 CodeLutin, Tony Chemit
+ %%
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ #L%
+--%>
+<%@ taglib prefix="s" uri="/struts-tags" %>
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+<div class="info_error">
+ <ul class="actionErrors">
+ <li>
+ <span>
+ <s:text name="pollen.security.error.illegal_access"/>
+ <br/>
+ <strong>
+ <s:property value='%{getText(#parameters.errorMessage)}'/>
+ </strong>
+ </span>
+ </li>
+ </ul>
+</div>
Property changes on: trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/security/illegal_access.jsp
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision HeadURL
Added: svn:eol-style
+ native
Deleted: trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/security/poll_access_required.jsp
===================================================================
--- trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/security/poll_access_required.jsp 2012-06-15 21:13:46 UTC (rev 3486)
+++ trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/security/poll_access_required.jsp 2012-06-15 21:26:08 UTC (rev 3487)
@@ -1,33 +0,0 @@
-<%--
-#%L
-Pollen :: UI (struts2)
-$Id$
-$HeadURL$
-%%
-Copyright (C) 2009 - 2012 CodeLutin, Tony Chemit
-%%
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
-#L%
---%>
-<%@ taglib prefix="s" uri="/struts-tags" %>
-<%@ page contentType="text/html;charset=UTF-8" language="java" %>
-<div class="info_error">
- <ul class="actionErrors">
- <li>
- <span>
- <s:text name="pollen.security.error.poll_access_required"/>
- </span>
- </li>
- </ul>
-</div>
Deleted: trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/security/poll_creator_required.jsp
===================================================================
--- trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/security/poll_creator_required.jsp 2012-06-15 21:13:46 UTC (rev 3486)
+++ trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/security/poll_creator_required.jsp 2012-06-15 21:26:08 UTC (rev 3487)
@@ -1,33 +0,0 @@
-<%--
-#%L
-Pollen :: UI (struts2)
-$Id$
-$HeadURL$
-%%
-Copyright (C) 2009 - 2012 CodeLutin, Tony Chemit
-%%
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
-#L%
---%>
-<%@ taglib prefix="s" uri="/struts-tags" %>
-<%@ page contentType="text/html;charset=UTF-8" language="java" %>
-<div class="info_error">
- <ul class="actionErrors">
- <li>
- <span>
- <s:text name="pollen.security.error.creator_required"/>
- </span>
- </li>
- </ul>
-</div>
Deleted: trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/security/poll_required.jsp
===================================================================
--- trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/security/poll_required.jsp 2012-06-15 21:13:46 UTC (rev 3486)
+++ trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/security/poll_required.jsp 2012-06-15 21:26:08 UTC (rev 3487)
@@ -1,33 +0,0 @@
-<%--
-#%L
-Pollen :: UI (struts2)
-$Id$
-$HeadURL$
-%%
-Copyright (C) 2009 - 2012 CodeLutin, Tony Chemit
-%%
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
-#L%
---%>
-<%@ taglib prefix="s" uri="/struts-tags" %>
-<%@ page contentType="text/html;charset=UTF-8" language="java" %>
-<div class="info_error">
- <ul class="actionErrors">
- <li>
- <span>
- <s:text name="pollen.security.error.poll_required"/>
- </span>
- </li>
- </ul>
-</div>
Deleted: trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/security/result_access_required.jsp
===================================================================
--- trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/security/result_access_required.jsp 2012-06-15 21:13:46 UTC (rev 3486)
+++ trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/security/result_access_required.jsp 2012-06-15 21:26:08 UTC (rev 3487)
@@ -1,33 +0,0 @@
-<%--
-#%L
-Pollen :: UI (struts2)
-$Id$
-$HeadURL$
-%%
-Copyright (C) 2009 - 2012 CodeLutin, Tony Chemit
-%%
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
-#L%
---%>
-<%@ taglib prefix="s" uri="/struts-tags" %>
-<%@ page contentType="text/html;charset=UTF-8" language="java" %>
-<div class="info_error">
- <ul class="actionErrors">
- <li>
- <span>
- <s:text name="pollen.security.error.result_access_required"/>
- </span>
- </li>
- </ul>
-</div>
Modified: trunk/pollen-ui-struts2/src/test/java/org/chorem/pollen/ui/PollenFixtures.java
===================================================================
--- trunk/pollen-ui-struts2/src/test/java/org/chorem/pollen/ui/PollenFixtures.java 2012-06-15 21:13:46 UTC (rev 3486)
+++ trunk/pollen-ui-struts2/src/test/java/org/chorem/pollen/ui/PollenFixtures.java 2012-06-15 21:26:08 UTC (rev 3487)
@@ -132,15 +132,15 @@
}
public String poll_requiredURL() {
- return baseUrl() + "security/poll_required";
+ return baseUrl() + "security/illegal_access";
}
public String poll_access_requiredURL() {
- return baseUrl() + "security/poll_access_required";
+ return baseUrl() + "security/illegal_access";
}
public String poll_creator_requiredURL() {
- return baseUrl() + "security/poll_creator_required";
+ return baseUrl() + "security/illegal_access";
}
public String createPollURL() {
Modified: trunk/pollen-ui-struts2/src/test/java/org/chorem/pollen/ui/its/CreateFreeTextPollSIT.java
===================================================================
--- trunk/pollen-ui-struts2/src/test/java/org/chorem/pollen/ui/its/CreateFreeTextPollSIT.java 2012-06-15 21:13:46 UTC (rev 3486)
+++ trunk/pollen-ui-struts2/src/test/java/org/chorem/pollen/ui/its/CreateFreeTextPollSIT.java 2012-06-15 21:26:08 UTC (rev 3487)
@@ -34,7 +34,7 @@
/**
* Test the well work of a Free text poll creation page.
- *
+ * <p/>
* Tested cases :
* <ul>
* <li>Classic creation with filled mandatory fields (OK)</li>
@@ -51,7 +51,6 @@
* </ul>
*
* @author ymartel <martel(a)codelutin.com>
- *
* @since 1.4
*/
public class CreateFreeTextPollSIT extends PollenBaseWebDriverIT {
@@ -472,7 +471,8 @@
submit.click();
// No choices, should stay on create poll page
- checkCurrentUrl(fixtures.createPollURL(), false);
+ //FIXME-tchemit-2012-06-15 (see http://chorem.org/issues/618)
+ checkCurrentUrl(fixtures.savePollURL(), false);
}
Modified: trunk/pollen-ui-struts2/src/test/java/org/chorem/pollen/ui/its/PollenBaseWebDriverIT.java
===================================================================
--- trunk/pollen-ui-struts2/src/test/java/org/chorem/pollen/ui/its/PollenBaseWebDriverIT.java 2012-06-15 21:13:46 UTC (rev 3486)
+++ trunk/pollen-ui-struts2/src/test/java/org/chorem/pollen/ui/its/PollenBaseWebDriverIT.java 2012-06-15 21:26:08 UTC (rev 3487)
@@ -72,7 +72,7 @@
@Rule
public WebDriverResource seleniumServer;
- protected PollenFixtures fixtures ;
+ protected PollenFixtures fixtures;
protected WebDriver driver;
@@ -112,7 +112,6 @@
} else {
expectedUrl = fallBackUrl;
}
-
checkCurrentUrl(expectedUrl, strict);
}
@@ -120,13 +119,12 @@
* Check that the current URL is the expected one.
* If it is a strict comparison, the URL should be the same that the wanted.
* If not, it only checks that the current URL start with the wanted url.
- *
*/
protected void checkCurrentUrl(String expectedUrl, boolean strict) {
if (strict) {
- Assert.assertEquals(expectedUrl, driver.getCurrentUrl());
+ Assert.assertEquals("Current url [" + driver.getCurrentUrl() + "] should be " + expectedUrl, expectedUrl, driver.getCurrentUrl());
} else {
- Assert.assertTrue(driver.getCurrentUrl().startsWith(expectedUrl));
+ Assert.assertTrue("Current url [" + driver.getCurrentUrl() + "] should starts with " + expectedUrl, driver.getCurrentUrl().startsWith(expectedUrl));
}
}
@@ -181,7 +179,7 @@
if (safeDrivers == null) {
List<Class<? extends WebDriver>> allDrivers = Lists.newArrayList();
-// allDrivers.add(HtmlUnitDriver.class);
+ allDrivers.add(HtmlUnitDriver.class);
allDrivers.add(FirefoxDriver.class);
// allDrivers.add(ChromeDriver.class);
// allDrivers.add(InternetExplorerDriver.class);
Modified: trunk/pollen-ui-struts2/src/test/java/org/chorem/pollen/ui/its/SecurityAccessSIT.java
===================================================================
--- trunk/pollen-ui-struts2/src/test/java/org/chorem/pollen/ui/its/SecurityAccessSIT.java 2012-06-15 21:13:46 UTC (rev 3486)
+++ trunk/pollen-ui-struts2/src/test/java/org/chorem/pollen/ui/its/SecurityAccessSIT.java 2012-06-15 21:26:08 UTC (rev 3487)
@@ -323,7 +323,7 @@
* @throws Exception
*/
@Test
- public void accessNormalPoolActionsAsOwner() throws Exception {
+ public void accessNormalPollActionsAsOwner() throws Exception {
// Go on home page
gotoUrl(fixtures.homeURL());
1
0