branch feature/28_avatars updated (350108b4 -> 24e6ad02)
This is an automated email from the git hooks/post-receive script. New change to branch feature/28_avatars in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git omits 350108b4 ajout e variable dans le package.json omits a9ba220a refs #28 utilisation de l'avatar omits c0153a85 refs #28 forumlaire d'upload de l'avatar omits 8c8503c4 refs #28 finalement on stocke l'avatar dans une resource en base meme quand ça vient d'un tiers omits 7d02cf80 refs #28 message si avatar non chargé omits 13096a6c refs #28 ajout de l'avatar pour l'utilisateur + possibilité d'en choisir un parmi les providers disponibles adds 91d1a280 passage à la version 3.1.0-SNAPSHOT adds 3efc4383 passage à la version 3.1.0 pour le js adds 8ab5eda8 correction du footer en anglais adds a774bbd8 Limitations du nombre votants (ref #58), Déplacement des méthodes de transformation des entités en bean dans les services adds 6b46dc9a indiquer la limite de votants pour un sondage (ref #58) adds bf74bb03 ne pas afficher les votes ignorés (ref #58) adds 9ba5ccb2 Dans les listes des sondages : voir les sondage hors limites du nombre de votants (ref #58) adds 5cd67c81 Création et modification d'un sondage restreint, avertir si le nombre de participant dépasse le nombre maximum de votants (ref #58) adds 9f142759 envoyer un mail quand le nombre de votants dépasse la valeur max (ref #58) adds a59ea622 Merge branch 'feature/58-limitation-des-votants' into develop new 9b760b6e refs #28 ajout de l'avatar pour l'utilisateur + possibilité d'en choisir un parmi les providers disponibles new 47dd3508 refs #28 message si avatar non chargé new 9caec977 refs #28 finalement on stocke l'avatar dans une resource en base meme quand ça vient d'un tiers new d1e7140e refs #28 forumlaire d'upload de l'avatar new 16c884e0 refs #28 utilisation de l'avatar new 0b084777 ajout e variable dans le package.json new 24e6ad02 rebase This update added new revisions after undoing existing revisions. That is to say, some revisions that were in the old version of the branch are not in the new version. This situation occurs when a user --force pushes a change and generates a repository containing something like this: * -- * -- B -- O -- O -- O (350108b4) \ N -- N -- N refs/heads/feature/28_avatars (24e6ad02) You should already have received notification emails for all of the O revisions, and so the following emails describe only the N revisions from the common base, B. Any revisions marked "omits" are not gone; other references still refer to them. Any revisions marked "discards" are gone forever. The 7 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 24e6ad02ac0ead09b2d055f551f32bcc7c94b723 Author: Kevin Morin <morin@codelutin.com> Date: Fri Sep 29 11:37:16 2017 +0200 rebase commit 0b0847773d28b33d3f335a57b42e2c788011d9de Author: Kevin Morin <morin@codelutin.com> Date: Fri Sep 29 10:02:28 2017 +0200 ajout e variable dans le package.json commit 16c884e01c8cbead7aaf4c8e2bee6d01fdbd578b Author: Kevin Morin <morin@codelutin.com> Date: Thu Sep 28 11:12:43 2017 +0200 refs #28 utilisation de l'avatar commit d1e7140e8550cec3c833305d93de37a8e085768d Author: Kevin Morin <morin@codelutin.com> Date: Tue Sep 26 10:55:28 2017 +0200 refs #28 forumlaire d'upload de l'avatar commit 9caec9779a14f73cb004f551f9a8bc138da298c6 Author: Kevin Morin <morin@codelutin.com> Date: Fri Sep 22 17:42:51 2017 +0200 refs #28 finalement on stocke l'avatar dans une resource en base meme quand ça vient d'un tiers commit 47dd3508f0a2309a4be61a6098b72a14673d475a Author: Kevin Morin <morin@codelutin.com> Date: Fri Sep 22 10:39:10 2017 +0200 refs #28 message si avatar non chargé commit 9b760b6ec8ce7bd2f9ae40ee98071fe32e86c597 Author: Kevin Morin <morin@codelutin.com> Date: Tue Sep 19 18:10:32 2017 +0200 refs #28 ajout de l'avatar pour l'utilisateur + possibilité d'en choisir un parmi les providers disponibles Summary of changes: pollen-persistence/pom.xml | 2 +- .../pollen/persistence/entity/PollTopiaDao.java | 12 ++ .../pollen/persistence/entity/VoteToChoices.java | 15 +- .../pollen/persistence/entity/VoteTopiaDao.java | 11 ++ .../db/migration/h2/V3_1_0_1__add_premium.sql | 8 + ..._2__add_avatar.sql => V3_1_0_2__add_avatar.sql} | 0 .../migration/postgresql/V3_1_0_1__add_premium.sql | 8 + ..._2__add_avatar.sql => V3_1_0_2__add_avatar.sql} | 0 pollen-persistence/src/main/xmi/pollen.properties | 2 +- pollen-persistence/src/main/xmi/pollen.zargo | Bin 28921 -> 29157 bytes pollen-rest-api/pom.xml | 2 +- .../org/chorem/pollen/rest/api/AuthApiTest.java | 8 +- .../chorem/pollen/rest/api/PollenUserApiTest.java | 2 +- pollen-services/pom.xml | 2 +- pollen-services/src/main/config/PollenServices.ini | 8 +- .../chorem/pollen/services/PollenUIContext.java | 10 ++ .../services/bean/ChildFavoriteListBean.java | 23 --- .../chorem/pollen/services/bean/ChoiceBean.java | 29 ---- .../chorem/pollen/services/bean/CommentBean.java | 44 ------ .../pollen/services/bean/FavoriteListBean.java | 20 --- .../services/bean/FavoriteListMemberBean.java | 24 --- .../pollen/services/bean/LoginProviderBean.java | 23 --- .../org/chorem/pollen/services/bean/PollBean.java | 133 ++-------------- .../chorem/pollen/services/bean/PollenBean.java | 4 - .../chorem/pollen/services/bean/PollenBeans.java | 49 +----- .../pollen/services/bean/PollenUserBean.java | 66 +++----- .../chorem/pollen/services/bean/ReportBean.java | 21 --- .../pollen/services/bean/UserCredentialBean.java | 21 +-- .../org/chorem/pollen/services/bean/VoteBean.java | 80 ++-------- .../pollen/services/bean/VoteToChoiceBean.java | 24 --- .../chorem/pollen/services/bean/VoterListBean.java | 36 ++--- .../pollen/services/bean/VoterListMemberBean.java | 34 ----- .../bean/export/ChildFavoriteListExport.java | 16 -- .../bean/resource/AbstractResourceBean.java | 27 +--- .../services/bean/resource/ResourceFileBean.java | 46 +++--- .../services/bean/resource/ResourceMetaBean.java | 12 +- .../services/bean/resource/ResourceStreamBean.java | 34 +---- .../pollen/services/service/ChoiceService.java | 57 ++++--- .../pollen/services/service/CommentService.java | 45 ++++-- .../services/service/FavoriteListService.java | 73 ++++++--- .../pollen/services/service/FeedbackService.java | 3 +- .../pollen/services/service/FixturesService.java | 14 +- .../chorem/pollen/services/service/GtuService.java | 50 +++--- .../services/service/NotificationService.java | 9 ++ .../pollen/services/service/PollService.java | 168 +++++++++++++++------ .../services/service/PollenResourceService.java | 50 ++++-- .../services/service/PollenServiceSupport.java | 43 +----- .../pollen/services/service/PollenUserService.java | 127 +++++++++------- .../pollen/services/service/ReportService.java | 30 +++- .../pollen/services/service/SocialAuthService.java | 17 ++- .../services/service/VoteCountingService.java | 13 +- .../pollen/services/service/VoteService.java | 104 +++++++++---- .../pollen/services/service/VoterListService.java | 89 ++++++----- .../pollen/services/service/mail/EmailService.java | 8 + ...atedEmail.java => ExceedingMaxVotersEmail.java} | 29 ++-- .../email/ExceedingMaxVotersEmail.mustache | 5 + .../email/ExceedingMaxVotersEmail_fr.mustache | 6 + .../i18n/pollen-services_en_GB.properties | 2 + .../i18n/pollen-services_fr_FR.properties | 2 + .../services/service/PollenUserServiceTest.java | 8 +- pollen-ui-riot-js/package.json | 2 +- pollen-ui-riot-js/pom.xml | 2 +- pollen-ui-riot-js/src/main/web/css/custom.css | 6 +- pollen-ui-riot-js/src/main/web/i18n/en.json | 13 +- pollen-ui-riot-js/src/main/web/i18n/fr.json | 11 +- pollen-ui-riot-js/src/main/web/js/Session.js | 3 +- .../src/main/web/js/VoterListService.js | 25 ++- .../src/main/web/tag/UserProfile.tag.html | 1 + .../src/main/web/tag/admin/UserCard.tag.html | 16 ++ .../src/main/web/tag/admin/UserEditModal.tag.html | 19 +++ .../src/main/web/tag/components/InnerHtml.tag.html | 14 ++ .../main/web/tag/components/date-picker.tag.html | 13 +- .../src/main/web/tag/poll/Poll.tag.html | 34 ++++- .../src/main/web/tag/poll/PollCard.tag.html | 26 +++- .../src/main/web/tag/poll/Votes.tag.html | 29 +++- .../src/main/web/tag/voterList/VoterList.tag.html | 17 ++- pollen-votecounting-aggregator/pom.xml | 2 +- pollen-votecounting-api/pom.xml | 2 +- pollen-votecounting-borda/pom.xml | 2 +- pollen-votecounting-condorcet/pom.xml | 2 +- pollen-votecounting-coombs/pom.xml | 2 +- pollen-votecounting-instant-runoff/pom.xml | 2 +- pollen-votecounting-normal/pom.xml | 2 +- pollen-votecounting-number/pom.xml | 2 +- pollen-votecounting-percentage/pom.xml | 2 +- pom.xml | 2 +- 86 files changed, 1010 insertions(+), 1049 deletions(-) create mode 100644 pollen-persistence/src/main/resources/db/migration/h2/V3_1_0_1__add_premium.sql rename pollen-persistence/src/main/resources/db/migration/h2/{V3_0_1_2__add_avatar.sql => V3_1_0_2__add_avatar.sql} (100%) create mode 100644 pollen-persistence/src/main/resources/db/migration/postgresql/V3_1_0_1__add_premium.sql rename pollen-persistence/src/main/resources/db/migration/postgresql/{V3_0_1_2__add_avatar.sql => V3_1_0_2__add_avatar.sql} (100%) copy pollen-services/src/main/java/org/chorem/pollen/services/service/mail/{PollCreatedEmail.java => ExceedingMaxVotersEmail.java} (69%) create mode 100644 pollen-services/src/main/resources/email/ExceedingMaxVotersEmail.mustache create mode 100644 pollen-services/src/main/resources/email/ExceedingMaxVotersEmail_fr.mustache create mode 100644 pollen-ui-riot-js/src/main/web/tag/components/InnerHtml.tag.html -- 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/28_avatars in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit 9b760b6ec8ce7bd2f9ae40ee98071fe32e86c597 Author: Kevin Morin <morin@codelutin.com> Date: Tue Sep 19 18:10:32 2017 +0200 refs #28 ajout de l'avatar pour l'utilisateur + possibilité d'en choisir un parmi les providers disponibles --- .../db/migration/h2/V3_0_0_11__add_avatar.sql | 2 ++ .../migration/postgresql/V3_0_0_11__add_avatar.sql | 2 ++ .../chorem/pollen/rest/api/v1/PollenUserApi.java | 17 +++++++++++++ .../pollen/services/bean/PollenUserBean.java | 10 ++++++++ .../pollen/services/service/SocialAuthService.java | 18 ++++++++++++++ pollen-ui-riot-js/src/main/web/js/UserService.js | 6 +++++ pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html | 28 ++++++++++++++++++++-- .../src/main/web/tag/UserProfile.tag.html | 24 +++++++++++++++++++ 8 files changed, 105 insertions(+), 2 deletions(-) diff --git a/pollen-persistence/src/main/resources/db/migration/h2/V3_0_0_11__add_avatar.sql b/pollen-persistence/src/main/resources/db/migration/h2/V3_0_0_11__add_avatar.sql new file mode 100644 index 00000000..197b01b4 --- /dev/null +++ b/pollen-persistence/src/main/resources/db/migration/h2/V3_0_0_11__add_avatar.sql @@ -0,0 +1,2 @@ +-- add user's avatar +alter table pollenUser add avatar VARCHAR(255); diff --git a/pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_0_11__add_avatar.sql b/pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_0_11__add_avatar.sql new file mode 100644 index 00000000..197b01b4 --- /dev/null +++ b/pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_0_11__add_avatar.sql @@ -0,0 +1,2 @@ +-- add user's avatar +alter table pollenUser add avatar VARCHAR(255); 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 130a8212..0968efa3 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 @@ -155,4 +155,21 @@ public class PollenUserApi { socialAuthService.deleteUserCredential(credentialId); } + + @Path("/users/{userId}/avatar/{provider}") + @POST + public String setAvatar(@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.setAvatarToUser(userId, socialAuthManager, paramsMap); + } } 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 a070b2d1..f18ab44f 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 @@ -55,6 +55,8 @@ public class PollenUserBean extends PollenBean<PollenUser> { protected boolean gtuValidated; + protected String avatar; + protected Date premiumTo; protected boolean premium; @@ -143,6 +145,14 @@ public class PollenUserBean extends PollenBean<PollenUser> { this.gtuValidated = gtuValidated; } + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + public Date getPremiumTo() { return premiumTo; } 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 8300665d..61150e32 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 @@ -269,4 +269,22 @@ public class SocialAuthService extends PollenServiceSupport { getUserCredentialDao().delete(credential); commit(); } + + public String setAvatarToUser(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(); + + connectedUser.setAvatar(p.getProfileImageURL()); + commit(); + + return connectedUser.getAvatar(); + } } 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 c203638a..d1cceefa 100644 --- a/pollen-ui-riot-js/src/main/web/js/UserService.js +++ b/pollen-ui-riot-js/src/main/web/js/UserService.js @@ -81,6 +81,12 @@ class UserService extends FetchService { let url = "/v1/gtu/validate"; return this.post(url); } + + getProviderAvatar(userId, query) { + let url = this._getUrlPrefix(userId) + "/avatar/" + query.loginProvider; + let body = JSON.stringify(query); + return this.post(url, body); + } } 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 7b29d834..ef16fc1b 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 @@ -236,8 +236,12 @@ require("./popup/GtuChangeModal.tag.html"); }); route("/user/profile", () => { - this.bus.trigger("pageChanged", "userProfile"); - riot.mount(this.refs.content, "userprofile"); + if (!session.isConnected()) { + route("/signin?url=/user/profile"); + } else { + this.bus.trigger("pageChanged", "userProfile"); + riot.mount(this.refs.content, "userprofile"); + } }); route("/favoriteLists", () => { this.bus.trigger("pageChanged", "favoriteLists"); @@ -301,6 +305,26 @@ require("./popup/GtuChangeModal.tag.html"); this.bus.off("user", callback); }); } + + } else if (q.action === "avatar" && session.isConnected()) { + let callback = (user) => { + userService.getProviderAvatar(user.id, q).then(() => { + location.replace(session.pollenUIContext.uiEndPoint + "/#user/profile"); + }, (e) => { + e.text().then(label => { + location.replace(session.pollenUIContext.uiEndPoint + "/#user/profile?error=" + label); + }); + }); + }; + + if (session.getUser()) { + callback(session.getUser()); + } else { + this.bus.on("user", (user) => { + callback(user); + this.bus.off("user", callback); + }); + } } } else { 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 19f5f9c5..57fd0a0b 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 @@ -164,6 +164,18 @@ require("./components/HumanInput.tag.html"); </a> </p> </div> + + <div class="o-form-element align-center" if="{loginProviders.length > 0}"> + <p>Avatar</p> + <p><img src="{user.avatar}" onerror="{test}"/></p> + <p> + <a each="{loginProvider in loginProviders}" class="provider-link" + onclick="{getProviderAvatar(loginProvider)}"> + <i class="fa fa-{authService.providerIcons[loginProvider]}" if="{authService.providerIcons[loginProvider]}"></i> + <span if="{!authService.providerIcons[loginProvider]}">{loginProvider}</span> + </a> + </p> + </div> </div> </div> @@ -190,6 +202,10 @@ require("./components/HumanInput.tag.html"); this.update(); }; +this.test = (e) => { +console.log(e) +} + this.resendValidation = () => { this.authService.resendValidation(this.user.email); }; @@ -263,6 +279,14 @@ require("./components/HumanInput.tag.html"); }); }; + getProviderAvatar= (provider) => (e) => { + let redirection = encodeURIComponent(location.origin + location.pathname + + "?loginProvider=" + provider + "&action=avatar"); + this.authService.getLoginProviderUrl(provider, redirection).then(result => { + location.assign(result); + }); + }; + this.listen("user", this.onUserChange); </script> -- 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/28_avatars in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit 47dd3508f0a2309a4be61a6098b72a14673d475a Author: Kevin Morin <morin@codelutin.com> Date: Fri Sep 22 10:39:10 2017 +0200 refs #28 message si avatar non chargé --- .../org/chorem/pollen/rest/api/v1/AuthApi.java | 1 + pollen-ui-riot-js/src/main/web/i18n/en.json | 2 + pollen-ui-riot-js/src/main/web/i18n/fr.json | 2 + pollen-ui-riot-js/src/main/web/tag/SignIn.tag.html | 2 +- .../src/main/web/tag/UserProfile.tag.html | 84 ++++++++++++---------- 5 files changed, 52 insertions(+), 39 deletions(-) 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 33ece430..04dc258e 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 @@ -227,6 +227,7 @@ public class AuthApi { return getLoginResponseFromPollenUser(serviceContext, securityService, securityContext, userPollenEntityRef); } + //FIXME post ou put et pas get @Path("/logout") @DELETE public Response logout(@Context SecurityService securityService, 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 b3325075..18469062 100644 --- a/pollen-ui-riot-js/src/main/web/i18n/en.json +++ b/pollen-ui-riot-js/src/main/web/i18n/en.json @@ -416,6 +416,8 @@ "userProfile_loginProviders": "External accounts", "userProfile_linkProvider": "Link an external account to connect to Pollen:", "userProfile_unlinkProviderMessage": "Unlink this external account? You will not be able to connect to your Pollen account with this external account.", + "userProfile_avatar": "Avatar", + "userProfile_avatarLoadingFailed": "If your avatar does not display, check that you did not enabled the tracking protection.", "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/i18n/fr.json b/pollen-ui-riot-js/src/main/web/i18n/fr.json index 3559b6b1..6824e7ca 100644 --- a/pollen-ui-riot-js/src/main/web/i18n/fr.json +++ b/pollen-ui-riot-js/src/main/web/i18n/fr.json @@ -416,6 +416,8 @@ "userProfile_loginProviders": "Comptes externes", "userProfile_linkProvider": "Associez un compte externe pour vous connecter à Pollen :", "userProfile_unlinkProviderMessage": "Désassossier ce compte externe ? Vous ne pourrez plus vous connectez à votre compte Pollen avec ce compte externe.", + "userProfile_avatar": "Avatar", + "userProfile_avatarLoadingFailed": "Si votre avatar ne s'affiche pas, vérifiez que vous n'avez pas activé la protection contre le pistage.", "choice_description_placeholder": "Vous pouvez saisir une description pour ce choix", "date-picker_today": "Aujourd'hui", "date-picker_dateplaceholder": "Date", 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 3d1c9140..c28927a5 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 @@ -160,7 +160,7 @@ require("./components/HumanInput.tag.html"); } @media (orientation: landscape) { - .body-content { + .body-container { flex-basis: 50%; } } 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 57fd0a0b..42e4cd7f 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 @@ -141,43 +141,49 @@ require("./components/HumanInput.tag.html"); </div> </form> - <div class="providers"> - <h3 class="c-heading"><i class="fa fa-sign-in"/> {__.loginProviders}</h3> - <div class="user-credentials"> - <div each="{credential, index in user.credentials}" class="user-credential {index % 2 == 0 ? 'even' : 'odd'}"> - <i if="{authService.providerIcons[credential.provider]}" - class="fa fa-{authService.providerIcons[credential.provider]}"></i> - <span if="{!authService.providerIcons[credential.provider]}">{credential.userName}</span> - <span class="credential-name">{credential.userName} <em if="{credential.emailAddress}">({credential.emailAddress})</em></span> - <button if="{user.withPassword && user.email || user.credentials.length > 1}" - onclick="{unlinkProvider(credential.id, index)}" class="c-button u-small c-button--error"><i class="fa fa-trash"></i></button> + <div class="providers"> + <h3 class="c-heading"><i class="fa fa-sign-in"/> {__.loginProviders}</h3> + <div class="user-credentials"> + <div each="{credential, index in user.credentials}" class="user-credential {index % 2 == 0 ? 'even' : 'odd'}"> + <i if="{authService.providerIcons[credential.provider]}" + class="fa fa-{authService.providerIcons[credential.provider]}"></i> + <span if="{!authService.providerIcons[credential.provider]}">{credential.userName}</span> + <span class="credential-name">{credential.userName} <em if="{credential.emailAddress}">({credential.emailAddress})</em></span> + <button if="{user.withPassword && user.email || user.credentials.length > 1}" + onclick="{unlinkProvider(credential.id, index)}" class="c-button u-small c-button--error"><i class="fa fa-trash"></i></button> + </div> </div> - </div> - - <div class="o-form-element align-center" if="{loginProviders.length > 0}"> - <p>{__.linkProvider}</p> - <p> - <a each="{loginProvider in loginProviders}" class="provider-link" - onclick="{linkProvider(loginProvider)}"> - <i class="fa fa-{authService.providerIcons[loginProvider]}" if="{authService.providerIcons[loginProvider]}"></i> - <span if="{!authService.providerIcons[loginProvider]}">{loginProvider}</span> - </a> - </p> - </div> - - <div class="o-form-element align-center" if="{loginProviders.length > 0}"> - <p>Avatar</p> - <p><img src="{user.avatar}" onerror="{test}"/></p> - <p> - <a each="{loginProvider in loginProviders}" class="provider-link" - onclick="{getProviderAvatar(loginProvider)}"> - <i class="fa fa-{authService.providerIcons[loginProvider]}" if="{authService.providerIcons[loginProvider]}"></i> - <span if="{!authService.providerIcons[loginProvider]}">{loginProvider}</span> - </a> - </p> - </div> - </div> + <div class="o-form-element align-center" if="{loginProviders.length > 0}"> + <p>{__.linkProvider}</p> + <p> + <a each="{loginProvider in loginProviders}" class="provider-link" + onclick="{linkProvider(loginProvider)}"> + <i class="fa fa-{authService.providerIcons[loginProvider]}" if="{authService.providerIcons[loginProvider]}"></i> + <span if="{!authService.providerIcons[loginProvider]}">{loginProvider}</span> + </a> + </p> + </div> + </div> + + <div class="avatar"> + <h3 class="c-heading"><i class="fa fa-sign-in"/> {__.avatar}</h3> + <div class="o-form-element align-center" if="{loginProviders.length > 0}"> + <p> + <img src="{user.avatar}" onerror="{avatarLoadingFailed}"/> + <i class="fa fa-question-circle cursor-help error" if="{avatarLoadingError}" title="{__.avatarLoadingFailed}"></i> + {} + </p> + <p> + <a each="{loginProvider in loginProviders}" class="provider-link" + onclick="{getProviderAvatar(loginProvider)}"> + <i class="fa fa-{authService.providerIcons[loginProvider]}" + if="{authService.providerIcons[loginProvider]}"></i> + <span if="{!authService.providerIcons[loginProvider]}">{loginProvider}</span> + </a> + </p> + </div> + </div> </div> </div> @@ -197,14 +203,16 @@ require("./components/HumanInput.tag.html"); this.update(); }); + this.avatarLoadingError = false; + this.onUserChange = (user) => { this.user = user || {}; this.update(); }; -this.test = (e) => { -console.log(e) -} + this.avatarLoadingFailed = (e) => { + this.avatarLoadingError = true; + } this.resendValidation = () => { this.authService.resendValidation(this.user.email); -- 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/28_avatars in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit 9caec9779a14f73cb004f551f9a8bc138da298c6 Author: Kevin Morin <morin@codelutin.com> Date: Fri Sep 22 17:42:51 2017 +0200 refs #28 finalement on stocke l'avatar dans une resource en base meme quand ça vient d'un tiers --- .../persistence/entity/PollenResourceTopiaDao.java | 12 + .../db/migration/h2/V3_0_0_11__add_avatar.sql | 2 - .../db/migration/h2/V3_0_1_2__add_avatar.sql | 3 + .../migration/postgresql/V3_0_0_11__add_avatar.sql | 2 - .../migration/postgresql/V3_0_1_2__add_avatar.sql | 3 + pollen-persistence/src/main/xmi/pollen.properties | 2 +- .../org/chorem/pollen/rest/api/v1/ApiUtils.java | 2 +- .../chorem/pollen/rest/api/v1/FavoriteListApi.java | 2 +- .../java/org/chorem/pollen/rest/api/v1/GtuApi.java | 3 + .../pollen/rest/api/v1/PollenResourceApi.java | 15 +- .../chorem/pollen/rest/api/v1/PollenUserApi.java | 4 +- .../bean/resource/AbstractResourceBean.java | 55 ++++ .../services/bean/{ => resource}/GtuMetaBean.java | 2 +- .../bean/{ => resource}/ResourceFileBean.java | 44 +-- .../bean/{ => resource}/ResourceMetaBean.java | 45 +-- .../bean/{ => resource}/ResourceStreamBean.java | 34 +-- .../chorem/pollen/services/service/GtuService.java | 4 +- .../services/service/PollenResourceService.java | 25 +- .../pollen/services/service/SocialAuthService.java | 30 +- .../src/main/web/tag/UserProfile.tag.html | 312 +++++++++++---------- 20 files changed, 309 insertions(+), 292 deletions(-) diff --git a/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/PollenResourceTopiaDao.java b/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/PollenResourceTopiaDao.java index 5410999c..ba1ac143 100644 --- a/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/PollenResourceTopiaDao.java +++ b/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/PollenResourceTopiaDao.java @@ -21,6 +21,9 @@ package org.chorem.pollen.persistence.entity; * #L% */ +import java.util.HashMap; +import java.util.Map; + /** * Created on 24/07/14. * @@ -59,4 +62,13 @@ public class PollenResourceTopiaDao extends AbstractPollenResourceTopiaDao<Polle } } + + public PollenResource findAvatarForUser(String userId) { + String hql = "SELECT " + PollenUser.PROPERTY_AVATAR + + " FROM " + PollenUser.class.getName() + " user " + + " WHERE user." + PollenUser.PROPERTY_TOPIA_ID + " = :userId"; + Map<String, Object> params = new HashMap<>(); + params.put("userId", userId); + return findUniqueOrNull(hql, params); + } } diff --git a/pollen-persistence/src/main/resources/db/migration/h2/V3_0_0_11__add_avatar.sql b/pollen-persistence/src/main/resources/db/migration/h2/V3_0_0_11__add_avatar.sql deleted file mode 100644 index 197b01b4..00000000 --- a/pollen-persistence/src/main/resources/db/migration/h2/V3_0_0_11__add_avatar.sql +++ /dev/null @@ -1,2 +0,0 @@ --- add user's avatar -alter table pollenUser add avatar VARCHAR(255); diff --git a/pollen-persistence/src/main/resources/db/migration/h2/V3_0_1_2__add_avatar.sql b/pollen-persistence/src/main/resources/db/migration/h2/V3_0_1_2__add_avatar.sql new file mode 100644 index 00000000..0bf88e60 --- /dev/null +++ b/pollen-persistence/src/main/resources/db/migration/h2/V3_0_1_2__add_avatar.sql @@ -0,0 +1,3 @@ +-- add user's avatar +alter table pollenUser add avatar VARCHAR(255); +alter table pollenUser ADD FOREIGN KEY (avatar) REFERENCES PollenResource(topiaId); diff --git a/pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_0_11__add_avatar.sql b/pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_0_11__add_avatar.sql deleted file mode 100644 index 197b01b4..00000000 --- a/pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_0_11__add_avatar.sql +++ /dev/null @@ -1,2 +0,0 @@ --- add user's avatar -alter table pollenUser add avatar VARCHAR(255); diff --git a/pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_1_2__add_avatar.sql b/pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_1_2__add_avatar.sql new file mode 100644 index 00000000..0bf88e60 --- /dev/null +++ b/pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_1_2__add_avatar.sql @@ -0,0 +1,3 @@ +-- add user's avatar +alter table pollenUser add avatar VARCHAR(255); +alter table pollenUser ADD FOREIGN KEY (avatar) REFERENCES PollenResource(topiaId); diff --git a/pollen-persistence/src/main/xmi/pollen.properties b/pollen-persistence/src/main/xmi/pollen.properties index d941b130..fb44dc92 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.1.0.1 +model.tagvalue.version=3.0.1.2 #model.tagValue.notGenerateToString=true #model.tagValue.constantPrefix=PROPERTY_ #model.tagValue.useEnumerationName=true 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 98b7ce7c..5834b267 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,7 +27,7 @@ import org.apache.commons.io.IOUtils; import org.chorem.pollen.persistence.entity.ResourceType; import org.chorem.pollen.rest.api.beans.Resource64Bean; import org.chorem.pollen.services.PollenTechnicalException; -import org.chorem.pollen.services.bean.ResourceFileBean; +import org.chorem.pollen.services.bean.resource.ResourceFileBean; import org.chorem.pollen.services.bean.export.ExportBean; import org.jboss.resteasy.plugins.providers.multipart.InputPart; import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput; diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/FavoriteListApi.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/FavoriteListApi.java index b0f92f74..5a6fe2b6 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/FavoriteListApi.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/FavoriteListApi.java @@ -33,7 +33,7 @@ import org.chorem.pollen.services.bean.PaginationResultBean; import org.chorem.pollen.services.bean.PollenBean; import org.chorem.pollen.services.bean.PollenEntityId; import org.chorem.pollen.services.bean.PollenEntityRef; -import org.chorem.pollen.services.bean.ResourceFileBean; +import org.chorem.pollen.services.bean.resource.ResourceFileBean; import org.chorem.pollen.services.bean.export.ExportBean; import org.chorem.pollen.services.service.FavoriteListImportException; import org.chorem.pollen.services.service.FavoriteListService; 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 index 91f23de1..b28619fb 100644 --- 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 @@ -1,5 +1,6 @@ package org.chorem.pollen.rest.api.v1; +<<<<<<< HEAD /*- * #%L * Pollen :: Rest Api @@ -23,6 +24,8 @@ 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.bean.resource.GtuMetaBean; +import org.chorem.pollen.services.bean.resource.ResourceStreamBean; import org.chorem.pollen.services.service.GtuService; import javax.ws.rs.Consumes; diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenResourceApi.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenResourceApi.java index 5a1d251f..3cb4f974 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenResourceApi.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenResourceApi.java @@ -22,12 +22,13 @@ package org.chorem.pollen.rest.api.v1; */ import org.chorem.pollen.persistence.entity.PollenResource; +import org.chorem.pollen.persistence.entity.PollenUser; import org.chorem.pollen.rest.api.beans.Resource64Bean; import org.chorem.pollen.services.bean.PollenEntityId; import org.chorem.pollen.services.bean.PollenEntityRef; -import org.chorem.pollen.services.bean.ResourceFileBean; -import org.chorem.pollen.services.bean.ResourceMetaBean; -import org.chorem.pollen.services.bean.ResourceStreamBean; +import org.chorem.pollen.services.bean.resource.ResourceFileBean; +import org.chorem.pollen.services.bean.resource.ResourceMetaBean; +import org.chorem.pollen.services.bean.resource.ResourceStreamBean; import org.chorem.pollen.services.service.InvalidFormException; import org.chorem.pollen.services.service.PollenResourceService; import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput; @@ -129,4 +130,12 @@ public class PollenResourceApi { pollenResourceService.deleteResource(resourceId.getEntityId()); } + + @Path("/avatar/{userId}") + @GET + public Response getUserAvatar(@Context PollenResourceService pollenResourceService, + @PathParam("userId") PollenEntityId<PollenUser> userId) { + ResourceStreamBean resource = pollenResourceService.getAvatar(userId.getEntityId()); + return Response.ok(resource.getResourceContent(), resource.getContentType()).build(); + } } 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 0968efa3..4e6662d8 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 @@ -158,7 +158,7 @@ public class PollenUserApi { @Path("/users/{userId}/avatar/{provider}") @POST - public String setAvatar(@Context SocialAuthService socialAuthService, + public void setAvatar(@Context SocialAuthService socialAuthService, @Context HttpServletRequest request, @PathParam("userId") PollenEntityId<PollenUser> userId, @PathParam("provider") String provider, @@ -170,6 +170,6 @@ public class PollenUserApi { request.getSession().removeAttribute(ApiUtils.SOCIAL_AUTH_MANAGER_SESSION_KEY); Gson gson = new Gson(); Map<String, String> paramsMap = gson.fromJson(providerReturn, Map.class); - return socialAuthService.setAvatarToUser(userId, socialAuthManager, paramsMap); + socialAuthService.setAvatarToUser(userId, socialAuthManager, paramsMap); } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/AbstractResourceBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/AbstractResourceBean.java new file mode 100644 index 00000000..33ac329e --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/AbstractResourceBean.java @@ -0,0 +1,55 @@ +package org.chorem.pollen.services.bean.resource; + +import org.chorem.pollen.persistence.entity.PollenResource; +import org.chorem.pollen.persistence.entity.ResourceType; +import org.chorem.pollen.services.bean.PollenBean; + +/** + * @author Kevin Morin (Code Lutin) + */ +public abstract class AbstractResourceBean extends PollenBean<PollenResource> { + + protected String name; + + protected long size; + + protected String contentType; + + protected ResourceType resourceType; + + protected AbstractResourceBean(Class<PollenResource> entityType) { + super(entityType); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public long getSize() { + return size; + } + + public void setSize(long size) { + this.size = size; + } + + public String getContentType() { + return contentType; + } + + public void setContentType(String contentType) { + this.contentType = contentType; + } + + public ResourceType getResourceType() { + return resourceType; + } + + public void setResourceType(ResourceType resourceType) { + this.resourceType = resourceType; + } +} 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/resource/GtuMetaBean.java similarity index 95% rename from pollen-services/src/main/java/org/chorem/pollen/services/bean/GtuMetaBean.java rename to pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/GtuMetaBean.java index 254ed493..d71c06c8 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/GtuMetaBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/GtuMetaBean.java @@ -1,4 +1,4 @@ -package org.chorem.pollen.services.bean; +package org.chorem.pollen.services.bean.resource; /*- * #%L diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/ResourceFileBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceFileBean.java similarity index 66% rename from pollen-services/src/main/java/org/chorem/pollen/services/bean/ResourceFileBean.java rename to pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceFileBean.java index 61ae8b07..9b6355d5 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/ResourceFileBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceFileBean.java @@ -1,4 +1,4 @@ -package org.chorem.pollen.services.bean; +package org.chorem.pollen.services.bean.resource; /* * #%L @@ -23,7 +23,6 @@ package org.chorem.pollen.services.bean; import org.apache.commons.io.IOUtils; import org.chorem.pollen.persistence.entity.PollenResource; -import org.chorem.pollen.persistence.entity.ResourceType; import javax.sql.rowset.serial.SerialBlob; import java.io.File; @@ -40,18 +39,10 @@ import java.util.zip.ZipException; * * @author dralagen */ -public class ResourceFileBean extends PollenBean<PollenResource> { +public class ResourceFileBean extends AbstractResourceBean { protected File file; - protected String name; - - protected long size; - - protected String contentType; - - protected ResourceType resourceType; - public ResourceFileBean() { super(PollenResource.class); } @@ -64,30 +55,6 @@ public class ResourceFileBean extends PollenBean<PollenResource> { this.file = file; } - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public long getSize() { - return size; - } - - public void setSize(long size) { - this.size = size; - } - - public String getContentType() { - return contentType; - } - - public void setContentType(String contentType) { - this.contentType = contentType; - } - public Blob getResourceBlob() throws IOException, SQLException { InputStream stream; @@ -100,11 +67,4 @@ public class ResourceFileBean extends PollenBean<PollenResource> { return new SerialBlob(IOUtils.toByteArray(stream)); } - public ResourceType getResourceType() { - return resourceType; - } - - public void setResourceType(ResourceType resourceType) { - this.resourceType = resourceType; - } } 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/resource/ResourceMetaBean.java similarity index 56% rename from pollen-services/src/main/java/org/chorem/pollen/services/bean/ResourceMetaBean.java rename to pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceMetaBean.java index 7c6c0d9e..a646dd4f 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/resource/ResourceMetaBean.java @@ -1,4 +1,4 @@ -package org.chorem.pollen.services.bean; +package org.chorem.pollen.services.bean.resource; /* * #%L @@ -22,7 +22,6 @@ package org.chorem.pollen.services.bean; */ import org.chorem.pollen.persistence.entity.PollenResource; -import org.chorem.pollen.persistence.entity.ResourceType; import java.util.Date; @@ -31,15 +30,7 @@ import java.util.Date; * * @author dralagen */ -public class ResourceMetaBean extends PollenBean<PollenResource> { - - protected String name; - - protected long size; - - protected String contentType; - - protected ResourceType resourceType; +public class ResourceMetaBean extends AbstractResourceBean { protected Date uploadDate; @@ -47,38 +38,6 @@ public class ResourceMetaBean extends PollenBean<PollenResource> { super(PollenResource.class); } - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public long getSize() { - return size; - } - - public void setSize(long size) { - this.size = size; - } - - public String getContentType() { - return contentType; - } - - public void setContentType(String contentType) { - this.contentType = contentType; - } - - public ResourceType getResourceType() { - return resourceType; - } - - public void setResourceType(ResourceType resourceType) { - this.resourceType = resourceType; - } - public Date getUploadDate() { return uploadDate; } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/ResourceStreamBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceStreamBean.java similarity index 71% rename from pollen-services/src/main/java/org/chorem/pollen/services/bean/ResourceStreamBean.java rename to pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceStreamBean.java index c2a4088d..833b98ba 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/ResourceStreamBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceStreamBean.java @@ -1,4 +1,4 @@ -package org.chorem.pollen.services.bean; +package org.chorem.pollen.services.bean.resource; /* * #%L @@ -35,16 +35,10 @@ import java.sql.SQLException; * * @author dralagen */ -public class ResourceStreamBean extends PollenBean<PollenResource> { +public class ResourceStreamBean extends AbstractResourceBean { protected InputStream resourceContent; - protected String name; - - protected long size; - - protected String contentType; - public ResourceStreamBean() { super(PollenResource.class); } @@ -57,30 +51,6 @@ public class ResourceStreamBean extends PollenBean<PollenResource> { this.resourceContent = resourceContent; } - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public long getSize() { - return size; - } - - public void setSize(long size) { - this.size = size; - } - - public String getContentType() { - return contentType; - } - - public void setContentType(String contentType) { - this.contentType = contentType; - } - public Blob getResourceBlob() throws IOException, SQLException { return new SerialBlob(IOUtils.toByteArray(getResourceContent())); } 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 index 83a01416..2198b652 100644 --- 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 @@ -28,8 +28,8 @@ 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.chorem.pollen.services.bean.resource.GtuMetaBean; +import org.chorem.pollen.services.bean.resource.ResourceStreamBean; import org.nuiton.util.pagination.PaginationOrder; import java.util.Collections; 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 9cdd15f3..fe4e5fc8 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 @@ -29,9 +29,10 @@ import org.chorem.pollen.services.UnitHuman; import org.chorem.pollen.services.bean.GtuMetaBean; import org.chorem.pollen.services.bean.PollenEntityId; import org.chorem.pollen.services.bean.PollenEntityRef; -import org.chorem.pollen.services.bean.ResourceFileBean; -import org.chorem.pollen.services.bean.ResourceMetaBean; -import org.chorem.pollen.services.bean.ResourceStreamBean; +import org.chorem.pollen.services.bean.resource.AbstractResourceBean; +import org.chorem.pollen.services.bean.resource.ResourceFileBean; +import org.chorem.pollen.services.bean.resource.ResourceMetaBean; +import org.chorem.pollen.services.bean.resource.ResourceStreamBean; import org.nuiton.topia.persistence.TopiaIdFactory; import javax.imageio.ImageIO; @@ -162,6 +163,17 @@ public class PollenResourceService extends PollenServiceSupport implements Polle return PollenEntityRef.of(savedResource); } + public PollenResource createAvatarResource(ResourceStreamBean resource) throws InvalidFormException { + checkNotNull(resource); + checkIsNotPersisted(resource); + + ErrorMap errorMap = checkRessource(resource); + errorMap.failIfNotEmpty(); + + // commit done by the caller + return getPollenResourceDao().create(resource.toEntity()); + } + public void deleteResource(String resourceId) { checkNotNull(resourceId); checkIsAdmin(); @@ -177,6 +189,11 @@ public class PollenResourceService extends PollenServiceSupport implements Polle commit(); } + public ResourceStreamBean getAvatar(String userId) { + PollenResource resource = getPollenResourceDao().findAvatarForUser(userId); + return toBean(ResourceStreamBean.class, resource); + } + protected PollenResource getResource0(String resourceId) { return getPollenResourceDao().forTopiaIdEquals(resourceId).findUnique(); @@ -229,7 +246,7 @@ public class PollenResourceService extends PollenServiceSupport implements Polle return resourceId.getReducedId(); } - protected ErrorMap checkRessource(ResourceFileBean resource) { + protected ErrorMap checkRessource(AbstractResourceBean resource) { ErrorMap errorMap = new ErrorMap(); if (resource.getSize() > getPollenServiceConfig().getResourceMaxSize()) { 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 61150e32..38f5e17e 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 @@ -32,16 +32,21 @@ import org.brickred.socialauth.util.Constants; import org.brickred.socialauth.util.OAuthConfig; import org.chorem.pollen.persistence.entity.LoginProvider; import org.chorem.pollen.persistence.entity.LoginProviderTopiaDao; +import org.chorem.pollen.persistence.entity.PollenResource; import org.chorem.pollen.persistence.entity.PollenUser; import org.chorem.pollen.persistence.entity.PollenUserImpl; import org.chorem.pollen.persistence.entity.PollenUserTopiaDao; +import org.chorem.pollen.persistence.entity.ResourceType; import org.chorem.pollen.persistence.entity.UserCredential; import org.chorem.pollen.persistence.entity.UserCredentialImpl; 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.bean.resource.ResourceStreamBean; import org.chorem.pollen.services.service.security.PollenEmailOrProviderAccountAlreadyUsedException; +import java.net.URL; +import java.net.URLConnection; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -270,21 +275,34 @@ public class SocialAuthService extends PollenServiceSupport { commit(); } - public String setAvatarToUser(PollenEntityId<PollenUser> userId, SocialAuthManager manager, Map<String, String> paramsMap) throws Exception { + public void setAvatarToUser(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); + PollenResourceService pollenResourceService = getPollenResourceService(); + + if (connectedUser.getAvatar() != null) { + pollenResourceService.deleteResource(connectedUser.getAvatar().getTopiaId()); + } // get profile + AuthProvider provider = manager.connect(paramsMap); Profile p = provider.getUserProfile(); - - connectedUser.setAvatar(p.getProfileImageURL()); + String avatarUrl = p.getProfileImageURL(); + URLConnection connection = new URL(avatarUrl).openConnection(); + String contentType = connection.getContentType(); + ResourceStreamBean resourceStreamBean = new ResourceStreamBean(); + resourceStreamBean.setResourceContent(connection.getInputStream()); + resourceStreamBean.setName(connectedUser.getTopiaId()); + resourceStreamBean.setContentType(contentType); + resourceStreamBean.setSize(connection.getContentLength()); + resourceStreamBean.setResourceType(ResourceType.AVATAR); + PollenResource avatarResource = pollenResourceService.createAvatarResource(resourceStreamBean); +//TODO check error in avatar downloading + connectedUser.setAvatar(avatarResource); commit(); - - return connectedUser.getAvatar(); } } 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 42e4cd7f..0fcacbff 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 @@ -25,163 +25,166 @@ require("./components/HumanInput.tag.html"); <h1><i class="fa fa-user"/> {__.title}</h1> <div class="main-content"> - - <form ref="identity-form" class="identity-form"> - <HumanInput onsubmit={submitIdentity}/> - <h3 class="c-heading"><i class="fa fa-address-card"/> {__.identity}</h3> - <div class="o-form-element"> - <label class="c-label" for="name">{__.name}</label> - <input class="c-field {c-field--error : errors.name}" - type="text" - name="name" - ref="name" - value={user.name} - placeholder="{__.name_placeholder}" - required - maxlength="255"> - <div if="{errors.name}" - class="c-hint--static c-hint--error"> - {errors.name} + <div class="row-content"> + <form ref="identity-form" class="identity-form column-content"> + <HumanInput onsubmit={submitIdentity}/> + <h3 class="c-heading"><i class="fa fa-address-card"/> {__.identity}</h3> + <div class="o-form-element"> + <label class="c-label" for="name">{__.name}</label> + <input class="c-field {c-field--error : errors.name}" + type="text" + name="name" + ref="name" + value={user.name} + placeholder="{__.name_placeholder}" + required + maxlength="255"> + <div if="{errors.name}" + class="c-hint--static c-hint--error"> + {errors.name} + </div> </div> - </div> - <div class="o-form-element"> - <label class="c-label" for="email">{__.email}</label> - <div class="o-field o-field--icon-right"> - <input class="c-field {c-field--error : errors.email}" - type="email" - name="email" - ref="email" - value={user.email} - placeholder="{__.email_placeholder}" - required - maxlength="255"> - <i class="fa fa-fw fa-{user.emailIsValidate ? 'check' : 'refresh'} c-icon" - title={user.emailIsValidate ? __.emailValidate : __.emailValidationWaiting}></i> - </div> - <div if="{errors.email}" - class="c-hint--static c-hint--error"> - {errors.email} + <div class="o-form-element"> + <label class="c-label" for="email">{__.email}</label> + <div class="o-field o-field--icon-right"> + <input class="c-field {c-field--error : errors.email}" + type="email" + name="email" + ref="email" + value={user.email} + placeholder="{__.email_placeholder}" + required + maxlength="255"> + <i class="fa fa-fw fa-{user.emailIsValidate ? 'check' : 'refresh'} c-icon" + title={user.emailIsValidate ? __.emailValidate : __.emailValidationWaiting}></i> + </div> + <div if="{errors.email}" + class="c-hint--static c-hint--error"> + {errors.email} + </div> </div> - </div> - <div class="actions-right"> - <button type="button" - class="c-button c-button--gost-info" - if={!user.emailIsValidate} - onclick={resendValidation}> - <i class="fa fa-paper-plane" aria-hidden="true"></i> - {__.resendValidation} - </button> - <button type="submit" - class="c-button c-button--info"> - <i class="fa fa-check" aria-hidden="true"></i> - {__.saveIdentity} - </button> - </div> - </form> - - <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" if="{user.withPassword}"> - <label class="c-label" for="oldPassword">{__.oldPassword}</label> - <input class="c-field {c-field--error : errors.oldPassword}" - type="password" - name="oldPassword" - ref="oldPassword" - placeholder="{__.oldPassword_placeholder}" - required - maxlength="255"> - <div if="{errors.oldPassword}" - class="c-hint--static c-hint--error"> - {errors.oldPassword} + <div class="actions-right"> + <button type="button" + class="c-button c-button--gost-info" + if={!user.emailIsValidate} + onclick={resendValidation}> + <i class="fa fa-paper-plane" aria-hidden="true"></i> + {__.resendValidation} + </button> + <button type="submit" + class="c-button c-button--info"> + <i class="fa fa-check" aria-hidden="true"></i> + {__.saveIdentity} + </button> + </div> + </form> + + <form ref="password-form" class="password-form column-content"> + <HumanInput onsubmit={submitPassword}/> + <h3 class="c-heading"><i class="fa fa-key"/> {__.passwordChange}</h3> + <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" + name="oldPassword" + ref="oldPassword" + placeholder="{__.oldPassword_placeholder}" + required + maxlength="255"> + <div if="{errors.oldPassword}" + class="c-hint--static c-hint--error"> + {errors.oldPassword} + </div> </div> - </div> - <div class="o-form-element"> - <label class="c-label" for="newPassword">{__.newPassword}</label> - <input class="c-field {c-field--error : errors.newPassword}" - type="password" - name="newPassword" - ref="newPassword" - placeholder="{__.newPassword_placeholder}" - onblur="{checkNewPassword}" - required - maxlength="255"> - <div if="{errors.newPassword}" - class="c-hint--static c-hint--error"> - {errors.newPassword} + <div class="o-form-element"> + <label class="c-label" for="newPassword">{__.newPassword}</label> + <input class="c-field {c-field--error : errors.newPassword}" + type="password" + name="newPassword" + ref="newPassword" + placeholder="{__.newPassword_placeholder}" + onblur="{checkNewPassword}" + required + maxlength="255"> + <div if="{errors.newPassword}" + class="c-hint--static c-hint--error"> + {errors.newPassword} + </div> </div> - </div> - <div class="o-form-element"> - <label class="c-label" for="email">{__.repeatPassword}</label> - <input class="c-field {c-field--error : errors.repeatPassword}" - type="password" - name="repeatPassword" - ref="repeatPassword" - placeholder="{__.repeatPassword_placeholder}" - onblur="{checkPassword}" - onkeypress="{clearPasswordError}" - required - maxlength="255"> - <div if="{errors.repeatPassword}" - class="c-hint--static c-hint--error"> - {errors.repeatPassword} + <div class="o-form-element"> + <label class="c-label" for="email">{__.repeatPassword}</label> + <input class="c-field {c-field--error : errors.repeatPassword}" + type="password" + name="repeatPassword" + ref="repeatPassword" + placeholder="{__.repeatPassword_placeholder}" + onblur="{checkPassword}" + onkeypress="{clearPasswordError}" + required + maxlength="255"> + <div if="{errors.repeatPassword}" + class="c-hint--static c-hint--error"> + {errors.repeatPassword} + </div> </div> - </div> - <div class="actions-right"> - <button type="submit" - class="c-button c-button--info"> - <i class="fa fa-check" aria-hidden="true"></i> - {__.savePassword} - </button> - </div> - </form> - - <div class="providers"> - <h3 class="c-heading"><i class="fa fa-sign-in"/> {__.loginProviders}</h3> - <div class="user-credentials"> - <div each="{credential, index in user.credentials}" class="user-credential {index % 2 == 0 ? 'even' : 'odd'}"> - <i if="{authService.providerIcons[credential.provider]}" - class="fa fa-{authService.providerIcons[credential.provider]}"></i> - <span if="{!authService.providerIcons[credential.provider]}">{credential.userName}</span> - <span class="credential-name">{credential.userName} <em if="{credential.emailAddress}">({credential.emailAddress})</em></span> - <button if="{user.withPassword && user.email || user.credentials.length > 1}" - onclick="{unlinkProvider(credential.id, index)}" class="c-button u-small c-button--error"><i class="fa fa-trash"></i></button> - </div> - </div> + <div class="actions-right"> + <button type="submit" + class="c-button c-button--info"> + <i class="fa fa-check" aria-hidden="true"></i> + {__.savePassword} + </button> + </div> + </form> + </div> + <div class="row-content"> + <div class="providers column-content"> + <h3 class="c-heading"><i class="fa fa-sign-in"/> {__.loginProviders}</h3> + <div class="user-credentials"> + <div each="{credential, index in user.credentials}" class="user-credential {index % 2 == 0 ? 'even' : 'odd'}"> + <i if="{authService.providerIcons[credential.provider]}" + class="fa fa-{authService.providerIcons[credential.provider]}"></i> + <span if="{!authService.providerIcons[credential.provider]}">{credential.userName}</span> + <span class="credential-name">{credential.userName} <em if="{credential.emailAddress}">({credential.emailAddress})</em></span> + <button if="{user.withPassword && user.email || user.credentials.length > 1}" + onclick="{unlinkProvider(credential.id, index)}" class="c-button u-small c-button--error"><i class="fa fa-trash"></i></button> + </div> + </div> - <div class="o-form-element align-center" if="{loginProviders.length > 0}"> - <p>{__.linkProvider}</p> - <p> - <a each="{loginProvider in loginProviders}" class="provider-link" - onclick="{linkProvider(loginProvider)}"> - <i class="fa fa-{authService.providerIcons[loginProvider]}" if="{authService.providerIcons[loginProvider]}"></i> - <span if="{!authService.providerIcons[loginProvider]}">{loginProvider}</span> - </a> - </p> + <div class="o-form-element align-center" if="{loginProviders.length > 0}"> + <p>{__.linkProvider}</p> + <p> + <a each="{loginProvider in loginProviders}" class="provider-link" + onclick="{linkProvider(loginProvider)}"> + <i class="fa fa-{authService.providerIcons[loginProvider]}" if="{authService.providerIcons[loginProvider]}"></i> + <span if="{!authService.providerIcons[loginProvider]}">{loginProvider}</span> + </a> + </p> + </div> </div> - </div> - <div class="avatar"> - <h3 class="c-heading"><i class="fa fa-sign-in"/> {__.avatar}</h3> - <div class="o-form-element align-center" if="{loginProviders.length > 0}"> - <p> - <img src="{user.avatar}" onerror="{avatarLoadingFailed}"/> - <i class="fa fa-question-circle cursor-help error" if="{avatarLoadingError}" title="{__.avatarLoadingFailed}"></i> - {} - </p> - <p> - <a each="{loginProvider in loginProviders}" class="provider-link" - onclick="{getProviderAvatar(loginProvider)}"> - <i class="fa fa-{authService.providerIcons[loginProvider]}" - if="{authService.providerIcons[loginProvider]}"></i> - <span if="{!authService.providerIcons[loginProvider]}">{loginProvider}</span> - </a> - </p> + <div class="avatar column-content"> + <h3 class="c-heading"><i class="fa fa-sign-in"/> {__.avatar}</h3> + <div class="o-form-element align-center" if="{loginProviders.length > 0}"> + <p> + <!--FIXME get url from service--> + <img src="{session.configuration.endPoint}/v1/avatar/{user.id}" onerror="{avatarLoadingFailed}"/> + <i class="fa fa-question-circle cursor-help error" if="{avatarLoadingError}" title="{__.avatarLoadingFailed}"></i> + {} + </p> + <p> + <a each="{loginProvider in loginProviders}" class="provider-link" + onclick="{getProviderAvatar(loginProvider)}"> + <i class="fa fa-{authService.providerIcons[loginProvider]}" + if="{authService.providerIcons[loginProvider]}"></i> + <span if="{!authService.providerIcons[loginProvider]}">{loginProvider}</span> + </a> + </p> + </div> </div> </div> </div> @@ -189,10 +192,10 @@ require("./components/HumanInput.tag.html"); <script type="es6"> this.loaded = false; - let session = require("../js/Session"); - this.installBundle(session, "userProfile"); + this.session = require("../js/Session"); + this.installBundle(this.session, "userProfile"); this.errors = {}; - this.user = session.getUser() || {}; + this.user = this.session.getUser() || {}; let userService = require("../js/UserService"); this.authService = require("../js/AuthService"); let Message = require("../js/Message"); @@ -224,7 +227,7 @@ require("./components/HumanInput.tag.html"); this.user.name = this.refs.name.value; this.user.email = this.refs.email.value; userService.saveUser(this.user).then(() => { - session.updateUser(); + this.session.updateUser(); this.bus.trigger("message", new Message(this._l("updatedIdentity"), "success")); }); }; @@ -257,7 +260,7 @@ require("./components/HumanInput.tag.html"); this.refs.newPassword.value = ""; this.refs.repeatPassword.value = ""; this.update(); - session.updateUser(); + this.session.updateUser(); this.bus.trigger("message", new Message(this._l("updatedPassword"), "success")); }) .catch((errors) => { @@ -304,10 +307,19 @@ require("./components/HumanInput.tag.html"); .main-content { display: flex; flex-wrap: wrap; + flex-direction: column; + max-width: 1200px; + margin: auto; + } + + .main-content .row-content { + display: flex; + flex-wrap: wrap; + flex-direction: row; justify-content: space-around; } - .main-content > form { + .main-content .column-content { flex-grow: 1; max-width: 500px; padding: 0 5px; -- 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/28_avatars in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit d1e7140e8550cec3c833305d93de37a8e085768d Author: Kevin Morin <morin@codelutin.com> Date: Tue Sep 26 10:55:28 2017 +0200 refs #28 forumlaire d'upload de l'avatar --- .../pollen/rest/api/v1/PollenResourceApi.java | 8 -- .../chorem/pollen/rest/api/v1/PollenUserApi.java | 35 +++++++- .../services/service/PollenResourceService.java | 2 +- .../services/service/PollenServiceSupport.java | 4 + .../pollen/services/service/PollenUserService.java | 26 +++++- .../pollen/services/service/SocialAuthService.java | 7 +- .../services/service/security/SecurityService.java | 10 +++ pollen-ui-riot-js/src/main/web/i18n/en.json | 2 +- pollen-ui-riot-js/src/main/web/i18n/fr.json | 4 +- pollen-ui-riot-js/src/main/web/js/FetchService.js | 1 - pollen-ui-riot-js/src/main/web/js/UserService.js | 17 +++- pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html | 2 +- .../src/main/web/tag/PollenHeader.tag.html | 3 +- .../src/main/web/tag/UserProfile.tag.html | 95 ++++++++++++++++------ 14 files changed, 164 insertions(+), 52 deletions(-) diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenResourceApi.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenResourceApi.java index 3cb4f974..7decb52b 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenResourceApi.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenResourceApi.java @@ -22,7 +22,6 @@ package org.chorem.pollen.rest.api.v1; */ import org.chorem.pollen.persistence.entity.PollenResource; -import org.chorem.pollen.persistence.entity.PollenUser; import org.chorem.pollen.rest.api.beans.Resource64Bean; import org.chorem.pollen.services.bean.PollenEntityId; import org.chorem.pollen.services.bean.PollenEntityRef; @@ -131,11 +130,4 @@ public class PollenResourceApi { pollenResourceService.deleteResource(resourceId.getEntityId()); } - @Path("/avatar/{userId}") - @GET - public Response getUserAvatar(@Context PollenResourceService pollenResourceService, - @PathParam("userId") PollenEntityId<PollenUser> userId) { - ResourceStreamBean resource = pollenResourceService.getAvatar(userId.getEntityId()); - return Response.ok(resource.getResourceContent(), resource.getContentType()).build(); - } } 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 4e6662d8..d3740082 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 @@ -23,6 +23,7 @@ package org.chorem.pollen.rest.api.v1; import com.google.gson.Gson; import org.brickred.socialauth.SocialAuthManager; +import org.chorem.pollen.persistence.entity.PollenResource; import org.chorem.pollen.persistence.entity.PollenUser; import org.chorem.pollen.persistence.entity.UserCredential; import org.chorem.pollen.rest.api.beans.ChangePasswordBean; @@ -31,11 +32,15 @@ import org.chorem.pollen.services.bean.PaginationResultBean; import org.chorem.pollen.services.bean.PollenEntityId; import org.chorem.pollen.services.bean.PollenEntityRef; import org.chorem.pollen.services.bean.PollenUserBean; +import org.chorem.pollen.services.bean.resource.ResourceFileBean; +import org.chorem.pollen.services.bean.resource.ResourceStreamBean; import org.chorem.pollen.services.service.InvalidFormException; +import org.chorem.pollen.services.service.PollenResourceService; 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 org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.BeanParam; @@ -50,6 +55,7 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; import java.util.Map; import java.util.Objects; @@ -156,11 +162,10 @@ public class PollenUserApi { socialAuthService.deleteUserCredential(credentialId); } - @Path("/users/{userId}/avatar/{provider}") + @Path("/user/avatar/{provider}") @POST public void setAvatar(@Context SocialAuthService socialAuthService, @Context HttpServletRequest request, - @PathParam("userId") PollenEntityId<PollenUser> userId, @PathParam("provider") String provider, String providerReturn) throws Exception { @@ -170,6 +175,30 @@ public class PollenUserApi { request.getSession().removeAttribute(ApiUtils.SOCIAL_AUTH_MANAGER_SESSION_KEY); Gson gson = new Gson(); Map<String, String> paramsMap = gson.fromJson(providerReturn, Map.class); - socialAuthService.setAvatarToUser(userId, socialAuthManager, paramsMap); + socialAuthService.setAvatarToUser(socialAuthManager, paramsMap); + } + + @Path("/users/{userId}/avatar") + @GET + public Response getUserAvatar(@Context PollenResourceService pollenResourceService, + @PathParam("userId") PollenEntityId<PollenUser> userId) { + ResourceStreamBean resource = pollenResourceService.getAvatar(userId.getEntityId()); + return Response.ok(resource.getResourceContent(), resource.getContentType()).build(); + } + + @Path("/user/avatar") + @POST + @Consumes(MediaType.MULTIPART_FORM_DATA) + @Produces(MediaType.APPLICATION_JSON) + public PollenEntityRef<PollenResource> createResource(@Context PollenUserService pollenUserService, + MultipartFormDataInput input) throws InvalidFormException { + ResourceFileBean resourceBean = ApiUtils.multipartToResourceBean(input, "avatar"); + return pollenUserService.setAvatar(resourceBean); + } + + @Path("/user/avatar") + @DELETE + public void deleteUserAvatar(@Context PollenUserService pollenUserService) { + pollenUserService.deleteAvatar(); } } 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 fe4e5fc8..44b793fe 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 @@ -163,7 +163,7 @@ public class PollenResourceService extends PollenServiceSupport implements Polle return PollenEntityRef.of(savedResource); } - public PollenResource createAvatarResource(ResourceStreamBean resource) throws InvalidFormException { + public PollenResource createAvatarResource(AbstractResourceBean resource) throws InvalidFormException { checkNotNull(resource); checkIsNotPersisted(resource); 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 faa2887d..06c86f35 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 @@ -265,6 +265,10 @@ public abstract class PollenServiceSupport implements PollenService { getSecurityService().checkIsConnected(); } + public void checkIsConnected(String userId) { + getSecurityService().checkIsConnected(userId); + } + public void checkIsAdmin() { getSecurityService().checkIsAdmin(); } 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 9bb0ed06..59b6e985 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 @@ -26,10 +26,12 @@ import org.apache.commons.lang3.StringUtils; import org.apache.shiro.util.CollectionUtils; import org.chorem.pollen.persistence.entity.Comment; import org.chorem.pollen.persistence.entity.PollenPrincipal; +import org.chorem.pollen.persistence.entity.PollenResource; import org.chorem.pollen.persistence.entity.PollenToken; import org.chorem.pollen.persistence.entity.PollenUser; import org.chorem.pollen.persistence.entity.PollenUserTopiaDao; import org.chorem.pollen.persistence.entity.UserCredential; +import org.chorem.pollen.persistence.entity.ResourceType; import org.chorem.pollen.persistence.entity.Vote; import org.chorem.pollen.services.PollenService; import org.chorem.pollen.services.bean.PaginationParameterBean; @@ -37,6 +39,7 @@ import org.chorem.pollen.services.bean.PaginationResultBean; import org.chorem.pollen.services.bean.PollenEntityRef; import org.chorem.pollen.services.bean.PollenUserBean; import org.chorem.pollen.services.bean.UserCredentialBean; +import org.chorem.pollen.services.bean.resource.ResourceFileBean; import org.chorem.pollen.services.service.security.PollenInvalidEmailActivationTokenException; import org.chorem.pollen.services.service.security.PollenInvalidPasswordException; import org.chorem.pollen.services.service.security.PollenSecurityContext; @@ -185,7 +188,6 @@ public class PollenUserService extends PollenServiceSupport implements PollenSer PollenUser user = checkAndGetConnectedUser(); checkNotNull(newPassword); - ErrorMap errorMap = new ErrorMap(); boolean passwordNotBlank = checkNotBlank(errorMap, "newPassword", newPassword, l(getLocale(), "pollen.error.user.passwordEmpty")); @@ -266,6 +268,28 @@ public class PollenUserService extends PollenServiceSupport implements PollenSer } + public void deleteAvatar() { + checkIsConnected(); + PollenUser user = getConnectedUser(); + if (user.getAvatar() != null) { + getPollenResourceService().deleteResource(user.getAvatar().getTopiaId()); + } + commit(); + } + + public PollenEntityRef<PollenResource> setAvatar(ResourceFileBean resourceBean) throws InvalidFormException { + checkIsConnected(); + resourceBean.setResourceType(ResourceType.AVATAR); + PollenResource avatarResource = getPollenResourceService().createAvatarResource(resourceBean); + PollenUser user = getConnectedUser(); + if (user.getAvatar() != null) { + getPollenResourceService().deleteResource(user.getAvatar().getTopiaId()); + } + user.setAvatar(avatarResource); + commit(); + return PollenEntityRef.of(avatarResource); + } + protected ErrorMap checkPollenUser(PollenUserBean user) { ErrorMap errors = new ErrorMap(); 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 38f5e17e..52c9e449 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 @@ -115,7 +115,6 @@ public class SocialAuthService extends PollenServiceSupport { Map<String, String> paramsMap) throws Exception { PollenUser connectedUser = checkAndGetConnectedUser(); - AuthProvider provider = manager.connect(paramsMap); // get profile @@ -275,13 +274,9 @@ public class SocialAuthService extends PollenServiceSupport { commit(); } - public void setAvatarToUser(PollenEntityId<PollenUser> userId, SocialAuthManager manager, Map<String, String> paramsMap) throws Exception { + public void setAvatarToUser(SocialAuthManager manager, Map<String, String> paramsMap) throws Exception { checkIsConnected(); PollenUser connectedUser = getConnectedUser(); - if (!connectedUser.getTopiaId().equals(userId.getEntityId())) { - throw new PollenUnauthorizedException(userId.getReducedId()); - } - PollenResourceService pollenResourceService = getPollenResourceService(); if (connectedUser.getAvatar() != null) { 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 f351b350..6ab376a2 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 @@ -114,6 +114,16 @@ public class SecurityService extends PollenServiceSupport { } @Override + public void checkIsConnected(String userId) { + + PollenSecurityContext securityContext = getSecurityContext(); + if (!securityContext.isConnected() || !securityContext.getPollenUser().getTopiaId().equals(userId)) { + throw new PollenUnauthorizedException("connected"); + } + + } + + @Override public void checkIsAdmin() { PollenSecurityContext securityContext = getSecurityContext(); 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 18469062..a4a4eafc 100644 --- a/pollen-ui-riot-js/src/main/web/i18n/en.json +++ b/pollen-ui-riot-js/src/main/web/i18n/en.json @@ -417,7 +417,7 @@ "userProfile_linkProvider": "Link an external account to connect to Pollen:", "userProfile_unlinkProviderMessage": "Unlink this external account? You will not be able to connect to your Pollen account with this external account.", "userProfile_avatar": "Avatar", - "userProfile_avatarLoadingFailed": "If your avatar does not display, check that you did not enabled the tracking protection.", + "userProfile_deleteAvatarMessage": "Remove your avatar?", "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/i18n/fr.json b/pollen-ui-riot-js/src/main/web/i18n/fr.json index 6824e7ca..89435e5a 100644 --- a/pollen-ui-riot-js/src/main/web/i18n/fr.json +++ b/pollen-ui-riot-js/src/main/web/i18n/fr.json @@ -417,7 +417,9 @@ "userProfile_linkProvider": "Associez un compte externe pour vous connecter à Pollen :", "userProfile_unlinkProviderMessage": "Désassossier ce compte externe ? Vous ne pourrez plus vous connectez à votre compte Pollen avec ce compte externe.", "userProfile_avatar": "Avatar", - "userProfile_avatarLoadingFailed": "Si votre avatar ne s'affiche pas, vérifiez que vous n'avez pas activé la protection contre le pistage.", + "userProfile_deleteAvatarMessage": "Supprimer votre avatar ?", + "userProfile_uploadAvatar": "Téléverser un fichier", + "userProfile_getProviderAvatar": "ou utiliser votre avatar d'un service tiers", "choice_description_placeholder": "Vous pouvez saisir une description pour ce choix", "date-picker_today": "Aujourd'hui", "date-picker_dateplaceholder": "Date", diff --git a/pollen-ui-riot-js/src/main/web/js/FetchService.js b/pollen-ui-riot-js/src/main/web/js/FetchService.js index ae3de5a7..637f7e28 100644 --- a/pollen-ui-riot-js/src/main/web/js/FetchService.js +++ b/pollen-ui-riot-js/src/main/web/js/FetchService.js @@ -80,7 +80,6 @@ class FetchService { return this.fetch(url, "GET"); } - _addParamsToUrl(url, params) { if (params) { let query = "?"; 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 d1cceefa..b54ecc0f 100644 --- a/pollen-ui-riot-js/src/main/web/js/UserService.js +++ b/pollen-ui-riot-js/src/main/web/js/UserService.js @@ -82,11 +82,24 @@ class UserService extends FetchService { return this.post(url); } - getProviderAvatar(userId, query) { - let url = this._getUrlPrefix(userId) + "/avatar/" + query.loginProvider; + setProviderAvatar(query) { + let url = this._getUserUrlPrefix() + "/avatar/" + query.loginProvider; let body = JSON.stringify(query); return this.post(url, body); } + + getUserAvatarUrl(userId) { + return window.pollenConf.endPoint + this._getUsersUrlPrefix(userId) + "/avatar"; + } + + setUserAvatar(avatar) { + let url = this._getUserUrlPrefix() + "/avatar"; + return this.form(url, {avatar: avatar}, true); + } + + deleteAvatar() { + return this.doDelete(this._getUserUrlPrefix() + "/avatar"); + } } 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 ef16fc1b..b192e896 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 @@ -308,7 +308,7 @@ require("./popup/GtuChangeModal.tag.html"); } else if (q.action === "avatar" && session.isConnected()) { let callback = (user) => { - userService.getProviderAvatar(user.id, q).then(() => { + userService.setProviderAvatar(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/PollenHeader.tag.html b/pollen-ui-riot-js/src/main/web/tag/PollenHeader.tag.html index 9712a278..e9dc0480 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 @@ -22,6 +22,7 @@ */ require("./HeaderI18n.tag.html"); require("./popup/FeedbackModal.tag.html"); +require("./components/LetterAvatar.tag.html"); <PollenHeader> <a class="header-home instance-title" href="#home" target="_top"></a> @@ -46,7 +47,7 @@ require("./popup/FeedbackModal.tag.html"); <div class="dropdown" if={user}> <a class="header-link"> - <i class="fa fa-user-circle"/> + <LetterAvatar name={user && user.name} rounded="true"/> <span class="user-name action-label"> {user && user.name}</span> </a> <div class="dropdown-content right"> 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 0fcacbff..5e89f949 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 @@ -19,6 +19,7 @@ #L% --> require("./components/HumanInput.tag.html"); +require("./components/LetterAvatar.tag.html"); <UserProfile> <div class="container"> @@ -169,21 +170,32 @@ require("./components/HumanInput.tag.html"); <div class="avatar column-content"> <h3 class="c-heading"><i class="fa fa-sign-in"/> {__.avatar}</h3> - <div class="o-form-element align-center" if="{loginProviders.length > 0}"> - <p> - <!--FIXME get url from service--> - <img src="{session.configuration.endPoint}/v1/avatar/{user.id}" onerror="{avatarLoadingFailed}"/> - <i class="fa fa-question-circle cursor-help error" if="{avatarLoadingError}" title="{__.avatarLoadingFailed}"></i> - {} - </p> - <p> - <a each="{loginProvider in loginProviders}" class="provider-link" - onclick="{getProviderAvatar(loginProvider)}"> - <i class="fa fa-{authService.providerIcons[loginProvider]}" - if="{authService.providerIcons[loginProvider]}"></i> - <span if="{!authService.providerIcons[loginProvider]}">{loginProvider}</span> - </a> - </p> + <div class="avatar-container"> + <div class="avatar-column" if="{user.avatar}"> + <img src="{userService.getUserAvatarUrl(user.id)}"/> + <button onclick="{deleteAvatar}" class="c-button u-small c-button--error"><i class="fa fa-trash"></i></button> + </div> + <LetterAvatar class="avatar-column" name={user && user.name || ""} if="{!user.avatar}"/> + <div class="form-column"> + <div class="o-form-element"> + <label class="c-label" for="avatar">{__.uploadAvatar}</label> + <span class="c-input-group"> + <input type="file" class="c-field" ref="avatar" required/> + <button class="c-button" onclick="{uploadAvatar}"><i class="fa fa-upload"></i></button> + </span> + </div> + <div class="align-center" if="{loginProviders.length > 0}"> + {__.getProviderAvatar} + <div> + <a each="{loginProvider in loginProviders}" class="provider-link" + onclick="{getProviderAvatar(loginProvider)}"> + <i class="fa fa-{authService.providerIcons[loginProvider]}" + if="{authService.providerIcons[loginProvider]}"></i> + <span if="{!authService.providerIcons[loginProvider]}">{loginProvider}</span> + </a> + </div> + </div> + </div> </div> </div> </div> @@ -196,7 +208,7 @@ require("./components/HumanInput.tag.html"); this.installBundle(this.session, "userProfile"); this.errors = {}; this.user = this.session.getUser() || {}; - let userService = require("../js/UserService"); + this.userService = require("../js/UserService"); this.authService = require("../js/AuthService"); let Message = require("../js/Message"); @@ -206,17 +218,11 @@ require("./components/HumanInput.tag.html"); this.update(); }); - this.avatarLoadingError = false; - this.onUserChange = (user) => { this.user = user || {}; this.update(); }; - this.avatarLoadingFailed = (e) => { - this.avatarLoadingError = true; - } - this.resendValidation = () => { this.authService.resendValidation(this.user.email); }; @@ -226,7 +232,7 @@ require("./components/HumanInput.tag.html"); e.stopPropagation(); this.user.name = this.refs.name.value; this.user.email = this.refs.email.value; - userService.saveUser(this.user).then(() => { + this.userService.saveUser(this.user).then(() => { this.session.updateUser(); this.bus.trigger("message", new Message(this._l("updatedIdentity"), "success")); }); @@ -253,7 +259,7 @@ require("./components/HumanInput.tag.html"); if (this.errors.repeatPassword === undefined) { let oldPassword = this.user.withPassword ? this.refs.oldPassword.value : null; let newPassword = this.refs.newPassword.value; - userService.changePassword(oldPassword, newPassword).then(() => { + this.userService.changePassword(oldPassword, newPassword).then(() => { if (this.user.withPassword) { this.refs.oldPassword.value = ""; } @@ -283,14 +289,14 @@ require("./components/HumanInput.tag.html"); if (!confirm) { return Promise.reject(); } - return userService.unlinkProvider(credentialId) + return this.userService.unlinkProvider(credentialId); }).then(result => { this.user.credentials.splice(index, 1); this.update(); }); }; - getProviderAvatar= (provider) => (e) => { + this.getProviderAvatar = (provider) => (e) => { let redirection = encodeURIComponent(location.origin + location.pathname + "?loginProvider=" + provider + "&action=avatar"); this.authService.getLoginProviderUrl(provider, redirection).then(result => { @@ -298,6 +304,26 @@ require("./components/HumanInput.tag.html"); }); }; + this.deleteAvatar = e => { + this.confirm(this.__.deleteAvatarMessage).then((confirm) => { + if (!confirm) { + return Promise.reject(); + } + return this.userService.deleteAvatar(); + }).then(result => { + this.user.avatar = null; + this.update(); + }); + }; + +//TODO check size and all + this.uploadAvatar = e => { + this.userService.setUserAvatar(this.refs.avatar.files[0]).then((result) => { + this.user.avatar = result; + this.update(); + }); + } + this.listen("user", this.onUserChange); </script> @@ -331,6 +357,7 @@ require("./components/HumanInput.tag.html"); .user-credentials { width: 100%; + margin-top: 20px; } .user-credential { @@ -354,6 +381,22 @@ require("./components/HumanInput.tag.html"); font-size: 2em; } + .avatar-container { + display: flex; + flex-direction: row; + } + + .avatar-column { + display: flex; + flex-direction: column; + margin: 20px 20px 0 0; + } + + .form-column { + display: flex; + flex-direction: column; + } + </style> </UserProfile> -- 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/28_avatars in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit 16c884e01c8cbead7aaf4c8e2bee6d01fdbd578b Author: Kevin Morin <morin@codelutin.com> Date: Thu Sep 28 11:12:43 2017 +0200 refs #28 utilisation de l'avatar --- .../java/org/chorem/pollen/rest/api/v1/GtuApi.java | 3 -- .../org/chorem/pollen/services/bean/PollBean.java | 12 ++++++++ .../services/bean/resource/ResourceMetaBean.java | 2 +- .../pollen/services/service/PollService.java | 7 ++++- .../pollen/services/service/PollenUserService.java | 8 +++-- .../pollen/services/service/SocialAuthService.java | 5 ++- .../src/main/web/js/ResourceService.js | 4 +++ .../src/main/web/tag/PollenHeader.tag.html | 4 +-- .../src/main/web/tag/UserProfile.tag.html | 18 ++++++----- .../src/main/web/tag/components/Avatar.tag.html | 36 ++++++++++++++++++++++ .../web/tag/favoriteList/FavoriteList.tag.html | 2 -- .../src/main/web/tag/poll/Choice.tag.html | 3 +- .../src/main/web/tag/poll/ChoiceView.tag.html | 6 ++-- .../src/main/web/tag/poll/PollCard.tag.html | 3 +- 14 files changed, 85 insertions(+), 28 deletions(-) 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 index b28619fb..ebb04d88 100644 --- 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 @@ -1,6 +1,5 @@ package org.chorem.pollen.rest.api.v1; -<<<<<<< HEAD /*- * #%L * Pollen :: Rest Api @@ -22,8 +21,6 @@ package org.chorem.pollen.rest.api.v1; * #L% */ -import org.chorem.pollen.services.bean.GtuMetaBean; -import org.chorem.pollen.services.bean.ResourceStreamBean; import org.chorem.pollen.services.bean.resource.GtuMetaBean; import org.chorem.pollen.services.bean.resource.ResourceStreamBean; import org.chorem.pollen.services.service.GtuService; 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 f7f0c2e7..b8babfaf 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 @@ -140,6 +140,9 @@ public class PollBean extends PollenBean<Poll> { protected int maxVoters; + protected String creatorAvatar; + + public String getPermission() { return permission; } @@ -455,11 +458,20 @@ public class PollBean extends PollenBean<Poll> { this.gtuValidated = gtuValidated; } +<<<<<<< HEAD public int getMaxVoters() { return maxVoters; } public void setMaxVoters(int maxVoters) { this.maxVoters = maxVoters; +======= + public String getCreatorAvatar() { + return creatorAvatar; + } + + public void setCreatorAvatar(String creatorAvatar) { + this.creatorAvatar = creatorAvatar; +>>>>>>> refs #28 utilisation de l'avatar } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceMetaBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceMetaBean.java index a646dd4f..9cd1e54a 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceMetaBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceMetaBean.java @@ -34,7 +34,7 @@ public class ResourceMetaBean extends AbstractResourceBean { protected Date uploadDate; - protected ResourceMetaBean() { + public ResourceMetaBean() { super(PollenResource.class); } 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 050f9e7f..3c3f2a37 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 @@ -182,8 +182,13 @@ public class PollService extends PollenServiceSupport { bean.setGtuValidated(getGtuService().isGtuValidated(entity)); bean.setMaxVoters(getMaxVoters(entity)); + if (entity.getCreator().getPollenUser() != null && entity.getCreator().getPollenUser().getAvatar() != null) { + bean.setCreatorAvatar(getPollenResourceService().getReduceIdByTopiaId( + entity.getCreator().getPollenUser().getAvatar().getTopiaId())); + } + return bean; - }; + } protected int getMaxVoters(Poll poll) { boolean premium = poll.isPremium() || getUserService().isPremium(poll.getCreator().getPollenUser()); 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 59b6e985..3d9b7102 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 @@ -80,7 +80,9 @@ public class PollenUserService extends PollenServiceSupport implements PollenSer .collect(Collectors.toList())); } bean.setPremiumTo(entity.getPremiumTo()); - + if (entity.getAvatar() != null) { + bean.setAvatar(getPollenResourceService().getReduceIdByTopiaId(entity.getAvatar().getTopiaId())); + } bean.setGtuValidated(getGtuService().isGtuValidated(entity)); bean.setPremium(isPremium(entity)); @@ -272,7 +274,7 @@ public class PollenUserService extends PollenServiceSupport implements PollenSer checkIsConnected(); PollenUser user = getConnectedUser(); if (user.getAvatar() != null) { - getPollenResourceService().deleteResource(user.getAvatar().getTopiaId()); + getPollenResourceDao().delete(user.getAvatar()); } commit(); } @@ -283,7 +285,7 @@ public class PollenUserService extends PollenServiceSupport implements PollenSer PollenResource avatarResource = getPollenResourceService().createAvatarResource(resourceBean); PollenUser user = getConnectedUser(); if (user.getAvatar() != null) { - getPollenResourceService().deleteResource(user.getAvatar().getTopiaId()); + getPollenResourceDao().delete(user.getAvatar()); } user.setAvatar(avatarResource); 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 52c9e449..da9b9bbd 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 @@ -275,12 +275,11 @@ public class SocialAuthService extends PollenServiceSupport { } public void setAvatarToUser(SocialAuthManager manager, Map<String, String> paramsMap) throws Exception { - checkIsConnected(); - PollenUser connectedUser = getConnectedUser(); + PollenUser connectedUser = checkAndGetConnectedUser(); PollenResourceService pollenResourceService = getPollenResourceService(); if (connectedUser.getAvatar() != null) { - pollenResourceService.deleteResource(connectedUser.getAvatar().getTopiaId()); + getPollenResourceDao().delete(connectedUser.getAvatar()); } // get profile 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 9001f361..7de1ccc0 100644 --- a/pollen-ui-riot-js/src/main/web/js/ResourceService.js +++ b/pollen-ui-riot-js/src/main/web/js/ResourceService.js @@ -52,6 +52,10 @@ class ResourceService extends FetchService { return this.get(url); } + getPreviewUrl(resourceId) { + return this.endPoint + this._getUrlPrefix(resourceId) + "/preview"; + } + getMeta(resourceId) { let url = this._getUrlPrefix(resourceId) + "/meta"; return this.get(url); 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 e9dc0480..05a0c123 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 @@ -22,7 +22,7 @@ */ require("./HeaderI18n.tag.html"); require("./popup/FeedbackModal.tag.html"); -require("./components/LetterAvatar.tag.html"); +require("./components/Avatar.tag.html"); <PollenHeader> <a class="header-home instance-title" href="#home" target="_top"></a> @@ -47,7 +47,7 @@ require("./components/LetterAvatar.tag.html"); <div class="dropdown" if={user}> <a class="header-link"> - <LetterAvatar name={user && user.name} rounded="true"/> + <Avatar avatar={user.avatar} name={user.name} rounded="true"/> <span class="user-name action-label"> {user && user.name}</span> </a> <div class="dropdown-content right"> 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 5e89f949..5e0cf192 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 @@ -172,7 +172,7 @@ require("./components/LetterAvatar.tag.html"); <h3 class="c-heading"><i class="fa fa-sign-in"/> {__.avatar}</h3> <div class="avatar-container"> <div class="avatar-column" if="{user.avatar}"> - <img src="{userService.getUserAvatarUrl(user.id)}"/> + <img src="{resourceService.getPreviewUrl(user.avatar)}"/> <button onclick="{deleteAvatar}" class="c-button u-small c-button--error"><i class="fa fa-trash"></i></button> </div> <LetterAvatar class="avatar-column" name={user && user.name || ""} if="{!user.avatar}"/> @@ -208,8 +208,9 @@ require("./components/LetterAvatar.tag.html"); this.installBundle(this.session, "userProfile"); this.errors = {}; this.user = this.session.getUser() || {}; - this.userService = require("../js/UserService"); + let userService = require("../js/UserService"); this.authService = require("../js/AuthService"); + this.resourceService = require("../js/ResourceService"); let Message = require("../js/Message"); this.loginProviders = []; @@ -232,7 +233,7 @@ require("./components/LetterAvatar.tag.html"); e.stopPropagation(); this.user.name = this.refs.name.value; this.user.email = this.refs.email.value; - this.userService.saveUser(this.user).then(() => { + userService.saveUser(this.user).then(() => { this.session.updateUser(); this.bus.trigger("message", new Message(this._l("updatedIdentity"), "success")); }); @@ -259,7 +260,7 @@ require("./components/LetterAvatar.tag.html"); if (this.errors.repeatPassword === undefined) { let oldPassword = this.user.withPassword ? this.refs.oldPassword.value : null; let newPassword = this.refs.newPassword.value; - this.userService.changePassword(oldPassword, newPassword).then(() => { + userService.changePassword(oldPassword, newPassword).then(() => { if (this.user.withPassword) { this.refs.oldPassword.value = ""; } @@ -289,7 +290,7 @@ require("./components/LetterAvatar.tag.html"); if (!confirm) { return Promise.reject(); } - return this.userService.unlinkProvider(credentialId); + return userService.unlinkProvider(credentialId); }).then(result => { this.user.credentials.splice(index, 1); this.update(); @@ -309,7 +310,7 @@ require("./components/LetterAvatar.tag.html"); if (!confirm) { return Promise.reject(); } - return this.userService.deleteAvatar(); + return userService.deleteAvatar(); }).then(result => { this.user.avatar = null; this.update(); @@ -318,8 +319,9 @@ require("./components/LetterAvatar.tag.html"); //TODO check size and all this.uploadAvatar = e => { - this.userService.setUserAvatar(this.refs.avatar.files[0]).then((result) => { - this.user.avatar = result; + userService.setUserAvatar(this.refs.avatar.files[0]).then((result) => { + console.log(result); + this.user.avatar = result.id; this.update(); }); } diff --git a/pollen-ui-riot-js/src/main/web/tag/components/Avatar.tag.html b/pollen-ui-riot-js/src/main/web/tag/components/Avatar.tag.html new file mode 100644 index 00000000..b5e875da --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/components/Avatar.tag.html @@ -0,0 +1,36 @@ +require("./LetterAvatar.tag.html"); +<Avatar> + <LetterAvatar name={opts.name} rounded={opts.rounded} if={!opts.avatar} /> + + <div class="avatar {rounded: opts.rounded}" + style="background-image: url('{resourceService.getPreviewUrl(opts.avatar)}');" + show={opts.avatar}> + </div> + + <script> + this.session = require("../../js/Session"); + this.installBundle(this.session, "avatar"); + this.resourceService = require("../../js/ResourceService"); + this.avatarLoaded = false; + + this.onAvatarLoaded = e => { + this.avatarLoaded = true; + this.update(); + }; + </script> + + <style> + + .avatar { + width: 50px; + height:50px; + background-size: 50px 50px; + background-position: center; + background-repeat: no-repeat; + } + .avatar.rounded { + border-radius: 100%; + } + + </style> +</Avatar> \ No newline at end of file diff --git a/pollen-ui-riot-js/src/main/web/tag/favoriteList/FavoriteList.tag.html b/pollen-ui-riot-js/src/main/web/tag/favoriteList/FavoriteList.tag.html index ceac20ac..32733a09 100644 --- a/pollen-ui-riot-js/src/main/web/tag/favoriteList/FavoriteList.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/favoriteList/FavoriteList.tag.html @@ -164,8 +164,6 @@ require("../components/LoadingCard.tag.html"); favoriteListService.favoriteList(this.favoriteList.id).then(results => { this.favoriteList = results; this.loaded = true; - console.log("reloadFavoriteListInfos"); - console.log(results); this.update(); }); }; 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 46a9cacc..2046ce78 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 @@ -53,7 +53,7 @@ require("../components/time-picker.tag.html"); </button> <div if="{originalFile}" class="original-file {opts.choice.choiceType === 'RESOURCE' ? 'selected' : 'hidden'}"> - <img src="{session.configuration.endPoint}/v1/resources/{originalFile}/preview"/> + <img src="{resourceService.getPreviewUrl(originalFile)}"/> <span> {originalFile.name} <i class="fa fa-remove" @@ -126,6 +126,7 @@ require("../components/time-picker.tag.html"); <script type="es6"> this.session = require("../../js/Session"); + this.resourceService = require("../../js/ResourceService"); let moment = require("moment"); moment.locale(this.session.locale); diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/ChoiceView.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/ChoiceView.tag.html index 5c7bd0d5..9cd1dfce 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/ChoiceView.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/ChoiceView.tag.html @@ -39,7 +39,7 @@ require("../components/MultiLineLabel.tag.html"); </span> <div class="choice-ressource" if={opts.choice.choiceType === "RESOURCE" && meta && isImage(meta)}> - <img class="image-preview" src="{session.configuration.endPoint}/v1/resources/{opts.choice.choiceValue}/preview"/> + <img class="image-preview" src="{resourceService.getPreviewUrl(opts.choice.choiceValue)}"/> </div> <div class="choice-ressource" if={opts.choice.choiceType === "RESOURCE" && meta && !isImage(meta)}> @@ -92,13 +92,13 @@ require("../components/MultiLineLabel.tag.html"); </div> <script type="es6"> - let ResourceService = require("../../js/ResourceService"); this.session = require("../../js/Session"); + this.resourceService = require("../../js/ResourceService"); this.installBundle(this.session, "choice"); this.showModalImage = false; if (this.opts.choice.choiceType === "RESOURCE") { - ResourceService.getMeta(this.opts.choice.choiceValue).then(meta => { + this.resourceService.getMeta(this.opts.choice.choiceValue).then(meta => { this.meta = meta; this.update(); }); diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/PollCard.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/PollCard.tag.html index a2347c15..1cb3bb78 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/PollCard.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/PollCard.tag.html @@ -18,6 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #L% --> +require("../components/Avatar.tag.html"); <PollCard class="poll-{opts.poll.status.toLowerCase()}"> <div class="card-actions"> @@ -48,7 +49,7 @@ </div> <div class="poll-creator" title={opts.poll.creatorName}> - <LetterAvatar name={opts.poll.creatorName} rounded="true"/> + <Avatar avatar={opts.poll.creatorAvatar} name={opts.poll.creatorName} rounded="true"/> <div class="creator-name"> {opts.poll.creatorName} <div class="creation-date"> -- 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/28_avatars in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit 0b0847773d28b33d3f335a57b42e2c788011d9de Author: Kevin Morin <morin@codelutin.com> Date: Fri Sep 29 10:02:28 2017 +0200 ajout e variable dans le package.json --- pollen-ui-riot-js/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pollen-ui-riot-js/package.json b/pollen-ui-riot-js/package.json index b4552cd5..8a8a684d 100644 --- a/pollen-ui-riot-js/package.json +++ b/pollen-ui-riot-js/package.json @@ -24,7 +24,7 @@ } ], "scripts": { - "start": "webpack-dev-server --hot --inline --host 0.0.0.0 --public localhost:8080", + "start": "webpack-dev-server --hot --inline --host 0.0.0.0 --public ${POLLEN_UI_CONTEXT:-localhost:8080}", "package": "webpack --bail" }, "devDependencies": { -- 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/28_avatars in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit 24e6ad02ac0ead09b2d055f551f32bcc7c94b723 Author: Kevin Morin <morin@codelutin.com> Date: Fri Sep 29 11:37:16 2017 +0200 rebase --- ..._2__add_avatar.sql => V3_1_0_2__add_avatar.sql} | 0 ..._2__add_avatar.sql => V3_1_0_2__add_avatar.sql} | 0 pollen-persistence/src/main/xmi/pollen.properties | 2 +- pollen-persistence/src/main/xmi/pollen.zargo | Bin 28560 -> 29157 bytes .../org/chorem/pollen/services/bean/PollBean.java | 5 ++-- .../bean/resource/AbstractResourceBean.java | 4 +++ .../services/bean/resource/ResourceFileBean.java | 27 +++++++++++++++------ .../services/bean/resource/ResourceMetaBean.java | 6 +++++ .../services/bean/resource/ResourceStreamBean.java | 10 ++++++-- .../pollen/services/service/ChoiceService.java | 1 - .../services/service/PollenResourceService.java | 17 ++++--------- .../pollen/services/service/PollenUserService.java | 13 ++++++++-- .../src/main/web/tag/UserProfile.tag.html | 1 + 13 files changed, 57 insertions(+), 29 deletions(-) diff --git a/pollen-persistence/src/main/resources/db/migration/h2/V3_0_1_2__add_avatar.sql b/pollen-persistence/src/main/resources/db/migration/h2/V3_1_0_2__add_avatar.sql similarity index 100% rename from pollen-persistence/src/main/resources/db/migration/h2/V3_0_1_2__add_avatar.sql rename to pollen-persistence/src/main/resources/db/migration/h2/V3_1_0_2__add_avatar.sql diff --git a/pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_1_2__add_avatar.sql b/pollen-persistence/src/main/resources/db/migration/postgresql/V3_1_0_2__add_avatar.sql similarity index 100% rename from pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_1_2__add_avatar.sql rename to pollen-persistence/src/main/resources/db/migration/postgresql/V3_1_0_2__add_avatar.sql diff --git a/pollen-persistence/src/main/xmi/pollen.properties b/pollen-persistence/src/main/xmi/pollen.properties index fb44dc92..4d9d4fbb 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.1.2 +model.tagvalue.version=3.1.0.2 #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 99dbdb63..e77a7ac6 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-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 b8babfaf..dd89ed27 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 @@ -458,20 +458,19 @@ public class PollBean extends PollenBean<Poll> { this.gtuValidated = gtuValidated; } -<<<<<<< HEAD public int getMaxVoters() { return maxVoters; } public void setMaxVoters(int maxVoters) { this.maxVoters = maxVoters; -======= + } + public String getCreatorAvatar() { return creatorAvatar; } public void setCreatorAvatar(String creatorAvatar) { this.creatorAvatar = creatorAvatar; ->>>>>>> refs #28 utilisation de l'avatar } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/AbstractResourceBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/AbstractResourceBean.java index 33ac329e..e5376071 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/AbstractResourceBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/AbstractResourceBean.java @@ -4,6 +4,8 @@ import org.chorem.pollen.persistence.entity.PollenResource; import org.chorem.pollen.persistence.entity.ResourceType; import org.chorem.pollen.services.bean.PollenBean; +import java.sql.Blob; + /** * @author Kevin Morin (Code Lutin) */ @@ -52,4 +54,6 @@ public abstract class AbstractResourceBean extends PollenBean<PollenResource> { public void setResourceType(ResourceType resourceType) { this.resourceType = resourceType; } + + public abstract Blob getResourceBlob(); } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceFileBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceFileBean.java index 9b6355d5..9b01cb24 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceFileBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceFileBean.java @@ -22,7 +22,10 @@ package org.chorem.pollen.services.bean.resource; */ import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.chorem.pollen.persistence.entity.PollenResource; +import org.chorem.pollen.services.PollenTechnicalException; import javax.sql.rowset.serial.SerialBlob; import java.io.File; @@ -41,6 +44,9 @@ import java.util.zip.ZipException; */ public class ResourceFileBean extends AbstractResourceBean { + /** Logger. */ + private static final Log log = LogFactory.getLog(ResourceFileBean.class); + protected File file; public ResourceFileBean() { @@ -55,16 +61,21 @@ public class ResourceFileBean extends AbstractResourceBean { this.file = file; } - public Blob getResourceBlob() throws IOException, SQLException { - InputStream stream; - + @Override + public Blob getResourceBlob() { try { - stream = new GZIPInputStream(new FileInputStream(getFile())); - } catch (ZipException e) { - stream = new FileInputStream(getFile()); - } + InputStream stream; + try { + stream = new GZIPInputStream(new FileInputStream(getFile())); + } catch (ZipException e) { + stream = new FileInputStream(getFile()); + } - return new SerialBlob(IOUtils.toByteArray(stream)); + return new SerialBlob(IOUtils.toByteArray(stream)); + + } catch (SQLException | IOException e) { + throw new PollenTechnicalException(e); + } } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceMetaBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceMetaBean.java index 9cd1e54a..205af501 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceMetaBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceMetaBean.java @@ -23,6 +23,7 @@ package org.chorem.pollen.services.bean.resource; import org.chorem.pollen.persistence.entity.PollenResource; +import java.sql.Blob; import java.util.Date; /** @@ -45,4 +46,9 @@ public class ResourceMetaBean extends AbstractResourceBean { public void setUploadDate(Date uploadDate) { this.uploadDate = uploadDate; } + + @Override + public Blob getResourceBlob() { + return null; + } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceStreamBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceStreamBean.java index 833b98ba..9f94e900 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceStreamBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceStreamBean.java @@ -23,6 +23,7 @@ package org.chorem.pollen.services.bean.resource; import org.apache.commons.io.IOUtils; import org.chorem.pollen.persistence.entity.PollenResource; +import org.chorem.pollen.services.PollenTechnicalException; import javax.sql.rowset.serial.SerialBlob; import java.io.IOException; @@ -51,7 +52,12 @@ public class ResourceStreamBean extends AbstractResourceBean { this.resourceContent = resourceContent; } - public Blob getResourceBlob() throws IOException, SQLException { - return new SerialBlob(IOUtils.toByteArray(getResourceContent())); + @Override + public Blob getResourceBlob() { + try { + return new SerialBlob(IOUtils.toByteArray(getResourceContent())); + } catch (SQLException | IOException e) { + throw new PollenTechnicalException(e); + } } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/ChoiceService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/ChoiceService.java index ae12f859..af4a67ff 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/ChoiceService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/ChoiceService.java @@ -324,7 +324,6 @@ public class ChoiceService extends PollenServiceSupport { choiceDate.setTimeInMillis(Long.parseLong(choice.getChoiceValue())); } catch (NumberFormatException e) { - e.printStackTrace(); check(errors, "choiceValue", false, l(getLocale(), "pollen.error.choice.choiceDateInvalid", choice.getChoiceValue())); } if (choiceDate != null) { 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 44b793fe..f3d41c15 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 @@ -26,10 +26,10 @@ 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; -import org.chorem.pollen.services.bean.GtuMetaBean; import org.chorem.pollen.services.bean.PollenEntityId; import org.chorem.pollen.services.bean.PollenEntityRef; import org.chorem.pollen.services.bean.resource.AbstractResourceBean; +import org.chorem.pollen.services.bean.resource.GtuMetaBean; import org.chorem.pollen.services.bean.resource.ResourceFileBean; import org.chorem.pollen.services.bean.resource.ResourceMetaBean; import org.chorem.pollen.services.bean.resource.ResourceStreamBean; @@ -171,7 +171,7 @@ public class PollenResourceService extends PollenServiceSupport implements Polle errorMap.failIfNotEmpty(); // commit done by the caller - return getPollenResourceDao().create(resource.toEntity()); + return getPollenResourceDao().create(saveResource(resource)); } public void deleteResource(String resourceId) { @@ -191,7 +191,7 @@ public class PollenResourceService extends PollenServiceSupport implements Polle public ResourceStreamBean getAvatar(String userId) { PollenResource resource = getPollenResourceDao().findAvatarForUser(userId); - return toBean(ResourceStreamBean.class, resource); + return toResourceStreamBean(resource); } protected PollenResource getResource0(String resourceId) { @@ -200,7 +200,7 @@ public class PollenResourceService extends PollenServiceSupport implements Polle } - protected PollenResource saveResource(ResourceFileBean resource) { + protected PollenResource saveResource(AbstractResourceBean resource) { boolean resourceExist = resource.isPersisted(); @@ -216,14 +216,7 @@ public class PollenResourceService extends PollenServiceSupport implements Polle toSave.setContentType(resource.getContentType()); toSave.setSize(resource.getSize()); toSave.setResourceType(resource.getResourceType()); - try { - toSave.setResourceContent(resource.getResourceBlob()); - } catch (IOException | SQLException e) { - e.printStackTrace(); - - // no save - return null; - } + toSave.setResourceContent(resource.getResourceBlob()); return toSave; } 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 3d9b7102..9b94f51b 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 @@ -23,6 +23,8 @@ package org.chorem.pollen.services.service; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.apache.shiro.util.CollectionUtils; import org.chorem.pollen.persistence.entity.Comment; import org.chorem.pollen.persistence.entity.PollenPrincipal; @@ -30,8 +32,8 @@ import org.chorem.pollen.persistence.entity.PollenResource; import org.chorem.pollen.persistence.entity.PollenToken; import org.chorem.pollen.persistence.entity.PollenUser; import org.chorem.pollen.persistence.entity.PollenUserTopiaDao; -import org.chorem.pollen.persistence.entity.UserCredential; import org.chorem.pollen.persistence.entity.ResourceType; +import org.chorem.pollen.persistence.entity.UserCredential; import org.chorem.pollen.persistence.entity.Vote; import org.chorem.pollen.services.PollenService; import org.chorem.pollen.services.bean.PaginationParameterBean; @@ -47,6 +49,8 @@ import org.nuiton.util.pagination.PaginationOrder; import org.nuiton.util.pagination.PaginationParameter; import org.nuiton.util.pagination.PaginationResult; +import java.io.IOException; +import java.sql.SQLException; import java.util.Date; import java.util.List; import java.util.Objects; @@ -62,6 +66,9 @@ import static org.nuiton.i18n.I18n.l; */ public class PollenUserService extends PollenServiceSupport implements PollenService { + /** Logger. */ + private static final Log log = LogFactory.getLog(PollenUserService.class); + public PollenUserBean toPollenUserBean(PollenUser entity) { PollenUserBean bean = new PollenUserBean(); bean.setEntityId(entity.getTopiaId()); @@ -263,7 +270,9 @@ public class PollenUserService extends PollenServiceSupport implements PollenSer try { validateUserEmail(admin.getTopiaId(), admin.getEmailActivationToken().getToken()); } catch (PollenInvalidEmailActivationTokenException e) { - e.printStackTrace(); + if (log.isErrorEnabled()) { + log.error("Email of default user is not valid", e); + } } commit(); } 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 5e0cf192..0fe89cfe 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 @@ -322,6 +322,7 @@ require("./components/LetterAvatar.tag.html"); userService.setUserAvatar(this.refs.avatar.files[0]).then((result) => { console.log(result); this.user.avatar = result.id; + this.session.updateUser(); this.update(); }); } -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
participants (1)
-
chorem.org scm