This is an automated email from the git hooks/post-receive script. New commit to branch feature/1_socialauth in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit ef68f13ec531f3bbbf6ee5f376c6806cb8d17835 Author: Kevin Morin <morin@codelutin.com> Date: Mon Sep 4 15:21:58 2017 +0200 refs #1 permettre d'ajouter des comptes tiers à un compte existant --- .../persistence/entity/UserCredentialTopiaDao.java | 30 +++++++ .../db/migration/h2/V3_0_0_8__add_credentials.sql | 1 + .../postgresql/V3_0_0_8__add_credentials.sql | 1 + pollen-persistence/src/main/xmi/pollen.zargo | Bin 28069 -> 28138 bytes .../pollen/rest/api/PollenRestApiApplication.java | 4 +- .../PollenEmailAlreadyUsedExceptionMapper.java | 20 ----- ...rProviderAccountAlreadyUsedExceptionMapper.java | 20 +++++ .../org/chorem/pollen/rest/api/v1/ApiUtils.java | 2 + .../org/chorem/pollen/rest/api/v1/AuthApi.java | 11 ++- .../chorem/pollen/rest/api/v1/PollenUserApi.java | 39 +++++++-- .../pollen/services/bean/PollenUserBean.java | 21 +++++ .../pollen/services/bean/UserCredentialBean.java | 49 +++++++++++ .../pollen/services/service/PollenUserService.java | 1 + .../pollen/services/service/SocialAuthService.java | 90 +++++++++++++++++---- .../security/PollenEmailAlreadyUsedException.java | 11 --- ...EmailOrProviderAccountAlreadyUsedException.java | 11 +++ 16 files changed, 249 insertions(+), 62 deletions(-) diff --git a/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/UserCredentialTopiaDao.java b/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/UserCredentialTopiaDao.java new file mode 100644 index 00000000..68302fed --- /dev/null +++ b/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/UserCredentialTopiaDao.java @@ -0,0 +1,30 @@ +package org.chorem.pollen.persistence.entity; + +import java.util.HashMap; +import java.util.Map; + +public class UserCredentialTopiaDao extends AbstractUserCredentialTopiaDao<UserCredential> { + + public boolean isCredentialValid(String provider, String credentialUserId, String userTopiaId, String email) { + String query = "SELECT COUNT(*)" + + " FROM " + PollenUser.class.getName() + " AS user RIGHT JOIN user." + PollenUser.PROPERTY_USER_CREDENTIAL + " AS credential" + + " WHERE" + + " (credential." + UserCredential.PROPERTY_PROVIDER + " = :provider" + + " AND credential." + UserCredential.PROPERTY_USER_ID + " = :credentialUserId)"; + if (email != null) { + query += " OR (user." + PollenUser.PROPERTY_TOPIA_ID + " = :userTopiaId" + + " AND credential." + UserCredential.PROPERTY_EMAIL + " = :credentialEmail)" + + " OR user." + PollenUser.PROPERTY_EMAIL + " = :userEmail"; + } + + Map<String, Object> params = new HashMap<>(); + params.put("provider", provider); + params.put("credentialUserId", credentialUserId); + if (email != null) { + params.put("userEmail", email); + params.put("userTopiaId", userTopiaId); + params.put("credentialEmail", email); + } + return count(query, params) == 0; + } +} diff --git a/pollen-persistence/src/main/resources/db/migration/h2/V3_0_0_8__add_credentials.sql b/pollen-persistence/src/main/resources/db/migration/h2/V3_0_0_8__add_credentials.sql index 1825b8ae..48fadea4 100644 --- a/pollen-persistence/src/main/resources/db/migration/h2/V3_0_0_8__add_credentials.sql +++ b/pollen-persistence/src/main/resources/db/migration/h2/V3_0_0_8__add_credentials.sql @@ -6,6 +6,7 @@ CREATE TABLE USERCREDENTIAL ( TOPIACREATEDATE TIMESTAMP, PROVIDER VARCHAR(255), USERID VARCHAR(255), + USERNAME VARCHAR(255), EMAIL VARCHAR(255), POLLENUSER VARCHAR(255), FOREIGN KEY (POLLENUSER) references POLLENUSER(TOPIAID) diff --git a/pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_0_8__add_credentials.sql b/pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_0_8__add_credentials.sql index 2280308e..d1f2803d 100644 --- a/pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_0_8__add_credentials.sql +++ b/pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_0_8__add_credentials.sql @@ -6,6 +6,7 @@ CREATE TABLE USERCREDENTIAL ( TOPIACREATEDATE TIMESTAMP, PROVIDER VARCHAR(255), USERID VARCHAR(255), + USERNAME VARCHAR(255), EMAIL VARCHAR(255), POLLENUSER VARCHAR(255), FOREIGN KEY (POLLENUSER) references POLLENUSER(TOPIAID) diff --git a/pollen-persistence/src/main/xmi/pollen.zargo b/pollen-persistence/src/main/xmi/pollen.zargo index 0f29e782..7ce056d6 100644 Binary files a/pollen-persistence/src/main/xmi/pollen.zargo and b/pollen-persistence/src/main/xmi/pollen.zargo differ diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/PollenRestApiApplication.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/PollenRestApiApplication.java index 271b223a..687e4f38 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/PollenRestApiApplication.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/PollenRestApiApplication.java @@ -7,7 +7,7 @@ import org.chorem.pollen.rest.api.exceptionMappers.FavoriteListImportExceptionMa import org.chorem.pollen.rest.api.exceptionMappers.InvalidEntityLinkExceptionMapper; import org.chorem.pollen.rest.api.exceptionMappers.InvalidFormExceptionMapper; import org.chorem.pollen.rest.api.exceptionMappers.PollenAuthenticationExceptionMapper; -import org.chorem.pollen.rest.api.exceptionMappers.PollenEmailAlreadyUsedExceptionMapper; +import org.chorem.pollen.rest.api.exceptionMappers.PollenEmailOrProviderAccountAlreadyUsedExceptionMapper; import org.chorem.pollen.rest.api.exceptionMappers.PollenEmailNotValidatedExceptionMapper; import org.chorem.pollen.rest.api.exceptionMappers.PollenInvalidEmailActivationTokenExceptionMapper; import org.chorem.pollen.rest.api.exceptionMappers.PollenInvalidPermissionExceptionMapper; @@ -62,7 +62,7 @@ public class PollenRestApiApplication extends Application { new PollenInvalidPermissionExceptionMapper(), new PollenInvalidEmailActivationTokenExceptionMapper(), new PollenEmailNotValidatedExceptionMapper(), - new PollenEmailAlreadyUsedExceptionMapper(), + new PollenEmailOrProviderAccountAlreadyUsedExceptionMapper(), new PollenUserBannedExceptionMapper(), new InvalidFormExceptionMapper(), new FavoriteListImportExceptionMapper(), diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/exceptionMappers/PollenEmailAlreadyUsedExceptionMapper.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/exceptionMappers/PollenEmailAlreadyUsedExceptionMapper.java deleted file mode 100644 index 3b1ec37b..00000000 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/exceptionMappers/PollenEmailAlreadyUsedExceptionMapper.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.chorem.pollen.rest.api.exceptionMappers; - -import org.chorem.pollen.services.service.security.PollenEmailAlreadyUsedException; - -import javax.ws.rs.core.Response; - -/** - * @author Sylvain Bavencoff - bavencoff@codelutin.com - */ -public class PollenEmailAlreadyUsedExceptionMapper extends PollenAbstractExceptionMapper<PollenEmailAlreadyUsedException> { - - public PollenEmailAlreadyUsedExceptionMapper() { - super(Response.Status.FORBIDDEN); - } - - @Override - protected Object getEntity(PollenEmailAlreadyUsedException exception) { - return "emailAlreadyUsed"; - } -} diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/exceptionMappers/PollenEmailOrProviderAccountAlreadyUsedExceptionMapper.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/exceptionMappers/PollenEmailOrProviderAccountAlreadyUsedExceptionMapper.java new file mode 100644 index 00000000..d6671c68 --- /dev/null +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/exceptionMappers/PollenEmailOrProviderAccountAlreadyUsedExceptionMapper.java @@ -0,0 +1,20 @@ +package org.chorem.pollen.rest.api.exceptionMappers; + +import org.chorem.pollen.services.service.security.PollenEmailOrProviderAccountAlreadyUsedException; + +import javax.ws.rs.core.Response; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class PollenEmailOrProviderAccountAlreadyUsedExceptionMapper extends PollenAbstractExceptionMapper<PollenEmailOrProviderAccountAlreadyUsedException> { + + public PollenEmailOrProviderAccountAlreadyUsedExceptionMapper() { + super(Response.Status.FORBIDDEN); + } + + @Override + protected Object getEntity(PollenEmailOrProviderAccountAlreadyUsedException exception) { + return "emailOrProviderAccountAlreadyUsed"; + } +} diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/ApiUtils.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/ApiUtils.java index cebdb51c..dec31e1b 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/ApiUtils.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/ApiUtils.java @@ -27,6 +27,8 @@ import java.util.regex.Pattern; */ public class ApiUtils { + public static final String SOCIAL_AUTH_MANAGER_SESSION_KEY = "socialAuthManager"; + public static Response exportBeanToResponse(ExportBean exportBean) { InputStream inputStream = IOUtils.toInputStream(exportBean.getContent(), Charsets.UTF_8); diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/AuthApi.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/AuthApi.java index fc2ac99b..776a4f6c 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/AuthApi.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/AuthApi.java @@ -80,7 +80,6 @@ public class AuthApi { public static final String COOKIE_POLLEN_AUTH = "pollen-auth"; private static final String COOKIE_POLLEN_CONNECTED = "pollen-connected"; private static final int COOKIE_MAX_AGE = 60 * 60 * 24 * 365; // 1 year - private static final String SOCIAL_AUTH_MANAGER_SESSION_KEY = "socialAuthManager"; public static Response.ResponseBuilder removeAuthCookie(Response.ResponseBuilder reponseBuilder) { @@ -203,7 +202,7 @@ public class AuthApi { throws Exception { SocialAuthManager socialAuthManager = socialAuthService.getSocialAuthManager(); - request.getSession(true).setAttribute(SOCIAL_AUTH_MANAGER_SESSION_KEY, socialAuthManager); + request.getSession(true).setAttribute(ApiUtils.SOCIAL_AUTH_MANAGER_SESSION_KEY, socialAuthManager); return socialAuthManager.getAuthenticationUrl(providerId, providerRedirection); } @@ -214,15 +213,15 @@ public class AuthApi { @Context SecurityService securityService, @Context PollenSecurityContext securityContext, @Context HttpServletRequest request, - @HeaderParam("authorization") String authorization) + String providerReturn) throws Exception { SocialAuthManager socialAuthManager = - (SocialAuthManager) request.getSession().getAttribute(SOCIAL_AUTH_MANAGER_SESSION_KEY); + (SocialAuthManager) request.getSession().getAttribute(ApiUtils.SOCIAL_AUTH_MANAGER_SESSION_KEY); //socialAuthManager - request.getSession().removeAttribute(SOCIAL_AUTH_MANAGER_SESSION_KEY); + request.getSession().removeAttribute(ApiUtils.SOCIAL_AUTH_MANAGER_SESSION_KEY); Gson gson = new Gson(); - Map<String, String> paramsMap = gson.fromJson(authorization, Map.class); + Map<String, String> paramsMap = gson.fromJson(providerReturn, Map.class); PollenEntityRef<PollenUser> userPollenEntityRef = socialAuthService.login(socialAuthManager, paramsMap); return getLoginResponseFromPollenUser(serviceContext, securityService, securityContext, userPollenEntityRef); diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenUserApi.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenUserApi.java index 123e13c3..188b9ea7 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenUserApi.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenUserApi.java @@ -21,7 +21,10 @@ package org.chorem.pollen.rest.api.v1; * #L% */ +import com.google.gson.Gson; +import org.brickred.socialauth.SocialAuthManager; import org.chorem.pollen.persistence.entity.PollenUser; +import org.chorem.pollen.persistence.entity.UserCredential; import org.chorem.pollen.rest.api.beans.ChangePasswordBean; import org.chorem.pollen.services.bean.PaginationParameterBean; import org.chorem.pollen.services.bean.PaginationResultBean; @@ -30,9 +33,11 @@ import org.chorem.pollen.services.bean.PollenEntityRef; import org.chorem.pollen.services.bean.PollenUserBean; import org.chorem.pollen.services.service.InvalidFormException; import org.chorem.pollen.services.service.PollenUserService; +import org.chorem.pollen.services.service.SocialAuthService; import org.chorem.pollen.services.service.security.PollenInvalidEmailActivationTokenException; import org.chorem.pollen.services.service.security.PollenSecurityContext; +import javax.servlet.http.HttpServletRequest; import javax.ws.rs.BeanParam; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; @@ -45,6 +50,7 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; +import java.util.Map; import java.util.Objects; /** @@ -65,7 +71,6 @@ public class PollenUserApi { @QueryParam("search") String search) { return pollenUserService.getUsers(paginationParameter, search); - } @Path("/users/connected") @@ -74,7 +79,6 @@ public class PollenUserApi { PollenUser pollenUser = securityContext.getPollenUser(); Objects.requireNonNull(pollenUser,"Could not find connected user"); return pollenUserService.getUser(pollenUser.getTopiaId()); - } @Path("/users/{userId}") @@ -83,7 +87,6 @@ public class PollenUserApi { @PathParam("userId") PollenEntityId<PollenUser> userId) { return pollenUserService.getUser(userId.getEntityId()); - } @Path("/users") @@ -92,7 +95,6 @@ public class PollenUserApi { PollenUserBean user) throws InvalidFormException { return pollenUserService.createUser(user); - } @Path("/users/{userId}") @@ -101,7 +103,6 @@ public class PollenUserApi { PollenUserBean user) throws InvalidFormException { return pollenUserService.editUser(user); - } @Path("/users/{userId}") @@ -111,7 +112,6 @@ public class PollenUserApi { @QueryParam("anonymize") boolean anonymize) { pollenUserService.deleteUser(userId.getEntityId(), anonymize); - } @Path("/users/{userId}") @@ -121,7 +121,6 @@ public class PollenUserApi { @QueryParam("token") String token) throws PollenInvalidEmailActivationTokenException { pollenUserService.validateUserEmail(userId.getEntityId(), token); - } @Path("/users/{userId}/password") @@ -131,6 +130,32 @@ public class PollenUserApi { ChangePasswordBean bean) throws InvalidFormException { pollenUserService.changePassword(userId.getEntityId(), bean.getOldPassword(), bean.getNewPassword()); + } + + @Path("/users/{userId}/credentials/{provider}") + @POST + public String addUserCredential(@Context SocialAuthService socialAuthService, + @Context HttpServletRequest request, + @PathParam("userId") PollenEntityId<PollenUser> userId, + @PathParam("provider") String provider, + String providerReturn) throws Exception { + + SocialAuthManager socialAuthManager = + (SocialAuthManager) request.getSession().getAttribute(ApiUtils.SOCIAL_AUTH_MANAGER_SESSION_KEY); + //socialAuthManager + request.getSession().removeAttribute(ApiUtils.SOCIAL_AUTH_MANAGER_SESSION_KEY); + Gson gson = new Gson(); + Map<String, String> paramsMap = gson.fromJson(providerReturn, Map.class); + return socialAuthService.addCredentialToUser(userId, socialAuthManager, paramsMap); + } + + @Path("/users/{userId}/credentials/{credentialId}") + @DELETE + public void deleteUserCredential(@Context SocialAuthService socialAuthService, + @Context HttpServletRequest request, + @PathParam("userId") PollenEntityId<PollenUser> userId, + @PathParam("credentialId") PollenEntityId<UserCredential> credentialId) throws Exception { + socialAuthService.deleteUserCredential(userId, credentialId); } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollenUserBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollenUserBean.java index 42d33279..d167d9eb 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollenUserBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollenUserBean.java @@ -24,6 +24,10 @@ package org.chorem.pollen.services.bean; import org.chorem.pollen.persistence.entity.PollenUser; import org.chorem.pollen.persistence.entity.PollenUserImpl; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + /** * Created on 5/15/14. * @@ -48,6 +52,8 @@ public class PollenUserBean extends PollenBean<PollenUser> { protected boolean withPassword; + protected List<UserCredentialBean> credentials = new ArrayList<>(); + public PollenUserBean() { super(PollenUser.class); } @@ -65,6 +71,13 @@ public class PollenUserBean extends PollenBean<PollenUser> { setPassword(entity.getPassword()); setEmailIsValidate(entity.getEmailActivationToken() == null); setWithPassword(entity.getPassword() != null); + setCredentials(entity.getUserCredential().stream() + .map(userCredential -> { + UserCredentialBean userCredentialBean = new UserCredentialBean(); + userCredentialBean.fromEntity(userCredential); + return userCredentialBean; + }) + .collect(Collectors.toList())); } @Override @@ -146,4 +159,12 @@ public class PollenUserBean extends PollenBean<PollenUser> { public void setWithPassword(boolean withPassword) { this.withPassword = withPassword; } + + public List<UserCredentialBean> getCredentials() { + return credentials; + } + + public void setCredentials(List<UserCredentialBean> credentials) { + this.credentials = credentials; + } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/UserCredentialBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/UserCredentialBean.java new file mode 100644 index 00000000..d88f3444 --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/UserCredentialBean.java @@ -0,0 +1,49 @@ +package org.chorem.pollen.services.bean; + +import org.chorem.pollen.persistence.entity.UserCredential; +import org.chorem.pollen.persistence.entity.UserCredentialImpl; + +/** + * @author Kevin Morin (Code Lutin) + */ +public class UserCredentialBean extends PollenBean<UserCredential> { + + protected String provider; + protected String userName; + + protected UserCredentialBean() { + super(UserCredential.class); + } + + @Override + public void fromEntity(UserCredential entity) { + setEntityId(entity.getTopiaId()); + setProvider(entity.getProvider()); + setUserName(entity.getUserName()); + } + + @Override + public UserCredential toEntity() { + UserCredential entity = new UserCredentialImpl(); + entity.setTopiaId(getEntityId()); + entity.setProvider(getProvider()); + entity.setUserName(getUserName()); + return entity; + } + + public String getProvider() { + return provider; + } + + public void setProvider(String provider) { + this.provider = provider; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } +} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenUserService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenUserService.java index 5db9468d..ae57949f 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenUserService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenUserService.java @@ -137,6 +137,7 @@ public class PollenUserService extends PollenServiceSupport implements PollenSer anonymizeUser(user); } + getUserCredentialDao().deleteAll(user.getUserCredential()); getPollenUserDao().delete(user); commit(); diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/SocialAuthService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/SocialAuthService.java index 0132f818..bfa301af 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/SocialAuthService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/SocialAuthService.java @@ -16,9 +16,12 @@ import org.chorem.pollen.persistence.entity.PollenUserImpl; import org.chorem.pollen.persistence.entity.PollenUserTopiaDao; import org.chorem.pollen.persistence.entity.UserCredential; import org.chorem.pollen.persistence.entity.UserCredentialImpl; +import org.chorem.pollen.persistence.entity.UserCredentialTopiaDao; import org.chorem.pollen.services.bean.LoginProviderBean; +import org.chorem.pollen.services.bean.PollenEntityId; import org.chorem.pollen.services.bean.PollenEntityRef; -import org.chorem.pollen.services.service.security.PollenEmailAlreadyUsedException; +import org.chorem.pollen.services.service.security.PollenEmailOrProviderAccountAlreadyUsedException; +import org.chorem.pollen.services.service.security.PollenUnauthorizedException; import java.util.ArrayList; import java.util.List; @@ -46,30 +49,26 @@ public class SocialAuthService extends PollenServiceSupport { PollenUserTopiaDao userDao = getPollenUserDao(); Optional<PollenUser> pollenUserForCredential = userDao.tryFindUserWithCredential(p.getProviderId(), p.getValidatedId()); - String name = p.getDisplayName(); - if (name == null) { - name = p.getFirstName() + " " + p.getLastName(); - } - if (pollenUserForCredential.isPresent()) { - if (log.isInfoEnabled()) { - log.info("credentials found : " + name); + if (log.isDebugEnabled()) { + log.debug("credentials found"); } pollenUser = pollenUserForCredential.get(); } else if (userDao.emailExists(p.getEmail())) { - throw new PollenEmailAlreadyUsedException(); + throw new PollenEmailOrProviderAccountAlreadyUsedException(); } else { - if (log.isInfoEnabled()) { - log.info("create new user : " + name); + String name = p.getFullName(); + if (name == null) { + name = p.getFirstName() + " " + p.getLastName(); + } + + if (log.isDebugEnabled()) { + log.debug("create new user : " + name); } - UserCredential credential = new UserCredentialImpl(); - credential.setProvider(p.getProviderId()); - credential.setUserId(p.getValidatedId()); - credential.setEmail(p.getEmail()); - credential = getUserCredentialDao().create(credential); + UserCredential credential = createUserCredential(p); pollenUser = new PollenUserImpl(); pollenUser.setName(name); @@ -88,6 +87,51 @@ public class SocialAuthService extends PollenServiceSupport { return getSecurityService().getSessionTokenForUser(pollenUser); } + public String addCredentialToUser(PollenEntityId<PollenUser> userId, + SocialAuthManager manager, + Map<String, String> paramsMap) throws Exception { + + checkIsConnected(); + PollenUser connectedUser = getConnectedUser(); + if (!connectedUser.getTopiaId().equals(userId.getEntityId())) { + throw new PollenUnauthorizedException(userId.getReducedId()); + } + + AuthProvider provider = manager.connect(paramsMap); + + // get profile + Profile p = provider.getUserProfile(); + + boolean credentialValid = getUserCredentialDao().isCredentialValid(p.getProviderId(), + p.getValidatedId(), + connectedUser.getTopiaId(), + p.getEmail()); + if (!credentialValid) { + throw new PollenEmailOrProviderAccountAlreadyUsedException(); + } + + UserCredential credential = createUserCredential(p); + connectedUser.addUserCredential(credential); + commit(); + + return credential.getUserName(); + } + + protected UserCredential createUserCredential(Profile p) { + String accountName = p.getDisplayName(); + if (accountName == null) { + accountName = p.getFullName(); + } + + UserCredential credential = new UserCredentialImpl(); + credential.setProvider(p.getProviderId()); + credential.setUserId(p.getValidatedId()); + credential.setUserName(accountName); + credential.setEmail(p.getEmail()); + credential = getUserCredentialDao().create(credential); + return credential; + } + public SocialAuthManager getSocialAuthManager() throws Exception { //Create an instance of SocialAuthConfgi object SocialAuthConfig config = SocialAuthConfig.getDefault(); @@ -185,4 +229,18 @@ public class SocialAuthService extends PollenServiceSupport { dao.delete(dao.forTopiaIdEquals(providerId).findUnique()); commit(); } + + public void deleteUserCredential(PollenEntityId<PollenUser> userId, PollenEntityId<UserCredential> credentialId) { + checkNotNull(credentialId); + + checkIsConnected(); + PollenUser connectedUser = getConnectedUser(); + if (!connectedUser.getTopiaId().equals(userId.getEntityId())) { + throw new PollenUnauthorizedException(userId.getReducedId()); + } + + UserCredentialTopiaDao dao = getUserCredentialDao(); + dao.delete(dao.forTopiaIdEquals(credentialId.getEntityId()).findUnique()); + commit(); + } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/security/PollenEmailAlreadyUsedException.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/security/PollenEmailAlreadyUsedException.java deleted file mode 100644 index afd67772..00000000 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/security/PollenEmailAlreadyUsedException.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.chorem.pollen.services.service.security; - -/** - * @author Kevin Morin (Code Lutin) - */ -public class PollenEmailAlreadyUsedException extends Exception { - - public PollenEmailAlreadyUsedException() { - super("emailAlreadyUsed"); - } -} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/security/PollenEmailOrProviderAccountAlreadyUsedException.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/security/PollenEmailOrProviderAccountAlreadyUsedException.java new file mode 100644 index 00000000..cb5bf239 --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/security/PollenEmailOrProviderAccountAlreadyUsedException.java @@ -0,0 +1,11 @@ +package org.chorem.pollen.services.service.security; + +/** + * @author Kevin Morin (Code Lutin) + */ +public class PollenEmailOrProviderAccountAlreadyUsedException extends Exception { + + public PollenEmailOrProviderAccountAlreadyUsedException() { + super("emailOrProviderAccountAlreadyUsed"); + } +} -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.