branch feature/1_socialauth updated (c04a57ed -> d20e8ccc)
This is an automated email from the git hooks/post-receive script. New change to branch feature/1_socialauth in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git from c04a57ed refs #1 erreur si l'utilisateur veut se connecter via un service tiers et que son email est deja utilisé par un autre compte Pollen new 52a15fd5 refs #1 envoi d'un mail à la création d'un compte a partir d'un service tiers new 3b091220 refs #1 permettre l'ajout d'un mot de passe à des comptes créés à partir de service tiers new d20e8ccc refs #1 permettre d'ajouter des comptes tiers à un compte existant The 3 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 d20e8cccd0f2aa719ec15b108a13b583c8f049b8 Author: Kevin Morin <morin@codelutin.com> Date: Mon Sep 4 15:21:58 2017 +0200 refs #1 permettre d'ajouter des comptes tiers à un compte existant commit 3b0912205a842e282c2be9b4d36ea1e89720a5f1 Author: Kevin Morin <morin@codelutin.com> Date: Thu Aug 31 16:08:45 2017 +0200 refs #1 permettre l'ajout d'un mot de passe à des comptes créés à partir de service tiers commit 52a15fd5cdd12976cc22c029b18dc438fd8bf2b6 Author: Kevin Morin <morin@codelutin.com> Date: Thu Aug 31 14:57:45 2017 +0200 refs #1 envoi d'un mail à la création d'un compte a partir d'un service tiers Summary of changes: .../persistence/entity/UserCredentialTopiaDao.java | 30 +++++++ .../db/migration/h2/V3_0_0_8__add_credentials.sql | 1 + .../postgresql/V3_0_0_8__add_credentials.sql | 1 + pollen-persistence/src/main/xmi/pollen.zargo | Bin 28069 -> 28138 bytes .../pollen/rest/api/PollenRestApiApplication.java | 4 +- .../PollenEmailAlreadyUsedExceptionMapper.java | 20 ----- ...rProviderAccountAlreadyUsedExceptionMapper.java | 20 +++++ .../org/chorem/pollen/rest/api/v1/ApiUtils.java | 2 + .../org/chorem/pollen/rest/api/v1/AuthApi.java | 11 ++- .../chorem/pollen/rest/api/v1/PollenUserApi.java | 39 +++++++-- .../chorem/pollen/services/PollenUIContext.java | 10 +++ .../pollen/services/bean/PollenUserBean.java | 33 +++++++- .../pollen/services/bean/UserCredentialBean.java | 49 +++++++++++ .../services/service/NotificationService.java | 11 +++ .../pollen/services/service/PollenUserService.java | 9 +- .../pollen/services/service/SocialAuthService.java | 92 +++++++++++++++++---- .../pollen/services/service/mail/EmailService.java | 35 ++++++++ ...va => UserAccountCreatedFromProviderEmail.java} | 38 ++++----- .../security/PollenAuthenticationException.java | 4 + .../security/PollenEmailAlreadyUsedException.java | 11 --- ...EmailOrProviderAccountAlreadyUsedException.java | 11 +++ .../services/service/security/SecurityService.java | 10 ++- .../UserAccountCreatedFromProviderEmail.mustache | 10 +++ ...UserAccountCreatedFromProviderEmail_fr.mustache | 11 +++ .../i18n/pollen-services_en_GB.properties | 20 +++++ .../i18n/pollen-services_fr_FR.properties | 20 +++++ .../service/PollenUIUrlRenderServiceTest.java | 1 + pollen-ui-riot-js/src/main/web/i18n.json | 2 + pollen-ui-riot-js/src/main/web/js/Session.js | 3 +- pollen-ui-riot-js/src/main/web/tag/SignIn.tag.html | 2 +- .../src/main/web/tag/UserProfile.tag.html | 11 ++- .../src/main/web/tag/poll/Polls.tag.html | 2 +- 32 files changed, 426 insertions(+), 97 deletions(-) create mode 100644 pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/UserCredentialTopiaDao.java delete mode 100644 pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/exceptionMappers/PollenEmailAlreadyUsedExceptionMapper.java create mode 100644 pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/exceptionMappers/PollenEmailOrProviderAccountAlreadyUsedExceptionMapper.java create mode 100644 pollen-services/src/main/java/org/chorem/pollen/services/bean/UserCredentialBean.java copy pollen-services/src/main/java/org/chorem/pollen/services/service/mail/{UserAccountCreatedEmail.java => UserAccountCreatedFromProviderEmail.java} (66%) delete mode 100644 pollen-services/src/main/java/org/chorem/pollen/services/service/security/PollenEmailAlreadyUsedException.java create mode 100644 pollen-services/src/main/java/org/chorem/pollen/services/service/security/PollenEmailOrProviderAccountAlreadyUsedException.java create mode 100644 pollen-services/src/main/resources/email/UserAccountCreatedFromProviderEmail.mustache create mode 100644 pollen-services/src/main/resources/email/UserAccountCreatedFromProviderEmail_fr.mustache -- 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/1_socialauth in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit 52a15fd5cdd12976cc22c029b18dc438fd8bf2b6 Author: Kevin Morin <morin@codelutin.com> Date: Thu Aug 31 14:57:45 2017 +0200 refs #1 envoi d'un mail à la création d'un compte a partir d'un service tiers --- .../chorem/pollen/services/PollenUIContext.java | 10 +++ .../services/service/NotificationService.java | 11 ++++ .../pollen/services/service/SocialAuthService.java | 2 + .../pollen/services/service/mail/EmailService.java | 35 ++++++++++ .../mail/UserAccountCreatedFromProviderEmail.java | 76 ++++++++++++++++++++++ .../UserAccountCreatedFromProviderEmail.mustache | 10 +++ ...UserAccountCreatedFromProviderEmail_fr.mustache | 11 ++++ .../i18n/pollen-services_en_GB.properties | 20 ++++++ .../i18n/pollen-services_fr_FR.properties | 20 ++++++ .../service/PollenUIUrlRenderServiceTest.java | 1 + pollen-ui-riot-js/src/main/web/js/Session.js | 3 +- pollen-ui-riot-js/src/main/web/tag/SignIn.tag.html | 2 +- 12 files changed, 199 insertions(+), 2 deletions(-) diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/PollenUIContext.java b/pollen-services/src/main/java/org/chorem/pollen/services/PollenUIContext.java index b74ddd3a..c2bdcd61 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/PollenUIContext.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/PollenUIContext.java @@ -21,6 +21,8 @@ public class PollenUIContext implements Serializable { private String resourceDownloadUrl; + private String profileUrl; + public String getUiEndPoint() { return uiEndPoint; } @@ -76,4 +78,12 @@ public class PollenUIContext implements Serializable { public void setResourceDownloadUrl(String resourceDownloadUrl) { this.resourceDownloadUrl = resourceDownloadUrl; } + + public String getProfileUrl() { + return profileUrl; + } + + public void setProfileUrl(String profileUrl) { + this.profileUrl = profileUrl; + } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/NotificationService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/NotificationService.java index 50e62797..074c6198 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/NotificationService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/NotificationService.java @@ -29,6 +29,7 @@ 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.persistence.entity.Report; +import org.chorem.pollen.persistence.entity.UserCredential; import org.chorem.pollen.persistence.entity.Vote; import org.chorem.pollen.persistence.entity.VoterList; import org.chorem.pollen.persistence.entity.VoterListMember; @@ -51,6 +52,7 @@ import org.chorem.pollen.services.service.mail.PollReportForAdminEmail; import org.chorem.pollen.services.service.mail.ResendValidationEmail; import org.chorem.pollen.services.service.mail.RestrictedPollInvitationEmail; import org.chorem.pollen.services.service.mail.UserAccountCreatedEmail; +import org.chorem.pollen.services.service.mail.UserAccountCreatedFromProviderEmail; import org.chorem.pollen.services.service.mail.UserAccountDeletedEmail; import org.chorem.pollen.services.service.mail.UserAccountEditedEmail; import org.chorem.pollen.services.service.mail.UserAccountEmailValidatedEmail; @@ -81,6 +83,15 @@ public class NotificationService extends PollenServiceSupport { } } + public void onUserCreatedFromProvider(PollenUser user, UserCredential credential) { + if (StringUtils.isNotBlank(user.getEmail())) { + EmailService emailService = getEmailService(); + UserAccountCreatedFromProviderEmail email = emailService.newUserAccountCreatedFromProviderEmail(user, credential); + email.addTo(user.getEmail()); + emailService.send(email); + } + } + public void onResendValidation(PollenUser user) { EmailService emailService = getEmailService(); ResendValidationEmail email = emailService.newUserResendValidationEmail(user); diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/SocialAuthService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/SocialAuthService.java index 8c9f7284..0132f818 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/SocialAuthService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/SocialAuthService.java @@ -81,6 +81,8 @@ public class SocialAuthService extends PollenServiceSupport { pollenUser = userDao.create(pollenUser); commit(); + + getNotificationService().onUserCreatedFromProvider(pollenUser, credential); } return getSecurityService().getSessionTokenForUser(pollenUser); diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/EmailService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/EmailService.java index f1dbe453..eed9fe95 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/EmailService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/EmailService.java @@ -44,6 +44,7 @@ import org.chorem.pollen.persistence.entity.PollenPrincipal; import org.chorem.pollen.persistence.entity.PollenResource; import org.chorem.pollen.persistence.entity.PollenUser; import org.chorem.pollen.persistence.entity.Report; +import org.chorem.pollen.persistence.entity.UserCredential; import org.chorem.pollen.persistence.entity.Vote; import org.chorem.pollen.services.bean.FeedbackBean; import org.chorem.pollen.services.bean.PollenEntityId; @@ -63,6 +64,9 @@ import java.util.Locale; import java.util.Map; import java.util.Set; +import static org.nuiton.i18n.I18n.n; +import static org.nuiton.i18n.I18n.t; + /** * Created on 4/30/14. * @@ -76,6 +80,28 @@ public class EmailService extends PollenServiceSupport { public static final String RECIPIENT_SEPARATOR = ";"; + static { + n("pollen.service.mail.loginProvider.amazon"); + n("pollen.service.mail.loginProvider.facebook"); + n("pollen.service.mail.loginProvider.flickr"); + n("pollen.service.mail.loginProvider.foursquare"); + n("pollen.service.mail.loginProvider.github"); + n("pollen.service.mail.loginProvider.googleplus"); + n("pollen.service.mail.loginProvider.hotmail"); + n("pollen.service.mail.loginProvider.instagram"); + n("pollen.service.mail.loginProvider.linkedin"); + n("pollen.service.mail.loginProvider.linkedin2"); + n("pollen.service.mail.loginProvider.mendeley"); + n("pollen.service.mail.loginProvider.myspace"); + n("pollen.service.mail.loginProvider.nimble"); + n("pollen.service.mail.loginProvider.runkeeper"); + n("pollen.service.mail.loginProvider.salesforce"); + n("pollen.service.mail.loginProvider.stackexchange"); + n("pollen.service.mail.loginProvider.twitter"); + n("pollen.service.mail.loginProvider.yahoo"); + n("pollen.service.mail.loginProvider.yammer"); + } + public ChoiceAddedEmail newChoiceAddedEmail(Poll poll, Choice choice) { ChoiceAddedEmail email = new ChoiceAddedEmail(getLocale()); email.setPoll(poll); @@ -213,6 +239,15 @@ public class EmailService extends PollenServiceSupport { return email; } + public UserAccountCreatedFromProviderEmail newUserAccountCreatedFromProviderEmail(PollenUser user, + UserCredential credential) { + UserAccountCreatedFromProviderEmail email = new UserAccountCreatedFromProviderEmail(getLocale()); + email.setUser(user); + email.setProvider(t("pollen.service.mail.loginProvider." + credential.getProvider())); + email.setProfileUrl(getUIContext().getProfileUrl()); + return email; + } + public UserAccountEditedEmail newUserAccountEditedEmail(PollenUser user) { UserAccountEditedEmail email = new UserAccountEditedEmail(getLocale()); email.setUser(user); diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/UserAccountCreatedFromProviderEmail.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/UserAccountCreatedFromProviderEmail.java new file mode 100644 index 00000000..8f7adec3 --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/UserAccountCreatedFromProviderEmail.java @@ -0,0 +1,76 @@ +package org.chorem.pollen.services.service.mail; + +/* + * #%L + * Pollen :: Service + * %% + * Copyright (C) 2009 - 2017 Code Lutin, 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.persistence.entity.PollenUser; +import org.nuiton.i18n.I18n; + +import java.util.Locale; + +/** + * Created on 4/30/14. + * + * @author Tony Chemit - dev@tchemit.fr + * @since 2.0 + */ +public class UserAccountCreatedFromProviderEmail extends PollenMail { + + private PollenUser user; + private String provider; + private String profileUrl; + + protected UserAccountCreatedFromProviderEmail(Locale locale) { + super(locale); + } + + @Override + public String getSubject() { + if (user.getName() == null) { + return I18n.l(locale, "pollen.service.mail.UserAccountCreatedFromProviderEmail.subject", user.getEmail()); + } + return I18n.l(locale, "pollen.service.mail.UserAccountCreatedFromProviderEmail.subject", user.getName()); + } + + public PollenUser getUser() { + return user; + } + + public void setUser(PollenUser user) { + this.user = user; + } + + public String getProvider() { + return provider; + } + + public void setProvider(String provider) { + this.provider = provider; + } + + public String getProfileUrl() { + return profileUrl; + } + + public void setProfileUrl(String profileUrl) { + this.profileUrl = profileUrl; + } +} diff --git a/pollen-services/src/main/resources/email/UserAccountCreatedFromProviderEmail.mustache b/pollen-services/src/main/resources/email/UserAccountCreatedFromProviderEmail.mustache new file mode 100644 index 00000000..e477bd98 --- /dev/null +++ b/pollen-services/src/main/resources/email/UserAccountCreatedFromProviderEmail.mustache @@ -0,0 +1,10 @@ +Welcome {{user.name}}, + +You have just signed in for the first time with your {{provider}} account. + +A Pollen account has ben automatically created with your profile information: +Name: {{user.name}} +Email: {{user.email}} + +You can edit this information in the following page: {{profileUrl}} +You also can set a password to sign in to Pollen without using {{provider}}. \ No newline at end of file diff --git a/pollen-services/src/main/resources/email/UserAccountCreatedFromProviderEmail_fr.mustache b/pollen-services/src/main/resources/email/UserAccountCreatedFromProviderEmail_fr.mustache new file mode 100644 index 00000000..7619d044 --- /dev/null +++ b/pollen-services/src/main/resources/email/UserAccountCreatedFromProviderEmail_fr.mustache @@ -0,0 +1,11 @@ +Bonjour {{user.name}}, + +Vous venez de vous connecter à Pollen pour la première fois à partir de votre compte {{provider}}. + +Un compte Pollen a été automatiquement créé avec les informations de votre profil : + +Nom : {{user.name}} +Courriel : {{user.email}} + +Vous pouvez modifier ces informations sur la page suivante : {{profileUrl}} +Vous pouvez également renseigner un mot de passe pour pouvoir vous connecter à Pollen sans passer par {{provider}}. \ No newline at end of file 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 aeb42167..b19d9a81 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 @@ -155,6 +155,7 @@ pollen.service.mail.PollVoteReminderEmail.subject=[Pollen] Reminder to vote on p pollen.service.mail.ResendValidationEmail.subject=[Pollen] Invitation to validate your account %s pollen.service.mail.RestrictedPollInvitationEmail.subject=[Pollen] Invitation to vote on poll %s pollen.service.mail.UserAccountCreatedEmail.subject=[Pollen] Confirmation of account creation %s +pollen.service.mail.UserAccountCreatedFromProviderEmail.subject=[Pollen] Confirmation of account creation %s pollen.service.mail.UserAccountDeletedEmail.subject=[Pollen] Confirmation of deletion of the account %s pollen.service.mail.UserAccountEditedEmail.subject=[Pollen] Update of the account %s pollen.service.mail.UserAccountEmailValidatedEmail.subject=[Pollen] Validation of your account %s @@ -164,3 +165,22 @@ pollen.service.mail.VoteDeletedEmail.subject=[Pollen] A vote was deleted in poll pollen.service.mail.VoteEditedEmail.subject=[Pollen] A vote was edited in poll %s pollen.service.mail.VoteSummaryEmail.subject=[Pollen] Summary of the votes since %s for the poll %s pollen.service.mail.feedbackEmail.subject=[Pollen] feedback - %s +pollen.service.mail.loginProvider.amazon=Amazon +pollen.service.mail.loginProvider.facebook=Facebook +pollen.service.mail.loginProvider.flickr=Flickr +pollen.service.mail.loginProvider.foursquare=Foursquare +pollen.service.mail.loginProvider.github=Github +pollen.service.mail.loginProvider.googleplus=Google +pollen.service.mail.loginProvider.hotmail=Hotmail +pollen.service.mail.loginProvider.instagram=Instagram +pollen.service.mail.loginProvider.linkedin=LinkedIn +pollen.service.mail.loginProvider.linkedin2=LinkedIn +pollen.service.mail.loginProvider.mendeley=Mendeley +pollen.service.mail.loginProvider.myspace=MySpace +pollen.service.mail.loginProvider.nimble=Nimble +pollen.service.mail.loginProvider.runkeeper=Runkeeper +pollen.service.mail.loginProvider.salesforce=Salesforce +pollen.service.mail.loginProvider.stackexchange=Stack Exchange +pollen.service.mail.loginProvider.twitter=Twitter +pollen.service.mail.loginProvider.yahoo=Yahoo +pollen.service.mail.loginProvider.yammer=Yammer 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 5cd63aff..ab2f93c8 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 @@ -154,6 +154,7 @@ pollen.service.mail.PollVoteReminderEmail.subject=[Pollen] Rappel du vote au son pollen.service.mail.ResendValidationEmail.subject=[Pollen] Validez votre compte %s pollen.service.mail.RestrictedPollInvitationEmail.subject=[Pollen] Invitation au sondage %s pollen.service.mail.UserAccountCreatedEmail.subject=[Pollen] Confirmation de création du compte %s +pollen.service.mail.UserAccountCreatedFromProviderEmail.subject=[Pollen] Confirmation de création du compte %s pollen.service.mail.UserAccountDeletedEmail.subject=[Pollen] Confirmation de suppression du compte %s pollen.service.mail.UserAccountEditedEmail.subject=[Pollen] Édition du compte %s pollen.service.mail.UserAccountEmailValidatedEmail.subject=[Pollen] Valiation de votre compte %s @@ -162,3 +163,22 @@ pollen.service.mail.VoteAddedEmail.subject=[Pollen] Un nouveau vote a été ajou pollen.service.mail.VoteDeletedEmail.subject=[Pollen] Un vote a été supprimé sur le sondage %s pollen.service.mail.VoteEditedEmail.subject=[Pollen] Un vote a été modifié du sondage %s pollen.service.mail.feedbackEmail.subject=[Pollen] retour utilisateur - %s +pollen.service.mail.loginProvider.amazon=Amazon +pollen.service.mail.loginProvider.facebook=Facebook +pollen.service.mail.loginProvider.flickr=Flickr +pollen.service.mail.loginProvider.foursquare=Foursquare +pollen.service.mail.loginProvider.github=Github +pollen.service.mail.loginProvider.googleplus=Google +pollen.service.mail.loginProvider.hotmail=Hotmail +pollen.service.mail.loginProvider.instagram=Instagram +pollen.service.mail.loginProvider.linkedin=LinkedIn +pollen.service.mail.loginProvider.linkedin2=LinkedIn +pollen.service.mail.loginProvider.mendeley=Mendeley +pollen.service.mail.loginProvider.myspace=MySpace +pollen.service.mail.loginProvider.nimble=Nimble +pollen.service.mail.loginProvider.runkeeper=Runkeeper +pollen.service.mail.loginProvider.salesforce=Salesforce +pollen.service.mail.loginProvider.stackexchange=Stack Exchange +pollen.service.mail.loginProvider.twitter=Twitter +pollen.service.mail.loginProvider.yahoo=Yahoo +pollen.service.mail.loginProvider.yammer=Yammer diff --git a/pollen-services/src/test/java/org/chorem/pollen/services/service/PollenUIUrlRenderServiceTest.java b/pollen-services/src/test/java/org/chorem/pollen/services/service/PollenUIUrlRenderServiceTest.java index 2081fc10..41517f1e 100644 --- a/pollen-services/src/test/java/org/chorem/pollen/services/service/PollenUIUrlRenderServiceTest.java +++ b/pollen-services/src/test/java/org/chorem/pollen/services/service/PollenUIUrlRenderServiceTest.java @@ -47,6 +47,7 @@ public class PollenUIUrlRenderServiceTest extends AbstractPollenServiceTest { pollenUIContext.setPollEditUrl(UI_END_POINT + "/#poll/edit/{pollId}/{token}"); pollenUIContext.setPollVoteUrl(UI_END_POINT + "/#poll/vote/{pollId}/{token}"); pollenUIContext.setPollVoteEditUrl(UI_END_POINT + "/#poll/vote/{pollId}/{voteId}/{token}"); + pollenUIContext.setProfileUrl(UI_END_POINT + "/#user/profile"); } @Test diff --git a/pollen-ui-riot-js/src/main/web/js/Session.js b/pollen-ui-riot-js/src/main/web/js/Session.js index 5582ba2a..2c5da6ed 100644 --- a/pollen-ui-riot-js/src/main/web/js/Session.js +++ b/pollen-ui-riot-js/src/main/web/js/Session.js @@ -46,7 +46,8 @@ class Session { pollVoteEditUrl: window.location.origin + "/#poll/{pollId}/vote/{voteId}/{token}", pollEditUrl: window.location.origin + "/#poll/{pollId}/edit/{token}", resourceUrl: this.configuration.endPoint + "/v1/resources/{resourceId}", - resourceDownloadUrl: this.configuration.endPoint + "/v1/resources/{resourceId}/download" + resourceDownloadUrl: this.configuration.endPoint + "/v1/resources/{resourceId}/download", + profileUrl: this.configuration.endPoint + "/#user/profile" }; // pour contenir les traductions this.i18n = require("../i18n.json"); diff --git a/pollen-ui-riot-js/src/main/web/tag/SignIn.tag.html b/pollen-ui-riot-js/src/main/web/tag/SignIn.tag.html index f58786ac..10f992e7 100644 --- a/pollen-ui-riot-js/src/main/web/tag/SignIn.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/SignIn.tag.html @@ -52,7 +52,7 @@ require("./components/HumanInput.tag.html"); <div class="c-hint--static c-hint--error">{message}</div> <p><a onclick="{newPassword}">{__.lostpassword}</a></p> </div> - <div class="o-form-element align-center"> + <div class="o-form-element align-center" if="{loginProviders.length > 0}"> <p>Ou connectez vous avec votre compte :</p> <p> <a each="{loginProvider in loginProviders}" class="provider-link" -- 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/1_socialauth in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit 3b0912205a842e282c2be9b4d36ea1e89720a5f1 Author: Kevin Morin <morin@codelutin.com> Date: Thu Aug 31 16:08:45 2017 +0200 refs #1 permettre l'ajout d'un mot de passe à des comptes créés à partir de service tiers --- .../java/org/chorem/pollen/services/bean/PollenUserBean.java | 12 +++++++++++- .../chorem/pollen/services/service/PollenUserService.java | 8 +++++--- .../service/security/PollenAuthenticationException.java | 4 ++++ .../pollen/services/service/security/SecurityService.java | 10 +++++++++- pollen-ui-riot-js/src/main/web/i18n.json | 2 ++ pollen-ui-riot-js/src/main/web/tag/UserProfile.tag.html | 11 ++++++++--- pollen-ui-riot-js/src/main/web/tag/poll/Polls.tag.html | 2 +- 7 files changed, 40 insertions(+), 9 deletions(-) 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 9bb64057..42d33279 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 @@ -46,6 +46,8 @@ public class PollenUserBean extends PollenBean<PollenUser> { protected boolean emailIsValidate; + protected boolean withPassword; + public PollenUserBean() { super(PollenUser.class); } @@ -62,7 +64,7 @@ public class PollenUserBean extends PollenBean<PollenUser> { setEmail(entity.getEmail()); setPassword(entity.getPassword()); setEmailIsValidate(entity.getEmailActivationToken() == null); - + setWithPassword(entity.getPassword() != null); } @Override @@ -136,4 +138,12 @@ public class PollenUserBean extends PollenBean<PollenUser> { public void setBanned(boolean banned) { this.banned = banned; } + + public boolean isWithPassword() { + return withPassword; + } + + public void setWithPassword(boolean withPassword) { + this.withPassword = withPassword; + } } 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 b3cf72ef..5db9468d 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 @@ -82,8 +82,11 @@ public class PollenUserService extends PollenServiceSupport implements PollenSer checkIsConnected(); checkNotNull(userId); - PollenUser pollenUser = getUser0(userId); - + PollenUser pollenUser = getConnectedUser(); + if (!userId.equals(pollenUser.getTopiaId())) { + checkIsAdmin(); + pollenUser = getUser0(userId); + } return toBean(PollenUserBean.class, pollenUser, pollenUserFunction); } @@ -146,7 +149,6 @@ public class PollenUserService extends PollenServiceSupport implements PollenSer String newPassword) throws InvalidFormException { checkNotNull(userId); - checkNotNull(oldPassword); checkNotNull(newPassword); PollenUser user = getUser0(userId); diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/security/PollenAuthenticationException.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/security/PollenAuthenticationException.java index f2635c8a..85ac88cd 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/security/PollenAuthenticationException.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/security/PollenAuthenticationException.java @@ -31,6 +31,10 @@ public class PollenAuthenticationException extends Exception { private static final long serialVersionUID = 1L; + public PollenAuthenticationException() { + super(); + } + public PollenAuthenticationException(Exception e) { super(e); } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/security/SecurityService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/security/SecurityService.java index 1ccb28bb..f351b350 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/security/SecurityService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/security/SecurityService.java @@ -25,6 +25,7 @@ import com.google.common.base.Joiner; import com.google.common.base.Preconditions; import com.google.common.collect.Sets; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.shiro.authc.AuthenticationException; @@ -125,6 +126,10 @@ public class SecurityService extends PollenServiceSupport { public PollenEntityRef<PollenUser> login(String login, String password, Boolean rememberMe) throws PollenAuthenticationException, PollenEmailNotValidatedException, PollenUserBannedException { + if (StringUtils.isBlank(password)) { + throw new PollenAuthenticationException(); + } + Subject subject = getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(login, password); if (rememberMe != null) { @@ -335,7 +340,10 @@ public class SecurityService extends PollenServiceSupport { public void checkUserPassword(PollenUser user, String password) throws PollenInvalidPasswordException { - String encodedPassword = serviceContext.encodePassword(user.getSalt(), password); + String encodedPassword = null; + if (password != null) { + encodedPassword = serviceContext.encodePassword(user.getSalt(), password); + } boolean valid = Objects.equals(encodedPassword, user.getPassword()); if (user.isBanned() || !valid) { throw new PollenInvalidPasswordException(); diff --git a/pollen-ui-riot-js/src/main/web/i18n.json b/pollen-ui-riot-js/src/main/web/i18n.json index 4dea55f4..93c25c00 100644 --- a/pollen-ui-riot-js/src/main/web/i18n.json +++ b/pollen-ui-riot-js/src/main/web/i18n.json @@ -394,6 +394,7 @@ "userProfile_repeatPassword_placeholder": "Répétez votre mot de passe", "userProfile_repeatPassword_error": "Les deux mots de passe ne sont pas identiques.", "userProfile_savePassword": "Enregistrer", + "userProfile_updatedPassword": "Votre mot de passe a été mis à jour", "choice_description_placeholder": "Vous pouvez saisir une description pour ce choix", "date-picker_today": "Aujourd'hui", "date-picker_dateplaceholder": "Date", @@ -937,6 +938,7 @@ "userProfile_repeatPassword_placeholder": "Confirm your new password", "userProfile_repeatPassword_error": "The two passwords are not identical.", "userProfile_savePassword": "Save", + "userProfile_updatedPassword": "Your password has been updated", "choice_description_placeholder": "You can enter a description for this choice", "date-picker_today": "Today", "date-picker_dateplaceholder": "Date", diff --git a/pollen-ui-riot-js/src/main/web/tag/UserProfile.tag.html b/pollen-ui-riot-js/src/main/web/tag/UserProfile.tag.html index c06bed10..f7e2eda0 100644 --- a/pollen-ui-riot-js/src/main/web/tag/UserProfile.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/UserProfile.tag.html @@ -64,7 +64,7 @@ require("./components/HumanInput.tag.html"); <form ref="password-form" class="password-form"> <HumanInput onsubmit={submitPassword}/> <h3 class="c-heading"><i class="fa fa-key"/> {__.passwordChange}</h3> - <div class="o-form-element"> + <div class="o-form-element" if="{user.withPassword}"> <label class="c-label" for="oldPassword">{__.oldPassword}</label> <input class="c-field {c-field--error : errors.oldPassword}" type="password" @@ -131,6 +131,7 @@ require("./components/HumanInput.tag.html"); this.user = session.getUser() || {}; let userService = require("../js/UserService"); let authService = require("../js/AuthService"); + let Message = require("../js/Message"); this.onUserChange = (user) => { this.user = user || {}; @@ -170,13 +171,17 @@ require("./components/HumanInput.tag.html"); this.checkPassword(); if (this.errors.repeatPassword === undefined) { - let oldPassword = this.refs.oldPassword.value; + let oldPassword = this.user.withPassword ? this.refs.oldPassword.value : null; let newPassword = this.refs.newPassword.value; userService.changePassword(this.user.id, oldPassword, newPassword).then(() => { - this.refs.oldPassword.value = ""; + if (this.user.withPassword) { + this.refs.oldPassword.value = ""; + } this.refs.newPassword.value = ""; this.refs.repeatPassword.value = ""; + this.user.withPassword = true; this.update(); + this.bus.trigger("message", new Message(this._l("updatedPassword"), "success")); }) .catch((errors) => { this.errors = errors; 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 6f403e32..8fb9e3e7 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 @@ -96,7 +96,7 @@ require("../components/Search.tag.html"); return pollService.assignPoll(finds[1], finds[2]).then((result) => { if (result) { this.refresh(); - this.bus.trigger("message", new Message(this._l("assignSuccessMessage", result.title), "succes")); + this.bus.trigger("message", new Message(this._l("assignSuccessMessage", result.title), "success")); } else { this.bus.trigger("message", new Message(this.__.alreadyAssignMessage, "warning")); } -- 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/1_socialauth in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit d20e8cccd0f2aa719ec15b108a13b583c8f049b8 Author: Kevin Morin <morin@codelutin.com> Date: Mon Sep 4 15:21:58 2017 +0200 refs #1 permettre d'ajouter des comptes tiers à un compte existant --- .../persistence/entity/UserCredentialTopiaDao.java | 30 +++++++ .../db/migration/h2/V3_0_0_8__add_credentials.sql | 1 + .../postgresql/V3_0_0_8__add_credentials.sql | 1 + pollen-persistence/src/main/xmi/pollen.zargo | Bin 28069 -> 28138 bytes .../pollen/rest/api/PollenRestApiApplication.java | 4 +- .../PollenEmailAlreadyUsedExceptionMapper.java | 20 ----- ...rProviderAccountAlreadyUsedExceptionMapper.java | 20 +++++ .../org/chorem/pollen/rest/api/v1/ApiUtils.java | 2 + .../org/chorem/pollen/rest/api/v1/AuthApi.java | 11 ++- .../chorem/pollen/rest/api/v1/PollenUserApi.java | 39 +++++++-- .../pollen/services/bean/PollenUserBean.java | 21 +++++ .../pollen/services/bean/UserCredentialBean.java | 49 +++++++++++ .../pollen/services/service/PollenUserService.java | 1 + .../pollen/services/service/SocialAuthService.java | 90 +++++++++++++++++---- .../security/PollenEmailAlreadyUsedException.java | 11 --- ...EmailOrProviderAccountAlreadyUsedException.java | 11 +++ 16 files changed, 249 insertions(+), 62 deletions(-) diff --git a/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/UserCredentialTopiaDao.java b/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/UserCredentialTopiaDao.java new file mode 100644 index 00000000..68302fed --- /dev/null +++ b/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/UserCredentialTopiaDao.java @@ -0,0 +1,30 @@ +package org.chorem.pollen.persistence.entity; + +import java.util.HashMap; +import java.util.Map; + +public class UserCredentialTopiaDao extends AbstractUserCredentialTopiaDao<UserCredential> { + + public boolean isCredentialValid(String provider, String credentialUserId, String userTopiaId, String email) { + String query = "SELECT COUNT(*)" + + " FROM " + PollenUser.class.getName() + " AS user RIGHT JOIN user." + PollenUser.PROPERTY_USER_CREDENTIAL + " AS credential" + + " WHERE" + + " (credential." + UserCredential.PROPERTY_PROVIDER + " = :provider" + + " AND credential." + UserCredential.PROPERTY_USER_ID + " = :credentialUserId)"; + if (email != null) { + query += " OR (user." + PollenUser.PROPERTY_TOPIA_ID + " = :userTopiaId" + + " AND credential." + UserCredential.PROPERTY_EMAIL + " = :credentialEmail)" + + " OR user." + PollenUser.PROPERTY_EMAIL + " = :userEmail"; + } + + Map<String, Object> params = new HashMap<>(); + params.put("provider", provider); + params.put("credentialUserId", credentialUserId); + if (email != null) { + params.put("userEmail", email); + params.put("userTopiaId", userTopiaId); + params.put("credentialEmail", email); + } + return count(query, params) == 0; + } +} diff --git a/pollen-persistence/src/main/resources/db/migration/h2/V3_0_0_8__add_credentials.sql b/pollen-persistence/src/main/resources/db/migration/h2/V3_0_0_8__add_credentials.sql index 1825b8ae..48fadea4 100644 --- a/pollen-persistence/src/main/resources/db/migration/h2/V3_0_0_8__add_credentials.sql +++ b/pollen-persistence/src/main/resources/db/migration/h2/V3_0_0_8__add_credentials.sql @@ -6,6 +6,7 @@ CREATE TABLE USERCREDENTIAL ( TOPIACREATEDATE TIMESTAMP, PROVIDER VARCHAR(255), USERID VARCHAR(255), + USERNAME VARCHAR(255), EMAIL VARCHAR(255), POLLENUSER VARCHAR(255), FOREIGN KEY (POLLENUSER) references POLLENUSER(TOPIAID) diff --git a/pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_0_8__add_credentials.sql b/pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_0_8__add_credentials.sql index 2280308e..d1f2803d 100644 --- a/pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_0_8__add_credentials.sql +++ b/pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_0_8__add_credentials.sql @@ -6,6 +6,7 @@ CREATE TABLE USERCREDENTIAL ( TOPIACREATEDATE TIMESTAMP, PROVIDER VARCHAR(255), USERID VARCHAR(255), + USERNAME VARCHAR(255), EMAIL VARCHAR(255), POLLENUSER VARCHAR(255), FOREIGN KEY (POLLENUSER) references POLLENUSER(TOPIAID) diff --git a/pollen-persistence/src/main/xmi/pollen.zargo b/pollen-persistence/src/main/xmi/pollen.zargo index 0f29e782..7ce056d6 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 271b223a..687e4f38 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,7 +7,7 @@ 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.PollenEmailAlreadyUsedExceptionMapper; +import org.chorem.pollen.rest.api.exceptionMappers.PollenEmailOrProviderAccountAlreadyUsedExceptionMapper; import org.chorem.pollen.rest.api.exceptionMappers.PollenEmailNotValidatedExceptionMapper; import org.chorem.pollen.rest.api.exceptionMappers.PollenInvalidEmailActivationTokenExceptionMapper; import org.chorem.pollen.rest.api.exceptionMappers.PollenInvalidPermissionExceptionMapper; @@ -62,7 +62,7 @@ public class PollenRestApiApplication extends Application { new PollenInvalidPermissionExceptionMapper(), new PollenInvalidEmailActivationTokenExceptionMapper(), new PollenEmailNotValidatedExceptionMapper(), - new PollenEmailAlreadyUsedExceptionMapper(), + new PollenEmailOrProviderAccountAlreadyUsedExceptionMapper(), new PollenUserBannedExceptionMapper(), new InvalidFormExceptionMapper(), new FavoriteListImportExceptionMapper(), diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/exceptionMappers/PollenEmailAlreadyUsedExceptionMapper.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/exceptionMappers/PollenEmailAlreadyUsedExceptionMapper.java deleted file mode 100644 index 3b1ec37b..00000000 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/exceptionMappers/PollenEmailAlreadyUsedExceptionMapper.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.chorem.pollen.rest.api.exceptionMappers; - -import org.chorem.pollen.services.service.security.PollenEmailAlreadyUsedException; - -import javax.ws.rs.core.Response; - -/** - * @author Sylvain Bavencoff - bavencoff@codelutin.com - */ -public class PollenEmailAlreadyUsedExceptionMapper extends PollenAbstractExceptionMapper<PollenEmailAlreadyUsedException> { - - public PollenEmailAlreadyUsedExceptionMapper() { - super(Response.Status.FORBIDDEN); - } - - @Override - protected Object getEntity(PollenEmailAlreadyUsedException exception) { - return "emailAlreadyUsed"; - } -} diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/exceptionMappers/PollenEmailOrProviderAccountAlreadyUsedExceptionMapper.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/exceptionMappers/PollenEmailOrProviderAccountAlreadyUsedExceptionMapper.java new file mode 100644 index 00000000..d6671c68 --- /dev/null +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/exceptionMappers/PollenEmailOrProviderAccountAlreadyUsedExceptionMapper.java @@ -0,0 +1,20 @@ +package org.chorem.pollen.rest.api.exceptionMappers; + +import org.chorem.pollen.services.service.security.PollenEmailOrProviderAccountAlreadyUsedException; + +import javax.ws.rs.core.Response; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class PollenEmailOrProviderAccountAlreadyUsedExceptionMapper extends PollenAbstractExceptionMapper<PollenEmailOrProviderAccountAlreadyUsedException> { + + public PollenEmailOrProviderAccountAlreadyUsedExceptionMapper() { + super(Response.Status.FORBIDDEN); + } + + @Override + protected Object getEntity(PollenEmailOrProviderAccountAlreadyUsedException exception) { + return "emailOrProviderAccountAlreadyUsed"; + } +} diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/ApiUtils.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/ApiUtils.java index cebdb51c..dec31e1b 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/ApiUtils.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/ApiUtils.java @@ -27,6 +27,8 @@ import java.util.regex.Pattern; */ public class ApiUtils { + public static final String SOCIAL_AUTH_MANAGER_SESSION_KEY = "socialAuthManager"; + public static Response exportBeanToResponse(ExportBean exportBean) { InputStream inputStream = IOUtils.toInputStream(exportBean.getContent(), Charsets.UTF_8); diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/AuthApi.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/AuthApi.java index fc2ac99b..776a4f6c 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/AuthApi.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/AuthApi.java @@ -80,7 +80,6 @@ public class AuthApi { public static final String COOKIE_POLLEN_AUTH = "pollen-auth"; private static final String COOKIE_POLLEN_CONNECTED = "pollen-connected"; private static final int COOKIE_MAX_AGE = 60 * 60 * 24 * 365; // 1 year - private static final String SOCIAL_AUTH_MANAGER_SESSION_KEY = "socialAuthManager"; public static Response.ResponseBuilder removeAuthCookie(Response.ResponseBuilder reponseBuilder) { @@ -203,7 +202,7 @@ public class AuthApi { throws Exception { SocialAuthManager socialAuthManager = socialAuthService.getSocialAuthManager(); - request.getSession(true).setAttribute(SOCIAL_AUTH_MANAGER_SESSION_KEY, socialAuthManager); + request.getSession(true).setAttribute(ApiUtils.SOCIAL_AUTH_MANAGER_SESSION_KEY, socialAuthManager); return socialAuthManager.getAuthenticationUrl(providerId, providerRedirection); } @@ -214,15 +213,15 @@ public class AuthApi { @Context SecurityService securityService, @Context PollenSecurityContext securityContext, @Context HttpServletRequest request, - @HeaderParam("authorization") String authorization) + String providerReturn) throws Exception { SocialAuthManager socialAuthManager = - (SocialAuthManager) request.getSession().getAttribute(SOCIAL_AUTH_MANAGER_SESSION_KEY); + (SocialAuthManager) request.getSession().getAttribute(ApiUtils.SOCIAL_AUTH_MANAGER_SESSION_KEY); //socialAuthManager - request.getSession().removeAttribute(SOCIAL_AUTH_MANAGER_SESSION_KEY); + request.getSession().removeAttribute(ApiUtils.SOCIAL_AUTH_MANAGER_SESSION_KEY); Gson gson = new Gson(); - Map<String, String> paramsMap = gson.fromJson(authorization, Map.class); + Map<String, String> paramsMap = gson.fromJson(providerReturn, Map.class); PollenEntityRef<PollenUser> userPollenEntityRef = socialAuthService.login(socialAuthManager, paramsMap); return getLoginResponseFromPollenUser(serviceContext, securityService, securityContext, userPollenEntityRef); diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenUserApi.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenUserApi.java index 123e13c3..188b9ea7 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenUserApi.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenUserApi.java @@ -21,7 +21,10 @@ package org.chorem.pollen.rest.api.v1; * #L% */ +import com.google.gson.Gson; +import org.brickred.socialauth.SocialAuthManager; import org.chorem.pollen.persistence.entity.PollenUser; +import org.chorem.pollen.persistence.entity.UserCredential; import org.chorem.pollen.rest.api.beans.ChangePasswordBean; import org.chorem.pollen.services.bean.PaginationParameterBean; import org.chorem.pollen.services.bean.PaginationResultBean; @@ -30,9 +33,11 @@ import org.chorem.pollen.services.bean.PollenEntityRef; import org.chorem.pollen.services.bean.PollenUserBean; import org.chorem.pollen.services.service.InvalidFormException; import org.chorem.pollen.services.service.PollenUserService; +import org.chorem.pollen.services.service.SocialAuthService; import org.chorem.pollen.services.service.security.PollenInvalidEmailActivationTokenException; import org.chorem.pollen.services.service.security.PollenSecurityContext; +import javax.servlet.http.HttpServletRequest; import javax.ws.rs.BeanParam; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; @@ -45,6 +50,7 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; +import java.util.Map; import java.util.Objects; /** @@ -65,7 +71,6 @@ public class PollenUserApi { @QueryParam("search") String search) { return pollenUserService.getUsers(paginationParameter, search); - } @Path("/users/connected") @@ -74,7 +79,6 @@ public class PollenUserApi { PollenUser pollenUser = securityContext.getPollenUser(); Objects.requireNonNull(pollenUser,"Could not find connected user"); return pollenUserService.getUser(pollenUser.getTopiaId()); - } @Path("/users/{userId}") @@ -83,7 +87,6 @@ public class PollenUserApi { @PathParam("userId") PollenEntityId<PollenUser> userId) { return pollenUserService.getUser(userId.getEntityId()); - } @Path("/users") @@ -92,7 +95,6 @@ public class PollenUserApi { PollenUserBean user) throws InvalidFormException { return pollenUserService.createUser(user); - } @Path("/users/{userId}") @@ -101,7 +103,6 @@ public class PollenUserApi { PollenUserBean user) throws InvalidFormException { return pollenUserService.editUser(user); - } @Path("/users/{userId}") @@ -111,7 +112,6 @@ public class PollenUserApi { @QueryParam("anonymize") boolean anonymize) { pollenUserService.deleteUser(userId.getEntityId(), anonymize); - } @Path("/users/{userId}") @@ -121,7 +121,6 @@ public class PollenUserApi { @QueryParam("token") String token) throws PollenInvalidEmailActivationTokenException { pollenUserService.validateUserEmail(userId.getEntityId(), token); - } @Path("/users/{userId}/password") @@ -131,6 +130,32 @@ public class PollenUserApi { ChangePasswordBean bean) throws InvalidFormException { pollenUserService.changePassword(userId.getEntityId(), bean.getOldPassword(), bean.getNewPassword()); + } + + @Path("/users/{userId}/credentials/{provider}") + @POST + public String addUserCredential(@Context SocialAuthService socialAuthService, + @Context HttpServletRequest request, + @PathParam("userId") PollenEntityId<PollenUser> userId, + @PathParam("provider") String provider, + String providerReturn) throws Exception { + + SocialAuthManager socialAuthManager = + (SocialAuthManager) request.getSession().getAttribute(ApiUtils.SOCIAL_AUTH_MANAGER_SESSION_KEY); + //socialAuthManager + request.getSession().removeAttribute(ApiUtils.SOCIAL_AUTH_MANAGER_SESSION_KEY); + Gson gson = new Gson(); + Map<String, String> paramsMap = gson.fromJson(providerReturn, Map.class); + return socialAuthService.addCredentialToUser(userId, socialAuthManager, paramsMap); + } + + @Path("/users/{userId}/credentials/{credentialId}") + @DELETE + public void deleteUserCredential(@Context SocialAuthService socialAuthService, + @Context HttpServletRequest request, + @PathParam("userId") PollenEntityId<PollenUser> userId, + @PathParam("credentialId") PollenEntityId<UserCredential> credentialId) throws Exception { + socialAuthService.deleteUserCredential(userId, credentialId); } } 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 42d33279..d167d9eb 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 @@ -24,6 +24,10 @@ package org.chorem.pollen.services.bean; import org.chorem.pollen.persistence.entity.PollenUser; import org.chorem.pollen.persistence.entity.PollenUserImpl; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + /** * Created on 5/15/14. * @@ -48,6 +52,8 @@ public class PollenUserBean extends PollenBean<PollenUser> { protected boolean withPassword; + protected List<UserCredentialBean> credentials = new ArrayList<>(); + public PollenUserBean() { super(PollenUser.class); } @@ -65,6 +71,13 @@ public class PollenUserBean extends PollenBean<PollenUser> { setPassword(entity.getPassword()); setEmailIsValidate(entity.getEmailActivationToken() == null); setWithPassword(entity.getPassword() != null); + setCredentials(entity.getUserCredential().stream() + .map(userCredential -> { + UserCredentialBean userCredentialBean = new UserCredentialBean(); + userCredentialBean.fromEntity(userCredential); + return userCredentialBean; + }) + .collect(Collectors.toList())); } @Override @@ -146,4 +159,12 @@ public class PollenUserBean extends PollenBean<PollenUser> { public void setWithPassword(boolean withPassword) { this.withPassword = withPassword; } + + public List<UserCredentialBean> getCredentials() { + return credentials; + } + + public void setCredentials(List<UserCredentialBean> credentials) { + this.credentials = credentials; + } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/UserCredentialBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/UserCredentialBean.java new file mode 100644 index 00000000..d88f3444 --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/UserCredentialBean.java @@ -0,0 +1,49 @@ +package org.chorem.pollen.services.bean; + +import org.chorem.pollen.persistence.entity.UserCredential; +import org.chorem.pollen.persistence.entity.UserCredentialImpl; + +/** + * @author Kevin Morin (Code Lutin) + */ +public class UserCredentialBean extends PollenBean<UserCredential> { + + protected String provider; + protected String userName; + + protected UserCredentialBean() { + super(UserCredential.class); + } + + @Override + public void fromEntity(UserCredential entity) { + setEntityId(entity.getTopiaId()); + setProvider(entity.getProvider()); + setUserName(entity.getUserName()); + } + + @Override + public UserCredential toEntity() { + UserCredential entity = new UserCredentialImpl(); + entity.setTopiaId(getEntityId()); + entity.setProvider(getProvider()); + entity.setUserName(getUserName()); + return entity; + } + + public String getProvider() { + return provider; + } + + public void setProvider(String provider) { + this.provider = provider; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } +} 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 5db9468d..ae57949f 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 @@ -137,6 +137,7 @@ public class PollenUserService extends PollenServiceSupport implements PollenSer anonymizeUser(user); } + getUserCredentialDao().deleteAll(user.getUserCredential()); getPollenUserDao().delete(user); commit(); diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/SocialAuthService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/SocialAuthService.java index 0132f818..bfa301af 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/SocialAuthService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/SocialAuthService.java @@ -16,9 +16,12 @@ import org.chorem.pollen.persistence.entity.PollenUserImpl; import org.chorem.pollen.persistence.entity.PollenUserTopiaDao; import org.chorem.pollen.persistence.entity.UserCredential; import org.chorem.pollen.persistence.entity.UserCredentialImpl; +import org.chorem.pollen.persistence.entity.UserCredentialTopiaDao; import org.chorem.pollen.services.bean.LoginProviderBean; +import org.chorem.pollen.services.bean.PollenEntityId; import org.chorem.pollen.services.bean.PollenEntityRef; -import org.chorem.pollen.services.service.security.PollenEmailAlreadyUsedException; +import org.chorem.pollen.services.service.security.PollenEmailOrProviderAccountAlreadyUsedException; +import org.chorem.pollen.services.service.security.PollenUnauthorizedException; import java.util.ArrayList; import java.util.List; @@ -46,30 +49,26 @@ public class SocialAuthService extends PollenServiceSupport { PollenUserTopiaDao userDao = getPollenUserDao(); Optional<PollenUser> pollenUserForCredential = userDao.tryFindUserWithCredential(p.getProviderId(), p.getValidatedId()); - String name = p.getDisplayName(); - if (name == null) { - name = p.getFirstName() + " " + p.getLastName(); - } - if (pollenUserForCredential.isPresent()) { - if (log.isInfoEnabled()) { - log.info("credentials found : " + name); + if (log.isDebugEnabled()) { + log.debug("credentials found"); } pollenUser = pollenUserForCredential.get(); } else if (userDao.emailExists(p.getEmail())) { - throw new PollenEmailAlreadyUsedException(); + throw new PollenEmailOrProviderAccountAlreadyUsedException(); } else { - if (log.isInfoEnabled()) { - log.info("create new user : " + name); + String name = p.getFullName(); + if (name == null) { + name = p.getFirstName() + " " + p.getLastName(); + } + + if (log.isDebugEnabled()) { + log.debug("create new user : " + name); } - UserCredential credential = new UserCredentialImpl(); - credential.setProvider(p.getProviderId()); - credential.setUserId(p.getValidatedId()); - credential.setEmail(p.getEmail()); - credential = getUserCredentialDao().create(credential); + UserCredential credential = createUserCredential(p); pollenUser = new PollenUserImpl(); pollenUser.setName(name); @@ -88,6 +87,51 @@ public class SocialAuthService extends PollenServiceSupport { return getSecurityService().getSessionTokenForUser(pollenUser); } + public String addCredentialToUser(PollenEntityId<PollenUser> userId, + SocialAuthManager manager, + Map<String, String> paramsMap) throws Exception { + + checkIsConnected(); + PollenUser connectedUser = getConnectedUser(); + if (!connectedUser.getTopiaId().equals(userId.getEntityId())) { + throw new PollenUnauthorizedException(userId.getReducedId()); + } + + AuthProvider provider = manager.connect(paramsMap); + + // get profile + Profile p = provider.getUserProfile(); + + boolean credentialValid = getUserCredentialDao().isCredentialValid(p.getProviderId(), + p.getValidatedId(), + connectedUser.getTopiaId(), + p.getEmail()); + if (!credentialValid) { + throw new PollenEmailOrProviderAccountAlreadyUsedException(); + } + + UserCredential credential = createUserCredential(p); + connectedUser.addUserCredential(credential); + commit(); + + return credential.getUserName(); + } + + protected UserCredential createUserCredential(Profile p) { + String accountName = p.getDisplayName(); + if (accountName == null) { + accountName = p.getFullName(); + } + + UserCredential credential = new UserCredentialImpl(); + credential.setProvider(p.getProviderId()); + credential.setUserId(p.getValidatedId()); + credential.setUserName(accountName); + credential.setEmail(p.getEmail()); + credential = getUserCredentialDao().create(credential); + return credential; + } + public SocialAuthManager getSocialAuthManager() throws Exception { //Create an instance of SocialAuthConfgi object SocialAuthConfig config = SocialAuthConfig.getDefault(); @@ -185,4 +229,18 @@ public class SocialAuthService extends PollenServiceSupport { dao.delete(dao.forTopiaIdEquals(providerId).findUnique()); commit(); } + + public void deleteUserCredential(PollenEntityId<PollenUser> userId, PollenEntityId<UserCredential> credentialId) { + checkNotNull(credentialId); + + checkIsConnected(); + PollenUser connectedUser = getConnectedUser(); + if (!connectedUser.getTopiaId().equals(userId.getEntityId())) { + throw new PollenUnauthorizedException(userId.getReducedId()); + } + + UserCredentialTopiaDao dao = getUserCredentialDao(); + dao.delete(dao.forTopiaIdEquals(credentialId.getEntityId()).findUnique()); + commit(); + } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/security/PollenEmailAlreadyUsedException.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/security/PollenEmailAlreadyUsedException.java deleted file mode 100644 index afd67772..00000000 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/security/PollenEmailAlreadyUsedException.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.chorem.pollen.services.service.security; - -/** - * @author Kevin Morin (Code Lutin) - */ -public class PollenEmailAlreadyUsedException extends Exception { - - public PollenEmailAlreadyUsedException() { - super("emailAlreadyUsed"); - } -} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/security/PollenEmailOrProviderAccountAlreadyUsedException.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/security/PollenEmailOrProviderAccountAlreadyUsedException.java new file mode 100644 index 00000000..cb5bf239 --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/security/PollenEmailOrProviderAccountAlreadyUsedException.java @@ -0,0 +1,11 @@ +package org.chorem.pollen.services.service.security; + +/** + * @author Kevin Morin (Code Lutin) + */ +public class PollenEmailOrProviderAccountAlreadyUsedException extends Exception { + + public PollenEmailOrProviderAccountAlreadyUsedException() { + super("emailOrProviderAccountAlreadyUsed"); + } +} -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
participants (1)
-
chorem.org scm