r3595 - in trunk: pollen-persistence/src/main/java/org/chorem/pollen pollen-persistence/src/main/java/org/chorem/pollen/business/persistence pollen-persistence/src/main/resources/i18n pollen-persistence/src/main/xmi pollen-persistence/src/test/java/org/chorem/pollen/business/persistence pollen-services/src/main/java/org/chorem/pollen pollen-services/src/main/java/org/chorem/pollen/entities/migration pollen-services/src/main/java/org/chorem/pollen/services/impl pollen-services/src/main/resou
Author: tchemit Date: 2012-08-12 13:45:39 +0200 (Sun, 12 Aug 2012) New Revision: 3595 Url: http://chorem.org/repositories/revision/pollen/3595 Log: D?\195?\169sol?\195?\169 un gros commit avec plein de truc en m?\195?\170me temps :( refs #746: Improve security model refs #717: Restricted and authentication user refs #742: Option to allow all users to show voting of others users refs #743: Add option to allow or not comment in poll refs #590: Refactor votecounting module refs #642: Review persistence module Added: trunk/pollen-persistence/src/main/java/org/chorem/pollen/business/persistence/PollCommentVisibility.java trunk/pollen-persistence/src/main/java/org/chorem/pollen/business/persistence/PollVoteVisibility.java trunk/pollen-services/src/main/java/org/chorem/pollen/PollenUserSecurityContext.java trunk/pollen-services/src/main/java/org/chorem/pollen/entities/migration/PollenMigrationCallbackV1_4_5.java Modified: trunk/pollen-persistence/src/main/java/org/chorem/pollen/PollenConfiguration.java trunk/pollen-persistence/src/main/java/org/chorem/pollen/PollenConfigurationOption.java trunk/pollen-persistence/src/main/java/org/chorem/pollen/business/persistence/PollAccountDAOImpl.java trunk/pollen-persistence/src/main/java/org/chorem/pollen/business/persistence/PollImpl.java trunk/pollen-persistence/src/main/resources/i18n/pollen-persistence_en_GB.properties trunk/pollen-persistence/src/main/resources/i18n/pollen-persistence_fr_FR.properties trunk/pollen-persistence/src/main/xmi/pollen.properties trunk/pollen-persistence/src/main/xmi/pollen.zargo trunk/pollen-persistence/src/test/java/org/chorem/pollen/business/persistence/CommentDAOImplTest.java trunk/pollen-persistence/src/test/java/org/chorem/pollen/business/persistence/PersonListDAOImplTest.java trunk/pollen-persistence/src/test/java/org/chorem/pollen/business/persistence/PersonToListDAOImplTest.java trunk/pollen-persistence/src/test/java/org/chorem/pollen/business/persistence/PollAccountDAOImplTest.java trunk/pollen-persistence/src/test/java/org/chorem/pollen/business/persistence/PollDAOImplTest.java trunk/pollen-persistence/src/test/java/org/chorem/pollen/business/persistence/UserAccountDAOImplTest.java trunk/pollen-persistence/src/test/java/org/chorem/pollen/business/persistence/VoteDAOImplTest.java trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/EmailService.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/PollVoteCountingService.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/META-INF/services/org.nuiton.topia.migration.TopiaMigrationCallbackByClassNG$MigrationCallBackForVersion trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/PollenUIUtils.java trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/PollenActionSupport.java trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/PollenActionSupportForEdition.java trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/PollenActionSupportForVote.java 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/GetInvitedPolls.java trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/json/GetParticipatedPolls.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/DeleteVote.java trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/ResultForPoll.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/actions/user/CreateFavoriteList.java trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/user/CreateFavoriteListVoter.java trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/user/EditFavoriteList.java trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/user/EditFavoriteListVoter.java 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/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/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/webapp/WEB-INF/jsp/poll/pollForm.jsp trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/vote.jsp Modified: trunk/pollen-persistence/src/main/java/org/chorem/pollen/PollenConfiguration.java =================================================================== --- trunk/pollen-persistence/src/main/java/org/chorem/pollen/PollenConfiguration.java 2012-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-persistence/src/main/java/org/chorem/pollen/PollenConfiguration.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -27,6 +27,8 @@ import org.apache.commons.lang3.builder.ReflectionToStringBuilder; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.chorem.pollen.business.persistence.PollCommentVisibility; +import org.chorem.pollen.business.persistence.PollVoteVisibility; import org.chorem.pollen.common.ChoiceType; import org.chorem.pollen.common.PollType; import org.nuiton.util.ApplicationConfig; @@ -115,6 +117,20 @@ return result; } + public PollVoteVisibility getDefaultPollVoteVisibility() { + PollVoteVisibility result = applicationConfig.getOption( + PollVoteVisibility.class, + PollenConfigurationOption.DEFAULT_POLL_VOTE_VISIBILITY.key); + return result; + } + + public PollCommentVisibility getDefaultPollCommentVisibility() { + PollCommentVisibility result = applicationConfig.getOption( + PollCommentVisibility.class, + PollenConfigurationOption.DEFAULT_POLL_COMMENT_VISIBILITY.key); + return result; + } + public String getAdminLogin() { String result = applicationConfig.getOption( PollenConfigurationOption.ADMIN_LOGIN.key); Modified: trunk/pollen-persistence/src/main/java/org/chorem/pollen/PollenConfigurationOption.java =================================================================== --- trunk/pollen-persistence/src/main/java/org/chorem/pollen/PollenConfigurationOption.java 2012-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-persistence/src/main/java/org/chorem/pollen/PollenConfigurationOption.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -22,6 +22,8 @@ */ package org.chorem.pollen; +import org.chorem.pollen.business.persistence.PollCommentVisibility; +import org.chorem.pollen.business.persistence.PollVoteVisibility; import org.chorem.pollen.common.ChoiceType; import org.chorem.pollen.common.PollType; import org.hibernate.dialect.H2Dialect; @@ -94,6 +96,20 @@ /** Default choice type to use at a new poll creation. */ DEFAULT_CHOICE_TYPE("pollen.default.choiceType", n_("pollen.configuration.defaultChoiceType"), ChoiceType.TEXT.name(), ChoiceType.class), + /** + * Default poll vote visibility to use at a new poll creation. + * + * @since 1.4.5 + */ + DEFAULT_POLL_VOTE_VISIBILITY("pollen.default.pollVoteVisibility", n_("pollen.configuration.defaultPollVoteVisibility"), PollVoteVisibility.EVERYBODY.name(), PollVoteVisibility.class), + + /** + * Default poll comment visibility to use at a new poll creation. + * + * @since 1.4.5 + */ + DEFAULT_POLL_COMMENT_VISIBILITY("pollen.default.pollCommentVisibility", n_("pollen.configuration.defaultPollCommentVisibility"), PollCommentVisibility.EVERYBODY.name(), PollCommentVisibility.class), + /** db driver. */ DB_DRIVER("hibernate.connection.driver_class", n_("pollen.configuration.dbDriver"), org.h2.Driver.class.getName(), Class.class), Modified: trunk/pollen-persistence/src/main/java/org/chorem/pollen/business/persistence/PollAccountDAOImpl.java =================================================================== --- trunk/pollen-persistence/src/main/java/org/chorem/pollen/business/persistence/PollAccountDAOImpl.java 2012-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-persistence/src/main/java/org/chorem/pollen/business/persistence/PollAccountDAOImpl.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -31,8 +31,18 @@ public class PollAccountDAOImpl<E extends PollAccount> extends PollAccountDAOAbstract<E> { - public E getRestrictedPollAccount(String pollId, - String accountId) throws TopiaException { + /** + * Get a restricted poll account for a given poll + * ( using his {@code pollId} ) using the + * {@link PollAccount#getAccountId()} of the pollAccount. + * + * @param pollId pollId of the poll + * @param accountId the accountId of the pollAccount to find + * @return the found pollAccount, or {@code null} if not foud + * @throws TopiaException if any db pb + */ + public E getRestrictedPollAccountByAccountId(String pollId, + String accountId) throws TopiaException { Preconditions.checkNotNull(pollId); Preconditions.checkNotNull(accountId); @@ -47,22 +57,84 @@ return result; } - public E getRestrictedPollAccount(String pollId, - UserAccount userAccount) throws TopiaException { + /** + * Get a restricted poll account for a given poll + * ( using his {@code pollId} ) using the + * {@link PollAccount#getEmail()} of the pollAccount. + * + * @param pollId pollId of the poll + * @param email the email of the pollAccount to find + * @return the found pollAccount, or {@code null} if not found + * @throws TopiaException if any db pb + */ + public E getRestrictedPollAccountByEmail(String pollId, + String email) throws TopiaException { Preconditions.checkNotNull(pollId); - Preconditions.checkNotNull(userAccount); + Preconditions.checkNotNull(email); TopiaQuery query = new TopiaQuery(PersonToList.class, "p"). addFrom(Poll.class, "poll"). setSelect("p." + PersonToList.PROPERTY_POLL_ACCOUNT). addWhere("poll." + Poll.PROPERTY_POLL_ID, TopiaQuery.Op.EQ, pollId). - addWhere("p." + PersonToList.PROPERTY_POLL_ACCOUNT + "." + PollAccount.PROPERTY_EMAIL, TopiaQuery.Op.EQ, userAccount.getEmail()). + addWhere("p." + PersonToList.PROPERTY_POLL_ACCOUNT + "." + PollAccount.PROPERTY_EMAIL, TopiaQuery.Op.EQ, email). addInElements("p", "poll." + Poll.PROPERTY_VOTING_LIST + "." + VotingList.PROPERTY_POLL_ACCOUNT_PERSON_TO_LIST); E result = findByQuery(query); return result; } + /** + * Get the pollAccount of a voter for a given {@code pollId} using his + * {@code accountId}. + * + * @param pollId the poll where to seek + * @param accountId the account id to test + * @return the found pollAccount, or {@code null} if not found + * @throws TopiaException if any db pb + */ + public PollAccount getVoterPollAccountByAccountId(String pollId, + String accountId) throws TopiaException { + + Preconditions.checkNotNull(pollId); + Preconditions.checkNotNull(accountId); + + TopiaQuery query = createQuery("e") + .addFrom(Poll.class, "p") + .addFrom(Vote.class, "v") + .addEquals("p." + Poll.PROPERTY_POLL_ID, pollId) + .addInElements("v", "p." + Poll.PROPERTY_VOTE) + .addWhere("e = v." + Vote.PROPERTY_POLL_ACCOUNT) + .addEquals("e." + PollAccount.PROPERTY_ACCOUNT_ID, accountId); + PollAccount result = findByQuery(query); + return result; + } + + /** + * Get the pollAccount of a voter for a given {@code pollId} using his + * {@code user}. + * + * @param pollId the poll id where to seek + * @param user the user account to test + * @return the found pollAccount, or {@code null} if not found + * @throws TopiaException if any db pb + */ + public PollAccount getVoterPollAccountByUserAccount(String pollId, + UserAccount user) throws TopiaException { + + Preconditions.checkNotNull(pollId); + Preconditions.checkNotNull(user); + + TopiaQuery query = createQuery("e") + .addFrom(Poll.class, "p") + .addFrom(Vote.class, "v") + .addEquals("p." + Poll.PROPERTY_POLL_ID, pollId) + .addInElements("v", "p." + Poll.PROPERTY_VOTE) + .addWhere("e = v." + Vote.PROPERTY_POLL_ACCOUNT) + .addEquals("e." + PollAccount.PROPERTY_USER_ACCOUNT, user); + PollAccount result = findByQuery(query); + return result; + } + public List<E> getFavoriteListUsers(PersonList favoriteList, TopiaFilterPagerUtil.FilterPagerBean pager) throws TopiaException { @@ -103,23 +175,23 @@ return result; } - public PollAccount findByPollVoteUser(Poll poll, - UserAccount user) throws TopiaException { +// public PollAccount findByPollVoteUser(Poll poll, +// UserAccount user) throws TopiaException { +// +// Preconditions.checkNotNull(poll); +// Preconditions.checkNotNull(user); +// +// TopiaQuery query = createQuery("e") +// .addFrom(Poll.class, "p") +// .addFrom(Vote.class, "v") +// .addEquals("p", poll) +// .addInElements("v", "p." + Poll.PROPERTY_VOTE) +// .addWhere("e = v." + Vote.PROPERTY_POLL_ACCOUNT) +// .addEquals("e." + PollAccount.PROPERTY_USER_ACCOUNT, user); +// PollAccount result = findByQuery(query); +// return result; +// } - Preconditions.checkNotNull(poll); - Preconditions.checkNotNull(user); - - TopiaQuery query = createQuery("e") - .addFrom(Poll.class, "p") - .addFrom(Vote.class, "v") - .addEquals("p", poll) - .addInElements("v", "p." + Poll.PROPERTY_VOTE) - .addWhere("e = v." + Vote.PROPERTY_POLL_ACCOUNT) - .addEquals("e." + PollAccount.PROPERTY_USER_ACCOUNT, user); - PollAccount result = findByQuery(query); - return result; - } - public boolean existsByPollVoteAccountId(String pollId, String accountId) throws TopiaException { Added: trunk/pollen-persistence/src/main/java/org/chorem/pollen/business/persistence/PollCommentVisibility.java =================================================================== --- trunk/pollen-persistence/src/main/java/org/chorem/pollen/business/persistence/PollCommentVisibility.java (rev 0) +++ trunk/pollen-persistence/src/main/java/org/chorem/pollen/business/persistence/PollCommentVisibility.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -0,0 +1,64 @@ +package org.chorem.pollen.business.persistence; +/* + * #%L + * Pollen :: Persistence + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 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% + */ + +import org.chorem.pollen.common.I18nAble; + +import static org.nuiton.i18n.I18n.n_; + +/** + * Define how comment can be shown in a poll. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4.5 + */ +public enum PollCommentVisibility implements I18nAble { + + /** Nobody can see comments. */ + NOBODY(n_("pollen.pollCommentVisibilty.nobody")), + /** Every body can see comments. */ + EVERYBODY(n_("pollen.pollCommentVisibilty.everybody")); + + private final String i18nKey; + + PollCommentVisibility(String i18nKey) { + this.i18nKey = i18nKey; + } + + @Override + public String getI18nKey() { + return i18nKey; + } + + public static PollCommentVisibility valueOf(int ordinal) { + + PollCommentVisibility result = null; + for (PollCommentVisibility curr : PollCommentVisibility.values()) { + if (curr.ordinal() == ordinal) { + result = curr; + break; + } + } + return result; + } +} Property changes on: trunk/pollen-persistence/src/main/java/org/chorem/pollen/business/persistence/PollCommentVisibility.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Modified: trunk/pollen-persistence/src/main/java/org/chorem/pollen/business/persistence/PollImpl.java =================================================================== --- trunk/pollen-persistence/src/main/java/org/chorem/pollen/business/persistence/PollImpl.java 2012-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-persistence/src/main/java/org/chorem/pollen/business/persistence/PollImpl.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -24,6 +24,7 @@ import com.google.common.base.Preconditions; import com.google.common.collect.Lists; +import org.chorem.pollen.common.PollType; import java.util.Date; import java.util.List; @@ -33,6 +34,16 @@ private static final long serialVersionUID = 1L; @Override + public boolean isPollFree() { + return PollType.FREE == getPollType(); + } + + @Override + public boolean isAnonymous() { + return PollVoteVisibility.NOBODY == getPollVoteVisibility(); + } + + @Override public List<Vote> getVote() { if (vote == null) { vote = Lists.newArrayList(); Added: trunk/pollen-persistence/src/main/java/org/chorem/pollen/business/persistence/PollVoteVisibility.java =================================================================== --- trunk/pollen-persistence/src/main/java/org/chorem/pollen/business/persistence/PollVoteVisibility.java (rev 0) +++ trunk/pollen-persistence/src/main/java/org/chorem/pollen/business/persistence/PollVoteVisibility.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -0,0 +1,72 @@ +package org.chorem.pollen.business.persistence; +/* + * #%L + * Pollen :: Persistence + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 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% + */ + +import org.chorem.pollen.common.I18nAble; + +import static org.nuiton.i18n.I18n.n_; + +/** + * Define how vote can be visible in a poll. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4.5 + */ +public enum PollVoteVisibility implements I18nAble { + + /** + * Nobody can see vote. + * <p/> + * This means every votes are anonymous. + */ + NOBODY(n_("pollen.pollVoteVisibilty.nobody")), + /** Only creator (or Pollen adin) can see votes. */ + CREATOR_ONLY(n_("pollen.pollVoteVisibilty.creatorOnly")), + /** Only participant of poll can see votes. */ + PARTICIPANT_ONLY(n_("pollen.pollVoteVisibilty.participantOnly")), + /** Every body can see votes. */ + EVERYBODY(n_("pollen.pollVoteVisibilty.everybody")); + + private final String i18nKey; + + PollVoteVisibility(String i18nKey) { + this.i18nKey = i18nKey; + } + + @Override + public String getI18nKey() { + return i18nKey; + } + + public static PollVoteVisibility valueOf(int ordinal) { + + PollVoteVisibility result = null; + for (PollVoteVisibility curr : PollVoteVisibility.values()) { + if (curr.ordinal() == ordinal) { + result = curr; + break; + } + } + return result; + } +} Property changes on: trunk/pollen-persistence/src/main/java/org/chorem/pollen/business/persistence/PollVoteVisibility.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Modified: trunk/pollen-persistence/src/main/resources/i18n/pollen-persistence_en_GB.properties =================================================================== --- trunk/pollen-persistence/src/main/resources/i18n/pollen-persistence_en_GB.properties 2012-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-persistence/src/main/resources/i18n/pollen-persistence_en_GB.properties 2012-08-12 11:45:39 UTC (rev 3595) @@ -11,7 +11,9 @@ pollen.configuration.dbPassword=Password to connect to database pollen.configuration.dbUrl=Database connection url pollen.configuration.defaultChoiceType=Default choice type to use at a new poll creation +pollen.configuration.defaultPollCommentVisibility=Default comment visiblity to use at a new poll creation pollen.configuration.defaultPollType=Default poll type to use at a new poll creation +pollen.configuration.defaultPollVoteVisibility=Default vote visibility to use at a new poll creation pollen.configuration.defaultVoteCountingType=Default vote counting type to use at a new poll creation pollen.configuration.emaiDirectory=directory to store emails before sending them pollen.configuration.emailFrom=from for email sending configuration @@ -22,3 +24,9 @@ pollen.configuration.nbVoteByPage=nb votes to display per page pollen.configuration.siteUrl=Application url pollen.configuration.tmpDirectory=Temporary directory (is cleaned at each startup of application) +pollen.pollCommentVisibilty.everybody=Use comments on poll +pollen.pollCommentVisibilty.nobody=No usage of comments on poll +pollen.pollVoteVisibilty.creatorOnly=Visible for creator +pollen.pollVoteVisibilty.everybody=Public vote +pollen.pollVoteVisibilty.nobody=Anonymous poll +pollen.pollVoteVisibilty.participantOnly=Visible for participant Modified: trunk/pollen-persistence/src/main/resources/i18n/pollen-persistence_fr_FR.properties =================================================================== --- trunk/pollen-persistence/src/main/resources/i18n/pollen-persistence_fr_FR.properties 2012-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-persistence/src/main/resources/i18n/pollen-persistence_fr_FR.properties 2012-08-12 11:45:39 UTC (rev 3595) @@ -10,9 +10,11 @@ pollen.configuration.dbLogin=Login pour se connecter à la base de données pollen.configuration.dbPassword=Mot de passe pour se connecter à la base de données pollen.configuration.dbUrl=Url de connexion à la base de données -pollen.configuration.defaultChoiceType=Choix par défaut utilisation lors de la création d'un sondage -pollen.configuration.defaultPollType=Type de sondage lors de la création d'un sondage -pollen.configuration.defaultVoteCountingType=Type de dépouillement lors de la création d'un sondage +pollen.configuration.defaultChoiceType=Choix par défaut utiliser lors de la création d'un sondage +pollen.configuration.defaultPollCommentVisibility=Visiblité des commentaires par défaut à utiliser lors de la création d'un sondage +pollen.configuration.defaultPollType=Type de sondage par défaut à utiliser lors de la création d'un sondage +pollen.configuration.defaultPollVoteVisibility=Visibilité des votes par défaut à utiliser lors de la création d'un sondage +pollen.configuration.defaultVoteCountingType=Type de dépouillement par défaut à utiliser lors de la création d'un sondage pollen.configuration.emaiDirectory=Répertoire des emails pollen.configuration.emailFrom=Email de l'envoyeur dans les emails pollen.configuration.emailHost=Serveur d'envoie d'email @@ -22,3 +24,9 @@ pollen.configuration.nbVoteByPage=Nombre de votes à afficher par page pollen.configuration.siteUrl=Url publique de l'aplication (utilisée dans les emails envoyés) pollen.configuration.tmpDirectory=Répertoire temporaire (est nettoyé à chaque démarrage de l'application) +pollen.pollCommentVisibilty.everybody=Utiliser les commentaires +pollen.pollCommentVisibilty.nobody=Interdir les commentaires sur le sondage +pollen.pollVoteVisibilty.creatorOnly=Visible pour le créateur +pollen.pollVoteVisibilty.everybody=Vote publique +pollen.pollVoteVisibilty.nobody=Sondage anonyme +pollen.pollVoteVisibilty.participantOnly=Visible pour les participants Modified: trunk/pollen-persistence/src/main/xmi/pollen.properties =================================================================== --- trunk/pollen-persistence/src/main/xmi/pollen.properties 2012-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-persistence/src/main/xmi/pollen.properties 2012-08-12 11:45:39 UTC (rev 3595) @@ -24,7 +24,7 @@ #model.tagvalue.dbSchema=Pollen model.tagvalue.constantPrefix=PROPERTY_ model.tagvalue.java.lang.String=text -model.tagvalue.version=1.4 +model.tagvalue.version=1.4.5 model.tagvalue.doNotGenerateBooleanGetMethods=true model.tagvalue.indexForeignKeys=true Modified: trunk/pollen-persistence/src/main/xmi/pollen.zargo =================================================================== (Binary files differ) Modified: trunk/pollen-persistence/src/test/java/org/chorem/pollen/business/persistence/CommentDAOImplTest.java =================================================================== --- trunk/pollen-persistence/src/test/java/org/chorem/pollen/business/persistence/CommentDAOImplTest.java 2012-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-persistence/src/test/java/org/chorem/pollen/business/persistence/CommentDAOImplTest.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -34,7 +34,7 @@ * Tests the {@link CommentDAOImpl}. * * @author tchemit <chemit@codelutin.com> - * @since 1.5 + * @since 1.4.5 */ public class CommentDAOImplTest extends AbstractDAOTest { Modified: trunk/pollen-persistence/src/test/java/org/chorem/pollen/business/persistence/PersonListDAOImplTest.java =================================================================== --- trunk/pollen-persistence/src/test/java/org/chorem/pollen/business/persistence/PersonListDAOImplTest.java 2012-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-persistence/src/test/java/org/chorem/pollen/business/persistence/PersonListDAOImplTest.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -34,7 +34,7 @@ * Tests the {@link PersonListDAOImpl}. * * @author tchemit <chemit@codelutin.com> - * @since 1.5 + * @since 1.4.5 */ public class PersonListDAOImplTest extends AbstractDAOTest { Modified: trunk/pollen-persistence/src/test/java/org/chorem/pollen/business/persistence/PersonToListDAOImplTest.java =================================================================== --- trunk/pollen-persistence/src/test/java/org/chorem/pollen/business/persistence/PersonToListDAOImplTest.java 2012-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-persistence/src/test/java/org/chorem/pollen/business/persistence/PersonToListDAOImplTest.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -31,7 +31,7 @@ * Tests the {@link PersonToListDAOImpl}. * * @author tchemit <chemit@codelutin.com> - * @since 1.5 + * @since 1.4.5 */ public class PersonToListDAOImplTest extends AbstractDAOTest { Modified: trunk/pollen-persistence/src/test/java/org/chorem/pollen/business/persistence/PollAccountDAOImplTest.java =================================================================== --- trunk/pollen-persistence/src/test/java/org/chorem/pollen/business/persistence/PollAccountDAOImplTest.java 2012-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-persistence/src/test/java/org/chorem/pollen/business/persistence/PollAccountDAOImplTest.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -90,7 +90,7 @@ pollAccount3.addVotingListPersonToList(personToList3); PollAccount restrictedPollAccount = - pollAccountDAO.getRestrictedPollAccount(pollId, accountId); + pollAccountDAO.getRestrictedPollAccountByAccountId(pollId, accountId); Assert.assertNotNull(restrictedPollAccount); Assert.assertEquals(accountId, restrictedPollAccount.getAccountId()); @@ -98,7 +98,7 @@ Assert.assertTrue(restrictedPollAccount.getVotingListPersonToList().contains(personToList)); PollAccount restrictedPollAccount2 = - pollAccountDAO.getRestrictedPollAccount(pollId, accountId2); + pollAccountDAO.getRestrictedPollAccountByAccountId(pollId, accountId2); Assert.assertNotNull(restrictedPollAccount2); Assert.assertEquals(accountId2, restrictedPollAccount2.getAccountId()); @@ -107,7 +107,7 @@ Assert.assertTrue(restrictedPollAccount2.getVotingListPersonToList().contains(personToList2)); PollAccount restrictedPollAccount3 = - pollAccountDAO.getRestrictedPollAccount(pollId, accountId3); + pollAccountDAO.getRestrictedPollAccountByAccountId(pollId, accountId3); Assert.assertNotNull(restrictedPollAccount3); Assert.assertEquals(accountId3, restrictedPollAccount3.getAccountId()); @@ -116,7 +116,7 @@ Assert.assertTrue(restrictedPollAccount3.getVotingListPersonToList().contains(personToList3)); PollAccount restrictedPollAccount4 = - pollAccountDAO.getRestrictedPollAccount(pollId, System.nanoTime() + "--"); + pollAccountDAO.getRestrictedPollAccountByAccountId(pollId, System.nanoTime() + "--"); Assert.assertNull(restrictedPollAccount4); } Modified: trunk/pollen-persistence/src/test/java/org/chorem/pollen/business/persistence/PollDAOImplTest.java =================================================================== --- trunk/pollen-persistence/src/test/java/org/chorem/pollen/business/persistence/PollDAOImplTest.java 2012-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-persistence/src/test/java/org/chorem/pollen/business/persistence/PollDAOImplTest.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -39,7 +39,7 @@ * Tests the {@link PollDAOImpl}. * * @author tchemit <chemit@codelutin.com> - * @since 1.5 + * @since 1.4.5 */ public class PollDAOImplTest extends AbstractDAOTest { Modified: trunk/pollen-persistence/src/test/java/org/chorem/pollen/business/persistence/UserAccountDAOImplTest.java =================================================================== --- trunk/pollen-persistence/src/test/java/org/chorem/pollen/business/persistence/UserAccountDAOImplTest.java 2012-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-persistence/src/test/java/org/chorem/pollen/business/persistence/UserAccountDAOImplTest.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -34,7 +34,7 @@ * Tests the {@link UserAccountDAOImpl}. * * @author tchemit <chemit@codelutin.com> - * @since 1.5 + * @since 1.4.5 */ public class UserAccountDAOImplTest extends AbstractDAOTest { Modified: trunk/pollen-persistence/src/test/java/org/chorem/pollen/business/persistence/VoteDAOImplTest.java =================================================================== --- trunk/pollen-persistence/src/test/java/org/chorem/pollen/business/persistence/VoteDAOImplTest.java 2012-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-persistence/src/test/java/org/chorem/pollen/business/persistence/VoteDAOImplTest.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -35,7 +35,7 @@ * Tests the {@link VoteDAOImpl}. * * @author tchemit <chemit@codelutin.com> - * @since 1.5 + * @since 1.4.5 */ public class VoteDAOImplTest extends AbstractDAOTest { @@ -49,7 +49,7 @@ Poll poll1 = pollDAO.create(Poll.PROPERTY_POLL_ID, "pollId1"); Poll poll2 = pollDAO.create(Poll.PROPERTY_POLL_ID, "pollId2", - Poll.PROPERTY_ANONYMOUS, true); + Poll.PROPERTY_POLL_VOTE_VISIBILITY, PollVoteVisibility.NOBODY); Vote vote1 = voteDAO.create(); vote1.setTopiaCreateDate(DateUtil.createDate(0, 0, 0, 1, 1, 2010)); @@ -90,7 +90,7 @@ Poll poll1 = pollDAO.create(Poll.PROPERTY_POLL_ID, "pollId1"); Poll poll2 = pollDAO.create(Poll.PROPERTY_POLL_ID, "pollId2", - Poll.PROPERTY_ANONYMOUS, true); + Poll.PROPERTY_POLL_VOTE_VISIBILITY, PollVoteVisibility.NOBODY); Vote vote1 = voteDAO.create(); vote1.setTopiaCreateDate(DateUtil.createDate(0, 0, 0, 1, 1, 2010)); @@ -136,7 +136,7 @@ Poll poll1 = pollDAO.create(Poll.PROPERTY_POLL_ID, "pollId1"); Poll poll2 = pollDAO.create(Poll.PROPERTY_POLL_ID, "pollId2", - Poll.PROPERTY_ANONYMOUS, true); + Poll.PROPERTY_POLL_VOTE_VISIBILITY, PollVoteVisibility.NOBODY); String votingId1 = "votingId1"; String votingId2 = "votingId2"; Added: trunk/pollen-services/src/main/java/org/chorem/pollen/PollenUserSecurityContext.java =================================================================== --- trunk/pollen-services/src/main/java/org/chorem/pollen/PollenUserSecurityContext.java (rev 0) +++ trunk/pollen-services/src/main/java/org/chorem/pollen/PollenUserSecurityContext.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -0,0 +1,154 @@ +package org.chorem.pollen; + +import com.google.common.base.Preconditions; +import org.apache.commons.collections.CollectionUtils; +import org.chorem.pollen.bean.PollUri; +import org.chorem.pollen.bean.PollUrl; +import org.chorem.pollen.business.persistence.Poll; +import org.chorem.pollen.business.persistence.UserAccount; +import org.chorem.pollen.services.impl.SecurityService; + +import java.io.Serializable; +import java.util.Set; + +/** + * To store security context for a given user at each request. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4.5 + */ +public class PollenUserSecurityContext implements Serializable { + + private static final long serialVersionUID = 5348851531764083245L; + + /** + * Connected user account. + * <p/> + * Can be {@code null} if user is not connected. + */ + protected final UserAccount userAccount; + + /** + * Poll uri defining the poll - pollAccount to use. + * + * @see PollUri + */ + protected final PollUri pollUri; + + /** + * Current loaded poll according to the {@link #pollUri}. + * <p/> + * <strong>Note:</strong> this poll should be used by any action needed it. + */ + protected Poll poll; + + /** + * User roles on the poll. + * <p/> + * Loaded by the method {@link #loadUserRoles(SecurityService)}. + */ + protected Set<PollenUserSecurityRole> userRoles; + + public static PollenUserSecurityContext newContext(UserAccount userAccount, PollUri pollUri) { + PollenUserSecurityContext result = new PollenUserSecurityContext( + userAccount, + pollUri + ); + return result; + } + + protected PollenUserSecurityContext(UserAccount userAccount, PollUri pollUri) { + this.userAccount = userAccount; + this.pollUri = pollUri; + } + + public boolean isPollExists() { + return poll != null; + } + + public boolean isAdmin() { + return userAccount != null && userAccount.isAdministrator(); + } + + public boolean isWithAccountId() { + return pollUri != null && pollUri.isAccountIdNotBlank(); + } + + public boolean isCreator() { + return userRoles.contains(PollenUserSecurityRole.CREATOR); + } + + public boolean isVoter() { + return userRoles.contains(PollenUserSecurityRole.VOTER); + } + + public boolean isRestrictedVoter() { + return userRoles.contains(PollenUserSecurityRole.RESTRICTED_VOTER); + } + + public boolean hasNoRole() { + return CollectionUtils.isEmpty(userRoles); + } + + public UserAccount getUserAccount() { + return userAccount; + } + + public PollUri getPollUri() { + return pollUri; + } + + public Poll getPoll() { + return poll; + } + + public void setPoll(Poll poll) { + this.poll = poll; + } + + public void loadUserRoles(SecurityService securityService) { + Preconditions.checkNotNull(securityService); + Preconditions.checkNotNull(pollUri); + Preconditions.checkNotNull(poll); + userRoles = securityService.getUserRoles(poll, + getAccountId(), + userAccount); + } + + public String getAccountId() { + return pollUri == null ? null : pollUri.getAccountId(); + } + + public void removeAccountIdWhenConnected(PollUrl url) { + if (userAccount != null) { + + // remove accountId from url + url.getPollUri().setAccountId(null); + } + } + + /** + * To define a security role for a given pollen user which can be + * identified by his user account or a accountId. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4 + */ + public enum PollenUserSecurityRole { + + /** + * Creator of the poll. + * <p/> + * This role can access to everything, but can not vote. + */ + CREATOR, + /** A user that has voted on a poll. */ + VOTER, + /** + * A user that was invited to a restricted poll. + * <p/> + * It might have alreay voted or not. + */ + RESTRICTED_VOTER + } +} Property changes on: trunk/pollen-services/src/main/java/org/chorem/pollen/PollenUserSecurityContext.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/pollen-services/src/main/java/org/chorem/pollen/entities/migration/PollenMigrationCallbackV1_4_5.java =================================================================== --- trunk/pollen-services/src/main/java/org/chorem/pollen/entities/migration/PollenMigrationCallbackV1_4_5.java (rev 0) +++ trunk/pollen-services/src/main/java/org/chorem/pollen/entities/migration/PollenMigrationCallbackV1_4_5.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -0,0 +1,93 @@ +package org.chorem.pollen.entities.migration; +/* + * #%L + * Pollen :: Services + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 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% + */ + +import org.chorem.pollen.business.persistence.Poll; +import org.nuiton.topia.TopiaException; +import org.nuiton.topia.framework.TopiaContextImplementor; +import org.nuiton.topia.migration.TopiaMigrationCallbackByClassNG; +import org.nuiton.util.Version; +import org.nuiton.util.VersionUtil; + +import java.util.List; + +/** + * Migration for version {@code 1.4.5}. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4.5 + */ +public class PollenMigrationCallbackV1_4_5 extends TopiaMigrationCallbackByClassNG.MigrationCallBackForVersion { + + @Override + public Version getVersion() { + return VersionUtil.valueOf("1.4.5"); + } + + @Override + protected void prepareMigrationScript(TopiaContextImplementor tx, + List<String> queries, + boolean showSql, + boolean showProgression) throws TopiaException { + + // add pollVoteVisibility on poll (instead of anonymous flag on poll) + // see http://chorem.org/issues/742 + addPollVoteVisibility(queries); + + // add pollCommentVisibilite on Poll + // see http://chorem.org/issues/743 + addPollCommentVisibility(queries); + } + + private void addPollVoteVisibility(List<String> queries) throws TopiaException { + + // add pollVoteVisibility integer on poll + queries.add("ALTER TABLE poll ADD COLUMN " + + Poll.PROPERTY_POLL_VOTE_VISIBILITY + " INT NOT NULL DEFAULT 0;"); + + // Poll anonymous = PollVoteAnonymous.NOBODY = 0 + queries.add("UPDATE poll SET " + + Poll.PROPERTY_POLL_VOTE_VISIBILITY + " = 0 WHERE anonymous = true;"); + + // Poll anonymous = PollVoteAnonymous.EVERYBODY = 3 + queries.add("UPDATE poll SET " + + Poll.PROPERTY_POLL_VOTE_VISIBILITY + " = 3 WHERE anonymous = false;"); + + // remove Poll anonymous + queries.add("ALTER TABLE poll DROP COLUMN anonymous"); + } + + private void addPollCommentVisibility(List<String> queries) throws TopiaException { + + // add pollCommentVisibility integer on poll + queries.add("ALTER TABLE poll ADD COLUMN " + + Poll.PROPERTY_POLL_COMMENT_VISIBILITY + " INT NOT NULL DEFAULT 0;"); + + // All polls were previously authorize = PollCommentVisibility.EVERYBODY = 1 + queries.add("UPDATE poll SET " + + Poll.PROPERTY_POLL_COMMENT_VISIBILITY + " = 1;"); + + + } + +} Property changes on: trunk/pollen-services/src/main/java/org/chorem/pollen/entities/migration/PollenMigrationCallbackV1_4_5.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Modified: trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/EmailService.java =================================================================== --- trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/EmailService.java 2012-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/EmailService.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -36,7 +36,6 @@ import org.chorem.pollen.business.persistence.Poll; import org.chorem.pollen.business.persistence.PollAccount; import org.chorem.pollen.business.persistence.UserAccount; -import org.chorem.pollen.common.PollType; import org.chorem.pollen.services.PollenServiceSupport; import org.nuiton.util.StringUtil; @@ -139,7 +138,7 @@ if (StringUtils.isNotEmpty(poll.getCreator().getEmail())) { String subject, content; - if (PollType.FREE == poll.getPollType()) { + if (poll.isPollFree()) { subject = l_(locale, "pollen.email.createPoll.subject", pollTitle); content = l_(locale, "pollen.email.createPoll.content", 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-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollService.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -177,8 +177,11 @@ public Poll createPoll(Poll poll) { PollDAO pollDAO = getDAO(Poll.class); - Poll result = createWithProperties(pollDAO, - Poll.PROPERTY_POLL_ID, generateId()); + Poll result = createWithProperties( + pollDAO, + Poll.PROPERTY_POLL_ID, generateId(), + Poll.PROPERTY_POLL_VOTE_VISIBILITY, poll.getPollVoteVisibility(), + Poll.PROPERTY_POLL_COMMENT_VISIBILITY, poll.getPollCommentVisibility()); // check max number choice authorized (can not be more than // XXX-fdesbois-2012-04-11 : don't know why the maxNbChoice must be @@ -189,7 +192,6 @@ // poll.setMaxChoiceNb(poll.sizeChoice()); // } - result.setAnonymous(poll.isAnonymous()); result.setAnonymousVoteAllowed(poll.isAnonymousVoteAllowed()); result.setChoiceAddAllowed(poll.isChoiceAddAllowed()); result.setBeginChoiceDate(poll.getBeginChoiceDate()); @@ -382,7 +384,8 @@ pollDao.getParticipatedPolls(pager, userToUse); return result; } catch (TopiaException e) { - throw new PollenTechnicalException("Could not obtain running polls", e); + throw new PollenTechnicalException( + "Could not obtain running polls", e); } } @@ -393,7 +396,8 @@ List<Poll> results = dao.getRunningPolls(currentTime); return results; } catch (TopiaException e) { - throw new PollenTechnicalException("Could not obtain running polls", e); + throw new PollenTechnicalException( + "Could not obtain running polls", e); } } @@ -405,7 +409,8 @@ Poll result = dao.findByPollId(pollId); return result; } catch (TopiaException e) { - throw new PollenTechnicalException("Could not find poll with pollId '" + pollId + "'", e); + throw new PollenTechnicalException( + "Could not find poll with pollId '" + pollId + "'", e); } } @@ -421,7 +426,8 @@ } return result; } catch (TopiaException e) { - throw new PollenTechnicalException("Could not find poll with pollId '" + pollId + "'", e); + throw new PollenTechnicalException( + "Could not find poll with pollId '" + pollId + "'", e); } } @@ -443,60 +449,73 @@ public PollAccount getPollAccountEditable(String accountId, UserAccount userAccount, Poll poll) throws PollAccountNotFound { - PollAccount result = null; - if (StringUtils.isNotEmpty(accountId)) { - PollAccount pollAccountLoaded = getPollAccountByAccountId(accountId); - result = copyPollAccount(pollAccountLoaded); + PollAccountDAO dao = getDAO(PollAccount.class); - // Don't remove or update userAccount link if already set - if (userAccount != null && result.getUserAccount() == null) { - result.setUserAccount(userAccount); + PollAccount pollAccountLoaded = null; - if (log.isDebugEnabled()) { - log.debug(String.format( - "Attach User '%s' [%s] to the existing Account [%s]", - userAccount.getDisplayName(), - userAccount.getTopiaId(), - accountId - )); - } + boolean withUserAccount = userAccount != null; + + if (StringUtils.isNotEmpty(accountId)) { + + try { + pollAccountLoaded = + dao.getVoterPollAccountByAccountId(poll.getPollId(), accountId); + } catch (TopiaException e) { + throw new PollenTechnicalException(e); } } else { - // Retrieve existing pollAccount from user - if (userAccount != null) { - PollAccountDAO pollAccountDAO = getDAO(PollAccount.class); - PollAccount pollAccountLoaded; - try { - pollAccountLoaded = - pollAccountDAO.findByPollVoteUser(poll, userAccount); - } catch (TopiaException e) { - throw new PollenTechnicalException(e); - } + // Try to retrieve existing pollAccount from user - if (pollAccountLoaded != null) { - result = copyPollAccount(pollAccountLoaded); - } + if (withUserAccount) { - if (log.isDebugEnabled()) { - String account = - result == null - ? "null" - : result.getVotingId() + " [" + result.getAccountId() + "]"; + if (poll.isPollFree()) { - log.debug(String.format( - "PollAccount found from user '%s' = %s", - userAccount.getDisplayName(), account - )); + // try to find pollAccount from the list of voters + try { + pollAccountLoaded = + dao.getVoterPollAccountByUserAccount( + poll.getPollId(), userAccount); + } catch (TopiaException e) { + throw new PollenTechnicalException(e); + } + } else { + + // try to find pollAccount from the list of participants + try { + + pollAccountLoaded = + dao.getRestrictedPollAccountByEmail( + poll.getPollId(), userAccount.getEmail()); + } catch (TopiaException e) { + throw new PollenTechnicalException(e); + } } } + } - if (result == null) { - result = getNewPollAccount(userAccount); + PollAccount result = null; + + if (pollAccountLoaded != null) { + + // copy the loaded pollAccount + result = copyPollAccount(pollAccountLoaded); + + // Don't remove or update userAccount link if already set + if (withUserAccount && result.getUserAccount() == null) { + + // link pollAccount to his userAccount + result.setUserAccount(userAccount); } } + + if (result == null && withUserAccount) { + + // create a new pollAccount linked to given userAccount + result = getNewPollAccount(userAccount); + } return result; } @@ -517,6 +536,8 @@ result.setChoiceType(configuration.getDefaultChoiceType()); result.setVoteCountingType(configuration.getDefaultVoteCountingType()); result.setPollType(configuration.getDefaultPollType()); + result.setPollVoteVisibility(configuration.getDefaultPollVoteVisibility()); + result.setPollCommentVisibility(configuration.getDefaultPollCommentVisibility()); // Initialize creator of the poll PollAccountDAO pollAccountDAO = getDAO(PollAccount.class); Modified: trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollVoteCountingService.java =================================================================== --- trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollVoteCountingService.java 2012-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollVoteCountingService.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -43,7 +43,7 @@ * New Poll vote counting service. * * @author tchemit <chemit@codelutin.com> - * @since 1.5 + * @since 1.4.5 */ public class PollVoteCountingService extends PollenServiceSupport { 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-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/SecurityService.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -23,22 +23,21 @@ package org.chorem.pollen.services.impl; import com.google.common.base.Preconditions; -import com.google.common.collect.Sets; import org.apache.commons.lang3.StringUtils; import org.chorem.pollen.PollenTechnicalException; +import org.chorem.pollen.PollenUserSecurityContext; import org.chorem.pollen.bean.PollUri; -import org.chorem.pollen.bean.PollUrl; import org.chorem.pollen.business.persistence.Comment; 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.nuiton.topia.TopiaException; import java.util.Date; +import java.util.EnumSet; import java.util.Set; import static org.nuiton.i18n.I18n.n_; @@ -51,114 +50,93 @@ */ public class SecurityService extends PollenServiceSupport { - public boolean isPollAdmin(Poll poll, UserAccount pollenUserAccount) { - boolean result = pollenUserAccount != null && pollenUserAccount.isAdministrator() || - isPollCreator(poll, null, pollenUserAccount); - return result; - } + /** + * Obtain all user roles for the given {@code poll} using the optional + * {@code accountId} if one is given by url or optional {@code userAccount} + * if user is connected. + * + * @param poll the poll on which finding roles + * @param accountId the optional accountId to get back user + * @param userAccount the optional user account if user is connected + * @since 1.4.5 + */ + public Set<PollenUserSecurityContext.PollenUserSecurityRole> getUserRoles(Poll poll, + String accountId, + UserAccount userAccount) { - public boolean isPollCreator(Poll poll, String accountId, - UserAccount pollenUserAccount) { + Preconditions.checkNotNull(poll); - PollAccount creator = poll.getCreator(); + String pollId = poll.getPollId(); - boolean result = creator.getAccountId().equals(accountId); - if (!result) { + PollAccountDAO dao = getDAO(PollAccount.class); - if (pollenUserAccount != null) { + EnumSet<PollenUserSecurityContext.PollenUserSecurityRole> result = EnumSet.noneOf(PollenUserSecurityContext.PollenUserSecurityRole.class); - // try to match userAccount - result = pollenUserAccount.equals(creator.getUserAccount()); - } - } - return result; - } + if (StringUtils.isNotBlank(accountId)) { - public boolean isCanClosePoll(Poll poll, AccountIdRole accountIdRole) { + // there is a accountId + if (accountId.equals(poll.getCreator().getAccountId())) { - boolean result = !poll.isClosed(); + // user is creator of poll + result.add(PollenUserSecurityContext.PollenUserSecurityRole.CREATOR); + } - if (result) { + PollUri pollUri = PollUri.newPollUri(pollId, accountId); - // poll can be closed, check user can do action - result = accountIdRole == AccountIdRole.CREATOR; - } + if (poll.isPollFree()) { - return result; - } + // free poll, can only find a existing voter of this poll - public void removeAccountIdWhenConnected(PollUrl url, - UserAccount userAccount) { - if (userAccount != null) { + boolean found = isVoterAccountId(dao, pollUri); - // remove accountId from url - url.getPollUri().setAccountId(null); - } - } + if (found) { - /** - * To define meaning of a accountId. - * - * @author tchemit <chemit@codelutin.com> - * @since 1.4 - */ - public enum AccountIdRole { + // account is a voter + result.add(PollenUserSecurityContext.PollenUserSecurityRole.VOTER); + } + } else { - /** - * Creator of the poll. - * <p/> - * This role can access to everything, but can not vote. - */ - CREATOR, - /** A user that has voted on a poll. */ - VOTER, - /** - * A user that was invited to a restricted poll. - * <p/> - * It might have alreay voted or not. - */ - RESTRICTED_VOTER, - /** When accountId does not exists for a poll. */ - UNDEFINED - } + boolean found = isRestrictAccountId(dao, pollUri); - public static final Set<AccountIdRole> NONE_FREE_ACCOUNT_ID_ROLES = Sets.newHashSet( - AccountIdRole.RESTRICTED_VOTER, - AccountIdRole.CREATOR - ); + if (found) { - public AccountIdRole getAccountIdRole(Poll poll, String accountId) { + // account is a participant + result.add(PollenUserSecurityContext.PollenUserSecurityRole.RESTRICTED_VOTER); + } + } + } - Preconditions.checkNotNull(poll); + if (userAccount != null) { - AccountIdRole result = AccountIdRole.UNDEFINED; + if (userAccount.isAdministrator()) { - if (StringUtils.isNotBlank(accountId)) { + // user is adminstrator of Pollen, so can acts as creator of poll + result.add(PollenUserSecurityContext.PollenUserSecurityRole.CREATOR); + } - if (accountId.equals(poll.getCreator().getAccountId())) { + if (poll.isPollFree()) { - result = AccountIdRole.CREATOR; - } else { + if (!result.contains(PollenUserSecurityContext.PollenUserSecurityRole.VOTER)) { - PollAccountDAO dao = getDAO(PollAccount.class); + // try to find an existing voter from the userAccount + boolean found = isVoterAccountId(dao, pollId, userAccount); + if (found) { - PollUri pollUri = PollUri.newPollUri(poll.getPollId(), accountId); + // account is a voter + result.add(PollenUserSecurityContext.PollenUserSecurityRole.VOTER); + } - if (poll.getPollType() == PollType.FREE) { + } + } else { - // + if (!result.contains(PollenUserSecurityContext.PollenUserSecurityRole.RESTRICTED_VOTER)) { - boolean found = isVoterAccountId(dao, pollUri); - + // try to find an existing voter from the userAccount + boolean found = isRestrictAccountId(dao, pollId, userAccount); if (found) { - result = AccountIdRole.VOTER; - } - } else { - boolean found = isRestrictPollAccountId(dao, pollUri); - - if (found) { - result = AccountIdRole.RESTRICTED_VOTER; + // account is a voter + result.add(PollenUserSecurityContext.PollenUserSecurityRole.RESTRICTED_VOTER); } } } @@ -166,22 +144,16 @@ return result; } - public boolean isCanAccessResult(Poll poll, - String accountId, - SecurityService.AccountIdRole accountIdRole, - UserAccount userAccount) { + public boolean isCanAccessResult(PollenUserSecurityContext securityContext) { - if (isPollCreator(poll, accountId, userAccount)) { - accountIdRole = AccountIdRole.CREATOR; - } - - String errorMessage = isCanAccessResult(poll, accountIdRole); + String errorMessage = checkAccessResult(securityContext); return errorMessage == null; } - public String isCanAccessResult(Poll poll, - SecurityService.AccountIdRole accountIdRole) { + public String checkAccessResult(PollenUserSecurityContext securityContext) { + Poll poll = securityContext.getPoll(); + // check now poll results can be displayed boolean publicResults = poll.isPublicResults(); @@ -193,59 +165,33 @@ return n_("pollen.security.error.poll.not.closed.and.results.not.continuous"); } - if (!publicResults && - accountIdRole != SecurityService.AccountIdRole.CREATOR) { + if (!publicResults) { // 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; } - public String isCanAccessResult(Poll poll) { + public boolean isCanAccessVote(PollenUserSecurityContext securityContext) { - // check now poll results can be displayed + return checkCanAccessVote(securityContext) == null; + } - boolean publicResults = poll.isPublicResults(); - boolean continuousResults = poll.isContinuousResults(); + public String checkCanAccessVote(PollenUserSecurityContext securityContext) { - if (!continuousResults && !poll.isClosed()) { + Poll poll = securityContext.getPoll(); - // results are not continuous and poll is not closed - return n_("pollen.security.error.poll.not.closed.and.results.not.continuous"); - } + String accountId = securityContext.getAccountId(); - if (!publicResults) { + if (securityContext.isCreator()) { - // poll results are private, only poll admin can see results - return n_("pollen.security.error.poll.result.private.and.access.not.granted"); - } - - return null; - } - - public String isCanAccessVote(Poll poll, - String accountId, - AccountIdRole accountIdRole, - UserAccount userAccount) { - - if (AccountIdRole.CREATOR == accountIdRole) { - // poll admin can always access vote page return null; } - if (userAccount != null && userAccount.isAdministrator()) { + if (securityContext.isAdmin()) { // pollen admin can always access vote page return null; } @@ -257,14 +203,14 @@ return null; } - boolean pollIsFree = PollType.FREE == poll.getPollType(); + boolean pollIsFree = poll.isPollFree(); if (pollIsFree && poll.getCreator().getAccountId().equals(accountId)) { // on free poll, only the creator (using his creatorId as accountId) can not vote return n_("pollen.security.error.poll.free.creatorId.can.not.vote"); } - if (!pollIsFree && AccountIdRole.RESTRICTED_VOTER != accountIdRole) { + if (!pollIsFree && !securityContext.isRestrictedVoter()) { // on none free poll, only restricted user can vote return n_("pollen.security.error.poll.not.free.and.access.not.granted"); @@ -272,11 +218,12 @@ return null; } - public boolean isCanVote(Poll poll, - String accountId, - AccountIdRole accountIdRole, - UserAccount userAccount) { + public boolean isCanVote(PollenUserSecurityContext securityContext) { + Poll poll = securityContext.getPoll(); + String accountId = securityContext.getAccountId(); + UserAccount userAccount = securityContext.getUserAccount(); + Date now = serviceContext.getCurrentTime(); if (!poll.isRunning(now)) { @@ -285,14 +232,14 @@ return false; } - boolean pollIsFree = PollType.FREE == poll.getPollType(); + boolean pollIsFree = poll.isPollFree(); if (pollIsFree && poll.getCreator().getAccountId().equals(accountId)) { // on free poll, only the creator (using his creatorId as accountId) can not vote return false; } - if (!pollIsFree && AccountIdRole.RESTRICTED_VOTER != accountIdRole) { + if (!pollIsFree && !securityContext.isRestrictedVoter()) { // on none free poll, only restricted user can vote @@ -301,7 +248,8 @@ // try to find restricted user by user account PollAccountDAO dao = getDAO(PollAccount.class); - boolean restrictPollAccountId = isRestrictPollAccountId(dao, poll.getPollId(), userAccount); + boolean restrictPollAccountId = isRestrictAccountId( + dao, poll.getPollId(), userAccount); if (restrictPollAccountId) { @@ -317,10 +265,14 @@ return true; } - public boolean isCanModifyVote(Poll poll, String voteId, - String accountId, - UserAccount userConnected) { + public boolean isCanModifyVote(PollenUserSecurityContext securityContext, + String voteId) { + Poll poll = securityContext.getPoll(); + + String accountId = securityContext.getAccountId(); + UserAccount userConnected = securityContext.getUserAccount(); + Date now = serviceContext.getCurrentTime(); if (!poll.isRunning(now)) { @@ -364,12 +316,45 @@ return false; } - public boolean isCanDeleteVote(Poll poll, - String voteId, - String accountId, - AccountIdRole accountIdRole, - UserAccount userConnected) { + public boolean isCanDeleteComment(PollenUserSecurityContext securityContext, + Comment comment) { + String accountId = securityContext.getAccountId(); + UserAccount userAccount = securityContext.getUserAccount(); + + + if (securityContext.isCreator()) { + + // poll admin can always delete comments + return true; + } + + PollAccount commentAccount = comment.getPollAccount(); + + if (commentAccount.getAccountId().equals(accountId)) { + + // owner of comment (linked by accountId) can delete his comment + return true; + } + + if (userAccount != null) { + + if (userAccount.equals(commentAccount.getUserAccount())) { + // owner of comment (linked by userAccount) can delete his comment + return true; + } + } + return false; + } + + public boolean isCanDeleteVote(PollenUserSecurityContext securityContext, + String voteId) { + + Poll poll = securityContext.getPoll(); + + String accountId = securityContext.getAccountId(); + UserAccount userConnected = securityContext.getUserAccount(); + Date now = serviceContext.getCurrentTime(); if (!poll.isRunning(now)) { @@ -393,7 +378,7 @@ return false; } - if (accountIdRole == AccountIdRole.CREATOR) { + if (securityContext.isCreator()) { // poll admin can delete any vote return true; @@ -420,39 +405,27 @@ return false; } - public boolean isCanDeleteComment(Comment comment, - String accountId, - AccountIdRole accountIdRole, - UserAccount userAccount) { + public boolean isCanClosePoll(PollenUserSecurityContext securityContext) { - if (accountIdRole == AccountIdRole.CREATOR) { + Poll poll = securityContext.getPoll(); - // poll admin can always delete comments - return true; - } + boolean result = !poll.isClosed(); - PollAccount commentAccount = comment.getPollAccount(); + if (result) { - if (commentAccount.getAccountId().equals(accountId)) { - - // owner of comment (linked by accountId) can delete his comment - return true; + // poll can be closed, check user can do action + result = securityContext.isCreator(); } - if (userAccount != null) { - - if (userAccount.equals(commentAccount.getUserAccount())) { - // owner of comment (linked by userAccount) can delete his comment - return true; - } - } - return false; + return result; } private boolean isVoterAccountId(PollAccountDAO dao, PollUri uri) { try { - return dao.existsByPollVoteAccountId(uri.getPollId(), uri.getAccountId()); + PollAccount pollAccount = dao.getVoterPollAccountByAccountId( + uri.getPollId(), uri.getAccountId()); + return pollAccount != null; } catch (TopiaException e) { throw new PollenTechnicalException( @@ -461,11 +434,27 @@ } } - private boolean isRestrictPollAccountId(PollAccountDAO dao, PollUri uri) { + private boolean isVoterAccountId(PollAccountDAO dao, String pollId, + UserAccount userAccount) { try { + PollAccount pollAccount = dao.getVoterPollAccountByUserAccount( + pollId, userAccount); + return pollAccount != null; + + } catch (TopiaException e) { + throw new PollenTechnicalException( + "Could not check pollAccount existence from poll '" + + pollId + "' and userAccount '" + userAccount + "'", e); + } + } + + private boolean isRestrictAccountId(PollAccountDAO dao, PollUri uri) { + try { + PollAccount result = - dao.getRestrictedPollAccount(uri.getPollId(), uri.getAccountId()); + dao.getRestrictedPollAccountByAccountId(uri.getPollId(), + uri.getAccountId()); return result != null; @@ -476,11 +465,13 @@ } } - private boolean isRestrictPollAccountId(PollAccountDAO dao, String pollId, UserAccount userAccount) { + private boolean isRestrictAccountId(PollAccountDAO dao, + String pollId, + UserAccount userAccount) { try { PollAccount result = - dao.getRestrictedPollAccount(pollId, userAccount); + dao.getRestrictedPollAccountByEmail(pollId, userAccount.getEmail()); return result != null; @@ -490,104 +481,376 @@ pollId + "' and account '" + userAccount.getEmail() + "'", e); } } -// /** -// * 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) { + +// public void removeAccountIdWhenConnected(PollUrl url, +// UserAccount userAccount) { +// if (userAccount != null) { // +// // remove accountId from url +// url.getPollUri().setAccountId(null); +// } +// } +// +// public static final Set<PollenUserSecurityRole> NONE_FREE_ACCOUNT_ID_ROLES = Sets.newHashSet( +// PollenUserSecurityRole.RESTRICTED_VOTER, +// PollenUserSecurityRole.CREATOR +// ); +// +// public boolean isPollAdmin(Poll poll, UserAccount pollenUserAccount) { +// boolean result = pollenUserAccount != null && pollenUserAccount.isAdministrator() || +// isPollCreator(poll, null, pollenUserAccount); +// return result; +// } +// +// public boolean isPollCreator(Poll poll, String accountId, +// UserAccount pollenUserAccount) { +// +// PollAccount creator = poll.getCreator(); +// +// boolean result = creator.getAccountId().equals(accountId); +// if (!result) { +// +// if (pollenUserAccount != null) { +// +// // try to match userAccount +// result = pollenUserAccount.equals(creator.getUserAccount()); +// } +// } +// return result; +// } +// +// public boolean isCanClosePoll(Poll poll, PollenUserSecurityRole accountIdRole) { +// +// boolean result = !poll.isClosed(); +// +// if (result) { +// +// // poll can be closed, check user can do action +// result = accountIdRole == PollenUserSecurityRole.CREATOR; +// } +// +// return result; +// } +// +// public PollenUserSecurityRole getAccountIdRole(Poll poll, String accountId) { +// // Preconditions.checkNotNull(poll); -// Preconditions.checkNotNull(accountEditable); // -// Date now = serviceContext.getCurrentTime(); +// PollenUserSecurityRole result = PollenUserSecurityRole.UNDEFINED; // -// boolean result; -// if (poll.getCreator().equals(accountEditable)) { +// if (StringUtils.isNotBlank(accountId)) { // -// // The creator user can't vote -// result = false; -// } else { +// if (accountId.equals(poll.getCreator().getAccountId())) { // -// // The poll must be running and account allowed for restricted poll -// result = poll.isRunning(now); -// if (poll.getPollType() != PollType.FREE) { +// result = PollenUserSecurityRole.CREATOR; +// } else { // -// PersonToListDAO dao = getDAO(PersonToList.class); -// PersonToList personToList = -// dao.findByPollAndAccount(poll, accountEditable); +// PollAccountDAO dao = getDAO(PollAccount.class); // -// result &= personToList != null; +// PollUri pollUri = PollUri.newPollUri(poll.getPollId(), accountId); +// +// if (poll.getPollType() == PollType.FREE) { +// +// // +// +// boolean found = isVoterAccountId(dao, pollUri); +// +// if (found) { +// result = PollenUserSecurityRole.VOTER; +// } +// } else { +// +// boolean found = isRestrictAccountId(dao, pollUri); +// +// if (found) { +// result = PollenUserSecurityRole.RESTRICTED_VOTER; +// } +// } // } // } // return result; // } -// public boolean isUpdateAllowed(Poll poll, String voteId, -// String accountId, UserAccount userConnected) { +// public boolean isCanAccessResult(Poll poll, +// String accountId, +// SecurityService.PollenUserSecurityRole accountIdRole, +// UserAccount userAccount) { // +// if (isPollCreator(poll, accountId, userAccount)) { +// accountIdRole = PollenUserSecurityRole.CREATOR; +// } +// +// String errorMessage = isCanAccessResult(poll, accountIdRole); +// return errorMessage == null; +// } +// +// public String isCanAccessResult(Poll poll, +// SecurityService.PollenUserSecurityRole 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.PollenUserSecurityRole.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; +// } +// +// public String isCanAccessResult(Poll poll) { +// +// // 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) { +// +// // poll results are private, only poll admin can see results +// return n_("pollen.security.error.poll.result.private.and.access.not.granted"); +// } +// +// return null; +// } + +// public String isCanAccessVote(Poll poll, +// String accountId, +// PollenUserSecurityRole accountIdRole, +// UserAccount userAccount) { +// +// if (PollenUserSecurityRole.CREATOR == accountIdRole) { +// +// // poll admin can always access vote page +// return null; +// } +// +// if (userAccount != null && userAccount.isAdministrator()) { +// // pollen admin can always access vote page +// return null; +// } +// +// if (poll.isPublicResults()) { +// +// // with public results, everybody can access to vote page (but +// // can not vote for a non free poll) +// return null; +// } +// +// boolean pollIsFree = PollType.FREE == poll.getPollType(); +// +// if (pollIsFree && poll.getCreator().getAccountId().equals(accountId)) { +// +// // on free poll, only the creator (using his creatorId as accountId) can not vote +// return n_("pollen.security.error.poll.free.creatorId.can.not.vote"); +// } +// if (!pollIsFree && PollenUserSecurityRole.RESTRICTED_VOTER != accountIdRole) { +// +// // on none free poll, only restricted user can vote +// return n_("pollen.security.error.poll.not.free.and.access.not.granted"); +// } +// return null; +// } + +// public boolean isCanVote(Poll poll, +// String accountId, +// PollenUserSecurityRole accountIdRole, +// UserAccount userAccount) { +// // Date now = serviceContext.getCurrentTime(); // -// boolean result = false; +// if (!poll.isRunning(now)) { // +// // poll is not running, can not vote +// return false; +// } +// +// boolean pollIsFree = poll.isPollFree(); +// +// if (pollIsFree && poll.getCreator().getAccountId().equals(accountId)) { +// +// // on free poll, only the creator (using his creatorId as accountId) can not vote +// return false; +// } +// if (!pollIsFree && PollenUserSecurityRole.RESTRICTED_VOTER != accountIdRole) { +// +// // on none free poll, only restricted user can vote +// +// if (userAccount != null) { +// +// // try to find restricted user by user account +// PollAccountDAO dao = getDAO(PollAccount.class); +// +// boolean restrictPollAccountId = isRestrictAccountId(dao, poll.getPollId(), userAccount); +// +// if (restrictPollAccountId) { +// +// // ok admin is also restricted user of this poll +// return true; +// } +// +// } +// return false; +// } +// +// // ok can vote +// return true; +// } + +// public boolean isCanModifyVote(Poll poll, String voteId, +// String accountId, +// UserAccount userConnected) { +// +// Date now = serviceContext.getCurrentTime(); +// +// if (!poll.isRunning(now)) { +// +// // poll is not running can not modify anything +// return false; +// } +// +// if (poll.isAnonymous()) { +// +// // poll is anonymous, no vote can be modify +// return 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(); +// if (vote == null) { // -// // si le votant du vote correspond au votant actuel (pollAccountId) -// if (accountId != null -// && accountId.equals(votePollAccount.getAccountId())) { -// result = true; +// // vote not found, can not modify it +// return false; +// } +// +// PollAccount votePollAccount = vote.getPollAccount(); +// +// if (votePollAccount.getAccountId().equals(accountId)) { +// +// // accountId is voteAccountId, can modifiy the vote +// return true; +// } +// +// if (userConnected != null) { +// +// if (userConnected.equals(votePollAccount.getUserAccount())) { +// +// // user conntected is the voter +// return true; // } +// } // -// // si l'utilisateur du vote correspond à l'utilisateur actuel (user) -// if (userConnected != null) { -// UserAccount voteUserAccount = votePollAccount.getUserAccount(); -// result = userConnected.equals(voteUserAccount); +// // can not modify vote in other cases +// return false; +// } + +// public boolean isCanDeleteVote(Poll poll, +// String voteId, +// String accountId, +// PollenUserSecurityRole accountIdRole, +// UserAccount userConnected) { +// +// Date now = serviceContext.getCurrentTime(); +// +// if (!poll.isRunning(now)) { +// +// // poll is not running can not remove anything +// return false; +// } +// +// if (poll.isAnonymous()) { +// +// // poll is anonymous, no vote can be delete (?) FIXME Check this +// return false; +// } +// +// +// Vote vote = poll.getVoteByTopiaId(voteId); +// +// if (vote == null) { +// +// // vote not found, can not delete it +// return false; +// } +// +// if (accountIdRole == PollenUserSecurityRole.CREATOR) { +// +// // poll admin can delete any vote +// return true; +// } +// +// PollAccount votePollAccount = vote.getPollAccount(); +// +// if (votePollAccount.getAccountId().equals(accountId)) { +// +// // owner of vote (linked by accountId) can delete his own vote +// return true; +// } +// +// if (userConnected != null) { +// +// if (userConnected.equals(votePollAccount.getUserAccount())) { +// +// // owner of vote (linked by userAccount) can delete his own vote +// return true; // } // } -// return result; +// +// // can not modify vote in other cases +// return false; // } // public boolean isCanDeleteComment(Comment comment, -// PollAccount pollAccount, -// UserAccount userAccount, -// boolean isPollCreator) { +// String accountId, +// PollenUserSecurityRole accountIdRole, +// UserAccount userAccount) { // -// boolean result = false; +// if (accountIdRole == PollenUserSecurityRole.CREATOR) { // +// // poll admin can always delete comments +// return true; +// } +// // PollAccount commentAccount = comment.getPollAccount(); // -// if (isPollCreator) { +// if (commentAccount.getAccountId().equals(accountId)) { // -// // poll creator has admin rights on his poll -// result = true; -// } else if (userAccount != null) { +// // owner of comment (linked by accountId) can delete his comment +// return true; +// } // -// // loggued -// boolean isAdmin = userAccount.isAdministrator(); -//// boolean isCommentAccount = userAccount.equals(commentAccount.getUserAccount()); +// if (userAccount != null) { // -// // 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); +// if (userAccount.equals(commentAccount.getUserAccount())) { +// // owner of comment (linked by userAccount) can delete his comment +// return true; +// } // } -// return result; +// return false; // } - } 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-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/VoteService.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -132,7 +132,7 @@ } // Retrieve weight for Restricted Poll with existing account - if (poll.getPollType() != PollType.FREE && accountEditable.getTopiaId() != null) { + if (!poll.isPollFree()&& accountEditable.getTopiaId() != null) { PersonToListDAO personToListDAO = getDAO(PersonToList.class); PersonToList personToList = personToListDAO.findByPollAndAccount(poll, accountEditable); result.setWeight(personToList.getWeight()); @@ -200,7 +200,7 @@ pollToUpdate.addVote(result); // Update hasVoted flag for RESTRICTED/GROUP poll - if (PollType.FREE != poll.getPollType()) { + if (!poll.isPollFree()) { PersonToList personToList = pollToUpdate.getPersonToListByVote(result); personToList.setHasVoted(true); @@ -322,7 +322,7 @@ PollAccount voteAccount = entityToDelete.getPollAccount(); - if (PollType.FREE == poll.getPollType()) { + if (poll.isPollFree()) { // Delete vote PollAccount if the Poll is free and account is not the creator if (!voteAccount.equals(poll.getCreator())) { Modified: trunk/pollen-services/src/main/resources/META-INF/services/org.nuiton.topia.migration.TopiaMigrationCallbackByClassNG$MigrationCallBackForVersion =================================================================== --- trunk/pollen-services/src/main/resources/META-INF/services/org.nuiton.topia.migration.TopiaMigrationCallbackByClassNG$MigrationCallBackForVersion 2012-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-services/src/main/resources/META-INF/services/org.nuiton.topia.migration.TopiaMigrationCallbackByClassNG$MigrationCallBackForVersion 2012-08-12 11:45:39 UTC (rev 3595) @@ -2,4 +2,5 @@ org.chorem.pollen.entities.migration.PollenMigrationCallbackV1_2 org.chorem.pollen.entities.migration.PollenMigrationCallbackV1_3 org.chorem.pollen.entities.migration.PollenMigrationCallbackV1_3_1 -org.chorem.pollen.entities.migration.PollenMigrationCallbackV1_4 \ No newline at end of file +org.chorem.pollen.entities.migration.PollenMigrationCallbackV1_4 +org.chorem.pollen.entities.migration.PollenMigrationCallbackV1_4_5 \ No newline at end of file Modified: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/PollenUIUtils.java =================================================================== --- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/PollenUIUtils.java 2012-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/PollenUIUtils.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -22,8 +22,8 @@ */ package org.chorem.pollen.ui; +import org.chorem.pollen.PollenUserSecurityContext; import org.chorem.pollen.business.persistence.Poll; -import org.chorem.pollen.services.impl.SecurityService; import javax.servlet.ServletContext; import javax.servlet.ServletRequest; @@ -42,8 +42,10 @@ /** Keep the servlet context */ private static ServletContext servletContext; - private static final String ACCOUNT_ID_ROLE = "accountIdRole"; + private static final String POLLEN_USER_SECURITY_CONTEXT = "pollenUserSecurityContext"; +// private static final String ACCOUNT_ID_ROLE = "accountIdRole"; + public static ServletContext getServletContext() { return servletContext; } @@ -52,17 +54,23 @@ PollenUIUtils.servletContext = servletContext; } - public static void setAccountIdRole(ServletRequest request, - SecurityService.AccountIdRole accountIdRole) { - request.setAttribute(ACCOUNT_ID_ROLE, accountIdRole); + public static void setUserSecuritycontext(ServletRequest request, + PollenUserSecurityContext userRoles) { + request.setAttribute(POLLEN_USER_SECURITY_CONTEXT, userRoles); } - public static SecurityService.AccountIdRole getAccountIdRole(ServletRequest request) { - SecurityService.AccountIdRole result = (SecurityService.AccountIdRole) - request.getAttribute(ACCOUNT_ID_ROLE); + public static PollenUserSecurityContext getUserSecuritycontext(ServletRequest request) { + PollenUserSecurityContext result = (PollenUserSecurityContext) + request.getAttribute(POLLEN_USER_SECURITY_CONTEXT); return result; } +// public static SecurityService.PollenUserSecurityRole getAccountIdRole(ServletRequest request) { +// SecurityService.PollenUserSecurityRole result = (SecurityService.PollenUserSecurityRole) +// request.getAttribute(ACCOUNT_ID_ROLE); +// return result; +// } + public static String getVoteSizeMessage(Poll poll, Locale locale) { int i = poll.sizeVote(); Modified: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/PollenActionSupport.java =================================================================== --- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/PollenActionSupport.java 2012-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/PollenActionSupport.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -29,6 +29,8 @@ import org.apache.struts2.StrutsStatics; import org.chorem.pollen.PollenApplicationContext; import org.chorem.pollen.PollenConfiguration; +import org.chorem.pollen.PollenUserSecurityContext; +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.DefaultPollenServiceContext; @@ -392,4 +394,21 @@ } return securityService; } + + protected PollenUserSecurityContext newSecurityContext(String pollId, + String accountId, + Poll poll) { + return newSecurityContext(PollUri.newPollUri(pollId, accountId), poll); + } + + protected PollenUserSecurityContext newSecurityContext(PollUri pollUri, + Poll poll) { + PollenUserSecurityContext securityConext = PollenUserSecurityContext.newContext( + getPollenUserAccount(), pollUri + ); + if (poll != null) { + securityConext.setPoll(poll); + } + return securityConext; + } } Modified: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/PollenActionSupportForEdition.java =================================================================== --- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/PollenActionSupportForEdition.java 2012-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/PollenActionSupportForEdition.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -26,7 +26,7 @@ * Abase support action with predefine edition skin. * * @author tchemit <chemit@codelutin.com> - * @since 1.5 + * @since 1.4.5 */ public class PollenActionSupportForEdition extends PollenActionSupport { Modified: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/PollenActionSupportForVote.java =================================================================== --- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/PollenActionSupportForVote.java 2012-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/PollenActionSupportForVote.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -26,7 +26,7 @@ * Abase support action with predefine vote skin. * * @author tchemit <chemit@codelutin.com> - * @since 1.5 + * @since 1.4.5 */ public class PollenActionSupportForVote extends PollenActionSupport { 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-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/json/GetCreatedPolls.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -23,6 +23,7 @@ package org.chorem.pollen.ui.actions.json; import com.google.common.collect.Sets; +import org.chorem.pollen.PollenUserSecurityContext; import org.chorem.pollen.business.persistence.Poll; import org.chorem.pollen.entities.PollenBinderHelper; import org.chorem.pollen.services.impl.PollService; @@ -82,6 +83,7 @@ Binder<Poll, Poll> binder = PollenBinderHelper.getSimpleTopiaBinder(Poll.class); int index = 0; + for (Poll poll : pollList) { Map<String, Object> map = pollService.pollToMap(poll, binder); @@ -98,20 +100,24 @@ protected Set<String> getPollFunctions(Poll poll) { Set<String> result = Sets.newHashSet(); + PollenUserSecurityContext securityConext = newSecurityContext( + poll.getPollId(), null, poll + ); SecurityService securityService = getSecurityService(); - String canAccessResult = - securityService.isCanAccessResult(poll); + securityConext.loadUserRoles(securityService); - if (canAccessResult == null) { + boolean canAccessResult = securityService.isCanAccessResult(securityConext); + if (canAccessResult) { + // only if results are public result.add("result"); } else { result.add("noresult"); } - boolean canVote = securityService.isCanVote(poll, null, null, getPollenUserAccount()); + boolean canVote = securityService.isCanVote(securityConext); if (canVote) { result.add("vote"); @@ -119,10 +125,9 @@ // try to see if can access vote - String canAccessVote = securityService.isCanAccessVote( - poll, null, null, getPollenUserAccount()); + boolean canAccessVote = securityService.isCanAccessVote(securityConext); - if (canAccessVote == null) { + if (canAccessVote) { result.add("accessVote"); } else { @@ -131,7 +136,6 @@ } } - result.add("summary"); return result; } Modified: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/json/GetInvitedPolls.java =================================================================== --- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/json/GetInvitedPolls.java 2012-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/json/GetInvitedPolls.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -24,6 +24,7 @@ import com.google.common.collect.Sets; import org.apache.commons.lang3.tuple.Pair; +import org.chorem.pollen.PollenUserSecurityContext; import org.chorem.pollen.bean.PollUri; import org.chorem.pollen.business.persistence.Poll; import org.chorem.pollen.business.persistence.PollAccount; @@ -84,6 +85,7 @@ Binder<Poll, Poll> binder = PollenBinderHelper.getSimpleTopiaBinder(Poll.class); int index = 0; + for (Pair<Poll, PollAccount> entry : invitedPolls) { Poll poll = entry.getKey(); @@ -97,32 +99,37 @@ map.put("resultId", pollUri.getUri()); map.put("adminId", poll.getAdminId()); - Set<String> functions = getPollFunctions(poll); + Set<String> functions = getPollFunctions(poll, pollUri); map.put("functions", functions); polls[index++] = map; } return SUCCESS; } - protected Set<String> getPollFunctions(Poll poll) { + protected Set<String> getPollFunctions(Poll poll, + PollUri pollUri) { + + PollenUserSecurityContext securityConext = newSecurityContext( + pollUri, poll + ); + SecurityService securityService = getSecurityService(); + + securityConext.loadUserRoles(securityService); + Set<String> result = Sets.newHashSet(); result.add("vote"); - SecurityService securityService = getSecurityService(); + boolean canAccessResult = securityService.isCanAccessResult(securityConext); - String canAccessResult = - securityService.isCanAccessResult(poll); + if (canAccessResult) { - if (canAccessResult == null) { - // only if results are public result.add("result"); } else { result.add("noresult"); } - - boolean canAdminResult = securityService.isPollAdmin( - poll, getPollenUserAccount()); + + boolean canAdminResult = securityConext.isCreator(); if (canAdminResult) { result.add("summary"); } Modified: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/json/GetParticipatedPolls.java =================================================================== --- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/json/GetParticipatedPolls.java 2012-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/json/GetParticipatedPolls.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -24,10 +24,10 @@ import com.google.common.collect.Sets; import org.apache.commons.lang3.tuple.Pair; +import org.chorem.pollen.PollenUserSecurityContext; import org.chorem.pollen.bean.PollUri; import org.chorem.pollen.business.persistence.Poll; import org.chorem.pollen.business.persistence.PollAccount; -import org.chorem.pollen.common.PollType; import org.chorem.pollen.entities.PollenBinderHelper; import org.chorem.pollen.services.impl.PollService; import org.chorem.pollen.services.impl.SecurityService; @@ -85,6 +85,7 @@ Binder<Poll, Poll> binder = PollenBinderHelper.getSimpleTopiaBinder(Poll.class); int index = 0; + for (Pair<Poll, PollAccount> entry : participatedPolls) { Poll poll = entry.getKey(); @@ -98,30 +99,36 @@ map.put("voteId", pollUri.getUri()); // For Free poll, it's not necessary to keep the accountId - String resultId = poll.getPollType() == PollType.FREE + String resultId = poll.isPollFree() ? pollUri.getPollId() : pollUri.getUri(); map.put("resultId", resultId); map.put("adminId", poll.getAdminId()); - Set<String> functions = getPollFunctions(poll); + Set<String> functions = getPollFunctions(poll, pollUri); map.put("functions", functions); polls[index++] = map; } return SUCCESS; } - private Set<String> getPollFunctions(Poll poll) { + private Set<String> getPollFunctions(Poll poll, + PollUri pollUri) { Set<String> result = Sets.newHashSet(); - result.add("vote"); + PollenUserSecurityContext securityConext = newSecurityContext( + pollUri, poll + ); SecurityService securityService = getSecurityService(); - String canAccessResult = - securityService.isCanAccessResult(poll); + securityConext.loadUserRoles(securityService); - if (canAccessResult == null) { + result.add("vote"); + boolean canAccessResult = securityService.isCanAccessResult(securityConext); + + if (canAccessResult) { + // only if results are public result.add("result"); } else { @@ -129,8 +136,7 @@ } - boolean canAdminResult = securityService.isPollAdmin( - poll, getPollenUserAccount()); + boolean canAdminResult = securityConext.isCreator(); if (canAdminResult) { result.add("summary"); } 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-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/json/GetPollComments.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -24,8 +24,9 @@ import com.google.common.base.Preconditions; import com.google.common.collect.Sets; +import org.chorem.pollen.PollenUserSecurityContext; import org.chorem.pollen.business.persistence.Comment; -import org.chorem.pollen.business.persistence.UserAccount; +import org.chorem.pollen.business.persistence.Poll; import org.chorem.pollen.entities.PollenBinderHelper; import org.nuiton.util.beans.Binder; @@ -83,7 +84,10 @@ List<Comment> commentList = getPollCommentService().getComments( pager, pollId); - UserAccount userAccount = getPollenUserAccount(); + //TODO-tchemit-2012-06-03 Should use also pollAccountId (if specified in url)... + Poll poll = getPollService().getExistingPollByPollId(pollId); + PollenUserSecurityContext securityConext = newSecurityContext(pollId, null, poll); + securityConext.loadUserRoles(getSecurityService()); comments = new Map[commentList.size()]; Binder<Comment, Comment> binder = @@ -100,7 +104,7 @@ map.put("id", comment.getTopiaId()); Set<String> functions = getCommentFunctions( comment, - userAccount); + securityConext); map.put("functions", functions); comments[index++] = map; } @@ -108,11 +112,10 @@ } private Set<String> getCommentFunctions(Comment comment, - UserAccount userAccount) { + PollenUserSecurityContext securityContext) { Set<String> result = Sets.newHashSet(); - //TODO-tchemit-2012-06-03 Should use also pollAccountId (if specified in url)... boolean canDelete = getSecurityService().isCanDeleteComment( - comment, null, null, userAccount); + securityContext, comment); 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-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/AbstractPollForm.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -51,6 +51,8 @@ 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.PollCommentVisibility; +import org.chorem.pollen.business.persistence.PollVoteVisibility; import org.chorem.pollen.business.persistence.PreventRule; import org.chorem.pollen.business.persistence.UserAccount; import org.chorem.pollen.business.persistence.VotingList; @@ -115,6 +117,8 @@ private Map<String, String> choiceTypes; + private Map<String, String> pollVoteVisibilities; + /** Text choices. */ private List<Choice> textChoices; @@ -620,6 +624,10 @@ return choiceTypes; } + public Map<String, String> getPollVoteVisibilities() { + return pollVoteVisibilities; + } + public List<Choice> getTextChoices() { return textChoices; } @@ -681,8 +689,7 @@ } public boolean isFreePoll() { - PollType pollType = poll.getPollType(); - return pollType == PollType.FREE; + return poll.isPollFree(); } public boolean isGroupPoll() { @@ -690,6 +697,20 @@ return pollType == PollType.GROUP; } + public boolean isPollCommentVisible() { + PollCommentVisibility pollCommentVisibility = + poll.getPollCommentVisibility(); + return pollCommentVisibility == PollCommentVisibility.EVERYBODY; + } + + public void setPollCommentVisible(boolean newValue) { + if (newValue) { + poll.setPollCommentVisibility(PollCommentVisibility.EVERYBODY); + } else { + poll.setPollCommentVisibility(PollCommentVisibility.NOBODY); + } + } + public String getActionLabel() { return isEdit() ? _("pollen.action.editPoll") : _("pollen.action.createPoll"); @@ -712,7 +733,8 @@ public String getImageChoiceName(Choice choice) { String name = choice.getName(); try { - String result = URLEncoder.encode(IMAGECHOICES_THUMB_PREFIX + name, Charsets.UTF_8.name()); + String result = URLEncoder.encode(IMAGECHOICES_THUMB_PREFIX + name, + Charsets.UTF_8.name()); return result; } catch (UnsupportedEncodingException e) { throw new PollenTechnicalException( @@ -740,6 +762,7 @@ pollTypes = decorateToName(PollType.values()); choiceTypes = decorateToName(ChoiceType.values()); + pollVoteVisibilities = decorateToName(PollVoteVisibility.values()); voteCountingTypes = Maps.newTreeMap(); VoteCountingStrategyProvider strategyProvider = @@ -769,7 +792,8 @@ public Function<VotingList, VotingList> getVotingListCreator() { if (votingListCreator == null) { - votingListCreator = PollenServiceFunctions.newVotingListCreator(getPersontoListCreator()); + votingListCreator = PollenServiceFunctions.newVotingListCreator( + getPersontoListCreator()); } return votingListCreator; } 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-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/AbstractVoteAction.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -30,6 +30,7 @@ import org.apache.struts2.interceptor.ParameterAware; import org.apache.struts2.interceptor.ServletRequestAware; import org.chorem.pollen.PollenTechnicalException; +import org.chorem.pollen.PollenUserSecurityContext; import org.chorem.pollen.bean.PollResult; import org.chorem.pollen.bean.PollResultList; import org.chorem.pollen.bean.PollUrl; @@ -37,6 +38,8 @@ import org.chorem.pollen.business.persistence.Comment; import org.chorem.pollen.business.persistence.Poll; import org.chorem.pollen.business.persistence.PollAccount; +import org.chorem.pollen.business.persistence.PollCommentVisibility; +import org.chorem.pollen.business.persistence.PollVoteVisibility; import org.chorem.pollen.business.persistence.UserAccount; import org.chorem.pollen.business.persistence.Vote; import org.chorem.pollen.business.persistence.VoteToChoice; @@ -44,7 +47,6 @@ import org.chorem.pollen.common.PollType; import org.chorem.pollen.services.exceptions.PollAccountNotFound; import org.chorem.pollen.services.exceptions.PollNotFoundException; -import org.chorem.pollen.services.impl.SecurityService; import org.chorem.pollen.ui.PollenUIUtils; import org.chorem.pollen.ui.actions.PageSkin; import org.chorem.pollen.votecounting.strategy.VoteCountingStrategy; @@ -156,12 +158,19 @@ */ private Map<String, String[]> parameters; +// /** +// * The accountId role on this page. +// * +// * @since 1.4 +// */ +// private SecurityService.PollenUserSecurityRole accountIdRole; + /** - * The accountId role on this page. + * The user security context for this request. * - * @since 1.4 + * @since 1.4.5 */ - private SecurityService.AccountIdRole accountIdRole; + private PollenUserSecurityContext securityContext; /** * The incoming request (some stuff are store in it from security filters). @@ -237,6 +246,19 @@ } /** + * Is comment can be displayed (and then added) on this poll. + * + * @return {@code true} if comments can be displayed and then added or + * removed for this poll. + * @since 1.4.5 + */ + public boolean isCommentAllowed() { + PollCommentVisibility pollCommentVisibility = + getPoll().getPollCommentVisibility(); + return pollCommentVisibility == PollCommentVisibility.EVERYBODY; + } + + /** * Retourne si le choix fait partie du vote (s'il a été renseigné par le * votant). * @@ -308,7 +330,7 @@ public String getResultUrl() { PollUrl url = getPollUrlService().getPollResultUrl(poll); url.getPollUri().setAccountId(getAccountId()); - getSecurityService().removeAccountIdWhenConnected(url, getPollenUserAccount()); + securityContext.removeAccountIdWhenConnected(url); return url.getUrl(); } @@ -334,7 +356,8 @@ } public boolean isAnonymousVote() { - return poll.isAnonymous(); + PollVoteVisibility pollVoteVisibility = poll.getPollVoteVisibility(); + return pollVoteVisibility == PollVoteVisibility.NOBODY; } public boolean isPollChoiceRunning() { @@ -357,7 +380,7 @@ } public boolean isFreePoll() { - return poll.getPollType() == PollType.FREE; + return poll.isPollFree(); } public boolean isRestrictedPoll() { @@ -380,22 +403,6 @@ return poll.getChoiceType() == ChoiceType.IMAGE; } -// public boolean isNormalVoteCounting() { -// return poll.getVoteCountingType() == VoteCountingType.NORMAL; -// } -// -// public boolean isPercentageVoteCounting() { -// return poll.getVoteCountingType() == VoteCountingType.PERCENTAGE; -// } -// -// public boolean isCondorcetVoteCounting() { -// return poll.getVoteCountingType() == VoteCountingType.CONDORCET; -// } -// -// public boolean isNumberVoteCounting() { -// return poll.getVoteCountingType() == VoteCountingType.NUMBER; -// } - public boolean isVoteAllowed() { return voteAllowed; } @@ -405,28 +412,18 @@ } public boolean isModifyVoteAllowed(Vote vote) { - return getSecurityService().isCanModifyVote( - getPoll(), - vote.getTopiaId(), - getAccountId(), - getPollenUserAccount()); + return getSecurityService().isCanModifyVote(securityContext, + vote.getTopiaId()); } public boolean isDeleteCommentAllowed(Comment comment) { - return getSecurityService().isCanDeleteComment( - comment, - getUriId().getAccountId(), - accountIdRole, - getPollenUserAccount()); + return getSecurityService().isCanDeleteComment(securityContext, + comment); } public boolean isDeleteVoteAllowed(Vote vote) { - return getSecurityService().isCanDeleteVote( - getPoll(), - vote.getTopiaId(), - getUriId().getAccountId(), - accountIdRole, - getPollenUserAccount()); + return getSecurityService().isCanDeleteVote(securityContext, + vote.getTopiaId()); } public String getResultValue(Choice choice) { @@ -452,6 +449,8 @@ public String prepareVotePage() throws Exception { + securityContext = PollenUIUtils.getUserSecuritycontext(request); + boolean moderate = isModerate(); loadPoll(); @@ -463,30 +462,24 @@ // TODO no pagination for the moment, need to retrieve the correct page depends on current pollAccount votes = getVoteService().getAllVotes(poll); - accountIdRole = PollenUIUtils.getAccountIdRole(request); - // is vote allowed ? if (moderate) { + + // while moderate vote, no way to vote voteAllowed = false; - } else { - String accountId = getAccountId(); - if (accountIdRole == SecurityService.AccountIdRole.CREATOR) { - // remove accountId (can vote even if creator ?) - accountId = null; - } - voteAllowed = getSecurityService().isCanVote(poll, - accountId, - accountIdRole, - getPollenUserAccount()); + } else { +// String accountId = getAccountId(); +// if (accountIdRole == SecurityService.PollenUserSecurityRole.CREATOR) { +// +// // remove accountId (can vote even if creator ?) +// accountId = null; +// } + voteAllowed = getSecurityService().isCanVote(securityContext); } // is can display result link ? - resultAllowed = - getSecurityService().isCanAccessResult(poll, - getAccountId(), - accountIdRole, - getPollenUserAccount()); + resultAllowed = getSecurityService().isCanAccessResult(securityContext); if (voteAllowed) { @@ -513,10 +506,12 @@ feedFileExisting = getPollFeedService().isFeedExists(poll); - creatorUser = getSecurityService().isPollCreator(poll, - getAccountId(), - getPollenUserAccount()); +// creatorUser = getSecurityService().isPollCreator(poll, +// getAccountId(), +// getPollenUserAccount()); + creatorUser = securityContext.isCreator(); + if (log.isInfoEnabled()) { Date now = serviceContext.getCurrentTime(); log.info("pollChoiceOrVoteStarted = " + isPollChoiceOrVoteStarted()); Modified: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/DeleteVote.java =================================================================== --- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/DeleteVote.java 2012-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/DeleteVote.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -24,7 +24,6 @@ import com.google.common.base.Preconditions; import org.chorem.pollen.business.persistence.Poll; -import org.chorem.pollen.common.PollType; /** * To delete a poll vote. @@ -70,7 +69,7 @@ addFlashMessage(_("pollen.information.vote.deleted")); - if (poll.getPollType() == PollType.FREE && + if (poll.isPollFree() && getUriId().isAccountIdNotBlank() && !poll.getCreator().getAccountId().equals(getAccountId())) { Modified: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/ResultForPoll.java =================================================================== --- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/ResultForPoll.java 2012-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/ResultForPoll.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -32,7 +32,9 @@ import org.apache.commons.collections.CollectionUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.struts2.interceptor.ServletRequestAware; import org.apache.struts2.views.util.UrlHelper; +import org.chorem.pollen.PollenUserSecurityContext; import org.chorem.pollen.bean.PollResult; import org.chorem.pollen.bean.PollResultList; import org.chorem.pollen.bean.PollUrl; @@ -46,6 +48,7 @@ import org.chorem.pollen.votecounting.strategy.VoteCountingStrategy; import org.nuiton.util.StringUtil; +import javax.servlet.http.HttpServletRequest; import java.net.URL; import java.util.Date; import java.util.List; @@ -58,7 +61,7 @@ * @author tchemit <chemit@codelutin.com> * @since 1.3 */ -public class ResultForPoll extends AbstractPollUriIdAction { +public class ResultForPoll extends AbstractPollUriIdAction implements ServletRequestAware { private static final long serialVersionUID = 1L; @@ -131,6 +134,20 @@ @Inject(required = true) private UrlHelper urlHelper; + /** + * The user security context for this request. + * + * @since 1.4.5 + */ + private PollenUserSecurityContext securityContext; + + /** + * The incoming request (some stuff are store in it from security filters). + * + * @since 1.4.5 + */ + private transient HttpServletRequest request; + public ResultForPoll() { super(PageSkin.RESULT); } @@ -178,11 +195,11 @@ public String getVoteUrl() { PollUrl url = getPollUrlService().getPollVoteUrl(poll); url.getPollUri().setAccountId(getAccountId()); - if (poll.getPollType() == PollType.FREE) { + if (poll.isPollFree()) { // can removed accountId only for free poll //FIXME Should found out in ohter case the accountId (if exists for the connected id) if no accountId is given - getSecurityService().removeAccountIdWhenConnected(url, getPollenUserAccount()); + securityContext.removeAccountIdWhenConnected(url); } return url.getUrl(); } @@ -248,10 +265,13 @@ @Override public String execute() throws Exception { + securityContext = PollenUIUtils.getUserSecuritycontext(request); + String pollId = getPollId(); Preconditions.checkNotNull(pollId); - poll = getPollService().getExistingPollByPollId(pollId); +// poll = getPollService().getExistingPollByPollId(pollId); + poll = securityContext.getPoll(); feedFileExisting = getPollFeedService().isFeedExists(poll); @@ -261,10 +281,12 @@ byGroup = isGroupPoll(); } - creatorUser = getSecurityService().isPollCreator( - poll, - getAccountId(), getPollenUserAccount()); + creatorUser = securityContext.isCreator(); +// creatorUser = getSecurityService().isPollCreator( +// poll, +// getAccountId(), getPollenUserAccount()); + if (poll.isRunning(serviceContext.getCurrentTime())) { addFlashWarning(_("pollen.information.pollRunning")); } @@ -314,7 +336,7 @@ } public boolean isFreePoll() { - return poll.getPollType() == PollType.FREE; + return poll.isPollFree(); } public boolean isRestrictedPoll() { @@ -337,23 +359,6 @@ return poll.getChoiceType() == ChoiceType.IMAGE; } - // public boolean isNormalVoteCounting() { -// return poll.getVoteCountingType() == VoteCountingType.NORMAL; -// } -// -// public boolean isPercentageVoteCounting() { -// return poll.getVoteCountingType() == VoteCountingType.PERCENTAGE; -// } -// -// public boolean isCondorcetVoteCounting() { -// return poll.getVoteCountingType() == VoteCountingType.CONDORCET; -// } -// - //FIXME-tchemit-2012-06-24, why doing this ??? Should remove this... -// public boolean isNumberVoteCounting() { -// return poll.getVoteCountingType() == 3; -// } - public boolean isByGroup() { return byGroup; } @@ -432,4 +437,9 @@ List<String> choices = getChoices(); return StringUtil.join(choices, ",", true); } + + @Override + public void setServletRequest(HttpServletRequest request) { + this.request = request; + } } 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-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/SummaryPoll.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -24,10 +24,9 @@ import com.google.common.base.Preconditions; import org.apache.struts2.interceptor.ServletRequestAware; +import org.chorem.pollen.PollenUserSecurityContext; import org.chorem.pollen.bean.PollUrl; 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.PollenUIUtils; import org.chorem.pollen.ui.actions.PageSkin; @@ -51,11 +50,11 @@ private Poll poll; /** - * The accountId role on this page. + * The user security context for this request. * - * @since 1.4 + * @since 1.4.5 */ - private SecurityService.AccountIdRole accountIdRole; + private PollenUserSecurityContext securityContext; /** * The incoming request (some stuff are store in it from security filters). @@ -74,63 +73,63 @@ } public Poll getPoll() { - return poll; + return securityContext.getPoll(); } public String getVoteUrl() { PollUrl url = getPollUrlService().getPollVoteUrl(poll); - if (poll.getPollType() == PollType.FREE) { + if (poll.isPollFree()) { // can removed accountId only for free poll //FIXME Should found out in ohter case the accountId (if exists for the connected id) if no accountId is given - getSecurityService().removeAccountIdWhenConnected(url, getPollenUserAccount()); + securityContext.removeAccountIdWhenConnected(url); } return url.getUrl(); } public String getShowVoteUrl() { PollUrl url = getPollUrlService().getPollVoteUrl(poll); - if (poll.getPollType() == PollType.FREE) { + if (poll.isPollFree()) { // can removed accountId only for free poll //FIXME Should found out in ohter case the accountId (if exists for the connected id) if no accountId is given - getSecurityService().removeAccountIdWhenConnected(url, getPollenUserAccount()); + securityContext.removeAccountIdWhenConnected(url); } return url.getUrl(); } public String getModerateUrl() { PollUrl url = getPollUrlService().getPollModerateUrl(poll); - getSecurityService().removeAccountIdWhenConnected(url, getPollenUserAccount()); + securityContext.removeAccountIdWhenConnected(url); return url.getUrl(); } public String getEditUrl() { PollUrl url = getPollUrlService().getPollEditUrl(poll); - getSecurityService().removeAccountIdWhenConnected(url, getPollenUserAccount()); + securityContext.removeAccountIdWhenConnected(url); return url.getUrl(); } public String getCloneUrl() { PollUrl url = getPollUrlService().getPollCloneUrl(poll); - getSecurityService().removeAccountIdWhenConnected(url, getPollenUserAccount()); + securityContext.removeAccountIdWhenConnected(url); return url.getUrl(); } public String getExportUrl() { PollUrl url = getPollUrlService().getPollExportUrl(poll); - getSecurityService().removeAccountIdWhenConnected(url, getPollenUserAccount()); + securityContext.removeAccountIdWhenConnected(url); return url.getUrl(); } public String getResultUrl() { PollUrl url = getPollUrlService().getPollResultUrl(poll); - getSecurityService().removeAccountIdWhenConnected(url, getPollenUserAccount()); + securityContext.removeAccountIdWhenConnected(url); return url.getUrl(); } public boolean isCanClose() { - return getSecurityService().isCanClosePoll(poll, accountIdRole); + return getSecurityService().isCanClosePoll(securityContext); } public boolean isCanShowVote() { @@ -138,37 +137,35 @@ } public boolean isCanShowResult() { - String errorMessage = getSecurityService().isCanAccessResult( - poll, accountIdRole); - return errorMessage == null; + boolean result = getSecurityService().isCanAccessResult(securityContext); + return result; } public boolean isCanVote() { - String accountId = getAccountId(); - if (accountIdRole == SecurityService.AccountIdRole.CREATOR) { - - if (poll.getPollType() != PollType.FREE) { - - } else { - accountId = null; - } - } - return getSecurityService().isCanVote(poll, - accountId, - accountIdRole, - getPollenUserAccount()); +// String accountId = getAccountId(); +// if (accountIdRole == SecurityService.PollenUserSecurityRole.CREATOR) { +// +// if (poll.getPollType() != PollType.FREE) { +// +// } else { +// accountId = null; +// } +// } + return getSecurityService().isCanVote(securityContext); } @Override public String execute() throws Exception { - Preconditions.checkNotNull(getUriId()); +// Preconditions.checkNotNull(getUriId()); - String pollId = getUriId().getPollId(); +// String pollId = getUriId().getPollId(); - poll = getPollService().getExistingPollByPollId(pollId); + securityContext = PollenUIUtils.getUserSecuritycontext(request); + Preconditions.checkNotNull(securityContext); - accountIdRole = PollenUIUtils.getAccountIdRole(request); +// poll = getPollService().getExistingPollByPollId(pollId); +// poll = securityContext.getPoll(); return SUCCESS; } 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-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/VoteForPoll.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -32,7 +32,6 @@ import org.chorem.pollen.business.persistence.PollAccount; import org.chorem.pollen.business.persistence.Vote; import org.chorem.pollen.business.persistence.VoteToChoice; -import org.chorem.pollen.common.PollType; import org.chorem.pollen.services.impl.VoteService; import org.chorem.pollen.votecounting.strategy.VoteCountingStrategy; @@ -71,7 +70,7 @@ } if (isPollChoiceRunning()) { addFlashMessage(_("pollen.information.pollChoiceRunning")); - } + } if (!isCommentAllowed()) { addFlashMessage(_("pollen.information.pollCommentNotAuthorized")); } } @@ -187,7 +186,7 @@ // For free Poll, display the update Url (useless if user is logged or // not using a modify url) - if (PollType.FREE == poll.getPollType() && + if (poll.isPollFree() && !isUserLoggued() && StringUtils.isBlank(getAccountId())) { Modified: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/user/CreateFavoriteList.java =================================================================== --- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/user/CreateFavoriteList.java 2012-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/user/CreateFavoriteList.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -41,7 +41,7 @@ * To create a new favorite list. * * @author tchemit <chemit@codelutin.com> - * @since 1.5 + * @since 1.4.5 */ public class CreateFavoriteList extends PollenActionSupportForEdition implements FileUploadAware { Modified: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/user/CreateFavoriteListVoter.java =================================================================== --- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/user/CreateFavoriteListVoter.java 2012-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/user/CreateFavoriteListVoter.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -40,7 +40,7 @@ * Creates a new {@link PollAccount} inside a selected {@link PersonList}. * * @author tchemit <chemit@codelutin.com> - * @since 1.5 + * @since 1.4.5 */ public class CreateFavoriteListVoter extends PollenActionSupportForEdition implements Preparable, ParameterAware { Modified: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/user/EditFavoriteList.java =================================================================== --- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/user/EditFavoriteList.java 2012-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/user/EditFavoriteList.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -31,7 +31,7 @@ * Edit a given {@link PersonList}. * * @author tchemit <chemit@codelutin.com> - * @since 1.5 + * @since 1.4.5 */ public class EditFavoriteList extends PollenActionSupportForEdition { Modified: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/user/EditFavoriteListVoter.java =================================================================== --- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/user/EditFavoriteListVoter.java 2012-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/user/EditFavoriteListVoter.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -40,7 +40,7 @@ * Edits a {@link PollAccount} inside a selected {@link PersonList}. * * @author tchemit <chemit@codelutin.com> - * @since 1.5 + * @since 1.4.5 */ public class EditFavoriteListVoter extends PollenActionSupportForEdition implements Preparable, ParameterAware { 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-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/AbstractPollenAuthorization.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -30,6 +30,7 @@ import org.apache.shiro.web.filter.authz.AuthorizationFilter; import org.apache.shiro.web.util.WebUtils; import org.chorem.pollen.PollenApplicationContext; +import org.chorem.pollen.PollenUserSecurityContext; import org.chorem.pollen.bean.PollUri; import org.chorem.pollen.business.persistence.Poll; import org.chorem.pollen.business.persistence.UserAccount; @@ -37,6 +38,7 @@ import org.chorem.pollen.services.PollenServiceContext; import org.chorem.pollen.services.PollenServiceFactory; import org.chorem.pollen.services.impl.PollService; +import org.chorem.pollen.services.impl.SecurityService; import org.chorem.pollen.ui.PollenSession; import org.chorem.pollen.ui.PollenUIUtils; import org.nuiton.topia.TopiaContext; @@ -93,7 +95,38 @@ return servletContext; } - protected PollUri getPollUri(ServletRequest request) { + protected PollenUserSecurityContext createSecurityContext(ServletRequest request) { + + UserAccount userAccount = getPollenUserAccount(request); + PollUri pollUri = getPollUri(request); + PollenUserSecurityContext securityContext = PollenUserSecurityContext.newContext( + userAccount, pollUri + ); + + PollenServiceContext serviceContext = getServiceContext(request); + + SecurityService securityService = + serviceContext.newService(SecurityService.class); + + Poll poll = getPollIdSane(pollUri, serviceContext, request); + + if (poll != null) { + + securityContext.setPoll(poll); + + // load user roles + securityContext.loadUserRoles(securityService); + } + return securityContext; + } + + protected UserAccount getPollenUserAccount(ServletRequest request) { + PollenSession pollenSession = PollenSession.get(request); + + return pollenSession.getUserAccount(); + } + + private PollUri getPollUri(ServletRequest request) { String servletPath = ((HttpServletRequest) request).getServletPath(); Matcher m = URI_PATTERN.matcher(servletPath); @@ -107,16 +140,10 @@ return result; } - protected UserAccount getPollenUserAccount(ServletRequest request) { - PollenSession pollenSession = PollenSession.get(request); + private Poll getPollIdSane(PollUri pollUri, + PollenServiceContext serviceContext, + ServletRequest request) { - return pollenSession.getUserAccount(); - } - - protected Poll getPollIdSane(PollUri pollUri, - PollenServiceContext serviceContext, - ServletRequest request) { - Poll poll = null; String errorMessage = null; if (pollUri == null) { Modified: 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 2012-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/PollCreatorAccessRequired.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -22,11 +22,7 @@ */ 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.SecurityService; +import org.chorem.pollen.PollenUserSecurityContext; import org.chorem.pollen.ui.PollenUIUtils; import javax.servlet.ServletRequest; @@ -42,82 +38,42 @@ */ 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); + PollenUserSecurityContext securityContext = + createSecurityContext(request); - PollUri pollUri = getPollUri(request); + boolean isAccessAllowed = securityContext.isPollExists(); - SecurityService securityService = - serviceContext.newService(SecurityService.class); - - // get sane poll - Poll poll = getPollIdSane(pollUri, serviceContext, request); - - boolean isAccessAllowed = poll != null; - - SecurityService.AccountIdRole accountIdRole = - SecurityService.AccountIdRole.UNDEFINED; - if (isAccessAllowed) { - // pollId is sane (poll exists from it) + // pollId is sane - // test if user is admin - boolean isAdmin = adminFilter.isAccessAllowed(request, - response, - mappedValue); + if (securityContext.isWithAccountId()) { - boolean withAccountId = pollUri.isAccountIdNotBlank(); + // check accountId is sane - if (withAccountId) { + if (securityContext.hasNoRole()) { - // there is a account id, must validate it - accountIdRole = securityService.getAccountIdRole( - poll, pollUri.getAccountId()); - - if (accountIdRole == SecurityService.AccountIdRole.UNDEFINED) { - - // bad account Id + // bad accountId 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 + // accountId is sane // check now that account role is a creator - if (accountIdRole != SecurityService.AccountIdRole.CREATOR) { + if (!securityContext.isCreator()) { // not a creator, access not granted isAccessAllowed = false; @@ -129,8 +85,8 @@ if (isAccessAllowed) { - // store accountIdRole in request - PollenUIUtils.setAccountIdRole(request, accountIdRole); + // store security context in request + PollenUIUtils.setUserSecuritycontext(request, securityContext); } return isAccessAllowed; 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-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/PollResultAccessRequired.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -22,10 +22,7 @@ */ 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.PollenUserSecurityContext; import org.chorem.pollen.services.impl.SecurityService; import org.chorem.pollen.ui.PollenUIUtils; @@ -42,76 +39,33 @@ */ 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); + PollenUserSecurityContext securityContext = + createSecurityContext(request); - PollUri pollUri = getPollUri(request); + boolean isAccessAllowed = securityContext.isPollExists(); - SecurityService securityService = - serviceContext.newService(SecurityService.class); - - // get sane poll - Poll poll = getPollIdSane(pollUri, serviceContext, request); - - boolean isAccessAllowed = poll != null; - - SecurityService.AccountIdRole accountIdRole = null; - if (isAccessAllowed) { // pollId is sane (poll exists from it) - // test if user is admin - boolean isAdmin = adminFilter.isAccessAllowed(request, - response, - mappedValue); + if (securityContext.isWithAccountId()) { - boolean withAccountId = pollUri.isAccountIdNotBlank(); + // check accountId is sane - if (withAccountId) { + if (securityContext.hasNoRole()) { - // there is a account id, must validate it - accountIdRole = securityService.getAccountIdRole( - poll, pollUri.getAccountId()); - - if (accountIdRole == SecurityService.AccountIdRole.UNDEFINED) { - - // bad account Id + // bad accountId isAccessAllowed = false; registerError( request, n_("pollen.security.error.bad.accountId")); } - } else { - - // check if current userAccount is creator - UserAccount userAccount = getPollenUserAccount(request); - - boolean isCreator = securityService.isPollCreator( - poll, - null, - userAccount); - - if (isCreator) { - accountIdRole = SecurityService.AccountIdRole.CREATOR; - } } - - if (isAdmin) { - - // admin user acts as a poll creator - accountIdRole = SecurityService.AccountIdRole.CREATOR; - } } if (isAccessAllowed) { @@ -121,9 +75,11 @@ // check now poll results can be displayed - String errorMessage = securityService.isCanAccessResult( - poll, accountIdRole); + SecurityService securityService = + getServiceContext(request).newService(SecurityService.class); + String errorMessage = securityService.checkAccessResult(securityContext); + if (errorMessage != null) { // can not show results @@ -134,8 +90,8 @@ if (isAccessAllowed) { - // store accountIdRole in request - PollenUIUtils.setAccountIdRole(request, accountIdRole); + // store security context in request + PollenUIUtils.setUserSecuritycontext(request, securityContext); } return isAccessAllowed; } Modified: 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 2012-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/PollVoteAccessRequired.java 2012-08-12 11:45:39 UTC (rev 3595) @@ -22,9 +22,7 @@ */ package org.chorem.pollen.ui.security; -import org.chorem.pollen.bean.PollUri; -import org.chorem.pollen.business.persistence.Poll; -import org.chorem.pollen.services.PollenServiceContext; +import org.chorem.pollen.PollenUserSecurityContext; import org.chorem.pollen.services.impl.SecurityService; import org.chorem.pollen.ui.PollenUIUtils; @@ -41,62 +39,31 @@ */ 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); + PollenUserSecurityContext securityContext = + createSecurityContext(request); - PollUri pollUri = getPollUri(request); + boolean isAccessAllowed = securityContext.isPollExists(); - SecurityService securityService = - serviceContext.newService(SecurityService.class); - - // get sane poll - Poll poll = getPollIdSane(pollUri, serviceContext, request); - - boolean isAccessAllowed = poll != null; - - SecurityService.AccountIdRole accountIdRole = null; - if (isAccessAllowed) { // pollId is sane (poll exists from it) - // test if user is admin - boolean isAdmin = adminFilter.isAccessAllowed(request, - response, - mappedValue); + if (securityContext.isWithAccountId()) { - boolean withAccountId = pollUri.isAccountIdNotBlank(); + // check accountId is sane + if (securityContext.hasNoRole()) { - if (withAccountId) { - - // there is a account id, must validate it - accountIdRole = securityService.getAccountIdRole( - poll, pollUri.getAccountId()); - - if (accountIdRole == SecurityService.AccountIdRole.UNDEFINED) { - - // bad account Id + // bad accountId 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) { @@ -106,9 +73,12 @@ // check now poll votes can be displayed - String errorMessage = securityService.isCanAccessVote( - poll, pollUri.getAccountId(), accountIdRole, null); + SecurityService securityService = + getServiceContext(request).newService(SecurityService.class); + String errorMessage = + securityService.checkCanAccessVote(securityContext); + if (errorMessage != null) { // can not vote @@ -119,8 +89,8 @@ if (isAccessAllowed) { - // store accountIdRole in request - PollenUIUtils.setAccountIdRole(request, accountIdRole); + // store security context in request + PollenUIUtils.setUserSecuritycontext(request, securityContext); } 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-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-ui-struts2/src/main/resources/i18n/pollen-ui-struts2_en_GB.properties 2012-08-12 11:45:39 UTC (rev 3595) @@ -39,6 +39,7 @@ pollen.action.login=Log me In pollen.action.moderatePoll=Moderate the poll pollen.action.modify=Modify +pollen.action.pollAccessVote=Show votes pollen.action.pollChoiceDelete=Delete this choice pollen.action.pollChoiceDown=Down this choice pollen.action.pollChoiceUp=Up this choice @@ -55,7 +56,6 @@ pollen.action.pollResult.help=vote count and display results for this poll pollen.action.pollSummary=Poll summary pollen.action.pollVote=Vote -pollen.action.pollAccessVote=Show votes pollen.action.pollVotingListDelete=Delete the voting list pollen.action.pollVotingListEdit=Edit that voting list pollen.action.register=Register @@ -131,6 +131,10 @@ pollen.common.pollOption.notification=Receive notification emails pollen.common.pollOption.notification.help=An email is sent to you for each vote pollen.common.pollOption.notificationNumber=After each n votes +pollen.common.pollOption.pollCommentVisible=Authorise comments +pollen.common.pollOption.pollCommentVisible.help=This option permits to add / moderate / delete comments on the poll voting page +pollen.common.pollOption.pollVoteVisibility=Visibility of votes +pollen.common.pollOption.pollVoteVisibility.help=Choose how votes can be visible for this poll\:<br/><br/>Anonymous poll\: all votes are anonymous<br/><br/>Visible for creator (only creator or administrator can see votes)<br/><br/>Visible for participant (only poll participant can see votes)<br/><br/>Public poll (votes are visible for everybody) pollen.common.pollOption.publicResults=Public results pollen.common.pollOption.publicResults.help=Poll results are available for everybody pollen.common.pollOption.reminder=Send reminder emails @@ -286,6 +290,7 @@ pollen.information.pollCanNotVote=You are not authorize to vote, but still can you can access to votes (public results poll) pollen.information.pollChoiceRunning=Adding choices is allowed. pollen.information.pollClosed=This poll is closed. You can not vote anymore. +pollen.information.pollCommentNotAuthorized=Comments are not allowed on this poll. pollen.information.pollFinished=This poll is finished. You can not vote anymore. pollen.information.pollNotStarted=This poll has not started yet. pollen.information.pollRunning=The poll is not finished. Results may change. 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-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-ui-struts2/src/main/resources/i18n/pollen-ui-struts2_fr_FR.properties 2012-08-12 11:45:39 UTC (rev 3595) @@ -39,6 +39,7 @@ pollen.action.login=M'identifier pollen.action.moderatePoll=Modérer le sondage pollen.action.modify=Modifier +pollen.action.pollAccessVote=Accèder aux votes pollen.action.pollChoiceDelete=Supprimer ce choix pollen.action.pollChoiceDown=Descendre ce choix pollen.action.pollChoiceUp=Monter ce choix @@ -55,7 +56,6 @@ pollen.action.pollResult.help=Dépouiller et afficher les résultats du sondage pollen.action.pollSummary=Résumé du sondage pollen.action.pollVote=Voter -pollen.action.pollAccessVote=Accèder aux votes pollen.action.pollVotingListDelete=Supprimer le groupe de votants pollen.action.pollVotingListEdit=Editer ce groupe de votants pollen.action.register=S'enregistrer @@ -131,6 +131,10 @@ pollen.common.pollOption.notification=Recevoir des emails de notification pollen.common.pollOption.notification.help=Un email vous est envoyé à chaque vote pollen.common.pollOption.notificationNumber=Après n votes +pollen.common.pollOption.pollCommentVisible=Autoriser les commentaires +pollen.common.pollOption.pollCommentVisible.help=Cette option permet d'ajouter / modérer / supprimer des commentaires sur la page de vote du sondage +pollen.common.pollOption.pollVoteVisibility=Visibilité des votes +pollen.common.pollOption.pollVoteVisibility.help=Choisir la visibilité des votes dans le sondage \: Sondage anonyme (tous les votes sont anonymes)<br/><br/>Visibles pour le créateur (seul le créateur ou administrateur) peut voir les votes<br/><br/>Visible pour les participants (seuls les participants peuvent voir les votes)<br/><br/>Vote publique (tout le monde peut voir les votes) pollen.common.pollOption.publicResults=Résultats publics pollen.common.pollOption.publicResults.help=Les résultats du sondage sont consultables par tout le monde pollen.common.pollOption.reminder=Envoyer des emails de rappel @@ -287,6 +291,7 @@ pollen.information.pollCanNotVote=Vous n'êtes pas autorisé à voter, mais vous pouvez cependant accéder au votes (sondage à resultats publics) pollen.information.pollChoiceRunning=L'ajout de choix est possible. pollen.information.pollClosed=Ce sondage est clos. Vous ne pouvez plus voter. +pollen.information.pollCommentNotAuthorized=Les commentaires ne sont pas autorisés sur ce sondage. pollen.information.pollFinished=Ce sondage est terminé. Vous ne pouvez plus voter. pollen.information.pollNotStarted=Ce sondage n'a pas encore commencé. pollen.information.pollRunning=Ce sondage n'est pas terminé. Les résultats peuvent encore changer. Modified: trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/pollForm.jsp =================================================================== --- trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/pollForm.jsp 2012-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/pollForm.jsp 2012-08-12 11:45:39 UTC (rev 3595) @@ -204,11 +204,22 @@ alt="<s:text name='pollen.fieldset.vote.options.help'/>"/> </legend> - <s:checkbox key="poll.anonymous" + <s:checkbox key="pollCommentVisible" + label="%{getText('pollen.common.pollOption.pollCommentVisible')}" + disabled="%{voteStarted}" + tooltip="%{getText('pollen.common.pollOption.pollCommentVisible.help')}" + tooltipIconPath="/img/tooltip.png"/> + + <s:radio key='poll.pollVoteVisibility' list="pollVoteVisibilities" + label='%{getText("pollen.common.pollOption.pollVoteVisibility")}' + tooltip="%{getText('pollen.common.pollOption.pollVoteVisibility.help')}" + tooltipIconPath="/img/tooltip.png"/> + + <%--s:checkbox key="poll.anonymous" label="%{getText('pollen.common.pollOption.anonymous')}" disabled="%{voteStarted}" tooltip="%{getText('pollen.common.pollOption.anonymous.help')}" - tooltipIconPath="/img/tooltip.png"/> + tooltipIconPath="/img/tooltip.png"/--%> <s:checkbox key="poll.anonymousVoteAllowed" label="%{getText('pollen.common.pollOption.anonymousVoteAllowed')}" disabled="%{voteStarted}" Modified: trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/vote.jsp =================================================================== --- trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/vote.jsp 2012-08-12 11:02:43 UTC (rev 3594) +++ trunk/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/vote.jsp 2012-08-12 11:45:39 UTC (rev 3595) @@ -431,31 +431,36 @@ </div> </s:if> -<!-- Ajout de commentaires --> -<h3><s:text name="pollen.common.comments"/></h3> +<s:if test="commentAllowed"> -<div id="commentZone"> + <!-- Ajout de commentaires --> + <h3><s:text name="pollen.common.comments"/></h3> - <%--Show paginated comments--%> - <%@include file="displayPollComments.jsp" %> + <div id="commentZone"> - <div id="commentFormDiv"> + <%--Show paginated comments--%> + <%@include file="displayPollComments.jsp" %> - <s:form id='addCommentForm' method="POST" namespace="/poll" validate="true"> - <s:textfield key="commentAuthor" required="true" size="78" - label="%{getText('pollen.common.commentAuthor')}"/> - <s:textarea key="commentText" required="true" value='' - label="%{getText('pollen.common.commentText')}"/> + <div id="commentFormDiv"> - <div class="cleanBoth"> - <s:submit action="addComment/%{uriId}" key="pollen.action.addComment" - align="center"/> - </div> - </s:form> + <s:form id='addCommentForm' method="POST" namespace="/poll" + validate="true"> + <s:textfield key="commentAuthor" required="true" size="78" + label="%{getText('pollen.common.commentAuthor')}"/> + <s:textarea key="commentText" required="true" value='' + label="%{getText('pollen.common.commentText')}"/> + <div class="cleanBoth"> + <s:submit action="addComment/%{uriId}" key="pollen.action.addComment" + align="center"/> + </div> + </s:form> + + </div> + + <sj:dialog id="confirmDialog" resizable="false" autoOpen="false" + modal="true" + width="800"/> </div> - - <sj:dialog id="confirmDialog" resizable="false" autoOpen="false" modal="true" - width="800"/> -</div> </s:if> +</s:if>
participants (1)
-
tchemit@users.chorem.org