branch feature/11_attach_not_connected_poll_to_pllen_account created (now ae5dd5e)
This is an automated email from the git hooks/post-receive script. New change to branch feature/11_attach_not_connected_poll_to_pllen_account in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git at ae5dd5e refs #11 add form to link poll to user's account in the created poll page This branch includes the following new commits: new ebf63a8 refs #11 add service and api to assign a poll to a connected user new ae5dd5e refs #11 add form to link poll to user's account in the created poll page The 2 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "adds" were already present in the repository and have only been added to this reference. Detailed log of new commits: commit ae5dd5e6d979c0964e35baf167a0f37c6cc87b55 Author: Kevin Morin <morin@codelutin.com> Date: Mon Apr 24 16:45:57 2017 +0200 refs #11 add form to link poll to user's account in the created poll page commit ebf63a827f34053e45eb7516e2e393ad935d77d2 Author: Kevin Morin <morin@codelutin.com> Date: Mon Apr 24 16:45:18 2017 +0200 refs #11 add service and api to assign a poll to a connected user -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
This is an automated email from the git hooks/post-receive script. New commit to branch feature/11_attach_not_connected_poll_to_pllen_account in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit ebf63a827f34053e45eb7516e2e393ad935d77d2 Author: Kevin Morin <morin@codelutin.com> Date: Mon Apr 24 16:45:18 2017 +0200 refs #11 add service and api to assign a poll to a connected user --- .../org/chorem/pollen/rest/api/v1/PollApi.java | 4 ++ pollen-rest-api/src/main/resources/mapping | 33 +++++++------- .../pollen/services/service/PollService.java | 51 ++++++++++++++++------ .../pollen/services/service/PollServiceTest.java | 46 +++++++++++++++++++ 4 files changed, 104 insertions(+), 30 deletions(-) diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollApi.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollApi.java index 39a567f..cf8130a 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollApi.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollApi.java @@ -127,4 +127,8 @@ public class PollApi extends WebMotionController { return pollService.exportPoll(pollId.getEntityId()); } + + public PollBean assignPoll(PollService pollService, PollenEntityId<Poll> pollId) { + return pollService.assignPollToConnectedUser(pollId.getEntityId()); + } } diff --git a/pollen-rest-api/src/main/resources/mapping b/pollen-rest-api/src/main/resources/mapping index 6666858..5074d5f 100644 --- a/pollen-rest-api/src/main/resources/mapping +++ b/pollen-rest-api/src/main/resources/mapping @@ -100,27 +100,28 @@ DELETE /v1/favoriteLists/{favoriteListId}/lists/{childListId} FavoriteListApi. # PollApi -GET /v1/polls/new PollApi.getNewPoll -GET /v1/polls PollApi.getPolls -GET /v1/polls/created PollApi.getCreatedPolls -GET /v1/polls/invited PollApi.getInvitedPolls -GET /v1/polls/participated PollApi.getParticipatedPolls -POST /v1/polls PollApi.createPoll -POST,GET /v1/polls/create PollApi.createPoll -GET /v1/polls/edit PollApi.editPoll +GET /v1/polls/new PollApi.getNewPoll +GET /v1/polls PollApi.getPolls +GET /v1/polls/created PollApi.getCreatedPolls +GET /v1/polls/invited PollApi.getInvitedPolls +GET /v1/polls/participated PollApi.getParticipatedPolls +POST /v1/polls PollApi.createPoll +POST,GET /v1/polls/create PollApi.createPoll +GET /v1/polls/edit PollApi.editPoll #fix me -POST,PUT /v1/polls/{pollId} PollApi.editPoll -POST /v1/polls/{pollId}/edit PollApi.editPoll +POST,PUT /v1/polls/{pollId} PollApi.editPoll +POST /v1/polls/{pollId}/edit PollApi.editPoll -GET /v1/polls/{pollId} PollApi.getPoll -DELETE /v1/polls/{pollId} PollApi.deletePoll +GET /v1/polls/{pollId} PollApi.getPoll +DELETE /v1/polls/{pollId} PollApi.deletePoll -POST /v1/polls/{pollId}/clone PollApi.clonePoll +POST /v1/polls/{pollId}/clone PollApi.clonePoll -GET /v1/polls/{pollId}/export PollApi.exportPoll -PUT /v1/polls/{pollId}/close PollApi.closePoll -PUT /v1/polls/{pollId}/reopen PollApi.reopenPoll +GET /v1/polls/{pollId}/export PollApi.exportPoll +PUT /v1/polls/{pollId}/close PollApi.closePoll +PUT /v1/polls/{pollId}/reopen PollApi.reopenPoll +PUT /v1/polls/{pollId}/assign PollApi.assignPoll # PollenResourceApi 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 2a11fbf..71fff9e 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 @@ -40,6 +40,7 @@ import org.chorem.pollen.services.bean.PollenEntityRef; import org.chorem.pollen.services.bean.VoterListBean; import org.chorem.pollen.services.bean.VoterListMemberBean; import org.chorem.pollen.services.service.security.PermissionVerb; +import org.chorem.pollen.services.service.security.PollenUnauthorizedException; import org.chorem.pollen.votecounting.VoteCountingNotFound; import org.nuiton.util.pagination.PaginationParameter; import org.nuiton.util.pagination.PaginationResult; @@ -370,6 +371,32 @@ public class PollService extends PollenServiceSupport { } + public PollBean assignPollToConnectedUser(String pollId) { + + getSecurityContext().isConnected(); + + checkNotNull(pollId); + checkPermission(PermissionVerb.editPoll, pollId); + + Poll poll = getPoll0(pollId); + PollenUser creator = poll.getCreator().getPollenUser(); + PollenUser connectedUser = getConnectedUser(); + + if (creator != null) { + if (!creator.equals(connectedUser)) { + throw new PollenUnauthorizedException(connectedUser.getEmail()); + } else { + // no poll assigned + return null; + } + } + + poll.getCreator().setPollenUser(connectedUser); + commit(); + + return toBean(PollBean.class, poll, pollBeanFunction); + } + protected Poll savePoll(PollBean poll, List<ChoiceBean> choices) { boolean pollExists = poll.isPersisted(); @@ -391,24 +418,20 @@ public class PollService extends PollenServiceSupport { PollenPrincipal creatorToPersist = getSecurityService().generatePollenPrincipal(); - toSave.setCreator(creatorToPersist); - - existingChoices = new ArrayList<>(); - - } - - // -- creator -- // - - PollenUser connectedUser = getConnectedUser(); + // -- creator -- // - if (connectedUser != null) { + PollenUser connectedUser = getConnectedUser(); + if (connectedUser != null) { + // link to connected user + creatorToPersist.setPollenUser(connectedUser); - // link to connected user - toSave.getCreator().setPollenUser(connectedUser); + } else if (getSecurityContext().getMainPrincipal() == null) { + getSecurityContext().setMainPrincipal(creatorToPersist); + } - } else if (getSecurityContext().getMainPrincipal() == null){ + toSave.setCreator(creatorToPersist); - getSecurityContext().setMainPrincipal(toSave.getCreator()); + existingChoices = new ArrayList<>(); } diff --git a/pollen-services/src/test/java/org/chorem/pollen/services/service/PollServiceTest.java b/pollen-services/src/test/java/org/chorem/pollen/services/service/PollServiceTest.java index 8673736..8cc60af 100644 --- a/pollen-services/src/test/java/org/chorem/pollen/services/service/PollServiceTest.java +++ b/pollen-services/src/test/java/org/chorem/pollen/services/service/PollServiceTest.java @@ -24,11 +24,17 @@ package org.chorem.pollen.services.service; import org.chorem.pollen.persistence.entity.ChoiceType; import org.chorem.pollen.persistence.entity.Poll; import org.chorem.pollen.persistence.entity.PollType; +import org.chorem.pollen.persistence.entity.PollenUser; import org.chorem.pollen.services.AbstractPollenServiceTest; +import org.chorem.pollen.services.PollenFixtures; import org.chorem.pollen.services.PollenUIContext; import org.chorem.pollen.services.bean.ChoiceBean; import org.chorem.pollen.services.bean.PollBean; import org.chorem.pollen.services.bean.PollenEntityRef; +import org.chorem.pollen.services.service.security.PollenAuthenticationException; +import org.chorem.pollen.services.service.security.PollenInvalidPermissionException; +import org.chorem.pollen.services.service.security.PollenInvalidSessionTokenException; +import org.chorem.pollen.services.service.security.PollenUnauthorizedException; import org.chorem.pollen.services.service.security.SecurityService; import org.chorem.pollen.services.test.FakePollenSecurityContext; import org.junit.Assert; @@ -530,4 +536,44 @@ public class PollServiceTest extends AbstractPollenServiceTest { // // } + @Test + public void testAssignPollToConnectedUser() throws PollenInvalidSessionTokenException, PollenAuthenticationException { + Poll poll = fixture(PollenFixtures.POLL_NORMAL_ID); + Assert.assertNull(poll.getCreator().getPollenUser()); + try { + service.assignPollToConnectedUser(poll.getTopiaId()); + Assert.fail("An error should be thrown as no user is connected"); + + } catch (PollenInvalidPermissionException e) { + Assert.assertNull(poll.getCreator().getPollenUser()); + } + + login("tony@pollen.fake", "fake"); + try { + service.assignPollToConnectedUser(poll.getTopiaId()); + Assert.fail("An error should be thrown if the connected user does not provide the permission to edit the poll"); + + } catch (PollenInvalidPermissionException e) { + Assert.assertNull(poll.getCreator().getPollenUser()); + } + + securityService.getSecurityContext().setMainPrincipal(poll.getCreator()); + service.assignPollToConnectedUser(poll.getTopiaId()); + + PollenUser pollenUser = poll.getCreator().getPollenUser(); + Assert.assertNotNull(pollenUser); + Assert.assertEquals("tony@pollen.fake", pollenUser.getEmail()); + + login("jean@pollen.fake", "fake"); + try { + service.assignPollToConnectedUser(poll.getTopiaId()); + Assert.fail("An error should be thrown as the poll is already assigned to a user"); + + } catch (PollenUnauthorizedException e) { + Assert.assertNotNull(pollenUser); + Assert.assertEquals("tony@pollen.fake", pollenUser.getEmail()); + } + + } + } -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
This is an automated email from the git hooks/post-receive script. New commit to branch feature/11_attach_not_connected_poll_to_pllen_account in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit ae5dd5e6d979c0964e35baf167a0f37c6cc87b55 Author: Kevin Morin <morin@codelutin.com> Date: Mon Apr 24 16:45:57 2017 +0200 refs #11 add form to link poll to user's account in the created poll page --- .../org/chorem/pollen/rest/api/PollApiTest.java | 15 +++ pollen-ui-riot-js/src/main/web/i18n.json | 8 ++ pollen-ui-riot-js/src/main/web/js/PollService.js | 8 ++ .../src/main/web/tag/poll/Polls.tag.html | 112 ++++++++++++++++++++- 4 files changed, 140 insertions(+), 3 deletions(-) diff --git a/pollen-rest-api/src/test/java/org/chorem/pollen/rest/api/PollApiTest.java b/pollen-rest-api/src/test/java/org/chorem/pollen/rest/api/PollApiTest.java index e29032b..1d84aae 100644 --- a/pollen-rest-api/src/test/java/org/chorem/pollen/rest/api/PollApiTest.java +++ b/pollen-rest-api/src/test/java/org/chorem/pollen/rest/api/PollApiTest.java @@ -237,4 +237,19 @@ public class PollApiTest extends AbstractPollenRestApiTest { showTestResult(content); assertNotNull(content); } + + @Test + @Ignore + public void assignPoll() throws URISyntaxException, IOException { + + Poll poll = fixture(PollenFixtures.POLL_NORMAL_ID); + String pollId = encodeId(poll.getTopiaId()); + + Request request = createRequest(RestApiFixtures.polls(pollId, "assign")) + .addParameter(PollenRestApiRequestFilter.REQUEST_PERMISSION_PARAMETER, poll.getCreator().getPermission().getToken()) + .Put(); + String content = request.execute().returnContent().asString(); + showTestResult(content); + assertNotNull(content); + } } diff --git a/pollen-ui-riot-js/src/main/web/i18n.json b/pollen-ui-riot-js/src/main/web/i18n.json index 0c69fd3..e99ce24 100644 --- a/pollen-ui-riot-js/src/main/web/i18n.json +++ b/pollen-ui-riot-js/src/main/web/i18n.json @@ -88,6 +88,10 @@ "poll_votes_results_unit_7_many": "votes", "poll_votes_voteNotOpen": "Les votes ne sont pas encore ouverts.", "polls_createdPolls": "Mes sondages", + "polls_assignPollToMe": "Attacher le sondage", + "polls_assignPollToMe_title": "Attacher un sondage à mon compte", + "polls_assignPollToMe_desc": "Si vous avez créé un sondage sans être connecté, vous pouvez le rattacher à votre compte en remplissant ce formulaire avec l'url d'administration du sondage.", + "polls_assignSuccessMessage": "Le sondage suivant a bien été rattaché à votre compte :", "polls_invitedPolls": "Mes invitations", "polls_participatedPolls": "Mes participations", "polls_polls": "Tous les sondages", @@ -462,6 +466,10 @@ "poll_votes_results_unit_7_many": "votes", "poll_votes_voteNotOpen": "Votes are not open.", "polls_createdPolls": "My polls", + "polls_assignPollToMe": "Link a poll to my account", + "polls_assignPollToMe_title": "Link the poll", + "polls_assignPollToMe_desc": "If you created a poll without being connected, you can link it to your account by fillin the form below with the administration url of the poll.", + "polls_assignSuccessMessage": "The following poll has successfully been linked to your account:", "polls_invitedPolls": "My invitations", "polls_participatedPolls": "My participations", "polls_polls": "All polls", diff --git a/pollen-ui-riot-js/src/main/web/js/PollService.js b/pollen-ui-riot-js/src/main/web/js/PollService.js index 536a455..90e836d 100644 --- a/pollen-ui-riot-js/src/main/web/js/PollService.js +++ b/pollen-ui-riot-js/src/main/web/js/PollService.js @@ -79,6 +79,14 @@ class PollService extends FetchService { } return this.put(url); } + + assignPoll(pollId, permission) { + let url = "/v1/polls/" + pollId + "/assign"; + if (permission) { + url += "?permission=" + permission; + } + return this.put(url); + } } module.exports = singleton(PollService); diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/Polls.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/Polls.tag.html index f952e38..61392ca 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/Polls.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/Polls.tag.html @@ -23,22 +23,71 @@ require("./PollCard.tag.html"); </div> </div> - <Pagination pagination={pagination} onchange="{refresh}"/> + <Pagination pagination={pagination} onchange="{refresh}" /> - <PollCard each={poll in polls} poll={poll}/> + <PollCard each={poll in polls} poll={poll} /> - <Pagination pagination={pagination} onchange="{refresh}"/> + <Pagination pagination={pagination} onchange="{refresh}" /> </div> <div show={polls.length === 0} class="c-alert c-alert--info"> {__.noPoll} </div> + + + + <form if={opts.method === "createdPolls"} onsubmit="{assignPoll}" class="assign-form"> + <fieldset> + <legend>{__.assignPollToMe_title}</legend> + + <p><i class="fa fa-question-circle-o"></i> {__.assignPollToMe_desc}</p> + <div class="o-form-element"> + <div class="o-field o-field--icon-left"> + <i class="fa fa-fw fa-link c-icon"></i> + <input class="c-field" + type="text" + name="pollToAssign" + ref="pollToAssign" + placeholder={pollToAssignPlaceholder} + pattern={pollToAssignUrlPattern} + required> + </div> + </div> + + <div class="actions"> + <div class="actions-left"> + <div id="assign-poll-success-message" if={assignedPollTitle}> + <div class="close-message" onclick="{closeMessage}"><i class="fa fa-times" aria-hidden="true"></i></div> + <p> + {__.assignSuccessMessage} + </p> + <p> + <em>{assignedPollTitle}</em> + </p> + </div> + </div> + <div class="actions-right"> + <button type="submit" + class="c-button c-button--info pull-right"> + <i class="fa fa-link"/> + {__.assignPollToMe} + </button> + </div> + </div> + </fieldset> + </form> </div> </div> +</Polls> + +<style> <script type="es6"> this.loaded = false; let session = require("../../js/Session"); this.installBundle(session, "polls"); + this.pollToAssignPlaceholder = session.pollenUIContext.uiEndPoint + "/#poll/xxxx/vote/xxxx"; + this.pollToAssignUrlPattern = session.pollenUIContext.uiEndPoint + "/#poll/(.+)/vote/(.+)"; + this.assignedPollTitle = undefined; this.pagination = { order: "topiaCreateDate", @@ -51,6 +100,7 @@ require("./PollCard.tag.html"); let pollService = require("../../js/PollService"); this.refresh = () => { + this.assignedPollTitle = undefined; return pollService[this.opts.method](this.pagination).then((result) => { this.polls = result.elements; Object.assign(this.pagination, result.pagination); @@ -72,6 +122,31 @@ require("./PollCard.tag.html"); this.refresh(); }; + this.assignPoll = (e) => { + e.preventDefault(); + e.stopPropagation(); + var pollUrl = this.refs.pollToAssign.value; + var regex = new RegExp(this.pollToAssignUrlPattern); + var finds = regex.exec(pollUrl); + + return pollService.assignPoll(finds[1], finds[2]).then((result) => { + if (result) { + this.refresh(); + console.log(result); + this.assignedPollTitle = result.title; + this.update(); + } + }); + }; + + this.closeMessage = (e) => { + e.preventDefault(); + e.stopPropagation(); + var messageElement = document.getElementById("assign-poll-success-message"); + messageElement.parentNode.removeChild(messageElement); + this.assignedPollTitle = undefined; + }; + </script> <style> @@ -92,5 +167,36 @@ require("./PollCard.tag.html"); width: 200px; } + .assign-form { + margin: 20px 0; + } + + .assign-form legend { + font-weight: bold; + color: #2c3e50; + } + + .assign-form fieldset { + padding: 20px; + border: 1px solid #96a8b2; + border-radius: 5px; + } + + #assign-poll-success-message { + position: relative; + background: #aaffaa; + padding: 10px 30px 10px; + box-shadow: 5px 5px 5px 0px #9b9b9b; + border-radius: 5px; + } + + .close-message { + position: absolute; + top: 10px; + right: 10px; + color: #666; + cursor: pointer; + } + </style> </Polls> -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
participants (1)
-
chorem.org scm