Skip to content

Commit

Permalink
Merge pull request #140 from khoa-nd/master
Browse files Browse the repository at this point in the history
Merged
  • Loading branch information
khoa-nd committed Jan 9, 2015
2 parents ab419c5 + 6eea1c7 commit 884823e
Show file tree
Hide file tree
Showing 42 changed files with 349 additions and 261 deletions.
15 changes: 12 additions & 3 deletions src/main/java/com/techlooper/config/CoreConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,23 @@
import org.dozer.loader.api.TypeMappingOptions;
import org.jasypt.util.password.PasswordEncryptor;
import org.jasypt.util.password.StrongPasswordEncryptor;
import org.jasypt.util.text.BasicTextEncryptor;
import org.jasypt.util.text.TextEncryptor;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.cache.support.CompositeCacheManager;
import org.springframework.context.annotation.*;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.env.Environment;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.social.facebook.api.FacebookProfile;
import org.springframework.social.google.api.plus.Person;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.annotation.Resource;
import java.util.Arrays;

@Configuration
Expand All @@ -39,6 +43,9 @@
@EnableCaching(proxyTargetClass = true)
public class CoreConfiguration {

@Resource
private Environment environment;

@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
Expand Down Expand Up @@ -87,7 +94,7 @@ protected void configure() {
.fields("accountEmail", "emailAddress", FieldsMappingOptions.copyByReference())
.fields("imageUrl", "profileImageUrl", FieldsMappingOptions.copyByReference());

mapping(FacebookProfile.class, com.techlooper.entity.UserEntity.class, TypeMappingOptions.oneWay())
mapping(com.techlooper.entity.FacebookProfile.class, com.techlooper.entity.UserEntity.class, TypeMappingOptions.oneWay())
.fields("email", "emailAddress", FieldsMappingOptions.copyByReference());

mapping(LinkedInProfile.class, com.techlooper.entity.UserEntity.class, TypeMappingOptions.oneWay())
Expand All @@ -101,8 +108,10 @@ protected void configure() {
}

@Bean
public PasswordEncryptor passwordEncryptor() {
return new StrongPasswordEncryptor();
public TextEncryptor textEncryptor() {
BasicTextEncryptor textEncryptor = new BasicTextEncryptor();
textEncryptor.setPassword(environment.getProperty("core.textEncryptor.password"));
return textEncryptor;
}

}
8 changes: 6 additions & 2 deletions src/main/java/com/techlooper/controller/SocialController.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.techlooper.model.SocialResponse;
import com.techlooper.repository.JsonConfigRepository;
import com.techlooper.service.SocialService;
import org.jasypt.util.text.TextEncryptor;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
Expand All @@ -32,6 +33,9 @@ public class SocialController {
@Resource
private JsonConfigRepository jsonConfigRepository;

@Resource
private TextEncryptor textEncryptor;

@ResponseBody
@RequestMapping("/getSocialConfig")
public List<SocialConfig> getSocialConfig(@RequestParam("providers[]") List<SocialProvider> providers) {
Expand All @@ -53,7 +57,7 @@ public SocialResponse auth(@PathVariable SocialProvider provider,
UserEntity userEntity = StringUtils.hasText(key) ? service.saveFootprint(accessGrant, key) : service.saveFootprint(accessGrant);
return SocialResponse.Builder.get()
.withToken(accessGrant.getAccessToken())
.withKey(userEntity.getKey()).build();
.withKey(textEncryptor.encrypt(userEntity.key())).build();
}

@ResponseBody
Expand All @@ -68,7 +72,7 @@ public SocialResponse auth1(@PathVariable SocialProvider provider, HttpServletRe
UserEntity userEntity = StringUtils.hasText(key) ? service.saveFootprint(accessGrant, key) : service.saveFootprint(accessGrant);
return SocialResponse.Builder.get()
.withToken(accessGrant.getValue())
.withKey(userEntity.getKey()).build();
.withKey(textEncryptor.encrypt(userEntity.key())).build();
}
AccessGrant accessGrant = service.getAccessGrant(null, null);
httpServletResponse.sendRedirect(accessGrant.getAuthorizeUrl());
Expand Down
19 changes: 12 additions & 7 deletions src/main/java/com/techlooper/controller/UserController.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,19 @@
import com.techlooper.model.SocialRequest;
import com.techlooper.model.UserInfo;
import com.techlooper.service.UserService;
import org.jasypt.util.text.TextEncryptor;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.simp.annotation.SendToUser;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.List;
import java.util.Optional;

/**
* Created by phuonghqh on 12/23/14.
Expand All @@ -27,6 +26,9 @@ public class UserController {
@Resource
private UserService userService;

@Resource
private TextEncryptor textEncryptor;

@ResponseBody
@RequestMapping(value = "/user/save", method = RequestMethod.POST)
public List<FieldError> save(@RequestBody @Valid UserInfo userInfo, BindingResult result, HttpServletResponse httpServletResponse) {
Expand All @@ -44,14 +46,17 @@ public List<FieldError> save(@RequestBody @Valid UserInfo userInfo, BindingResul
@MessageMapping("/user/findByKey")
@ResponseBody
@RequestMapping(value = "/user/findByKey", method = RequestMethod.POST)
public UserInfo getUserInfo(@RequestBody @Valid SocialRequest searchRequest/*, @DestinationVariable String username */) {
UserInfo userInfo = userService.findUserInfoByKey(searchRequest.getKey());
public UserInfo getUserInfo(@CookieValue("techlooper.key") String techlooperKey/*, @DestinationVariable String username */) {
UserInfo userInfo = userService.findUserInfoByKey(techlooperKey);
userInfo.getLoginSource();
return userInfo;
}

@ResponseBody
@RequestMapping(value = "/user/verifyUserLogin", method = RequestMethod.POST)
public void verifyUserLogin(@RequestBody(required = false) SocialRequest searchRequest) {
public void verifyUserLogin(@RequestBody SocialRequest searchRequest, @CookieValue("techlooper.key") String techlooperKey, HttpServletResponse httpServletResponse) {
if (!textEncryptor.encrypt(searchRequest.getEmailAddress()).equals(techlooperKey)) {
httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
}
}
}
20 changes: 5 additions & 15 deletions src/main/java/com/techlooper/entity/UserEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.techlooper.model.SocialProvider;
import org.springframework.data.annotation.Id;
import org.springframework.data.couchbase.core.mapping.Document;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;
Expand All @@ -28,14 +29,16 @@ public class UserEntity {

private AccessGrant accessGrant;

private String key;

private String username;

private Integer salary;

private String profileImageUrl;

public String key() {
return StringUtils.hasText(emailAddress) ? emailAddress : id;
}

public String getProfileImageUrl() {
return profileImageUrl;
}
Expand All @@ -60,14 +63,6 @@ public void setUsername(String username) {
this.username = username;
}

public String getKey() {
return key;
}

public void setKey(String key) {
this.key = key;
}

public AccessGrant getAccessGrant() {
return accessGrant;
}
Expand Down Expand Up @@ -151,11 +146,6 @@ public UserEntityBuilder withAccessGrant(AccessGrant accessGrant) {
return this;
}

public UserEntityBuilder withKey(String key) {
userEntity.key = key;
return this;
}

public UserEntity build() {
return userEntity;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.techlooper.exception;

/**
* Created by phuonghqh on 1/9/15.
*/
public class EntityNotFoundException extends Error {

public EntityNotFoundException(String msg) {
super(msg);
}
}
11 changes: 10 additions & 1 deletion src/main/java/com/techlooper/model/SocialRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,18 @@
*/
public class SocialRequest {

@NotNull
private String key;

private String emailAddress;

public String getEmailAddress() {
return emailAddress;
}

public void setEmailAddress(String emailAddress) {
this.emailAddress = emailAddress;
}

public String getKey() {
return key;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@

import com.techlooper.entity.UserEntity;
import com.techlooper.entity.UserProfile;
import com.techlooper.exception.EntityNotFoundException;
import com.techlooper.model.SocialConfig;
import com.techlooper.model.SocialProvider;
import com.techlooper.repository.JsonConfigRepository;
import com.techlooper.service.SocialService;
import com.techlooper.service.UserService;
import org.dozer.Mapper;
import org.jasypt.util.password.PasswordEncryptor;
import org.jasypt.util.text.TextEncryptor;
import org.springframework.social.connect.support.OAuth1ConnectionFactory;
import org.springframework.social.connect.support.OAuth2ConnectionFactory;
import org.springframework.social.oauth1.AuthorizedRequestToken;
Expand All @@ -19,6 +20,7 @@

import javax.annotation.Resource;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;

import static com.techlooper.entity.AccessGrant.AccessGrantBuilder.accessGrant;
import static com.techlooper.entity.UserEntity.UserEntityBuilder.userEntity;
Expand All @@ -28,60 +30,65 @@
*/
public abstract class AbstractSocialService implements SocialService {

@Resource
protected UserService userService;
@Resource
protected UserService userService;

@Resource
protected Mapper dozerBeanMapper;
@Resource
protected Mapper dozerBeanMapper;

@Resource
protected PasswordEncryptor passwordEncryptor;
@Resource
protected TextEncryptor textEncryptor;

protected SocialConfig socialConfig;
protected SocialConfig socialConfig;

public AbstractSocialService(JsonConfigRepository jsonConfigRepository, SocialProvider socialProvider) {
socialConfig = jsonConfigRepository.getSocialConfig().stream()
.filter(config -> socialProvider == config.getProvider()).findFirst().get();
}
public AbstractSocialService(JsonConfigRepository jsonConfigRepository, SocialProvider socialProvider) {
socialConfig = jsonConfigRepository.getSocialConfig().stream()
.filter(config -> socialProvider == config.getProvider()).findFirst().get();
}

public com.techlooper.entity.AccessGrant getAccessGrant(String accessCode) {
AccessGrant access = getOAuth2ConnectionFactory().getOAuthOperations().exchangeForAccess(accessCode, socialConfig.getRedirectUri(), null);
return dozerBeanMapper.map(access, com.techlooper.entity.AccessGrant.class);
}

public com.techlooper.entity.AccessGrant getAccessGrant(String accessCode) {
AccessGrant access = getOAuth2ConnectionFactory().getOAuthOperations().exchangeForAccess(accessCode, socialConfig.getRedirectUri(), null);
return dozerBeanMapper.map(access, com.techlooper.entity.AccessGrant.class);
}
public com.techlooper.entity.AccessGrant getAccessGrant(String accessToken, String accessSecret) {
OAuth1Operations oAuthOperations = getOAuth1ConnectionFactory().getOAuthOperations();
if (Optional.ofNullable(accessToken).isPresent()) {
OAuthToken token = oAuthOperations.exchangeForAccessToken(
new AuthorizedRequestToken(new OAuthToken(accessToken, null), accessSecret), null);
return dozerBeanMapper.map(token, com.techlooper.entity.AccessGrant.class);
}
OAuthToken token = oAuthOperations.fetchRequestToken(socialConfig.getRedirectUri(), null);
String authorizeUrl = oAuthOperations.buildAuthorizeUrl(token.getValue(), OAuth1Parameters.NONE);
return accessGrant().withAuthorizeUrl(authorizeUrl).build();
}

public com.techlooper.entity.AccessGrant getAccessGrant(String accessToken, String accessSecret) {
OAuth1Operations oAuthOperations = getOAuth1ConnectionFactory().getOAuthOperations();
if (Optional.ofNullable(accessToken).isPresent()) {
OAuthToken token = oAuthOperations.exchangeForAccessToken(
new AuthorizedRequestToken(new OAuthToken(accessToken, null), accessSecret), null);
return dozerBeanMapper.map(token, com.techlooper.entity.AccessGrant.class);
protected AccessGrant getAccessGrant(com.techlooper.entity.AccessGrant accessGrant) {
return new AccessGrant(accessGrant.getAccessToken(), accessGrant.getScope(), accessGrant.getRefreshToken(), accessGrant.getExpireTime());
}
OAuthToken token = oAuthOperations.fetchRequestToken(socialConfig.getRedirectUri(), null);
String authorizeUrl = oAuthOperations.buildAuthorizeUrl(token.getValue(), OAuth1Parameters.NONE);
return accessGrant().withAuthorizeUrl(authorizeUrl).build();
}

protected AccessGrant getAccessGrant(com.techlooper.entity.AccessGrant accessGrant) {
return new AccessGrant(accessGrant.getAccessToken(), accessGrant.getScope(), accessGrant.getRefreshToken(), accessGrant.getExpireTime());
}
public OAuth2ConnectionFactory getOAuth2ConnectionFactory() {
throw new UnsupportedOperationException("Method is not supported");
}

public OAuth1ConnectionFactory getOAuth1ConnectionFactory() {
throw new UnsupportedOperationException("Method is not supported");
}

public OAuth2ConnectionFactory getOAuth2ConnectionFactory() {
throw new UnsupportedOperationException("Method is not supported");
}
public abstract UserProfile getProfile(com.techlooper.entity.AccessGrant accessGrant);

public OAuth1ConnectionFactory getOAuth1ConnectionFactory() {
throw new UnsupportedOperationException("Method is not supported");
}
public UserEntity saveFootprint(com.techlooper.entity.AccessGrant accessGrant, String key) {
UserEntity entity = userService.findUserEntityByKey(key);
if (!Optional.ofNullable(entity).isPresent()) {
throw new EntityNotFoundException("Can not find User by key: " + key);
}

public abstract UserProfile getProfile(com.techlooper.entity.AccessGrant accessGrant);
CompletableFuture.supplyAsync(() -> getProfile(accessGrant)).thenAccept((profile) -> {
userEntity(entity).withProfile(socialConfig.getProvider(), profile);
userService.save(entity);
});

public UserEntity saveFootprint(com.techlooper.entity.AccessGrant accessGrant, String key) {
UserEntity entity = userService.findUserEntityByKey(key);
if (!Optional.ofNullable(entity).isPresent()) {
throw new UnsupportedOperationException("Method is not supported");
userEntity(entity).withProfile(socialConfig.getProvider(), null);
return entity;
}
userEntity(entity).withProfile(socialConfig.getProvider(), getProfile(accessGrant));
userService.save(entity);
return entity;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,7 @@ public UserEntity saveFootprint(AccessGrant accessGrant) {
if (!Optional.ofNullable(userEntity.getEmailAddress()).isPresent()) {
dozerBeanMapper.map(profileEntity, userEntity);
builder.withId(profileEntity.getEmail())
.withLoginSource(SocialProvider.FACEBOOK)
.withKey(passwordEncryptor.encryptPassword(profileEntity.getEmail()));
.withLoginSource(SocialProvider.FACEBOOK);
}
userService.save(userEntity);
return userEntity;
Expand Down
Loading

0 comments on commit 884823e

Please sign in to comment.