This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit 61999c79b87e920504a45b88eac9da32ddb8c6ff Author: Sylvain Bavencoff <bavencoff@codelutin.com> Date: Tue Sep 12 14:17:05 2017 +0200 gestion des CGU (ref #141) --- .../h2/V3_0_0_10__add_general_terms_of_use.sql | 3 + .../V3_0_0_10__add_general_terms_of_use.sql | 3 + pollen-persistence/src/main/xmi/pollen.properties | 2 +- pollen-persistence/src/main/xmi/pollen.zargo | Bin 28138 -> 28355 bytes .../pollen/rest/api/PollenRestApiApplication.java | 4 +- .../rest/api/PollenRestApiRequestFilter.java | 2 + .../java/org/chorem/pollen/rest/api/v1/GtuApi.java | 61 ++++++++++++ .../chorem/pollen/services/bean/GtuMetaBean.java | 17 ++++ .../org/chorem/pollen/services/bean/PollBean.java | 10 ++ .../pollen/services/bean/PollenUserBean.java | 10 ++ .../pollen/services/bean/ResourceMetaBean.java | 13 +++ .../chorem/pollen/services/service/GtuService.java | 107 +++++++++++++++++++++ .../pollen/services/service/PollService.java | 15 +++ .../services/service/PollenResourceService.java | 14 +++ .../services/service/PollenServiceSupport.java | 4 + .../pollen/services/service/PollenUserService.java | 7 ++ .../i18n/pollen-services_en_GB.properties | 1 + .../i18n/pollen-services_fr_FR.properties | 1 + pollen-ui-riot-js/src/main/web/i18n/en.json | 19 +++- pollen-ui-riot-js/src/main/web/i18n/fr.json | 19 +++- pollen-ui-riot-js/src/main/web/js/AuthService.js | 3 +- .../src/main/web/js/ResourceService.js | 10 ++ pollen-ui-riot-js/src/main/web/js/UserService.js | 5 + pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html | 32 ++++-- .../src/main/web/tag/PollenFooter.tag.html | 12 ++- .../src/main/web/tag/PollenHeader.tag.html | 1 + .../src/main/web/tag/PollenWaiter.tag.html | 4 +- pollen-ui-riot-js/src/main/web/tag/SignUp.tag.html | 6 +- .../src/main/web/tag/poll/Choice.tag.html | 2 +- .../src/main/web/tag/poll/EditPoll.tag.html | 66 +++++++------ 30 files changed, 403 insertions(+), 50 deletions(-) diff --git a/pollen-persistence/src/main/resources/db/migration/h2/V3_0_0_10__add_general_terms_of_use.sql b/pollen-persistence/src/main/resources/db/migration/h2/V3_0_0_10__add_general_terms_of_use.sql new file mode 100644 index 00000000..675f2d07 --- /dev/null +++ b/pollen-persistence/src/main/resources/db/migration/h2/V3_0_0_10__add_general_terms_of_use.sql @@ -0,0 +1,3 @@ +-- add general terms of use in poll and user +alter table poll add gtuValidationDate TIMESTAMP; +alter table pollenUser add gtuValidationDate TIMESTAMP; diff --git a/pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_0_10__add_general_terms_of_use.sql b/pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_0_10__add_general_terms_of_use.sql new file mode 100644 index 00000000..675f2d07 --- /dev/null +++ b/pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_0_10__add_general_terms_of_use.sql @@ -0,0 +1,3 @@ +-- add general terms of use in poll and user +alter table poll add gtuValidationDate TIMESTAMP; +alter table pollenUser add gtuValidationDate TIMESTAMP; diff --git a/pollen-persistence/src/main/xmi/pollen.properties b/pollen-persistence/src/main/xmi/pollen.properties index d172fe4c..926a53e6 100644 --- a/pollen-persistence/src/main/xmi/pollen.properties +++ b/pollen-persistence/src/main/xmi/pollen.properties @@ -18,7 +18,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # #L% ###m -model.tagvalue.version=3.0.0.9 +model.tagvalue.version=3.0.0.10 #model.tagValue.notGenerateToString=true #model.tagValue.constantPrefix=PROPERTY_ #model.tagValue.useEnumerationName=true diff --git a/pollen-persistence/src/main/xmi/pollen.zargo b/pollen-persistence/src/main/xmi/pollen.zargo index 7ce056d6..0da955ef 100644 Binary files a/pollen-persistence/src/main/xmi/pollen.zargo and b/pollen-persistence/src/main/xmi/pollen.zargo differ diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/PollenRestApiApplication.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/PollenRestApiApplication.java index 687e4f38..7a15fcfe 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/PollenRestApiApplication.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/PollenRestApiApplication.java @@ -7,8 +7,8 @@ import org.chorem.pollen.rest.api.exceptionMappers.FavoriteListImportExceptionMa import org.chorem.pollen.rest.api.exceptionMappers.InvalidEntityLinkExceptionMapper; import org.chorem.pollen.rest.api.exceptionMappers.InvalidFormExceptionMapper; import org.chorem.pollen.rest.api.exceptionMappers.PollenAuthenticationExceptionMapper; -import org.chorem.pollen.rest.api.exceptionMappers.PollenEmailOrProviderAccountAlreadyUsedExceptionMapper; import org.chorem.pollen.rest.api.exceptionMappers.PollenEmailNotValidatedExceptionMapper; +import org.chorem.pollen.rest.api.exceptionMappers.PollenEmailOrProviderAccountAlreadyUsedExceptionMapper; import org.chorem.pollen.rest.api.exceptionMappers.PollenInvalidEmailActivationTokenExceptionMapper; import org.chorem.pollen.rest.api.exceptionMappers.PollenInvalidPermissionExceptionMapper; import org.chorem.pollen.rest.api.exceptionMappers.PollenInvalidSessionTokenExceptionMapper; @@ -21,6 +21,7 @@ import org.chorem.pollen.rest.api.v1.CommentApi; import org.chorem.pollen.rest.api.v1.DocApi; import org.chorem.pollen.rest.api.v1.FavoriteListApi; import org.chorem.pollen.rest.api.v1.FeedbackApi; +import org.chorem.pollen.rest.api.v1.GtuApi; import org.chorem.pollen.rest.api.v1.PollApi; import org.chorem.pollen.rest.api.v1.PollenResourceApi; import org.chorem.pollen.rest.api.v1.PollenUserApi; @@ -56,6 +57,7 @@ public class PollenRestApiApplication extends Application { new VoteCountingTypeApi(), new VoterListApi(), new FeedbackApi(), + new GtuApi(), new PollenAuthenticationExceptionMapper(), new PollenInvalidSessionTokenExceptionMapper(), new PollenUnauthorizedExceptionMapper(), diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/PollenRestApiRequestFilter.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/PollenRestApiRequestFilter.java index cfb03701..35d400d4 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/PollenRestApiRequestFilter.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/PollenRestApiRequestFilter.java @@ -38,6 +38,7 @@ import org.chorem.pollen.services.service.CommentService; import org.chorem.pollen.services.service.FavoriteListService; import org.chorem.pollen.services.service.FeedService; import org.chorem.pollen.services.service.FeedbackService; +import org.chorem.pollen.services.service.GtuService; import org.chorem.pollen.services.service.NotificationService; import org.chorem.pollen.services.service.PollService; import org.chorem.pollen.services.service.PollenResourceService; @@ -181,6 +182,7 @@ public class PollenRestApiRequestFilter implements ContainerRequestFilter, Conta ResteasyProviderFactory.pushContext(PollenUserService.class, serviceContext.newService(PollenUserService.class)); ResteasyProviderFactory.pushContext(FeedbackService.class, serviceContext.newService(FeedbackService.class)); ResteasyProviderFactory.pushContext(SocialAuthService.class, serviceContext.newService(SocialAuthService.class)); + ResteasyProviderFactory.pushContext(GtuService.class, serviceContext.newService(GtuService.class)); } private PollenUIContext extractUIContext(ContainerRequestContext context) { diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/GtuApi.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/GtuApi.java new file mode 100644 index 00000000..bd2e4631 --- /dev/null +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/GtuApi.java @@ -0,0 +1,61 @@ +package org.chorem.pollen.rest.api.v1; + +import org.chorem.pollen.services.bean.GtuMetaBean; +import org.chorem.pollen.services.bean.ResourceStreamBean; +import org.chorem.pollen.services.service.GtuService; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.util.List; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +@Path("") +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public class GtuApi { + + @Path("/gtus") + @GET + @Produces(MediaType.APPLICATION_JSON) + public List<GtuMetaBean> getGtus(@Context GtuService gtuService) { + + return gtuService.getAllGtus(); + } + + @Path("/gtu/define") + @GET + @Produces(MediaType.APPLICATION_JSON) + public boolean isGtu(@Context GtuService gtuService) { + + return gtuService.isGtu(); + } + + @Path("/gtu") + @GET + @Produces(MediaType.APPLICATION_OCTET_STREAM) + public Response getGtu(@Context GtuService gtuService) { + + ResourceStreamBean resource = gtuService.getCurrentGtu(); + return Response.ok(resource.getResourceContent(), resource.getContentType()) + .header("content-disposition", "filename=\"" + resource.getName() + "\"") + .build(); + } + + @Path("/gtu/validate") + @PUT + @POST + public void validateGtu(@Context GtuService gtuService) { + + gtuService.validateGtu(); + } + +} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/GtuMetaBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/GtuMetaBean.java new file mode 100644 index 00000000..b7126cb4 --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/GtuMetaBean.java @@ -0,0 +1,17 @@ +package org.chorem.pollen.services.bean; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class GtuMetaBean extends ResourceMetaBean { + + protected boolean current; + + public boolean isCurrent() { + return current; + } + + public void setCurrent(boolean current) { + this.current = current; + } +} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollBean.java index d5104feb..c382bafa 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollBean.java @@ -144,6 +144,8 @@ public class PollBean extends PollenBean<Poll> { protected ReportResumeBean report; + protected boolean gtuValidated; + @Override public void fromEntity(Poll entity) { @@ -563,4 +565,12 @@ public class PollBean extends PollenBean<Poll> { public void setReport(ReportResumeBean report) { this.report = report; } + + public boolean isGtuValidated() { + return gtuValidated; + } + + public void setGtuValidated(boolean gtuValidated) { + this.gtuValidated = gtuValidated; + } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollenUserBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollenUserBean.java index e1a28095..d1d1ccb5 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollenUserBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollenUserBean.java @@ -54,6 +54,8 @@ public class PollenUserBean extends PollenBean<PollenUser> { protected List<UserCredentialBean> credentials = new ArrayList<>(); + protected boolean gtuValidated; + public PollenUserBean() { super(PollenUser.class); } @@ -169,4 +171,12 @@ public class PollenUserBean extends PollenBean<PollenUser> { public void setCredentials(List<UserCredentialBean> credentials) { this.credentials = credentials; } + + public boolean isGtuValidated() { + return gtuValidated; + } + + public void setGtuValidated(boolean gtuValidated) { + this.gtuValidated = gtuValidated; + } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/ResourceMetaBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/ResourceMetaBean.java index b4e67f9c..eea72c85 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/ResourceMetaBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/ResourceMetaBean.java @@ -25,6 +25,8 @@ import org.chorem.pollen.persistence.entity.PollenResource; import org.chorem.pollen.persistence.entity.PollenResourceImpl; import org.chorem.pollen.persistence.entity.ResourceType; +import java.util.Date; + /** * Created on 11/07/14. * @@ -40,6 +42,8 @@ public class ResourceMetaBean extends PollenBean<PollenResource> { protected ResourceType resourceType; + protected Date uploadDate; + protected ResourceMetaBean() { super(PollenResource.class); } @@ -52,6 +56,7 @@ public class ResourceMetaBean extends PollenBean<PollenResource> { setSize(entity.getSize()); setContentType(entity.getContentType()); setResourceType(entity.getResourceType()); + setUploadDate(entity.getTopiaCreateDate()); } @Override @@ -99,4 +104,12 @@ public class ResourceMetaBean extends PollenBean<PollenResource> { public void setResourceType(ResourceType resourceType) { this.resourceType = resourceType; } + + public Date getUploadDate() { + return uploadDate; + } + + public void setUploadDate(Date uploadDate) { + this.uploadDate = uploadDate; + } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/GtuService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/GtuService.java new file mode 100644 index 00000000..faf481a8 --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/GtuService.java @@ -0,0 +1,107 @@ +package org.chorem.pollen.services.service; + +import com.google.common.collect.Iterables; +import org.apache.commons.collections4.CollectionUtils; +import org.chorem.pollen.persistence.entity.Poll; +import org.chorem.pollen.persistence.entity.PollenResource; +import org.chorem.pollen.persistence.entity.PollenUser; +import org.chorem.pollen.persistence.entity.ResourceType; +import org.chorem.pollen.services.bean.GtuMetaBean; +import org.chorem.pollen.services.bean.ResourceStreamBean; +import org.nuiton.util.pagination.PaginationOrder; + +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Optional; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class GtuService extends PollenServiceSupport { + + public ResourceStreamBean getCurrentGtu() { + + ResourceStreamBean result = null; + + Optional<PollenResource> currentGtu = getCurrentGtu0(); + if (currentGtu.isPresent()) { + result = toBean(ResourceStreamBean.class, currentGtu.get()); + } + return result; + } + + public List<GtuMetaBean> getAllGtus() { + List<PollenResource> gtus = getPollenResourceDao() + .forResourceTypeEquals(ResourceType.GTU) + .setOrderByArguments(PollenResource.PROPERTY_TOPIA_CREATE_DATE) + .findAll(); + + String currentId = CollectionUtils.isNotEmpty(gtus) ? Iterables.getLast(gtus).getTopiaId() : null; + + return toBeanList(GtuMetaBean.class, gtus, input -> { + input.setCurrent(input.getEntityId().equals(currentId)); + return input; + }); + } + + public boolean isGtu() { + return getPollenResourceDao() + .forResourceTypeEquals(ResourceType.GTU) + .exists(); + } + + protected Optional<PollenResource> getCurrentGtu0() { + PaginationOrder order = new PaginationOrder(PollenResource.PROPERTY_TOPIA_CREATE_DATE, true); + return getPollenResourceDao() + .forResourceTypeEquals(ResourceType.GTU) + .setOrderByArguments(Collections.singleton(order)) + .tryFindFirst() + .toJavaUtil(); + } + + protected boolean isPollGtuValidated(String pollId) { + Poll poll = getPollService().getPoll0(pollId); + return isGtuValidated(poll); + } + + protected boolean isUserGtuValidated(String userId) { + PollenUser user = getUserService().getUser0(userId); + return isGtuValidated(user); + } + + public boolean isGtuValidated(PollenUser user) { + return isGtuValidatedForDate(user.getGtuValidationDate()); + } + + protected boolean isGtuValidatedForDate(Date validationDate) { + return getCurrentGtu0() + .map(PollenResource::getTopiaCreateDate) + .map(date -> validationDate != null && date.before(validationDate)) + .orElse(true); + } + + public boolean isGtuValidated(Poll poll) { + boolean validated; + + PollenUser user = poll.getCreator().getPollenUser(); + if (user != null) { + validated = isGtuValidated(user); + } else { + validated = isGtuValidatedForDate(poll.getGtuValidationDate()); + } + + return validated; + + } + + public void validateGtu() { + + checkIsConnected(); + PollenUser connectedUser = getConnectedUser(); + connectedUser.setGtuValidationDate(getNow()); + + commit(); + } + +} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java index 735c9901..abb5d74d 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java @@ -105,6 +105,8 @@ public class PollService extends PollenServiceSupport { long choiceCount = getChoiceService().getChoiceCount(input.getEntityId()); input.setChoiceCount(choiceCount); + input.setGtuValidated(getGtuService().isPollGtuValidated(input.getEntityId())); + return input; }; @@ -193,6 +195,7 @@ public class PollService extends PollenServiceSupport { pollBean.setCreatorName(connectedUser.getName()); pollBean.setCreatorEmail(connectedUser.getEmail()); + pollBean.setGtuValidated(getGtuService().isGtuValidated(connectedUser)); } @@ -498,6 +501,18 @@ public class PollService extends PollenServiceSupport { } } + // GTU + PollenUser connectedUser = getConnectedUser(); + if (connectedUser == null) { + if (!getGtuService().isGtuValidated(toSave) && poll.isGtuValidated()) { + toSave.setGtuValidationDate(getNow()); + } + } else { + if (!getGtuService().isGtuValidated(connectedUser) && poll.isGtuValidated()) { + connectedUser.setGtuValidationDate(getNow()); + } + } + return toSave; } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenResourceService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenResourceService.java index 78e676af..da8edb63 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenResourceService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenResourceService.java @@ -22,6 +22,7 @@ package org.chorem.pollen.services.service; */ import org.chorem.pollen.persistence.entity.PollenResource; +import org.chorem.pollen.persistence.entity.ResourceType; import org.chorem.pollen.services.PollenService; import org.chorem.pollen.services.PollenTechnicalException; import org.chorem.pollen.services.UnitHuman; @@ -117,6 +118,10 @@ public class PollenResourceService extends PollenServiceSupport implements Polle checkNotNull(resource); checkIsNotPersisted(resource); + if (ResourceType.GTU.equals(resource.getResourceType())) { + checkIsAdmin(); + } + ErrorMap errorMap = checkRessource(resource); errorMap.failIfNotEmpty(); @@ -130,6 +135,10 @@ public class PollenResourceService extends PollenServiceSupport implements Polle checkNotNull(resourceId); checkIsNotPersisted(resource); + if (ResourceType.GTU.equals(resource.getResourceType())) { + checkIsAdmin(); + } + ErrorMap errorMap = checkRessource(resource); errorMap.failIfNotEmpty(); @@ -144,6 +153,11 @@ public class PollenResourceService extends PollenServiceSupport implements Polle checkNotNull(resourceId); PollenResource resource = getResource0(resourceId); + + if (ResourceType.GTU.equals(resource.getResourceType())) { + checkIsAdmin(); + } + getPollenResourceDao().delete(resource); commit(); diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenServiceSupport.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenServiceSupport.java index 860e0266..6ea95d82 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenServiceSupport.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenServiceSupport.java @@ -137,6 +137,10 @@ public abstract class PollenServiceSupport implements PollenService { return newService(FeedService.class); } + protected GtuService getGtuService() { + return newService(GtuService.class); + } + protected PollService getPollService() { return newService(PollService.class); } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenUserService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenUserService.java index ae57949f..f8c3560e 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenUserService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenUserService.java @@ -58,6 +58,7 @@ public class PollenUserService extends PollenServiceSupport implements PollenSer private final Function<PollenUserBean, PollenUserBean> pollenUserFunction = input -> { input.setPassword(null); + input.setGtuValidated(getGtuService().isUserGtuValidated(input.getEntityId())); return input; }; @@ -307,6 +308,12 @@ public class PollenUserService extends PollenServiceSupport implements PollenSer !(user.isBanned() && user.isPersisted() && getConnectedUser() != null && user.getEntityId().equals(getConnectedUser().getTopiaId())), l(getLocale(), "pollen.error.user.bannedSelf")); + if (getGtuService().getCurrentGtu0().isPresent()) { + check(errors, "gtuValidated", + user.isPersisted() || user.isGtuValidated(), + l(getLocale(), "pollen.error.user.gtuValidation.required")); + } + return errors; } diff --git a/pollen-services/src/main/resources/i18n/pollen-services_en_GB.properties b/pollen-services/src/main/resources/i18n/pollen-services_en_GB.properties index ecca1ce1..69f6e9af 100644 --- a/pollen-services/src/main/resources/i18n/pollen-services_en_GB.properties +++ b/pollen-services/src/main/resources/i18n/pollen-services_en_GB.properties @@ -97,6 +97,7 @@ pollen.error.resource.maxSize=File "%s" of %4.2f %s can't be over %4.2f %s. pollen.error.resource.notExist=Image don't exist pollen.error.resource.resourceTypeRequired=Resource type is required pollen.error.user.bannedSelf=You can't banned yourself +pollen.error.user.gtuValidation.required=General terms of use validation is required pollen.error.user.mailEmpty=The email address can not be empty pollen.error.user.mailExist=The email address already exists pollen.error.user.mailInvalid=The email address is not valid diff --git a/pollen-services/src/main/resources/i18n/pollen-services_fr_FR.properties b/pollen-services/src/main/resources/i18n/pollen-services_fr_FR.properties index 9c285933..9beac41c 100644 --- a/pollen-services/src/main/resources/i18n/pollen-services_fr_FR.properties +++ b/pollen-services/src/main/resources/i18n/pollen-services_fr_FR.properties @@ -96,6 +96,7 @@ pollen.error.resource.maxSize=Le fichier « %s » de %4.2f %s ne doit pas dép pollen.error.resource.notExist=L'image n'existe pas sur le serveur pollen.error.resource.resourceTypeRequired=Le type de resource est obligatoire pollen.error.user.bannedSelf=Vous ne pouvez pas vous bannir vous-même +pollen.error.user.gtuValidation.required=L'acceptation des conditions générales d'utilisation est obligatoire. pollen.error.user.mailEmpty=L'adresse de courriel ne peut pas être vide pollen.error.user.mailExist=L'adresse de courriel existe déjà pollen.error.user.mailInvalid=L'adresse de courriel est invalide diff --git a/pollen-ui-riot-js/src/main/web/i18n/en.json b/pollen-ui-riot-js/src/main/web/i18n/en.json index 02f11441..2d04709a 100644 --- a/pollen-ui-riot-js/src/main/web/i18n/en.json +++ b/pollen-ui-riot-js/src/main/web/i18n/en.json @@ -213,6 +213,7 @@ "footer_contact": "Contact us", "footer_participate": "Get involved!", "footer_license": "Licence", + "footer_gtu": "GTU", "header_signin": "SignIn", "header_signup": "SignUp", "header_signout": "Disconnect", @@ -224,6 +225,7 @@ "header_myParticipatedPolls": "Participated polls", "header_polls": "Polls", "header_users": "Users", + "header_gtu": "GTU", "header_loginProviders": "Login providers", "header_myFavoriteLists": "My favorite lists", "header_createOtherPoll": "New standard poll", @@ -550,5 +552,20 @@ "loginProviders_deleteMessage": "Are you sure you want to delete this provider?", "loginProviders_emptyName": "The name is mandatory", "loginProviders_emptyKey": "The client key is mandatory", - "loginProviders_emptySecret": "The secret code is mandatory" + "loginProviders_emptySecret": "The secret code is mandatory", + "gtus_title": "General Terms of Use", + "gtus_noGtu": "No general terms of use", + "gtus_one": "general terms of use", + "gtus_many": "general terms of use", + "gtus_add": "Add a GTU", + "gtus_addGtu": "Add a new GTU ?", + "gtu_delete": "delete", + "gtu_download": "Download", + "gtu_current": "Current", + "gtu_deleteGtu": "Delete GTU ?", + "gtu_validation_before" : "I read and accept the", + "gtu_validation_link" : "general terms of use.", + "gtu_validation_after" : "", + "gtu_change_title": "CGU has change", + "gtu_change_action": "Accept" } diff --git a/pollen-ui-riot-js/src/main/web/i18n/fr.json b/pollen-ui-riot-js/src/main/web/i18n/fr.json index 26efafc5..7762ee73 100644 --- a/pollen-ui-riot-js/src/main/web/i18n/fr.json +++ b/pollen-ui-riot-js/src/main/web/i18n/fr.json @@ -213,6 +213,7 @@ "footer_contact": "Nous contacter", "footer_participate": "Contribuer au projet", "footer_license": "Licence", + "footer_gtu": "CGU", "header_signin": "Connexion", "header_signup": "Inscription", "header_signout": "Déconnexion", @@ -224,6 +225,7 @@ "header_myParticipatedPolls": "Mes participations", "header_polls": "Sondages", "header_users": "Utilisateurs", + "header_gtu": "CGU", "header_loginProviders": "Tiers de connexion", "header_myFavoriteLists": "Mes listes de votants", "header_createOtherPoll": "Nouveau sondage standard", @@ -550,5 +552,20 @@ "loginProviders_deleteMessage": "Êtes-vous sûr de vouloir supprimer ce tier ?", "loginProviders_emptyName": "Le nom est obligatoire", "loginProviders_emptyKey": "La clé client est obligatoire", - "loginProviders_emptySecret": "Le code secret est obligatoire" + "loginProviders_emptySecret": "Le code secret est obligatoire", + "gtus_title": "Conditions Générales d'Utilisation", + "gtus_noGtu": "Aucune condition générale d'utilisation ", + "gtus_one": "condition générales d'utilisation", + "gtus_many": "conditions générales d'utilisation", + "gtus_add": "Ajouter une CGU", + "gtus_addGtu": "Ajouter une nouvelle CGU ?", + "gtu_delete": "Supprimer", + "gtu_download": "Télécharger", + "gtu_current": "En Cours", + "gtu_deleteGtu": "Supprimer La CGU ?", + "gtu_validation_before" : "J'ai lu et j'accepte les", + "gtu_validation_link" : "conditions générales d'utilisation.", + "gtu_validation_after" : "", + "gtu_change_title": "Changement des CGU", + "gtu_change_action": "Accepter" } diff --git a/pollen-ui-riot-js/src/main/web/js/AuthService.js b/pollen-ui-riot-js/src/main/web/js/AuthService.js index aed4e7c4..b4d80d6e 100644 --- a/pollen-ui-riot-js/src/main/web/js/AuthService.js +++ b/pollen-ui-riot-js/src/main/web/js/AuthService.js @@ -53,7 +53,8 @@ class AuthService extends FetchService { let user1 = { name: user.name, email: user.email, - password: user.password + password: user.password, + gtuValidated: user.gtuValidated }; return this.post("/v1/users", user1); } diff --git a/pollen-ui-riot-js/src/main/web/js/ResourceService.js b/pollen-ui-riot-js/src/main/web/js/ResourceService.js index d6e0d38e..9001f361 100644 --- a/pollen-ui-riot-js/src/main/web/js/ResourceService.js +++ b/pollen-ui-riot-js/src/main/web/js/ResourceService.js @@ -61,6 +61,16 @@ class ResourceService extends FetchService { let url = this._getUrlPrefix(resourceId); return this.doDelete(url); } + + gtus() { + let url = "/v1/gtus"; + return this.get(url); + } + + isGtu() { + let url = "/v1/gtu/define"; + return this.get(url); + } } module.exports = singleton(ResourceService); diff --git a/pollen-ui-riot-js/src/main/web/js/UserService.js b/pollen-ui-riot-js/src/main/web/js/UserService.js index 32735ae2..396921a5 100644 --- a/pollen-ui-riot-js/src/main/web/js/UserService.js +++ b/pollen-ui-riot-js/src/main/web/js/UserService.js @@ -73,6 +73,11 @@ class UserService extends FetchService { let url = this._getUrlPrefix(userId) + "/credentials/" + credentialId; return this.doDelete(url); } + + gtuValidate() { + let url = "/v1/gtu/validate"; + return this.post(url); + } } module.exports = singleton(UserService); diff --git a/pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html b/pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html index dbcddc0d..85f7598f 100644 --- a/pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html @@ -32,14 +32,17 @@ require("./poll/Summary.tag.html"); require("./poll/Polls.tag.html"); require("./UserProfile.tag.html"); require("./admin/Users.tag.html"); +require("./admin/Gtus.tag.html"); require("./admin/LoginProviders.tag.html"); require("./favoriteList/FavoriteLists.tag.html"); require("./favoriteList/FavoriteList.tag.html"); require("./popup/ConfirmPopup.tag.html"); require("./popup/InformationPopup.tag.html"); +require("./popup/GtuChangeModal.tag.html"); <Pollen class="body-wrapper colors-default"> <ConfirmPopup/> <InformationPopup/> + <GtuChangeModal/> <PollenHeader/> <PollenWaiter parent-id="body-content"/> <div id="body-content" class="body-content"> @@ -154,6 +157,15 @@ require("./popup/InformationPopup.tag.html"); } }); + route("/gtu", () => { + if (!session.isConnected() && !session.getUser().administrator) { + route("/signin?url=/gtu"); + } else { + this.bus.trigger("pageChanged", "admin_gtus"); + riot.mount(this.refs.content, "gtus", {session: session}); + } + }); + route("/poll/*/choice", (pollId) => { riot.mount(this.refs.content, "poll", {pollId: pollId, tabName: "choices"}); }); @@ -200,7 +212,7 @@ require("./popup/InformationPopup.tag.html"); riot.mount(this.refs.content, "editpoll", {pollId: pollId, permission: permission, clone: true}); }); route("/poll/*/summary/*", (pollId, permission) => { - riot.mount(this.refs.content, "editpoll", {pollId: pollId, permission: permission, showSummary:true}); + riot.mount(this.refs.content, "editpoll", {pollId: pollId, permission: permission, showSummary: true}); }); route("/poll/*", (pollId) => { riot.mount(this.refs.content, "poll", {pollId: pollId}); @@ -236,21 +248,21 @@ require("./popup/InformationPopup.tag.html"); var q = route.query(); if (q.loginProvider != null) { if (q.action === "signin") { - session.signInProvider(q).then(() => { - let currentPage = localStorage.getItem("currentPage"); - localStorage.removeItem("currentPage"); + session.signInProvider(q).then(() => { + let currentPage = localStorage.getItem("currentPage"); + localStorage.removeItem("currentPage"); location.replace(session.pollenUIContext.uiEndPoint + "/" + currentPage); - }, (e) => { - let currentPage = localStorage.getItem("currentPage"); - localStorage.removeItem("currentPage"); - e.text().then(label => { + }, (e) => { + let currentPage = localStorage.getItem("currentPage"); + localStorage.removeItem("currentPage"); + e.text().then(label => { location.replace(session.pollenUIContext.uiEndPoint + "/" + currentPage + "?error=" + label); + }); }); - }); } else if (q.action === "link" && session.isConnected()) { let callback = (user) => { - userService.linkProvider(user.id, q).then((accountName) => { + userService.linkProvider(user.id, q).then(() => { location.replace(session.pollenUIContext.uiEndPoint + "/#user/profile"); }, (e) => { e.text().then(label => { diff --git a/pollen-ui-riot-js/src/main/web/tag/PollenFooter.tag.html b/pollen-ui-riot-js/src/main/web/tag/PollenFooter.tag.html index 9e50c3cb..acbcf0e5 100644 --- a/pollen-ui-riot-js/src/main/web/tag/PollenFooter.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/PollenFooter.tag.html @@ -25,12 +25,20 @@ <a href="http://list.chorem.org/cgi-bin/mailman/listinfo/pollen-users">{__.contact}</a> <a href="https://gitlab.nuiton.org/chorem/pollen">{__.participate}</a> <a href="http://www.gnu.org/licenses/agpl.html">{__.license}</a> + <a if={isGtu} href="{session.configuration.endPoint}/v1/gtu" target="_blank">{__.gtu}</a> <a href="http://www.codelutin.com/" target="_blank">Code Lutin</a> </div> <script type="es6"> - let session = require("../js/Session"); - this.installBundle(session, "footer"); + this.session = require("../js/Session"); + let resourceService = require("../js/ResourceService"); + this.installBundle(this.session, "footer"); + + resourceService.isGtu().then(result => { + this.isGtu = result; + this.update(); + }); + </script> <style> diff --git a/pollen-ui-riot-js/src/main/web/tag/PollenHeader.tag.html b/pollen-ui-riot-js/src/main/web/tag/PollenHeader.tag.html index 7974eccb..882e1130 100644 --- a/pollen-ui-riot-js/src/main/web/tag/PollenHeader.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/PollenHeader.tag.html @@ -37,6 +37,7 @@ require("./popup/FeedbackModal.tag.html"); <div class="dropdown-content right"> <a href="#user">{__.users}</a> <a href="#poll">{__.polls}</a> + <a href="#gtu">{__.gtu}</a> <a href="#loginProviders">{__.loginProviders}</a> </div> </div> diff --git a/pollen-ui-riot-js/src/main/web/tag/PollenWaiter.tag.html b/pollen-ui-riot-js/src/main/web/tag/PollenWaiter.tag.html index 6355ecba..010f49d7 100644 --- a/pollen-ui-riot-js/src/main/web/tag/PollenWaiter.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/PollenWaiter.tag.html @@ -2,12 +2,12 @@ <script> let NProgress = require("nprogress"); - NProgress.configure({ parent: "#" + this.opts.parentId}); + NProgress.configure({parent: "#" + this.opts.parentId}); let inProgress = new Set(); this.listen("loading", event => { inProgress.add(event); - if (inProgress.size === 1) { + if (this.isMounted && inProgress.size === 1) { NProgress.start(); } }); diff --git a/pollen-ui-riot-js/src/main/web/tag/SignUp.tag.html b/pollen-ui-riot-js/src/main/web/tag/SignUp.tag.html index 1d830d41..36a794b6 100644 --- a/pollen-ui-riot-js/src/main/web/tag/SignUp.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/SignUp.tag.html @@ -21,6 +21,7 @@ let route = require("riot-route"); require("./popup/ResendValidation.tag.html"); require("./components/HumanInput.tag.html"); +require("./components/GtuValidation.tag.html"); <SignUp class="body-content"> <div class="container"> @@ -90,6 +91,8 @@ require("./components/HumanInput.tag.html"); </div> </div> + <GtuValidation ref="gtuValidation"/> + <a class="resend-validation" onclick="{resendValidation}">{__.resendValidation}</a> <div class="actions-right"> @@ -127,7 +130,8 @@ require("./components/HumanInput.tag.html"); name: this.refs.name.value, email: this.refs.email.value, password: this.refs.password.value, - repeatPassword: this.refs.repeatPassword.value + repeatPassword: this.refs.repeatPassword.value, + gtuValidated: this.refs.gtuValidation.value() }; authService.signUp(user).then(() => { diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/Choice.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/Choice.tag.html index 479195fe..fdc16431 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/Choice.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/Choice.tag.html @@ -142,7 +142,7 @@ require("../components/time-picker.tag.html"); this.opts.choice.choiceType = "TEXT"; }; - this.onTextChange = (e) => { + this.onTextChange = () => { this.valueText = this.refs.choiceText.value; }; diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/EditPoll.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/EditPoll.tag.html index e37ff349..c8198329 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/EditPoll.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/EditPoll.tag.html @@ -60,34 +60,39 @@ require("../components/HumanInput.tag.html"); <VoterList if={!showSummary && form.step === 3 && form.model.pollType === "RESTRICTED"} form={form} ref="voters"/> <Summary if={showSummary} form={form}/> - <div class="actions" if={!showSummary}> - <a class="c-button c-button--ghost" - href={form.creation ? "#/home" : ("#/poll/" + form.model.id + "/vote/" + form.model.permission)}> - <i class="fa fa-undo" aria-hidden="true"></i> - {__.cancel} - </a> - <button type={form.creation || form.model.closed ? "button" : "submit"} if={form.step > 0} - class="c-button c-button--ghost" - onclick={previousStep}> - <i class="fa fa-chevron-left" aria-hidden="true"></i> - {__.previous} - </button> - <button if={form.step < form.steps.length - 1} - type="submit" - class="c-button c-button--ghost-info" - onclick={nextStep}> - {__.next} - <i class="fa fa-chevron-right " aria-hidden="true"></i> - </button> - - <button type="submit" - if={!form.creation || form.step === form.steps.length - 1} - class="c-button c-button--info" - show={!form.model.closed} - onclick={savePoll}> - <i class="fa fa-{form.creation ? 'plus' : 'check'}" aria-hidden="true"></i> - {__.save} - </button> + <div class="form-footer"> + <GtuValidation if={!form.model.gtuValidated && !showSummary && (!form.creation || form.step === form.steps.length - 1)} + ref="gtuValidation"/> + + <div class="actions" if={!showSummary}> + <a class="c-button c-button--ghost" + href={form.creation ? "#/home" : ("#/poll/" + form.model.id + "/vote/" + form.model.permission)}> + <i class="fa fa-undo" aria-hidden="true"></i> + {__.cancel} + </a> + <button type={form.creation || form.model.closed ? "button" : "submit"} if={form.step > 0} + class="c-button c-button--ghost" + onclick={previousStep}> + <i class="fa fa-chevron-left" aria-hidden="true"></i> + {__.previous} + </button> + <button if={form.step < form.steps.length - 1} + type="submit" + class="c-button c-button--ghost-info" + onclick={nextStep}> + {__.next} + <i class="fa fa-chevron-right " aria-hidden="true"></i> + </button> + + <button type="submit" + if={!form.creation || form.step === form.steps.length - 1} + class="c-button c-button--info" + show={!form.model.closed} + onclick={savePoll}> + <i class="fa fa-{form.creation ? 'plus' : 'check'}" aria-hidden="true"></i> + {__.save} + </button> + </div> </div> </div> </div> @@ -134,6 +139,9 @@ require("../components/HumanInput.tag.html"); } else if (this.form.step === 3) { this.refs.voters.submit(); } + if (!this.form.model.gtuValidated && !this.showSummary && (!this.form.creation || this.form.step === this.form.steps.length - 1)) { + this.form.model.gtuValidated = this.refs.gtuValidation.value(); + } if (this.callAfterSubmit) { this.callAfterSubmit(); this.update(); @@ -186,7 +194,7 @@ require("../components/HumanInput.tag.html"); padding-bottom: 0; } - .actions { + .form-footer { position: absolute; bottom: 0; left: 0; -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.