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 f0692bd563403b9ab4074f76219f445a678fd572 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 +- pollen-persistence/src/main/xmi/pollen.zargo | Bin 28419 -> 28921 bytes .../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 | 4 +- .../pollen/rest/api/v1/PollenResourceApi.java | 15 +- .../chorem/pollen/rest/api/v1/PollenUserApi.java | 4 +- .../pollen/services/bean/PollenUserBean.java | 5 +- .../AbstractResourceBean.java} | 49 +--- .../services/bean/{ => resource}/GtuMetaBean.java | 2 +- .../bean/{ => resource}/ResourceFileBean.java | 60 +--- .../services/bean/resource/ResourceMetaBean.java | 54 ++++ .../bean/{ => resource}/ResourceStreamBean.java | 50 +--- .../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 +++++++++++---------- 22 files changed, 318 insertions(+), 324 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 19fe27c2..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.0.0.11 +model.tagvalue.version=3.0.1.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 1642eec1..9df3975b 100644 Binary files a/pollen-persistence/src/main/xmi/pollen.zargo and b/pollen-persistence/src/main/xmi/pollen.zargo differ diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/ApiUtils.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/ApiUtils.java index dec31e1b..9f814048 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 @@ -6,7 +6,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 bd2e4631..a45e1d49 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,7 +1,7 @@ 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 fd44cb39..21272cad 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; @@ -145,4 +146,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 023864c8..053feff6 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 @@ -161,7 +161,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, @@ -173,6 +173,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/PollenUserBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollenUserBean.java index aea1b1d0..7af63ad3 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 @@ -84,7 +84,9 @@ public class PollenUserBean extends PollenBean<PollenUser> { }) .collect(Collectors.toList())); } - setAvatar(entity.getAvatar()); + if (entity.getAvatar() != null) { + setAvatar(entity.getAvatar().getTopiaId()); + } } @Override @@ -98,7 +100,6 @@ public class PollenUserBean extends PollenBean<PollenUser> { entity.setLanguage(getLanguage()); entity.setEmail(getEmail()); entity.setPassword(getPassword()); - entity.setAvatar(getAvatar()); return entity; 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/AbstractResourceBean.java similarity index 55% 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/AbstractResourceBean.java index eea72c85..685e6570 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/AbstractResourceBean.java @@ -1,38 +1,14 @@ -package org.chorem.pollen.services.bean; - -/* - * #%L - * Pollen :: Service - * %% - * Copyright (C) 2009 - 2017 Code Lutin, Tony Chemit - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ +package org.chorem.pollen.services.bean.resource; import org.chorem.pollen.persistence.entity.PollenResource; import org.chorem.pollen.persistence.entity.PollenResourceImpl; import org.chorem.pollen.persistence.entity.ResourceType; - -import java.util.Date; +import org.chorem.pollen.services.bean.PollenBean; /** - * Created on 11/07/14. - * - * @author dralagen + * @author Kevin Morin (Code Lutin) */ -public class ResourceMetaBean extends PollenBean<PollenResource> { +public abstract class AbstractResourceBean extends PollenBean<PollenResource> { protected String name; @@ -42,21 +18,17 @@ public class ResourceMetaBean extends PollenBean<PollenResource> { protected ResourceType resourceType; - protected Date uploadDate; - - protected ResourceMetaBean() { - super(PollenResource.class); + protected AbstractResourceBean(Class<PollenResource> entityType) { + super(entityType); } @Override public void fromEntity(PollenResource entity) { setEntityId(entity.getTopiaId()); - setName(entity.getName()); setSize(entity.getSize()); setContentType(entity.getContentType()); setResourceType(entity.getResourceType()); - setUploadDate(entity.getTopiaCreateDate()); } @Override @@ -64,7 +36,6 @@ public class ResourceMetaBean extends PollenBean<PollenResource> { PollenResource entity = new PollenResourceImpl(); entity.setTopiaId(getEntityId()); - entity.setName(getName()); entity.setSize(getSize()); entity.setContentType(getContentType()); @@ -104,12 +75,4 @@ public class ResourceMetaBean extends PollenBean<PollenResource> { public void setResourceType(ResourceType resourceType) { this.resourceType = resourceType; } - - public Date getUploadDate() { - return uploadDate; - } - - public void setUploadDate(Date uploadDate) { - this.uploadDate = uploadDate; - } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/GtuMetaBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/GtuMetaBean.java similarity index 85% 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 b7126cb4..26724203 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; /** * @author Sylvain Bavencoff - bavencoff@codelutin.com 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 60% 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 526d9fa2..a6326526 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,8 +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.PollenResourceImpl; -import org.chorem.pollen.persistence.entity.ResourceType; import javax.sql.rowset.serial.SerialBlob; import java.io.File; @@ -41,37 +39,23 @@ 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); } @Override public void fromEntity(PollenResource entity) { - setEntityId(entity.getTopiaId()); - - setName(entity.getName()); - setSize(entity.getSize()); - setContentType(entity.getContentType()); + super.fromEntity(entity); setResourceType(entity.getResourceType()); } @Override public PollenResource toEntity() { - PollenResource entity = new PollenResourceImpl(); - - entity.setTopiaId(getEntityId()); + PollenResource entity = super.toEntity(); try { entity.setResourceContent(getResourceBlob()); @@ -79,11 +63,6 @@ public class ResourceFileBean extends PollenBean<PollenResource> { e.printStackTrace(); } - entity.setName(getName()); - entity.setSize(getSize()); - entity.setContentType(getContentType()); - entity.setResourceType(getResourceType()); - return entity; } @@ -95,30 +74,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; @@ -131,11 +86,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/resource/ResourceMetaBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceMetaBean.java new file mode 100644 index 00000000..315f854e --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceMetaBean.java @@ -0,0 +1,54 @@ +package org.chorem.pollen.services.bean.resource; + +/* + * #%L + * Pollen :: Service + * %% + * Copyright (C) 2009 - 2017 Code Lutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ + +import org.chorem.pollen.persistence.entity.PollenResource; + +import java.util.Date; + +/** + * Created on 11/07/14. + * + * @author dralagen + */ +public class ResourceMetaBean extends AbstractResourceBean { + + protected Date uploadDate; + + protected ResourceMetaBean() { + super(PollenResource.class); + } + + @Override + public void fromEntity(PollenResource entity) { + super.fromEntity(entity); + setUploadDate(entity.getTopiaCreateDate()); + } + + public Date getUploadDate() { + return uploadDate; + } + + public void setUploadDate(Date uploadDate) { + this.uploadDate = uploadDate; + } +} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/ResourceStreamBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceStreamBean.java similarity index 65% 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 75cd147c..800f4520 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 @@ -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.PollenResourceImpl; import javax.sql.rowset.serial.SerialBlob; import java.io.IOException; @@ -36,40 +35,28 @@ 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); } @Override public void fromEntity(PollenResource entity) { - setEntityId(entity.getTopiaId()); + super.fromEntity(entity); try { setResourceContent(entity.getResourceContent().getBinaryStream()); } catch (SQLException e) { e.printStackTrace(); } - - setName(entity.getName()); - setSize(entity.getSize()); - setContentType(entity.getContentType()); } @Override public PollenResource toEntity() { - PollenResource entity = new PollenResourceImpl(); - - entity.setTopiaId(getEntityId()); + PollenResource entity = super.toEntity(); try { entity.setResourceContent(getResourceBlob()); @@ -77,11 +64,6 @@ public class ResourceStreamBean extends PollenBean<PollenResource> { e.printStackTrace(); } - entity.setName(getName()); - entity.setSize(getSize()); - entity.setContentType(getContentType()); - - return entity; } @@ -93,30 +75,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 faf481a8..e5a8dad8 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 @@ -6,8 +6,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 da8edb63..438a8074 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 @@ -28,9 +28,10 @@ import org.chorem.pollen.services.PollenTechnicalException; import org.chorem.pollen.services.UnitHuman; 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; @@ -131,6 +132,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 PollenEntityRef<PollenResource> editResource(String resourceId, ResourceFileBean resource) throws InvalidFormException { checkNotNull(resourceId); checkIsNotPersisted(resource); @@ -163,6 +175,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(); @@ -215,7 +232,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 e651320c..80d6eb97 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 @@ -11,18 +11,23 @@ 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.persistence.entity.UserCredentialTopiaDao; import org.chorem.pollen.services.bean.LoginProviderBean; import org.chorem.pollen.services.bean.PollenEntityId; import org.chorem.pollen.services.bean.PollenEntityRef; +import org.chorem.pollen.services.bean.resource.ResourceStreamBean; import org.chorem.pollen.services.service.security.PollenEmailOrProviderAccountAlreadyUsedException; import org.chorem.pollen.services.service.security.PollenUnauthorizedException; +import java.net.URL; +import java.net.URLConnection; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -248,21 +253,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 a0fa145b..001ec045 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 @@ -5,163 +5,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> @@ -169,10 +172,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"); @@ -204,7 +207,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")); }); }; @@ -237,7 +240,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) => { @@ -284,10 +287,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>.