diff --git a/pom.xml b/pom.xml
index 84eeb1b..6f5147b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,12 +4,12 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
- monkeyk.com
+ com.monkeyk
spring-oauth-server
0.5-beta
spring-oauth-server
war
- Spring Oauth Server
+ Spring Oauth Server[MongoDB]
UTF-8
@@ -18,16 +18,8 @@
4.0.1.RELEASE
2.0.7.RELEASE
2.5.4
-
1.8.6
-
- com.mysql.jdbc.Driver
- jdbc:mysql://localhost:3306/oauth2_test?autoReconnect=true&useUnicode=true&characterEncoding=utf8
- andaily
- andaily
-
- false
false
@@ -77,45 +69,6 @@
-
- org.codehaus.mojo
- sql-maven-plugin
- 1.4
-
-
- mysql
- mysql-connector-java
- 5.1.35
-
-
-
-
- ${jdbc.driver}
- ${jdbc.url}
- ${jdbc.user}
- ${jdbc.pass}
- ${jdbc.execute.skip}
-
-
-
-
- init db
- initialize
-
- execute
-
-
- ${jdbc.url}
- true
-
- others/database/initial_db.ddl
- others/database/oauth.ddl
-
- continue
-
-
-
-
maven-surefire-plugin
2.4
@@ -125,20 +78,6 @@
**/*Test.java
-
-
- jdbc.url
- ${jdbc.url}
-
-
- jdbc.username
- ${jdbc.user}
-
-
- jdbc.password
- ${jdbc.pass}
-
-
@@ -200,9 +139,9 @@
- commons-dbcp
- commons-dbcp
- 1.4
+ commons-io
+ commons-io
+ 2.4
commons-lang
@@ -210,11 +149,6 @@
2.6
-
- commons-io
- commons-io
- 2.4
-
org.springframework
@@ -246,6 +180,7 @@
spring-expression
${spring.version}
+
org.springframework
spring-web
@@ -271,11 +206,23 @@
org.springframework.security
spring-security-web
${spring.security.version}
+
+
+ org.springframework
+ spring-jdbc
+
+
org.springframework.security
spring-security-taglibs
${spring.security.version}
+
+
+ org.springframework
+ spring-jdbc
+
+
@@ -299,21 +246,20 @@
${spring.security.oauth.version}
-
+
- com.fasterxml.jackson.core
- jackson-databind
- ${fasterxml.jackson.version}
+ org.springframework.data
+ spring-data-mongodb
+ 1.5.6.RELEASE
- mysql
- mysql-connector-java
- 5.1.6
- compile
+ org.mongodb
+ mongo-java-driver
+ 2.13.3
-
+
log4j
log4j
@@ -327,6 +273,26 @@
compile
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ ${fasterxml.jackson.version}
+
+
javax.servlet
diff --git a/src/main/java/com/monkeyk/sos/domain/AbstractDomain.java b/src/main/java/com/monkeyk/sos/domain/AbstractDomain.java
deleted file mode 100644
index 3729964..0000000
--- a/src/main/java/com/monkeyk/sos/domain/AbstractDomain.java
+++ /dev/null
@@ -1,95 +0,0 @@
-package com.monkeyk.sos.domain;
-
-import com.monkeyk.sos.domain.shared.GuidGenerator;
-import com.monkeyk.sos.infrastructure.DateUtils;
-
-import java.io.Serializable;
-import java.time.LocalDateTime;
-
-/**
- * @author Shengzhao Li
- */
-public abstract class AbstractDomain implements Serializable {
-
- private static final long serialVersionUID = 6569365774429340632L;
- /**
- * Database id
- */
- protected int id;
-
- protected boolean archived;
- /**
- * Domain business guid.
- */
- protected String guid = GuidGenerator.generate();
-
- /**
- * The domain create time.
- */
- protected LocalDateTime createTime = DateUtils.now();
-
- public AbstractDomain() {
- }
-
- public int id() {
- return id;
- }
-
- public void id(int id) {
- this.id = id;
- }
-
- public boolean archived() {
- return archived;
- }
-
- public AbstractDomain archived(boolean archived) {
- this.archived = archived;
- return this;
- }
-
- public String guid() {
- return guid;
- }
-
- public void guid(String guid) {
- this.guid = guid;
- }
-
- public LocalDateTime createTime() {
- return createTime;
- }
-
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (!(o instanceof AbstractDomain)) {
- return false;
- }
- AbstractDomain that = (AbstractDomain) o;
- return guid.equals(that.guid);
- }
-
- @Override
- public int hashCode() {
- return guid.hashCode();
- }
-
- //For subclass override it
- public void saveOrUpdate() {
- }
-
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder();
- sb.append("{id=").append(id);
- sb.append(", archived=").append(archived);
- sb.append(", guid='").append(guid).append('\'');
- sb.append(", createTime=").append(createTime);
- sb.append('}');
- return sb.toString();
- }
-}
\ No newline at end of file
diff --git a/src/main/java/com/monkeyk/sos/domain/dto/UserDto.java b/src/main/java/com/monkeyk/sos/domain/dto/UserDto.java
index 7ae5b19..664f71c 100644
--- a/src/main/java/com/monkeyk/sos/domain/dto/UserDto.java
+++ b/src/main/java/com/monkeyk/sos/domain/dto/UserDto.java
@@ -13,11 +13,14 @@ package com.monkeyk.sos.domain.dto;
import com.monkeyk.sos.domain.user.Privilege;
import com.monkeyk.sos.domain.user.User;
+import com.monkeyk.sos.infrastructure.DateUtils;
import java.io.Serializable;
-import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
/**
* 2016/3/12
@@ -37,7 +40,7 @@ public class UserDto implements Serializable {
private String createTime;
- private List privileges = new ArrayList<>();
+ private Set privileges = new HashSet<>();
public UserDto() {
@@ -51,7 +54,7 @@ public class UserDto implements Serializable {
this.email = user.email();
this.privileges = user.privileges();
- this.createTime = user.createTime().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
+ this.createTime = DateUtils.toDateTime(user.createTime());
}
public String getCreateTime() {
@@ -94,19 +97,17 @@ public class UserDto implements Serializable {
this.email = email;
}
- public List getPrivileges() {
+ public Set getPrivileges() {
return privileges;
}
- public void setPrivileges(List privileges) {
+ public void setPrivileges(Set privileges) {
this.privileges = privileges;
}
public static List toDtos(List users) {
List dtos = new ArrayList<>(users.size());
- for (User user : users) {
- dtos.add(new UserDto(user));
- }
+ dtos.addAll(users.stream().map(UserDto::new).collect(Collectors.toList()));
return dtos;
}
}
diff --git a/src/main/java/com/monkeyk/sos/domain/dto/UserJsonDto.java b/src/main/java/com/monkeyk/sos/domain/dto/UserJsonDto.java
index c647908..24f4ccc 100644
--- a/src/main/java/com/monkeyk/sos/domain/dto/UserJsonDto.java
+++ b/src/main/java/com/monkeyk/sos/domain/dto/UserJsonDto.java
@@ -6,6 +6,8 @@ import com.monkeyk.sos.domain.user.User;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
/**
* @author Shengzhao Li
@@ -13,6 +15,7 @@ import java.util.List;
public class UserJsonDto implements Serializable {
+ private static final long serialVersionUID = 3323307820018705154L;
private String guid;
private boolean archived;
@@ -33,10 +36,8 @@ public class UserJsonDto implements Serializable {
this.phone = user.phone();
this.email = user.email();
- final List privilegeList = user.privileges();
- for (Privilege privilege : privilegeList) {
- this.privileges.add(privilege.name());
- }
+ final Set privilegeList = user.privileges();
+ this.privileges.addAll(privilegeList.stream().map(Privilege::name).collect(Collectors.toList()));
}
public boolean isArchived() {
diff --git a/src/main/java/com/monkeyk/sos/domain/oauth/AccessToken.java b/src/main/java/com/monkeyk/sos/domain/oauth/AccessToken.java
new file mode 100644
index 0000000..c9d2517
--- /dev/null
+++ b/src/main/java/com/monkeyk/sos/domain/oauth/AccessToken.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
+ * www.monkeyk.com
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information of
+ * MONKEYK Information Technology Co. Ltd ("Confidential Information").
+ * You shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement you
+ * entered into with MONKEYK Information Technology Co. Ltd.
+ */
+package com.monkeyk.sos.domain.oauth;
+
+import com.monkeyk.sos.infrastructure.DateUtils;
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.annotation.Version;
+import org.springframework.data.mongodb.core.mapping.Document;
+import org.springframework.security.oauth2.common.OAuth2AccessToken;
+import org.springframework.security.oauth2.common.util.SerializationUtils;
+import org.springframework.security.oauth2.provider.OAuth2Authentication;
+
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * 2015/10/29
+ *
+ * @author Shengzhao Li
+ */
+@Document(collection = "AccessToken")
+public class AccessToken implements Serializable {
+
+ private static final long serialVersionUID = 7588602587200382326L;
+
+
+ @Id
+ private String tokenId;
+
+
+ @CreatedDate
+ private Date createTime = DateUtils.now();
+
+ @Version
+ private Long version;
+
+
+ private byte[] token;
+
+ private String authenticationId;
+
+ private byte[] authentication;
+
+ private String username;
+
+ private String clientId;
+
+ private String refreshToken;
+
+ public AccessToken() {
+ }
+
+
+ public String tokenId() {
+ return tokenId;
+ }
+
+ public AccessToken tokenId(String tokenId) {
+ this.tokenId = tokenId;
+ return this;
+ }
+
+ public Date createTime() {
+ return createTime;
+ }
+
+
+ public Long version() {
+ return version;
+ }
+
+
+ public OAuth2AccessToken token() {
+ return SerializationUtils.deserialize(token);
+ }
+
+ public AccessToken token(OAuth2AccessToken token) {
+ this.token = SerializationUtils.serialize(token);
+ return this;
+ }
+
+ public String authenticationId() {
+ return authenticationId;
+ }
+
+ public AccessToken authenticationId(String authenticationId) {
+ this.authenticationId = authenticationId;
+ return this;
+ }
+
+ public OAuth2Authentication authentication() {
+ return SerializationUtils.deserialize(authentication);
+ }
+
+ public AccessToken authentication(OAuth2Authentication authentication) {
+ this.authentication = SerializationUtils.serialize(authentication);
+ return this;
+ }
+
+ public String username() {
+ return username;
+ }
+
+ public AccessToken username(String username) {
+ this.username = username;
+ return this;
+ }
+
+ public String clientId() {
+ return clientId;
+ }
+
+ public AccessToken clientId(String clientId) {
+ this.clientId = clientId;
+ return this;
+ }
+
+ public String refreshToken() {
+ return refreshToken;
+ }
+
+ public AccessToken refreshToken(String refreshToken) {
+ this.refreshToken = refreshToken;
+ return this;
+ }
+
+
+ @Override
+ public String toString() {
+ return "{" +
+ "tokenId='" + tokenId + '\'' +
+ ", createTime=" + createTime +
+ ", version=" + version +
+ ", authenticationId='" + authenticationId + '\'' +
+ ", username='" + username + '\'' +
+ ", clientId='" + clientId + '\'' +
+ ", refreshToken='" + refreshToken + '\'' +
+ '}';
+ }
+}
diff --git a/src/main/java/com/monkeyk/sos/domain/oauth/AccessTokenRepository.java b/src/main/java/com/monkeyk/sos/domain/oauth/AccessTokenRepository.java
new file mode 100644
index 0000000..7a29917
--- /dev/null
+++ b/src/main/java/com/monkeyk/sos/domain/oauth/AccessTokenRepository.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
+ * www.monkeyk.com
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information of
+ * MONKEYK Information Technology Co. Ltd ("Confidential Information").
+ * You shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement you
+ * entered into with MONKEYK Information Technology Co. Ltd.
+ */
+package com.monkeyk.sos.domain.oauth;
+
+
+import com.monkeyk.sos.domain.shared.Repository;
+
+import java.util.List;
+
+/**
+ * 2015/10/29
+ *
+ * @author Shengzhao Li
+ */
+
+public interface AccessTokenRepository extends Repository {
+
+ void saveAccessToken(AccessToken accessToken);
+
+ AccessToken findAccessToken(String tokenId);
+
+ void removeAccessToken(String tokenId);
+
+ void saveRefreshToken(RefreshToken refreshToken);
+
+ RefreshToken findRefreshToken(String tokenId);
+
+ void removeRefreshToken(String tokenId);
+
+ void removeAccessTokenByRefreshToken(String refreshToken);
+
+ AccessToken findAccessTokenByRefreshToken(String refreshToken);
+
+ AccessToken findAccessTokenByAuthenticationId(String authenticationId);
+
+ List findAccessTokensByUsername(String userName);
+
+ List findAccessTokensByClientId(String clientId);
+
+ List findAccessTokensByClientIdAndUsername(String clientId, String userName);
+}
\ No newline at end of file
diff --git a/src/main/java/com/monkeyk/sos/domain/oauth/AuthorizationCode.java b/src/main/java/com/monkeyk/sos/domain/oauth/AuthorizationCode.java
new file mode 100644
index 0000000..4513ee7
--- /dev/null
+++ b/src/main/java/com/monkeyk/sos/domain/oauth/AuthorizationCode.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
+ * www.monkeyk.com
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information of
+ * MONKEYK Information Technology Co. Ltd ("Confidential Information").
+ * You shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement you
+ * entered into with MONKEYK Information Technology Co. Ltd.
+ */
+package com.monkeyk.sos.domain.oauth;
+
+import com.monkeyk.sos.infrastructure.DateUtils;
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.annotation.Version;
+import org.springframework.data.mongodb.core.mapping.Document;
+import org.springframework.security.oauth2.common.util.SerializationUtils;
+import org.springframework.security.oauth2.provider.OAuth2Authentication;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 2015/10/28
+ *
+ * @author Shengzhao Li
+ */
+@Document(collection = "AuthorizationCode")
+public class AuthorizationCode implements Serializable {
+
+ private static final long serialVersionUID = 2775272095671208572L;
+
+
+ @Id
+ private String code;
+
+
+ @CreatedDate
+ private Date createTime = DateUtils.now();
+
+ @Version
+ private Long version;
+
+ private byte[] authenticationBytes;
+
+
+ public AuthorizationCode() {
+ }
+
+
+ public String code() {
+ return code;
+ }
+
+ public AuthorizationCode code(String code) {
+ this.code = code;
+ return this;
+ }
+
+ public Date createTime() {
+ return createTime;
+ }
+
+
+ public Long version() {
+ return version;
+ }
+
+
+ public OAuth2Authentication authentication() {
+ return SerializationUtils.deserialize(authenticationBytes);
+ }
+
+ public AuthorizationCode authentication(OAuth2Authentication authentication) {
+ this.authenticationBytes = SerializationUtils.serialize(authentication);
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ return "{" +
+ "code='" + code + '\'' +
+ ", createTime=" + createTime +
+ ", version=" + version +
+ ", authenticationBytes=" + authenticationBytes +
+ '}';
+ }
+}
diff --git a/src/main/java/com/monkeyk/sos/domain/oauth/CustomJdbcClientDetailsService.java b/src/main/java/com/monkeyk/sos/domain/oauth/CustomJdbcClientDetailsService.java
deleted file mode 100644
index 9ccfca3..0000000
--- a/src/main/java/com/monkeyk/sos/domain/oauth/CustomJdbcClientDetailsService.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.monkeyk.sos.domain.oauth;
-
-import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
-
-import javax.sql.DataSource;
-
-/**
- * Add archived = 0 condition
- *
- * @author Shengzhao Li
- */
-public class CustomJdbcClientDetailsService extends JdbcClientDetailsService {
-
- private static final String SELECT_CLIENT_DETAILS_SQL = "select client_id, client_secret, resource_ids, scope, authorized_grant_types, " +
- "web_server_redirect_uri, authorities, access_token_validity, refresh_token_validity, additional_information, autoapprove " +
- "from oauth_client_details where client_id = ? and archived = 0 ";
-
-
- public CustomJdbcClientDetailsService(DataSource dataSource) {
- super(dataSource);
- setSelectClientDetailsSql(SELECT_CLIENT_DETAILS_SQL);
- }
-
-
-}
\ No newline at end of file
diff --git a/src/main/java/com/monkeyk/sos/domain/oauth/OauthClientDetails.java b/src/main/java/com/monkeyk/sos/domain/oauth/OauthClientDetails.java
index 1e4297d..8d69a55 100644
--- a/src/main/java/com/monkeyk/sos/domain/oauth/OauthClientDetails.java
+++ b/src/main/java/com/monkeyk/sos/domain/oauth/OauthClientDetails.java
@@ -1,22 +1,38 @@
package com.monkeyk.sos.domain.oauth;
import com.monkeyk.sos.infrastructure.DateUtils;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.annotation.Version;
+import org.springframework.data.mongodb.core.mapping.Document;
+import org.springframework.security.oauth2.provider.ClientDetails;
+import org.springframework.security.oauth2.provider.client.BaseClientDetails;
import java.io.Serializable;
-import java.time.LocalDateTime;
+import java.util.Date;
/**
* @author Shengzhao Li
*/
+@Document(collection = "OauthClientDetails")
public class OauthClientDetails implements Serializable {
+ private static final long serialVersionUID = 3186665658971862447L;
- private static final long serialVersionUID = -6947822646185526939L;
- private LocalDateTime createTime = DateUtils.now();
+ @Id
+ private String clientId;
+
+ @CreatedDate
+ private Date createTime = DateUtils.now();
+
+ @Version
+ private Long version;
+
private boolean archived = false;
- private String clientId;
+
private String resourceIds;
private String clientSecret;
@@ -48,12 +64,14 @@ public class OauthClientDetails implements Serializable {
/**
* The access token validity period in seconds (optional).
* If unspecified a global default will be applied by the token services.
+ * Unit: second
*/
private Integer accessTokenValidity;
/**
* The refresh token validity period in seconds (optional).
* If unspecified a global default will be applied by the token services.
+ * Unit: second
*/
private Integer refreshTokenValidity;
@@ -66,40 +84,44 @@ public class OauthClientDetails implements Serializable {
*/
private boolean trusted = false;
- /**
- * Value is 'true' or 'false', default 'false'
- */
- private String autoApprove;
-
public OauthClientDetails() {
}
- public String autoApprove() {
- return autoApprove;
+
+ public ClientDetails toClientDetails() {
+ BaseClientDetails clientDetails = new BaseClientDetails(clientId, resourceIds, scope, authorizedGrantTypes, authorities, webServerRedirectUri);
+ clientDetails.setClientSecret(clientSecret);
+
+ if (StringUtils.isNotEmpty(additionalInformation)) {
+ clientDetails.addAdditionalInformation("information", additionalInformation);
+ }
+ clientDetails.setAccessTokenValiditySeconds(accessTokenValidity);
+ clientDetails.setRefreshTokenValiditySeconds(refreshTokenValidity);
+
+ return clientDetails;
}
- public OauthClientDetails autoApprove(String autoApprove) {
- this.autoApprove = autoApprove;
- return this;
+ public Long version() {
+ return version;
}
public boolean trusted() {
return trusted;
}
- public LocalDateTime createTime() {
+ public Date createTime() {
return createTime;
}
- public OauthClientDetails createTime(LocalDateTime createTime) {
- this.createTime = createTime;
- return this;
- }
-
public boolean archived() {
return archived;
}
+ public OauthClientDetails archived(boolean archived) {
+ this.archived = archived;
+ return this;
+ }
+
public String clientId() {
return clientId;
}
@@ -157,6 +179,7 @@ public class OauthClientDetails implements Serializable {
sb.append(", accessTokenValidity=").append(accessTokenValidity);
sb.append(", refreshTokenValidity=").append(refreshTokenValidity);
sb.append(", additionalInformation='").append(additionalInformation).append('\'');
+ sb.append(", version='").append(version).append('\'');
sb.append(", trusted=").append(trusted);
sb.append('}');
return sb.toString();
@@ -216,9 +239,4 @@ public class OauthClientDetails implements Serializable {
this.additionalInformation = additionalInformation;
return this;
}
-
- public OauthClientDetails archived(boolean archived) {
- this.archived = archived;
- return this;
- }
}
\ No newline at end of file
diff --git a/src/main/java/com/monkeyk/sos/domain/oauth/OauthRepository.java b/src/main/java/com/monkeyk/sos/domain/oauth/OauthRepository.java
index ebdd100..1edd96e 100644
--- a/src/main/java/com/monkeyk/sos/domain/oauth/OauthRepository.java
+++ b/src/main/java/com/monkeyk/sos/domain/oauth/OauthRepository.java
@@ -13,7 +13,13 @@ public interface OauthRepository extends Repository {
List findAllOauthClientDetails();
- void updateOauthClientDetailsArchive(String clientId, boolean archive);
+ boolean updateOauthClientDetailsArchive(String clientId, boolean archive);
void saveOauthClientDetails(OauthClientDetails clientDetails);
+
+ boolean removeOauthClientDetails(OauthClientDetails clientDetails);
+
+ void saveAuthorizationCode(AuthorizationCode authorizationCode);
+
+ AuthorizationCode removeAuthorizationCode(String code);
}
\ No newline at end of file
diff --git a/src/main/java/com/monkeyk/sos/domain/oauth/RefreshToken.java b/src/main/java/com/monkeyk/sos/domain/oauth/RefreshToken.java
new file mode 100644
index 0000000..7a8e91f
--- /dev/null
+++ b/src/main/java/com/monkeyk/sos/domain/oauth/RefreshToken.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
+ * www.monkeyk.com
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information of
+ * MONKEYK Information Technology Co. Ltd ("Confidential Information").
+ * You shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement you
+ * entered into with MONKEYK Information Technology Co. Ltd.
+ */
+package com.monkeyk.sos.domain.oauth;
+
+import com.monkeyk.sos.infrastructure.DateUtils;
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.annotation.Version;
+import org.springframework.data.mongodb.core.mapping.Document;
+import org.springframework.security.oauth2.common.OAuth2RefreshToken;
+import org.springframework.security.oauth2.common.util.SerializationUtils;
+import org.springframework.security.oauth2.provider.OAuth2Authentication;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 2015/10/29
+ *
+ * @author Shengzhao Li
+ */
+@Document(collection = "RefreshToken")
+public class RefreshToken implements Serializable {
+ private static final long serialVersionUID = 5529390717010301531L;
+
+
+ @Id
+ private String tokenId;
+
+
+ @CreatedDate
+ private Date createTime = DateUtils.now();
+
+ @Version
+ private Long version;
+
+
+ private byte[] token;
+
+ private byte[] authentication;
+
+
+ public RefreshToken() {
+ }
+
+ public String tokenId() {
+ return tokenId;
+ }
+
+ public RefreshToken tokenId(String tokenId) {
+ this.tokenId = tokenId;
+ return this;
+ }
+
+ public Date createTime() {
+ return createTime;
+ }
+
+
+ public Long version() {
+ return version;
+ }
+
+
+ public OAuth2RefreshToken token() {
+ return SerializationUtils.deserialize(token);
+ }
+
+ public RefreshToken token(OAuth2RefreshToken token) {
+ this.token = SerializationUtils.serialize(token);
+ return this;
+ }
+
+ public OAuth2Authentication authentication() {
+ return SerializationUtils.deserialize(authentication);
+ }
+
+ public RefreshToken authentication(OAuth2Authentication authentication) {
+ this.authentication = SerializationUtils.serialize(authentication);
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ return "{" +
+ "tokenId='" + tokenId + '\'' +
+ ", createTime=" + createTime +
+ ", version=" + version +
+ '}';
+ }
+}
diff --git a/src/main/java/com/monkeyk/sos/domain/shared/BeanProvider.java b/src/main/java/com/monkeyk/sos/domain/shared/BeanProvider.java
new file mode 100644
index 0000000..71cd8df
--- /dev/null
+++ b/src/main/java/com/monkeyk/sos/domain/shared/BeanProvider.java
@@ -0,0 +1,41 @@
+package com.monkeyk.sos.domain.shared;
+
+import org.springframework.context.ApplicationContext;
+
+/**
+ * @author Shengzhao Li
+ */
+public abstract class BeanProvider {
+
+ private static ApplicationContext applicationContext;
+
+ private BeanProvider() {
+ }
+
+ public static void initialize(ApplicationContext applicationContext) {
+ BeanProvider.applicationContext = applicationContext;
+ }
+
+ /**
+ * Get Bean by clazz.
+ *
+ * @param clazz Class
+ * @param class type
+ * @return Bean instance
+ */
+ public static T getBean(Class clazz) {
+ if (applicationContext == null) {
+ return null;
+ }
+ return applicationContext.getBean(clazz);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static T getBean(String beanId) {
+ if (applicationContext == null) {
+ return null;
+ }
+ return (T) applicationContext.getBean(beanId);
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/monkeyk/sos/domain/shared/security/WdcyUserDetails.java b/src/main/java/com/monkeyk/sos/domain/shared/security/WdcyUserDetails.java
index a22bbd3..f8fa564 100644
--- a/src/main/java/com/monkeyk/sos/domain/shared/security/WdcyUserDetails.java
+++ b/src/main/java/com/monkeyk/sos/domain/shared/security/WdcyUserDetails.java
@@ -9,6 +9,8 @@ import org.springframework.security.core.userdetails.UserDetails;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
/**
* @author Shengzhao Li
@@ -40,10 +42,8 @@ public class WdcyUserDetails implements UserDetails {
this.grantedAuthorities.add(new SimpleGrantedAuthority(ROLE_PREFIX + Privilege.UNITY.name()));
this.grantedAuthorities.add(new SimpleGrantedAuthority(ROLE_PREFIX + Privilege.MOBILE.name()));
} else {
- final List privileges = user.privileges();
- for (Privilege privilege : privileges) {
- this.grantedAuthorities.add(new SimpleGrantedAuthority(ROLE_PREFIX + privilege.name()));
- }
+ final Set privileges = user.privileges();
+ this.grantedAuthorities.addAll(privileges.stream().map(privilege -> new SimpleGrantedAuthority(ROLE_PREFIX + privilege.name())).collect(Collectors.toList()));
}
}
@@ -94,9 +94,6 @@ public class WdcyUserDetails implements UserDetails {
@Override
public String toString() {
- final StringBuilder sb = new StringBuilder();
- sb.append("{user=").append(user);
- sb.append('}');
- return sb.toString();
+ return "{user=" + user + '}';
}
}
\ No newline at end of file
diff --git a/src/main/java/com/monkeyk/sos/domain/user/User.java b/src/main/java/com/monkeyk/sos/domain/user/User.java
index 5bc0aa9..0924859 100644
--- a/src/main/java/com/monkeyk/sos/domain/user/User.java
+++ b/src/main/java/com/monkeyk/sos/domain/user/User.java
@@ -1,32 +1,54 @@
package com.monkeyk.sos.domain.user;
-import com.monkeyk.sos.domain.AbstractDomain;
-import java.time.LocalDateTime;
-import java.util.ArrayList;
+import com.monkeyk.sos.domain.shared.GuidGenerator;
+import com.monkeyk.sos.infrastructure.DateUtils;
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.annotation.Version;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+import java.io.Serializable;
import java.util.Date;
-import java.util.List;
+import java.util.HashSet;
+import java.util.Set;
/**
* @author Shengzhao Li
*/
-public class User extends AbstractDomain {
+@Document(collection = "user_")
+public class User implements Serializable {
- private static final long serialVersionUID = -2921689304753120556L;
+ private static final long serialVersionUID = -6117108610171201352L;
+ @Id
+ private String guid = GuidGenerator.generate();
+
+ @CreatedDate
+ private Date createTime = DateUtils.now();
+
+ @Version
+ private Long version;
+
+ //unique
private String username;
+
private String password;
private String phone;
private String email;
- //Default user is initial when create database, do not delete
+ //Default user is initialed
private boolean defaultUser = false;
private Date lastLoginTime;
- private List privileges = new ArrayList<>();
+ private Set privileges = new HashSet<>();
+
+
+ private boolean archived = false;
+
public User() {
}
@@ -38,6 +60,15 @@ public class User extends AbstractDomain {
this.email = email;
}
+
+ public Long version() {
+ return version;
+ }
+
+ public String guid() {
+ return guid;
+ }
+
public boolean defaultUser() {
return defaultUser;
}
@@ -50,6 +81,11 @@ public class User extends AbstractDomain {
return password;
}
+ public User password(String password) {
+ this.password = password;
+ return this;
+ }
+
public String phone() {
return phone;
}
@@ -58,21 +94,27 @@ public class User extends AbstractDomain {
return email;
}
- public List privileges() {
+ public Set privileges() {
return privileges;
}
+ public Date createTime() {
+ return createTime;
+ }
+
+
+ public boolean archived() {
+ return archived;
+ }
+
+ public User archived(boolean archived) {
+ this.archived = archived;
+ return this;
+ }
+
@Override
public String toString() {
- final StringBuilder sb = new StringBuilder();
- sb.append("{username='").append(username).append('\'');
- sb.append(", phone='").append(phone).append('\'');
- sb.append(", id='").append(id).append('\'');
- sb.append(", guid='").append(guid).append('\'');
- sb.append(", defaultUser='").append(defaultUser).append('\'');
- sb.append(", email='").append(email).append('\'');
- sb.append('}');
- return sb.toString();
+ return "{username='" + username + '\'' + ", phone='" + phone + '\'' + ", version='" + version + '\'' + ", defaultUser='" + defaultUser + '\'' + ", email='" + email + '\'' + '}';
}
public User email(String email) {
@@ -96,18 +138,7 @@ public class User extends AbstractDomain {
return lastLoginTime;
}
- public User lastLoginTime(Date lastLoginTime) {
+ public void lastLoginTime(Date lastLoginTime) {
this.lastLoginTime = lastLoginTime;
- return this;
- }
-
- public User createTime(LocalDateTime createTime) {
- this.createTime = createTime;
- return this;
- }
-
- public User password(String password) {
- this.password = password;
- return this;
}
}
\ No newline at end of file
diff --git a/src/main/java/com/monkeyk/sos/domain/user/UserRepository.java b/src/main/java/com/monkeyk/sos/domain/user/UserRepository.java
index eaf2c57..01cb60c 100644
--- a/src/main/java/com/monkeyk/sos/domain/user/UserRepository.java
+++ b/src/main/java/com/monkeyk/sos/domain/user/UserRepository.java
@@ -14,9 +14,13 @@ public interface UserRepository extends Repository {
void saveUser(User user);
- void updateUser(User user);
+ boolean updateUser(User user);
User findByUsername(String username);
+ List findAllUsers();
+
+ boolean removeUser(User user);
+
List findUsersByUsername(String username);
}
\ No newline at end of file
diff --git a/src/main/java/com/monkeyk/sos/infrastructure/DateUtils.java b/src/main/java/com/monkeyk/sos/infrastructure/DateUtils.java
index c21754f..fb23857 100644
--- a/src/main/java/com/monkeyk/sos/infrastructure/DateUtils.java
+++ b/src/main/java/com/monkeyk/sos/infrastructure/DateUtils.java
@@ -3,6 +3,7 @@ package com.monkeyk.sos.infrastructure;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
+import java.util.Date;
import java.util.Locale;
/**
@@ -19,8 +20,8 @@ public abstract class DateUtils {
private DateUtils() {
}
- public static LocalDateTime now() {
- return LocalDateTime.now();
+ public static Date now() {
+ return new Date();
}
@@ -28,12 +29,15 @@ public abstract class DateUtils {
return toDateTime(date, DEFAULT_DATE_TIME_FORMAT);
}
+ public static String toDateTime(Date date) {
+ return toDateTime(LocalDateTime.from(date.toInstant()), DEFAULT_DATE_TIME_FORMAT);
+ }
+
public static String toDateTime(LocalDateTime dateTime, String pattern) {
return dateTime.format(DateTimeFormatter.ofPattern(pattern, Locale.SIMPLIFIED_CHINESE));
}
-
public static String toDateText(LocalDate date, String pattern) {
if (date == null || pattern == null) {
return null;
diff --git a/src/main/java/com/monkeyk/sos/infrastructure/jdbc/OauthClientDetailsRowMapper.java b/src/main/java/com/monkeyk/sos/infrastructure/jdbc/OauthClientDetailsRowMapper.java
deleted file mode 100644
index 43910f7..0000000
--- a/src/main/java/com/monkeyk/sos/infrastructure/jdbc/OauthClientDetailsRowMapper.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
- * www.monkeyk.com
- * All rights reserved.
- *
- * This software is the confidential and proprietary information of
- * MONKEYK Information Technology Co. Ltd ("Confidential Information").
- * You shall not disclose such Confidential Information and shall use
- * it only in accordance with the terms of the license agreement you
- * entered into with MONKEYK Information Technology Co. Ltd.
- */
-package com.monkeyk.sos.infrastructure.jdbc;
-
-import com.monkeyk.sos.domain.oauth.OauthClientDetails;
-import org.springframework.jdbc.core.RowMapper;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.time.ZoneId;
-
-/**
- * 2015/11/16
- *
- * @author Shengzhao Li
- */
-public class OauthClientDetailsRowMapper implements RowMapper {
-
-
- public OauthClientDetailsRowMapper() {
- }
-
- @Override
- public OauthClientDetails mapRow(ResultSet rs, int i) throws SQLException {
- OauthClientDetails clientDetails = new OauthClientDetails();
-
- clientDetails.clientId(rs.getString("client_id"));
- clientDetails.resourceIds(rs.getString("resource_ids"));
- clientDetails.clientSecret(rs.getString("client_secret"));
-
- clientDetails.scope(rs.getString("scope"));
- clientDetails.authorizedGrantTypes(rs.getString("authorized_grant_types"));
- clientDetails.webServerRedirectUri(rs.getString("web_server_redirect_uri"));
-
- clientDetails.authorities(rs.getString("authorities"));
- clientDetails.accessTokenValidity(getInteger(rs, "access_token_validity"));
- clientDetails.refreshTokenValidity(getInteger(rs, "refresh_token_validity"));
-
- clientDetails.additionalInformation(rs.getString("additional_information"));
- clientDetails.createTime(rs.getTimestamp("create_time").toLocalDateTime());
- clientDetails.archived(rs.getBoolean("archived"));
-
- clientDetails.trusted(rs.getBoolean("trusted"));
- clientDetails.autoApprove(rs.getString("autoapprove"));
-
- return clientDetails;
- }
-
-
- private Integer getInteger(ResultSet rs, String columnName) throws SQLException {
- final Object object = rs.getObject(columnName);
- if (object != null) {
- return (Integer) object;
- }
- return null;
- }
-
-}
diff --git a/src/main/java/com/monkeyk/sos/infrastructure/jdbc/OauthRepositoryJdbc.java b/src/main/java/com/monkeyk/sos/infrastructure/jdbc/OauthRepositoryJdbc.java
deleted file mode 100644
index 6dffa8a..0000000
--- a/src/main/java/com/monkeyk/sos/infrastructure/jdbc/OauthRepositoryJdbc.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
- * www.monkeyk.com
- * All rights reserved.
- *
- * This software is the confidential and proprietary information of
- * MONKEYK Information Technology Co. Ltd ("Confidential Information").
- * You shall not disclose such Confidential Information and shall use
- * it only in accordance with the terms of the license agreement you
- * entered into with MONKEYK Information Technology Co. Ltd.
- */
-package com.monkeyk.sos.infrastructure.jdbc;
-
-import com.monkeyk.sos.domain.oauth.OauthClientDetails;
-import com.monkeyk.sos.domain.oauth.OauthRepository;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.stereotype.Repository;
-
-import java.util.List;
-
-/**
- * 2015/11/16
- *
- * @author Shengzhao Li
- */
-@Repository("oauthRepositoryJdbc")
-public class OauthRepositoryJdbc implements OauthRepository {
-
-
-
- private static OauthClientDetailsRowMapper oauthClientDetailsRowMapper = new OauthClientDetailsRowMapper();
-
-
- @Autowired
- private JdbcTemplate jdbcTemplate;
-
-
- @Override
- public OauthClientDetails findOauthClientDetails(String clientId) {
- final String sql = " select * from oauth_client_details where client_id = ? ";
- final List list = this.jdbcTemplate.query(sql, new Object[]{clientId}, oauthClientDetailsRowMapper);
- return list.isEmpty() ? null : list.get(0);
- }
-
- @Override
- public List findAllOauthClientDetails() {
- final String sql = " select * from oauth_client_details order by create_time desc ";
- return this.jdbcTemplate.query(sql, oauthClientDetailsRowMapper);
- }
-
- @Override
- public void updateOauthClientDetailsArchive(String clientId, boolean archive) {
- final String sql = " update oauth_client_details set archived = ? where client_id = ? ";
- this.jdbcTemplate.update(sql, archive, clientId);
- }
-
- @Override
- public void saveOauthClientDetails(final OauthClientDetails clientDetails) {
- final String sql = " insert into oauth_client_details(client_id,resource_ids,client_secret,scope,authorized_grant_types,web_server_redirect_uri," +
- " authorities,access_token_validity,refresh_token_validity,additional_information,trusted,autoapprove) values (?,?,?,?,?,?,?,?,?,?,?,?)";
-
- this.jdbcTemplate.update(sql, ps -> {
- ps.setString(1, clientDetails.clientId());
- ps.setString(2, clientDetails.resourceIds());
-
- ps.setString(3, clientDetails.clientSecret());
- ps.setString(4, clientDetails.scope());
-
- ps.setString(5, clientDetails.authorizedGrantTypes());
- ps.setString(6, clientDetails.webServerRedirectUri());
-
- ps.setString(7, clientDetails.authorities());
- ps.setObject(8, clientDetails.accessTokenValidity());
-
- ps.setObject(9, clientDetails.refreshTokenValidity());
- ps.setString(10, clientDetails.additionalInformation());
-
- ps.setBoolean(11, clientDetails.trusted());
- ps.setString(12, clientDetails.autoApprove());
-
- });
- }
-}
diff --git a/src/main/java/com/monkeyk/sos/infrastructure/jdbc/UserRepositoryJdbc.java b/src/main/java/com/monkeyk/sos/infrastructure/jdbc/UserRepositoryJdbc.java
deleted file mode 100644
index 7f91a5a..0000000
--- a/src/main/java/com/monkeyk/sos/infrastructure/jdbc/UserRepositoryJdbc.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
- * www.monkeyk.com
- * All rights reserved.
- *
- * This software is the confidential and proprietary information of
- * MONKEYK Information Technology Co. Ltd ("Confidential Information").
- * You shall not disclose such Confidential Information and shall use
- * it only in accordance with the terms of the license agreement you
- * entered into with MONKEYK Information Technology Co. Ltd.
- */
-package com.monkeyk.sos.infrastructure.jdbc;
-
-import com.monkeyk.sos.domain.user.Privilege;
-import com.monkeyk.sos.domain.user.User;
-import com.monkeyk.sos.domain.user.UserRepository;
-import org.apache.commons.lang.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.stereotype.Repository;
-
-import java.sql.Timestamp;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.stream.Collectors;
-
-/**
- * 2015/11/16
- *
- * @author Shengzhao Li
- */
-@Repository("userRepositoryJdbc")
-public class UserRepositoryJdbc implements UserRepository {
-
-
- private static UserRowMapper userRowMapper = new UserRowMapper();
-
- @Autowired
- private JdbcTemplate jdbcTemplate;
-
- @Override
- public User findByGuid(String guid) {
- final String sql = " select * from user_ where guid = ? ";
- final List list = this.jdbcTemplate.query(sql, new Object[]{guid}, userRowMapper);
-
- User user = null;
- if (!list.isEmpty()) {
- user = list.get(0);
- user.privileges().addAll(findPrivileges(user.id()));
- }
-
- return user;
- }
-
- private Collection findPrivileges(int userId) {
- final String sql = " select privilege from user_privilege where user_id = ? ";
- final List strings = this.jdbcTemplate.queryForList(sql, new Object[]{userId}, String.class);
-
- List privileges = new ArrayList<>(strings.size());
- privileges.addAll(strings.stream().map(Privilege::valueOf).collect(Collectors.toList()));
- return privileges;
- }
-
- @Override
- public void saveUser(final User user) {
- final String sql = " insert into user_(guid,archived,create_time,email,password,username,phone) " +
- " values (?,?,?,?,?,?,?) ";
- this.jdbcTemplate.update(sql, ps -> {
- ps.setString(1, user.guid());
- ps.setBoolean(2, user.archived());
-
- ps.setTimestamp(3, Timestamp.valueOf(user.createTime()));
- ps.setString(4, user.email());
-
- ps.setString(5, user.password());
- ps.setString(6, user.username());
-
- ps.setString(7, user.phone());
- });
-
- //get user id
- final Integer id = this.jdbcTemplate.queryForObject("select id from user_ where guid = ?", new Object[]{user.guid()}, Integer.class);
-
- //insert privileges
- for (final Privilege privilege : user.privileges()) {
- this.jdbcTemplate.update("insert into user_privilege(user_id, privilege) values (?,?)", ps -> {
- ps.setInt(1, id);
- ps.setString(2, privilege.name());
- });
- }
-
- }
-
- @Override
- public void updateUser(final User user) {
- final String sql = " update user_ set username = ?, password = ?, phone = ?,email = ? where guid = ? ";
- this.jdbcTemplate.update(sql, ps -> {
- ps.setString(1, user.username());
- ps.setString(2, user.password());
-
- ps.setString(3, user.phone());
- ps.setString(4, user.email());
-
- ps.setString(5, user.guid());
- });
- }
-
- @Override
- public User findByUsername(String username) {
- final String sql = " select * from user_ where username = ? and archived = 0 ";
- final List list = this.jdbcTemplate.query(sql, new Object[]{username}, userRowMapper);
-
- User user = null;
- if (!list.isEmpty()) {
- user = list.get(0);
- user.privileges().addAll(findPrivileges(user.id()));
- }
-
- return user;
- }
-
- @Override
- public List findUsersByUsername(String username) {
- String sql = " select * from user_ where archived = 0 ";
- Object[] params = new Object[]{};
- if (StringUtils.isNotEmpty(username)) {
- sql += " and username like ?";
- params = new Object[]{"%" + username + "%"};
- }
- sql += " order by create_time desc ";
-
- final List list = this.jdbcTemplate.query(sql, params, userRowMapper);
- for (User user : list) {
- user.privileges().addAll(findPrivileges(user.id()));
- }
- return list;
- }
-}
diff --git a/src/main/java/com/monkeyk/sos/infrastructure/jdbc/UserRowMapper.java b/src/main/java/com/monkeyk/sos/infrastructure/jdbc/UserRowMapper.java
deleted file mode 100644
index 4b60427..0000000
--- a/src/main/java/com/monkeyk/sos/infrastructure/jdbc/UserRowMapper.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
- * www.monkeyk.com
- * All rights reserved.
- *
- * This software is the confidential and proprietary information of
- * MONKEYK Information Technology Co. Ltd ("Confidential Information").
- * You shall not disclose such Confidential Information and shall use
- * it only in accordance with the terms of the license agreement you
- * entered into with MONKEYK Information Technology Co. Ltd.
- */
-package com.monkeyk.sos.infrastructure.jdbc;
-
-import com.monkeyk.sos.domain.user.User;
-import org.springframework.jdbc.core.RowMapper;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-
-/**
- * 2015/11/16
- *
- * @author Shengzhao Li
- */
-public class UserRowMapper implements RowMapper {
-
-
- public UserRowMapper() {
- }
-
- @Override
- public User mapRow(ResultSet rs, int i) throws SQLException {
- User user = new User();
-
- user.id(rs.getInt("id"));
- user.guid(rs.getString("guid"));
-
- user.archived(rs.getBoolean("archived"));
- user.createTime(rs.getTimestamp("create_time").toLocalDateTime());
-
- user.email(rs.getString("email"));
- user.phone(rs.getString("phone"));
-
- user.password(rs.getString("password"));
- user.username(rs.getString("username"));
-
- user.lastLoginTime(rs.getTimestamp("last_login_time"));
-
- return user;
- }
-}
diff --git a/src/main/java/com/monkeyk/sos/infrastructure/mongo/AbstractMongoSupport.java b/src/main/java/com/monkeyk/sos/infrastructure/mongo/AbstractMongoSupport.java
new file mode 100644
index 0000000..031a609
--- /dev/null
+++ b/src/main/java/com/monkeyk/sos/infrastructure/mongo/AbstractMongoSupport.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
+ * www.monkeyk.com
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information of
+ * MONKEYK Information Technology Co. Ltd ("Confidential Information").
+ * You shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement you
+ * entered into with MONKEYK Information Technology Co. Ltd.
+ */
+package com.monkeyk.sos.infrastructure.mongo;
+
+
+import com.monkeyk.sos.domain.shared.BeanProvider;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+
+import java.io.Serializable;
+
+/**
+ * 2015/10/28
+ *
+ * @author Shengzhao Li
+ */
+public abstract class AbstractMongoSupport {
+
+ protected static final String ID = "_id";
+
+
+ private MongoTemplate mongoTemplate;
+
+
+ protected AbstractMongoSupport() {
+ }
+
+ protected MongoTemplate mongoTemplate() {
+ if (mongoTemplate == null) {
+ mongoTemplate = BeanProvider.getBean(MongoTemplate.class);
+ }
+ return mongoTemplate;
+ }
+
+ protected T findById(Class clazz, Object id) {
+ Query query = new Query(new Criteria(ID).is(id));
+ return this.mongoTemplate().findOne(query, clazz);
+ }
+
+
+ protected Query createIDQuery(Object id) {
+ final Criteria criteria = new Criteria(ID).is(id);
+ return new Query(criteria);
+ }
+
+
+ public void setMongoTemplate(MongoTemplate mongoTemplate) {
+ this.mongoTemplate = mongoTemplate;
+ }
+}
diff --git a/src/main/java/com/monkeyk/sos/infrastructure/mongo/AccessTokenRepositoryMongo.java b/src/main/java/com/monkeyk/sos/infrastructure/mongo/AccessTokenRepositoryMongo.java
new file mode 100644
index 0000000..8365481
--- /dev/null
+++ b/src/main/java/com/monkeyk/sos/infrastructure/mongo/AccessTokenRepositoryMongo.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
+ * www.monkeyk.com
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information of
+ * MONKEYK Information Technology Co. Ltd ("Confidential Information").
+ * You shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement you
+ * entered into with MONKEYK Information Technology Co. Ltd.
+ */
+package com.monkeyk.sos.infrastructure.mongo;
+
+
+import com.monkeyk.sos.domain.oauth.AccessToken;
+import com.monkeyk.sos.domain.oauth.AccessTokenRepository;
+import com.monkeyk.sos.domain.oauth.RefreshToken;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * 2015/10/29
+ *
+ * @author Shengzhao Li
+ */
+@Repository("accessTokenRepositoryMongo")
+public class AccessTokenRepositoryMongo extends AbstractMongoSupport implements AccessTokenRepository {
+
+
+ @Override
+ public void saveAccessToken(AccessToken accessToken) {
+ this.mongoTemplate().save(accessToken);
+ }
+
+ @Override
+ public AccessToken findAccessToken(String tokenId) {
+ return findById(AccessToken.class, tokenId);
+ }
+
+ @Override
+ public void removeAccessToken(String tokenId) {
+ final AccessToken accessToken = findAccessToken(tokenId);
+ this.mongoTemplate().remove(accessToken);
+ }
+
+ @Override
+ public void saveRefreshToken(RefreshToken refreshToken) {
+ this.mongoTemplate().save(refreshToken);
+ }
+
+ @Override
+ public RefreshToken findRefreshToken(String tokenId) {
+ return findById(RefreshToken.class, tokenId);
+ }
+
+ @Override
+ public void removeRefreshToken(String tokenId) {
+ final RefreshToken refreshToken = findRefreshToken(tokenId);
+ this.mongoTemplate().remove(refreshToken);
+ }
+
+ @Override
+ public void removeAccessTokenByRefreshToken(String refreshToken) {
+ final AccessToken accessToken = findAccessTokenByRefreshToken(refreshToken);
+ this.mongoTemplate().remove(accessToken);
+ }
+
+ @Override
+ public AccessToken findAccessTokenByRefreshToken(String refreshToken) {
+ Query query = new Query(new Criteria("refreshToken").is(refreshToken));
+ return this.mongoTemplate().findOne(query, AccessToken.class);
+ }
+
+ @Override
+ public AccessToken findAccessTokenByAuthenticationId(String authenticationId) {
+ Query query = new Query(new Criteria("authenticationId").is(authenticationId));
+ return this.mongoTemplate().findOne(query, AccessToken.class);
+ }
+
+ @Override
+ public List findAccessTokensByUsername(String username) {
+ Query query = new Query(new Criteria("username").is(username));
+ return mongoTemplate().find(query, AccessToken.class);
+ }
+
+ @Override
+ public List findAccessTokensByClientId(String clientId) {
+ Query query = new Query(new Criteria("clientId").is(clientId));
+ return mongoTemplate().find(query, AccessToken.class);
+ }
+
+ @Override
+ public List findAccessTokensByClientIdAndUsername(String clientId, String userName) {
+ Query query = new Query(new Criteria("clientId").is(clientId));
+ query.addCriteria(new Criteria("username").is(userName));
+ return mongoTemplate().find(query, AccessToken.class);
+ }
+}
diff --git a/src/main/java/com/monkeyk/sos/infrastructure/mongo/OauthRepositoryMongo.java b/src/main/java/com/monkeyk/sos/infrastructure/mongo/OauthRepositoryMongo.java
new file mode 100644
index 0000000..b8601af
--- /dev/null
+++ b/src/main/java/com/monkeyk/sos/infrastructure/mongo/OauthRepositoryMongo.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
+ * www.monkeyk.com
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information of
+ * MONKEYK Information Technology Co. Ltd ("Confidential Information").
+ * You shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement you
+ * entered into with MONKEYK Information Technology Co. Ltd.
+ */
+package com.monkeyk.sos.infrastructure.mongo;
+
+
+
+import com.monkeyk.sos.domain.oauth.AuthorizationCode;
+import com.monkeyk.sos.domain.oauth.OauthClientDetails;
+import com.monkeyk.sos.domain.oauth.OauthRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.data.mongodb.core.query.Update;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * 2015/10/28
+ *
+ * @author Shengzhao Li
+ */
+@Repository("oauthRepositoryMongo")
+public class OauthRepositoryMongo extends AbstractMongoSupport implements OauthRepository {
+
+
+ private static final Logger LOG = LoggerFactory.getLogger(OauthRepositoryMongo.class);
+
+
+ @Override
+ public OauthClientDetails findOauthClientDetails(String clientId) {
+ LOG.debug("Call findOauthClientDetails, clientId = {}", clientId);
+ return findById(OauthClientDetails.class, clientId);
+ }
+
+ @Override
+ public List findAllOauthClientDetails() {
+ Query query = new Query();
+ query.with(new Sort(new Sort.Order(Sort.Direction.DESC, "createTime")));
+ return this.mongoTemplate().find(query, OauthClientDetails.class);
+ }
+
+ @Override
+ public boolean updateOauthClientDetailsArchive(String clientId, boolean archive) {
+ LOG.debug("Call updateOauthClientDetailsArchive, clientId = {}, archive = {}", clientId, archive);
+ Update update = new Update();
+ update.set("archived", archive);
+
+ Query query = createIDQuery(clientId);
+
+ this.mongoTemplate().updateFirst(query, update, OauthClientDetails.class);
+ return true;
+ }
+
+
+ @Override
+ public void saveOauthClientDetails(OauthClientDetails clientDetails) {
+ this.mongoTemplate().insert(clientDetails);
+ }
+
+ @Override
+ public boolean removeOauthClientDetails(OauthClientDetails clientDetails) {
+ LOG.debug("Call removeOauthClientDetails, clientDetails = {}", clientDetails);
+ mongoTemplate().remove(clientDetails);
+ return true;
+ }
+
+ @Override
+ public void saveAuthorizationCode(AuthorizationCode authorizationCode) {
+ this.mongoTemplate().save(authorizationCode);
+ }
+
+ @Override
+ public AuthorizationCode removeAuthorizationCode(String code) {
+ final AuthorizationCode authorizationCode = findById(AuthorizationCode.class, code);
+ this.mongoTemplate().remove(authorizationCode);
+ return authorizationCode;
+ }
+}
diff --git a/src/main/java/com/monkeyk/sos/infrastructure/mongo/UserRepositoryMongo.java b/src/main/java/com/monkeyk/sos/infrastructure/mongo/UserRepositoryMongo.java
new file mode 100644
index 0000000..878e092
--- /dev/null
+++ b/src/main/java/com/monkeyk/sos/infrastructure/mongo/UserRepositoryMongo.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
+ * www.monkeyk.com
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information of
+ * MONKEYK Information Technology Co. Ltd ("Confidential Information").
+ * You shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement you
+ * entered into with MONKEYK Information Technology Co. Ltd.
+ */
+package com.monkeyk.sos.infrastructure.mongo;
+
+
+import com.monkeyk.sos.domain.user.User;
+import com.monkeyk.sos.domain.user.UserRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.data.mongodb.core.query.Update;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * 2015/10/28
+ *
+ * @author Shengzhao Li
+ */
+@Repository("userRepositoryMongo")
+public class UserRepositoryMongo extends AbstractMongoSupport implements UserRepository {
+
+ private static final Logger LOG = LoggerFactory.getLogger(UserRepositoryMongo.class);
+
+
+ @Override
+ public User findByGuid(String guid) {
+ LOG.debug("Call findByGuid, guid = {}", guid);
+ return findById(User.class, guid);
+ }
+
+ @Override
+ public void saveUser(User user) {
+ this.mongoTemplate().insert(user);
+ }
+
+ @Override
+ public boolean updateUser(User user) {
+ Update update = new Update();
+ update.set("password", user.password())
+ .set("phone", user.phone())
+ .set("lastLoginTime", user.lastLoginTime())
+ .set("archived", user.archived())
+ .set("email", user.email());
+
+ update.set("privileges", user.privileges());
+
+ Query query = createIDQuery(user.guid());
+ this.mongoTemplate().updateFirst(query, update, User.class);
+ return true;
+ }
+
+ @Override
+ public User findByUsername(String username) {
+ LOG.debug("Call findByUsername, username = {}", username);
+ Query query = new Query(new Criteria("username").is(username));
+ return this.mongoTemplate().findOne(query, User.class);
+ }
+
+
+ @Override
+ public List findAllUsers() {
+ Query query = new Query().with(new Sort(Sort.Direction.DESC, "createTime"));
+ return mongoTemplate().find(query, User.class);
+ }
+
+ @Override
+ public boolean removeUser(User user) {
+ LOG.debug("Call removeUser, user = {}", user);
+ mongoTemplate().remove(user);
+ return true;
+ }
+
+ @Override
+ public List findUsersByUsername(String username) {
+ Query query = new Query(Criteria.where("username").is(username));
+ return mongoTemplate().find(query, User.class);
+ }
+}
diff --git a/src/main/java/com/monkeyk/sos/service/oauth/ExtractTokenKeyDigester.java b/src/main/java/com/monkeyk/sos/service/oauth/ExtractTokenKeyDigester.java
new file mode 100644
index 0000000..203f7b0
--- /dev/null
+++ b/src/main/java/com/monkeyk/sos/service/oauth/ExtractTokenKeyDigester.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
+ * www.monkeyk.com
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information of
+ * MONKEYK Information Technology Co. Ltd ("Confidential Information").
+ * You shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement you
+ * entered into with MONKEYK Information Technology Co. Ltd.
+ */
+package com.monkeyk.sos.service.oauth;
+
+/**
+ * 2015/11/9
+ *
+ * @author Shengzhao Li
+ */
+public interface ExtractTokenKeyDigester {
+
+
+ String digest(String tokenValue);
+
+
+}
diff --git a/src/main/java/com/monkeyk/sos/service/oauth/MD5ExtractTokenKeyDigester.java b/src/main/java/com/monkeyk/sos/service/oauth/MD5ExtractTokenKeyDigester.java
new file mode 100644
index 0000000..08554a3
--- /dev/null
+++ b/src/main/java/com/monkeyk/sos/service/oauth/MD5ExtractTokenKeyDigester.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
+ * www.monkeyk.com
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information of
+ * MONKEYK Information Technology Co. Ltd ("Confidential Information").
+ * You shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement you
+ * entered into with MONKEYK Information Technology Co. Ltd.
+ */
+package com.monkeyk.sos.service.oauth;
+
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * 2015/11/9
+ *
+ * @author Shengzhao Li
+ */
+public class MD5ExtractTokenKeyDigester implements ExtractTokenKeyDigester {
+
+
+ public MD5ExtractTokenKeyDigester() {
+ }
+
+
+ @Override
+ public String digest(String value) {
+ if (value == null) {
+ return null;
+ }
+ MessageDigest digest;
+ try {
+ digest = MessageDigest.getInstance("MD5");
+ } catch (NoSuchAlgorithmException e) {
+ throw new IllegalStateException("MD5 algorithm not available. Fatal (should be in the JDK).");
+ }
+
+ try {
+ byte[] bytes = digest.digest(value.getBytes("UTF-8"));
+ return String.format("%032x", new BigInteger(1, bytes));
+ } catch (UnsupportedEncodingException e) {
+ throw new IllegalStateException("UTF-8 encoding not available. Fatal (should be in the JDK).");
+ }
+ }
+}
diff --git a/src/main/java/com/monkeyk/sos/service/oauth/MongoAuthorizationCodeServices.java b/src/main/java/com/monkeyk/sos/service/oauth/MongoAuthorizationCodeServices.java
new file mode 100644
index 0000000..87e3756
--- /dev/null
+++ b/src/main/java/com/monkeyk/sos/service/oauth/MongoAuthorizationCodeServices.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
+ * www.monkeyk.com
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information of
+ * MONKEYK Information Technology Co. Ltd ("Confidential Information").
+ * You shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement you
+ * entered into with MONKEYK Information Technology Co. Ltd.
+ */
+package com.monkeyk.sos.service.oauth;
+
+
+import com.monkeyk.sos.domain.oauth.AuthorizationCode;
+import com.monkeyk.sos.domain.oauth.OauthRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.security.oauth2.provider.OAuth2Authentication;
+import org.springframework.security.oauth2.provider.code.RandomValueAuthorizationCodeServices;
+import org.springframework.util.Assert;
+
+/**
+ * 2015/10/28
+ *
+ * @author Shengzhao Li
+ */
+public class MongoAuthorizationCodeServices extends RandomValueAuthorizationCodeServices implements InitializingBean {
+
+
+ private static final Logger LOG = LoggerFactory.getLogger(MongoAuthorizationCodeServices.class);
+
+
+ private OauthRepository oauthRepository;
+
+
+ public MongoAuthorizationCodeServices() {
+ }
+
+
+ @Override
+ protected void store(String code, OAuth2Authentication authentication) {
+ AuthorizationCode authorizationCode = new AuthorizationCode()
+ .code(code).authentication(authentication);
+
+ oauthRepository.saveAuthorizationCode(authorizationCode);
+ LOG.debug("Store AuthorizationCode: {}", authorizationCode);
+ }
+
+ @Override
+ protected OAuth2Authentication remove(String code) {
+ AuthorizationCode authorizationCode = oauthRepository.removeAuthorizationCode(code);
+ LOG.debug("Remove AuthorizationCode: {}", authorizationCode);
+ return authorizationCode != null ? authorizationCode.authentication() : null;
+ }
+
+ public void setOauthRepository(OauthRepository oauthRepository) {
+ this.oauthRepository = oauthRepository;
+ }
+
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ Assert.notNull(oauthRepository, "oauthRepository is null");
+ }
+}
diff --git a/src/main/java/com/monkeyk/sos/service/oauth/MongoClientDetailsService.java b/src/main/java/com/monkeyk/sos/service/oauth/MongoClientDetailsService.java
new file mode 100644
index 0000000..077d338
--- /dev/null
+++ b/src/main/java/com/monkeyk/sos/service/oauth/MongoClientDetailsService.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
+ * www.monkeyk.com
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information of
+ * MONKEYK Information Technology Co. Ltd ("Confidential Information").
+ * You shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement you
+ * entered into with MONKEYK Information Technology Co. Ltd.
+ */
+package com.monkeyk.sos.service.oauth;
+
+
+import com.monkeyk.sos.domain.oauth.OauthClientDetails;
+import com.monkeyk.sos.domain.oauth.OauthRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.security.oauth2.provider.ClientDetails;
+import org.springframework.security.oauth2.provider.ClientDetailsService;
+import org.springframework.security.oauth2.provider.ClientRegistrationException;
+import org.springframework.util.Assert;
+
+
+/**
+ * 2015/10/28
+ *
+ * @author Shengzhao Li
+ */
+public class MongoClientDetailsService implements ClientDetailsService, InitializingBean {
+
+ private static final Logger LOG = LoggerFactory.getLogger(MongoClientDetailsService.class);
+
+ private OauthRepository oauthRepository;
+
+
+ public MongoClientDetailsService() {
+ }
+
+ @Override
+ public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
+ final OauthClientDetails oauthClientDetails = oauthRepository.findOauthClientDetails(clientId);
+ if (oauthClientDetails == null || oauthClientDetails.archived()) {
+ LOG.warn("Not found ClientDetails by clientId '{}', because null or archived", clientId);
+ throw new ClientRegistrationException("Not found ClientDetails by clientId '" + clientId + "', because null or archived");
+ }
+ return oauthClientDetails.toClientDetails();
+ }
+
+
+ public void setOauthRepository(OauthRepository oauthRepository) {
+ this.oauthRepository = oauthRepository;
+ }
+
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ Assert.notNull(oauthRepository);
+ }
+}
diff --git a/src/main/java/com/monkeyk/sos/service/oauth/MongoTokenStore.java b/src/main/java/com/monkeyk/sos/service/oauth/MongoTokenStore.java
new file mode 100644
index 0000000..dfc4bd7
--- /dev/null
+++ b/src/main/java/com/monkeyk/sos/service/oauth/MongoTokenStore.java
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
+ * www.monkeyk.com
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information of
+ * MONKEYK Information Technology Co. Ltd ("Confidential Information").
+ * You shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement you
+ * entered into with MONKEYK Information Technology Co. Ltd.
+ */
+package com.monkeyk.sos.service.oauth;
+
+
+import com.monkeyk.sos.domain.oauth.AccessToken;
+import com.monkeyk.sos.domain.oauth.AccessTokenRepository;
+import com.monkeyk.sos.domain.oauth.RefreshToken;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.security.oauth2.common.OAuth2AccessToken;
+import org.springframework.security.oauth2.common.OAuth2RefreshToken;
+import org.springframework.security.oauth2.provider.OAuth2Authentication;
+import org.springframework.security.oauth2.provider.token.AuthenticationKeyGenerator;
+import org.springframework.security.oauth2.provider.token.DefaultAuthenticationKeyGenerator;
+import org.springframework.security.oauth2.provider.token.TokenStore;
+import org.springframework.util.Assert;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 2015/10/28
+ *
+ * @author Shengzhao Li
+ */
+public class MongoTokenStore implements TokenStore, InitializingBean {
+
+ private static final Logger LOG = LoggerFactory.getLogger(MongoTokenStore.class);
+
+ private AccessTokenRepository tokenRepository;
+
+ private AuthenticationKeyGenerator authenticationKeyGenerator = new DefaultAuthenticationKeyGenerator();
+
+ private ExtractTokenKeyDigester extractTokenKeyDigester = new MD5ExtractTokenKeyDigester();
+
+ public MongoTokenStore() {
+ }
+
+
+ @Override
+ public OAuth2AccessToken getAccessToken(OAuth2Authentication authentication) {
+ final String authenticationId = authenticationKeyGenerator.extractKey(authentication);
+ OAuth2AccessToken accessToken = null;
+
+ try {
+ AccessToken token = tokenRepository.findAccessTokenByAuthenticationId(authenticationId);
+ accessToken = token != null ? token.token() : null;
+ } catch (IllegalArgumentException e) {
+ LOG.error("Could not extract access token for authentication {}", authentication);
+ }
+
+ if (accessToken != null
+ && !authenticationId.equals(authenticationKeyGenerator.extractKey(readAuthentication(accessToken.getValue())))) {
+ removeAccessToken(accessToken.getValue());
+ // Keep the store consistent (maybe the same user is represented by this authentication but the details have
+ // changed)
+ storeAccessToken(accessToken, authentication);
+ }
+
+ return accessToken;
+ }
+
+
+ @Override
+ public void storeAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) {
+ LOG.debug("Call storeAccessToken, token = {}, authentication = {}", token, authentication);
+ String refreshToken = token.getRefreshToken() != null ? token.getRefreshToken().getValue() : null;
+
+ AccessToken accessToken = new AccessToken()
+ .tokenId(extractTokenKey(token.getValue()))
+ .token(token)
+ .authenticationId(authenticationKeyGenerator.extractKey(authentication))
+ .username(authentication.isClientOnly() ? null : authentication.getName())
+ .clientId(authentication.getOAuth2Request().getClientId())
+ .authentication(authentication)
+ .refreshToken(extractTokenKey(refreshToken));
+
+ tokenRepository.saveAccessToken(accessToken);
+ }
+
+
+ @Override
+ public OAuth2AccessToken readAccessToken(String tokenValue) {
+ LOG.debug("Call readAccessToken, tokenValue = {}", tokenValue);
+ OAuth2AccessToken token = null;
+
+ try {
+ final String tokenId = extractTokenKey(tokenValue);
+
+ final AccessToken accessToken = tokenRepository.findAccessToken(tokenId);
+ token = accessToken == null ? null : accessToken.token();
+ } catch (IllegalArgumentException e) {
+ LOG.warn("Failed to deserialize access token for {}", tokenValue);
+ removeAccessToken(tokenValue);
+ }
+
+ return token;
+ }
+
+
+ @Override
+ public void removeAccessToken(OAuth2AccessToken token) {
+ removeAccessToken(token.getValue());
+ }
+
+
+ @Override
+ public OAuth2Authentication readAuthentication(OAuth2AccessToken token) {
+ return readAuthentication(token.getValue());
+ }
+
+ @Override
+ public OAuth2Authentication readAuthentication(String token) {
+ LOG.debug("Call readAuthentication, token = {}", token);
+ OAuth2Authentication authentication = null;
+ try {
+ final String tokenId = extractTokenKey(token);
+
+ AccessToken accessToken = tokenRepository.findAccessToken(tokenId);
+ authentication = accessToken == null ? null : accessToken.authentication();
+
+ } catch (IllegalArgumentException e) {
+ LOG.warn("Failed to deserialize authentication for {}", token);
+ removeAccessToken(token);
+ }
+
+ return authentication;
+ }
+
+
+ protected void removeAccessToken(String tokenValue) {
+ final String tokenId = extractTokenKey(tokenValue);
+ tokenRepository.removeAccessToken(tokenId);
+ }
+
+ @Override
+ public void storeRefreshToken(OAuth2RefreshToken refreshToken, OAuth2Authentication authentication) {
+ LOG.debug("Call storeRefreshToken, refreshToken = {}, authentication = {}", refreshToken, authentication);
+
+ RefreshToken token = new RefreshToken()
+ .tokenId(extractTokenKey(refreshToken.getValue()))
+ .token(refreshToken)
+ .authentication(authentication);
+
+ tokenRepository.saveRefreshToken(token);
+ }
+
+ @Override
+ public OAuth2RefreshToken readRefreshToken(String tokenValue) {
+ LOG.debug("Call readRefreshToken, tokenValue = {}", tokenValue);
+ OAuth2RefreshToken refreshToken = null;
+
+ try {
+ final String tokenId = extractTokenKey(tokenValue);
+
+ RefreshToken refreshTokenFounded = tokenRepository.findRefreshToken(tokenId);
+ refreshToken = refreshTokenFounded == null ? null : refreshTokenFounded.token();
+ } catch (IllegalArgumentException e) {
+ LOG.warn("Failed to deserialize refresh token for token {}", tokenValue);
+ removeRefreshToken(tokenValue);
+ }
+
+ return refreshToken;
+ }
+
+
+ @Override
+ public void removeRefreshToken(OAuth2RefreshToken token) {
+ removeRefreshToken(token.getValue());
+ }
+
+
+ protected void removeRefreshToken(String token) {
+ final String tokenId = extractTokenKey(token);
+ tokenRepository.removeRefreshToken(tokenId);
+ }
+
+ @Override
+ public OAuth2Authentication readAuthenticationForRefreshToken(OAuth2RefreshToken token) {
+ return readAuthenticationForRefreshToken(token.getValue());
+ }
+
+ protected OAuth2Authentication readAuthenticationForRefreshToken(String tokenValue) {
+ OAuth2Authentication authentication = null;
+
+ try {
+ final String tokenId = extractTokenKey(tokenValue);
+ RefreshToken refreshToken = tokenRepository.findRefreshToken(tokenId);
+
+ authentication = refreshToken == null ? null : refreshToken.authentication();
+ } catch (IllegalArgumentException e) {
+ LOG.warn("Failed to deserialize access token for {}", tokenValue);
+ removeRefreshToken(tokenValue);
+ }
+
+ return authentication;
+ }
+
+ @Override
+ public void removeAccessTokenUsingRefreshToken(OAuth2RefreshToken refreshToken) {
+ removeAccessTokenUsingRefreshToken(refreshToken.getValue());
+ }
+
+ protected void removeAccessTokenUsingRefreshToken(String refreshTokenValue) {
+ final String refreshToken = extractTokenKey(refreshTokenValue);
+ tokenRepository.removeAccessTokenByRefreshToken(refreshToken);
+ }
+
+
+ @Override
+ public Collection findTokensByClientId(String clientId) {
+ LOG.debug("Call findTokensByClientId, clientId = {}", clientId);
+ List accessTokens = new ArrayList<>();
+
+ List tokenList = tokenRepository.findAccessTokensByClientId(clientId);
+ for (AccessToken token : tokenList) {
+ final OAuth2AccessToken accessToken = token.token();
+ if (accessToken != null) {
+ accessTokens.add(accessToken);
+ }
+ }
+
+ return accessTokens;
+ }
+
+
+ @Override
+ public Collection findTokensByClientIdAndUserName(String clientId, String userName) {
+ LOG.debug("Call findTokensByUserName, clientId = {}, username = {}", clientId, userName);
+ List accessTokens = new ArrayList<>();
+
+ List tokenList = tokenRepository.findAccessTokensByClientIdAndUsername(clientId, userName);
+ for (AccessToken token : tokenList) {
+ final OAuth2AccessToken accessToken = token.token();
+ if (accessToken != null) {
+ accessTokens.add(accessToken);
+ }
+ }
+
+ return accessTokens;
+ }
+
+
+ protected String extractTokenKey(String value) {
+ return this.extractTokenKeyDigester.digest(value);
+ }
+
+ public void setTokenRepository(AccessTokenRepository tokenRepository) {
+ this.tokenRepository = tokenRepository;
+ }
+
+ public void setAuthenticationKeyGenerator(AuthenticationKeyGenerator authenticationKeyGenerator) {
+ this.authenticationKeyGenerator = authenticationKeyGenerator;
+ }
+
+ public void setExtractTokenKeyDigester(ExtractTokenKeyDigester extractTokenKeyDigester) {
+ this.extractTokenKeyDigester = extractTokenKeyDigester;
+ }
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ Assert.notNull(tokenRepository);
+ Assert.notNull(authenticationKeyGenerator);
+ }
+}
diff --git a/src/main/java/com/monkeyk/sos/web/ExtContextLoaderListener.java b/src/main/java/com/monkeyk/sos/web/ExtContextLoaderListener.java
new file mode 100644
index 0000000..cedc2e6
--- /dev/null
+++ b/src/main/java/com/monkeyk/sos/web/ExtContextLoaderListener.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2013 Andaily Information Technology Co. Ltd
+ * www.andaily.com
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information of
+ * Andaily Information Technology Co. Ltd ("Confidential Information").
+ * You shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement you
+ * entered into with Andaily Information Technology Co. Ltd.
+ */
+package com.monkeyk.sos.web;
+
+
+import com.monkeyk.sos.domain.shared.BeanProvider;
+import org.springframework.web.context.ContextLoaderListener;
+import org.springframework.web.context.WebApplicationContext;
+import org.springframework.web.context.support.WebApplicationContextUtils;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+
+/**
+ * 15-6-22
+ *
+ * @author Shengzhao Li
+ */
+public class ExtContextLoaderListener extends ContextLoaderListener {
+
+
+ @Override
+ public void contextInitialized(ServletContextEvent event) {
+ super.contextInitialized(event);
+ final ServletContext servletContext = event.getServletContext();
+
+ WebApplicationContext applicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
+ BeanProvider.initialize(applicationContext);
+ }
+}
diff --git a/src/main/java/com/monkeyk/sos/web/controller/UserFormDtoValidator.java b/src/main/java/com/monkeyk/sos/web/controller/UserFormDtoValidator.java
index 851add4..c28a469 100644
--- a/src/main/java/com/monkeyk/sos/web/controller/UserFormDtoValidator.java
+++ b/src/main/java/com/monkeyk/sos/web/controller/UserFormDtoValidator.java
@@ -9,7 +9,7 @@ import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
-import java.util.List;
+import java.util.Set;
/**
* 2016/3/25
@@ -38,7 +38,7 @@ public class UserFormDtoValidator implements Validator {
}
private void validatePrivileges(Errors errors, UserFormDto formDto) {
- final List privileges = formDto.getPrivileges();
+ final Set privileges = formDto.getPrivileges();
if (privileges == null || privileges.isEmpty()) {
errors.rejectValue("privileges", null, "Privileges is required");
}
diff --git a/src/main/resources/spring-oauth-server.properties b/src/main/resources/spring-oauth-server.properties
index 539c2c3..fac8c58 100644
--- a/src/main/resources/spring-oauth-server.properties
+++ b/src/main/resources/spring-oauth-server.properties
@@ -1,8 +1,11 @@
-#JDBC configuration information
-jdbc.driverClassName=com.mysql.jdbc.Driver
-############
-# localhost
-############
-jdbc.url=jdbc:mysql://localhost:3306/oauth2?autoReconnect=true&autoReconnectForPools=true&useUnicode=true&characterEncoding=utf8
-jdbc.username=andaily
-jdbc.password=andaily
\ No newline at end of file
+
+#MongoDB configuration
+
+mongo.host=127.0.0.1
+mongo.port=27017
+# DB name
+mongo.db=spring-oauth-server
+# Username, password
+mongo.username=mkk
+mongo.password=mkk
+
diff --git a/src/main/resources/spring/context.xml b/src/main/resources/spring/context.xml
index 49acc1a..cf8565a 100644
--- a/src/main/resources/spring/context.xml
+++ b/src/main/resources/spring/context.xml
@@ -1,11 +1,12 @@
+
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd">
@@ -21,30 +22,25 @@
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
-
-
-
-
-
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/spring/security.xml b/src/main/resources/spring/security.xml
index 7f245ad..619abf3 100644
--- a/src/main/resources/spring/security.xml
+++ b/src/main/resources/spring/security.xml
@@ -69,43 +69,23 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
+
+
+
-
-
-
-
-
-
@@ -121,9 +101,8 @@
-
-
+
+
@@ -131,7 +110,7 @@
user-approval-handler-ref="oauthUserApprovalHandler"
user-approval-page="oauth_approval"
error-page="oauth_error">
-
+
diff --git a/src/main/resources/spring/transaction.xml b/src/main/resources/spring/transaction.xml
deleted file mode 100644
index 7fe1d9e..0000000
--- a/src/main/resources/spring/transaction.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/main/webapp/WEB-INF/jsp/decorators/main.jsp b/src/main/webapp/WEB-INF/jsp/decorators/main.jsp
index ebc583c..0a4aa42 100644
--- a/src/main/webapp/WEB-INF/jsp/decorators/main.jsp
+++ b/src/main/webapp/WEB-INF/jsp/decorators/main.jsp
@@ -16,7 +16,7 @@
- - Spring Security&Oauth2
+ - Spring Security&Oauth2 [MongoDB]
diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml
index c70e61b..4011d94 100644
--- a/src/main/webapp/WEB-INF/web.xml
+++ b/src/main/webapp/WEB-INF/web.xml
@@ -5,12 +5,12 @@
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
- spring-oauth-server
+ spring-oauth-server[mongodb]
webAppRootKey
- spring-oauth-server
+ spring-oauth-server[mongodb]
@@ -72,7 +72,7 @@
- org.springframework.web.context.ContextLoaderListener
+ com.monkeyk.sos.web.ExtContextLoaderListener
diff --git a/src/test/java/com/monkeyk/sos/ContextTest.java b/src/test/java/com/monkeyk/sos/ContextTest.java
index efc0438..78b8caf 100644
--- a/src/test/java/com/monkeyk/sos/ContextTest.java
+++ b/src/test/java/com/monkeyk/sos/ContextTest.java
@@ -1,14 +1,14 @@
package com.monkeyk.sos;
import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.testng.AbstractTransactionalTestNGSpringContextTests;
+import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.springframework.test.context.transaction.BeforeTransaction;
/**
* @author Shengzhao Li
*/
@ContextConfiguration(locations = {"classpath:/spring/*.xml"}, initializers = {TestApplicationContextInitializer.class})
-public abstract class ContextTest extends AbstractTransactionalTestNGSpringContextTests {
+public abstract class ContextTest extends AbstractTestNGSpringContextTests {
@BeforeTransaction
public void beforeTest() {
diff --git a/src/test/java/com/monkeyk/sos/infrastructure/AbstractRepositoryTest.java b/src/test/java/com/monkeyk/sos/infrastructure/AbstractRepositoryTest.java
index 9608b36..7bbcdcf 100644
--- a/src/test/java/com/monkeyk/sos/infrastructure/AbstractRepositoryTest.java
+++ b/src/test/java/com/monkeyk/sos/infrastructure/AbstractRepositoryTest.java
@@ -1,8 +1,7 @@
package com.monkeyk.sos.infrastructure;
import com.monkeyk.sos.ContextTest;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.data.mongodb.core.MongoTemplate;
/**
* @author Shengzhao Li
@@ -10,13 +9,16 @@ import org.springframework.jdbc.core.JdbcTemplate;
public abstract class AbstractRepositoryTest extends ContextTest {
- @Autowired
- private JdbcTemplate jdbcTemplate;
+
+ private MongoTemplate mongoTemplate;
- public JdbcTemplate jdbcTemplate() {
- return jdbcTemplate;
+ //get MongoTemplate
+ protected MongoTemplate mongoTemplate() {
+ if (mongoTemplate == null) {
+ mongoTemplate = applicationContext.getBean(MongoTemplate.class);
+ }
+ return mongoTemplate;
}
-
}
\ No newline at end of file
diff --git a/src/test/java/com/monkeyk/sos/infrastructure/jdbc/OauthRepositoryJdbcTest.java b/src/test/java/com/monkeyk/sos/infrastructure/jdbc/OauthRepositoryJdbcTest.java
deleted file mode 100644
index b6a2f9f..0000000
--- a/src/test/java/com/monkeyk/sos/infrastructure/jdbc/OauthRepositoryJdbcTest.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
- * www.monkeyk.com
- * All rights reserved.
- *
- * This software is the confidential and proprietary information of
- * MONKEYK Information Technology Co. Ltd ("Confidential Information").
- * You shall not disclose such Confidential Information and shall use
- * it only in accordance with the terms of the license agreement you
- * entered into with MONKEYK Information Technology Co. Ltd.
- */
-package com.monkeyk.sos.infrastructure.jdbc;
-
-import com.monkeyk.sos.domain.oauth.OauthClientDetails;
-import com.monkeyk.sos.domain.oauth.OauthRepository;
-import com.monkeyk.sos.domain.shared.GuidGenerator;
-import com.monkeyk.sos.infrastructure.AbstractRepositoryTest;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.testng.annotations.Test;
-
-import java.util.List;
-
-import static org.testng.Assert.*;
-
-/*
- * @author Shengzhao Li
- */
-public class OauthRepositoryJdbcTest extends AbstractRepositoryTest {
-
-
- @Autowired
- private OauthRepository oauthRepositoryMyBatis;
-
-
- @Test
- public void findOauthClientDetails() {
- OauthClientDetails oauthClientDetails = oauthRepositoryMyBatis.findOauthClientDetails("unity-client");
- assertNull(oauthClientDetails);
-
- }
-
-
- @Test
- public void saveOauthClientDetails() {
-
- final String clientId = GuidGenerator.generate();
-
- OauthClientDetails clientDetails = new OauthClientDetails().clientId(clientId);
- oauthRepositoryMyBatis.saveOauthClientDetails(clientDetails);
-
- final OauthClientDetails oauthClientDetails = oauthRepositoryMyBatis.findOauthClientDetails(clientId);
- assertNotNull(oauthClientDetails);
- assertNotNull(oauthClientDetails.clientId());
- assertNull(oauthClientDetails.clientSecret());
-
- }
-
- @Test
- public void findAllOauthClientDetails() {
- final List allOauthClientDetails = oauthRepositoryMyBatis.findAllOauthClientDetails();
- assertNotNull(allOauthClientDetails);
- assertTrue(allOauthClientDetails.isEmpty());
- }
-
- @Test
- public void updateOauthClientDetailsArchive() {
- oauthRepositoryMyBatis.updateOauthClientDetailsArchive("ddooelddd", true);
- }
-
-
-}
\ No newline at end of file
diff --git a/src/test/java/com/monkeyk/sos/infrastructure/jdbc/UserRepositoryJdbcTest.java b/src/test/java/com/monkeyk/sos/infrastructure/jdbc/UserRepositoryJdbcTest.java
deleted file mode 100644
index 7d871e4..0000000
--- a/src/test/java/com/monkeyk/sos/infrastructure/jdbc/UserRepositoryJdbcTest.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
- * www.monkeyk.com
- * All rights reserved.
- *
- * This software is the confidential and proprietary information of
- * MONKEYK Information Technology Co. Ltd ("Confidential Information").
- * You shall not disclose such Confidential Information and shall use
- * it only in accordance with the terms of the license agreement you
- * entered into with MONKEYK Information Technology Co. Ltd.
- */
-package com.monkeyk.sos.infrastructure.jdbc;
-
-import com.monkeyk.sos.domain.user.User;
-import com.monkeyk.sos.domain.user.UserRepository;
-import com.monkeyk.sos.infrastructure.AbstractRepositoryTest;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.testng.annotations.Test;
-
-import java.util.List;
-
-import static org.testng.AssertJUnit.assertEquals;
-import static org.testng.AssertJUnit.assertNotNull;
-import static org.testng.AssertJUnit.assertNull;
-
-/*
- * @author Shengzhao Li
- */
-public class UserRepositoryJdbcTest extends AbstractRepositoryTest {
-
-
- @Autowired
- private UserRepository userRepository;
-
-
- @Test
- public void findByGuid() {
- User user = userRepository.findByGuid("oood");
- assertNull(user);
-
- user = new User("user", "123", "123", "ewo@honyee.cc");
- userRepository.saveUser(user);
-
- user = userRepository.findByGuid(user.guid());
- assertNotNull(user);
- assertNotNull(user.email());
-
-
- }
-
- @Test
- public void findUsersByUsername() {
- User user = userRepository.findByGuid("oood");
- assertNull(user);
-
- user = new User("user", "123", "123", "ewo@honyee.cc");
- userRepository.saveUser(user);
-
- final List list = userRepository.findUsersByUsername(user.username());
- assertNotNull(list);
-
- assertEquals(list.size(), 1);
-
- }
-
-
- @Test
- public void updateUser() {
- User user = new User("user", "123", "123", "ewo@honyee.cc");
- userRepository.saveUser(user);
-
- user = userRepository.findByGuid(user.guid());
- assertNotNull(user);
- assertNotNull(user.email());
-
- String newEmail = "test@honyee.cc";
- user.email(newEmail).phone("12344444");
- userRepository.updateUser(user);
-
- user = userRepository.findByGuid(user.guid());
- assertNotNull(user);
- assertEquals(user.email(), newEmail);
- }
-
-
- @Test
- public void findByUsername() {
- String username = "user";
- User user = new User(username, "123", "123", "ewo@honyee.cc");
- userRepository.saveUser(user);
-
- User result = userRepository.findByUsername(username);
- assertNotNull(result);
- }
-
-
- /*
- * Run the test must initial db firstly
- * */
- @Test(enabled = false)
- public void testPrivilege() {
-
- String guid = "55b713df1c6f423e842ad68668523c49";
- final User user = userRepository.findByGuid(guid);
-
- assertNotNull(user);
- assertEquals(user.privileges().size(), 1);
-
-
- }
-
-
-}
\ No newline at end of file
diff --git a/src/test/java/com/monkeyk/sos/infrastructure/mongo/AccessTokenRepositoryMongoTest.java b/src/test/java/com/monkeyk/sos/infrastructure/mongo/AccessTokenRepositoryMongoTest.java
new file mode 100644
index 0000000..df3887d
--- /dev/null
+++ b/src/test/java/com/monkeyk/sos/infrastructure/mongo/AccessTokenRepositoryMongoTest.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
+ * www.monkeyk.com
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information of
+ * MONKEYK Information Technology Co. Ltd ("Confidential Information").
+ * You shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement you
+ * entered into with MONKEYK Information Technology Co. Ltd.
+ */
+package com.monkeyk.sos.infrastructure.mongo;
+
+
+import com.monkeyk.sos.domain.oauth.AccessToken;
+import com.monkeyk.sos.domain.oauth.RefreshToken;
+import com.monkeyk.sos.domain.shared.GuidGenerator;
+import com.monkeyk.sos.infrastructure.AbstractRepositoryTest;
+import com.monkeyk.sos.infrastructure.DateUtils;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.oauth2.common.DefaultExpiringOAuth2RefreshToken;
+import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
+import org.springframework.security.oauth2.common.OAuth2AccessToken;
+import org.springframework.security.oauth2.common.OAuth2RefreshToken;
+import org.springframework.security.oauth2.provider.OAuth2Authentication;
+import org.springframework.security.oauth2.provider.OAuth2Request;
+import org.testng.annotations.Test;
+
+import java.util.Date;
+import java.util.List;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
+/*
+ * @author Shengzhao Li
+ */
+public class AccessTokenRepositoryMongoTest extends AbstractRepositoryTest {
+
+
+ private AccessTokenRepositoryMongo tokenRepositoryMongo;
+
+ private void prepTest() {
+ if (tokenRepositoryMongo == null) {
+ tokenRepositoryMongo = new AccessTokenRepositoryMongo();
+ tokenRepositoryMongo.setMongoTemplate(mongoTemplate());
+ }
+ }
+
+
+ @Test
+ public void removeAccessToken() {
+ prepTest();
+
+ String tokenId = GuidGenerator.generate();
+ final String refreshToken = GuidGenerator.generate();
+
+ OAuth2Request req = new OAuth2Request() {
+ };
+ Authentication userAu = new OAuth2Authentication(req, null);
+ OAuth2Authentication auth = new OAuth2Authentication(req, userAu);
+
+ OAuth2AccessToken tok = new DefaultOAuth2AccessToken(GuidGenerator.generate());
+ final String clientId = "client253";
+ final String username = "username1452";
+ final String authenticationId = GuidGenerator.generate();
+
+ AccessToken accessToken = new AccessToken()
+ .authentication(auth)
+ .token(tok)
+ .authenticationId(authenticationId)
+ .refreshToken(refreshToken)
+ .tokenId(tokenId).clientId(clientId).username(username);
+
+ tokenRepositoryMongo.saveAccessToken(accessToken);
+
+
+ final AccessToken token = tokenRepositoryMongo.findAccessToken(tokenId);
+ assertNotNull(token);
+ assertNotNull(token.createTime());
+ assertNotNull(token.clientId());
+ assertNotNull(token.authentication());
+ assertNotNull(token.token());
+
+
+ final AccessToken accessTokenByRefreshToken = tokenRepositoryMongo.findAccessTokenByRefreshToken(refreshToken);
+ assertNotNull(accessTokenByRefreshToken);
+
+
+ final List list = tokenRepositoryMongo.findAccessTokensByClientId(clientId);
+ assertEquals(list.size(), 1);
+
+ final List tokenList = tokenRepositoryMongo.findAccessTokensByUsername(username);
+ assertEquals(tokenList.size(), 1);
+
+ final AccessToken accessTokenByAuthenticationId = tokenRepositoryMongo.findAccessTokenByAuthenticationId(authenticationId);
+ assertNotNull(accessTokenByAuthenticationId);
+
+
+ tokenRepositoryMongo.removeAccessToken(token.tokenId());
+
+ }
+
+
+ @Test
+ public void removeRefreshToken() {
+ prepTest();
+
+ String tokenId = GuidGenerator.generate();
+
+ OAuth2Request req = new OAuth2Request() {
+ };
+ Authentication userAu = new OAuth2Authentication(req, null);
+ OAuth2Authentication auth = new OAuth2Authentication(req, userAu);
+
+ OAuth2RefreshToken toks = new DefaultExpiringOAuth2RefreshToken(GuidGenerator.generate(), new Date());
+
+ RefreshToken refreshToken = new RefreshToken()
+ .tokenId(tokenId).token(toks)
+ .authentication(auth);
+
+
+ tokenRepositoryMongo.saveRefreshToken(refreshToken);
+
+
+ final RefreshToken token = tokenRepositoryMongo.findRefreshToken(tokenId);
+ assertNotNull(token);
+ assertNotNull(token.tokenId());
+ assertNotNull(token.token());
+ assertNotNull(token.authentication());
+
+
+ tokenRepositoryMongo.removeRefreshToken(token.tokenId());
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/monkeyk/sos/infrastructure/mongo/OauthRepositoryMongoTest.java b/src/test/java/com/monkeyk/sos/infrastructure/mongo/OauthRepositoryMongoTest.java
new file mode 100644
index 0000000..6eb6db0
--- /dev/null
+++ b/src/test/java/com/monkeyk/sos/infrastructure/mongo/OauthRepositoryMongoTest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
+ * www.monkeyk.com
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information of
+ * MONKEYK Information Technology Co. Ltd ("Confidential Information").
+ * You shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement you
+ * entered into with MONKEYK Information Technology Co. Ltd.
+ */
+package com.monkeyk.sos.infrastructure.mongo;
+
+
+import com.monkeyk.sos.domain.oauth.AuthorizationCode;
+import com.monkeyk.sos.domain.oauth.OauthClientDetails;
+import com.monkeyk.sos.domain.shared.GuidGenerator;
+import com.monkeyk.sos.infrastructure.AbstractRepositoryTest;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.oauth2.provider.OAuth2Authentication;
+import org.springframework.security.oauth2.provider.OAuth2Request;
+import org.testng.annotations.Test;
+
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+/*
+ * @author Shengzhao Li
+ */
+public class OauthRepositoryMongoTest extends AbstractRepositoryTest {
+
+
+ private OauthRepositoryMongo oauthRepositoryMongo;
+
+
+ private void prepTest() {
+ if (oauthRepositoryMongo == null) {
+ oauthRepositoryMongo = new OauthRepositoryMongo();
+ oauthRepositoryMongo.setMongoTemplate(mongoTemplate());
+ }
+ }
+
+ @Test
+ public void testFindOauthClientDetails() throws Exception {
+ prepTest();
+
+ final OauthClientDetails clientDetails = oauthRepositoryMongo.findOauthClientDetails("clientId");
+ assertNull(clientDetails);
+
+ }
+
+ @Test(enabled = false)
+ public void removeAuthorizationCode() throws Exception {
+ prepTest();
+
+ final String code = GuidGenerator.generate();
+
+ OAuth2Request request = new OAuth2Request() {
+ };
+ Authentication userAuth = new OAuth2Authentication(request, null);
+ OAuth2Authentication auth = new OAuth2Authentication(request, userAuth);
+
+ AuthorizationCode authorizationCode = new AuthorizationCode()
+ .code(code).authentication(auth);
+
+
+ final AuthorizationCode code1 = oauthRepositoryMongo.removeAuthorizationCode(code);
+ assertNull(code1);
+
+ oauthRepositoryMongo.saveAuthorizationCode(authorizationCode);
+
+ final AuthorizationCode code2 = oauthRepositoryMongo.removeAuthorizationCode(code);
+ assertNotNull(code2);
+ assertNotNull(code2.code());
+ assertNotNull(code2.authentication());
+ assertNotNull(code2.createTime());
+
+ }
+
+ @Test
+ public void findAllOauthClientDetails() throws Exception {
+ prepTest();
+
+ final List list = oauthRepositoryMongo.findAllOauthClientDetails();
+ assertNotNull(list);
+
+ assertTrue(list.isEmpty());
+ }
+
+ @Test
+ public void updateOauthClientDetailsArchive() throws Exception {
+ prepTest();
+
+ OauthClientDetails clientDetails = new OauthClientDetails();
+ clientDetails.clientId("test").clientSecret("secret");
+
+ oauthRepositoryMongo.saveOauthClientDetails(clientDetails);
+
+ final OauthClientDetails oauthClientDetails = oauthRepositoryMongo.findOauthClientDetails(clientDetails.clientId());
+ assertNotNull(oauthClientDetails);
+ assertFalse(oauthClientDetails.archived());
+
+ oauthRepositoryMongo.updateOauthClientDetailsArchive(clientDetails.clientId(), true);
+
+ final OauthClientDetails details = oauthRepositoryMongo.findOauthClientDetails(clientDetails.clientId());
+ assertNotNull(details);
+ assertTrue(details.archived());
+
+ }
+
+ @Test
+ public void saveOauthClientDetails() throws Exception {
+ prepTest();
+
+ OauthClientDetails clientDetails = new OauthClientDetails();
+ clientDetails.clientId("test").clientSecret("secret");
+
+ oauthRepositoryMongo.saveOauthClientDetails(clientDetails);
+
+ final OauthClientDetails oauthClientDetails = oauthRepositoryMongo.findOauthClientDetails(clientDetails.clientId());
+ assertNotNull(oauthClientDetails);
+
+ final boolean b = oauthRepositoryMongo.removeOauthClientDetails(oauthClientDetails);
+ assertEquals(b, true);
+
+ final OauthClientDetails details = oauthRepositoryMongo.findOauthClientDetails(clientDetails.clientId());
+ assertNull(details);
+ }
+
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/monkeyk/sos/infrastructure/mongo/UserRepositoryMongoTest.java b/src/test/java/com/monkeyk/sos/infrastructure/mongo/UserRepositoryMongoTest.java
new file mode 100644
index 0000000..13bb161
--- /dev/null
+++ b/src/test/java/com/monkeyk/sos/infrastructure/mongo/UserRepositoryMongoTest.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2015 MONKEYK Information Technology Co. Ltd
+ * www.monkeyk.com
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information of
+ * MONKEYK Information Technology Co. Ltd ("Confidential Information").
+ * You shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement you
+ * entered into with MONKEYK Information Technology Co. Ltd.
+ */
+package com.monkeyk.sos.infrastructure.mongo;
+
+
+import com.monkeyk.sos.domain.user.Privilege;
+import com.monkeyk.sos.domain.user.User;
+import com.monkeyk.sos.infrastructure.AbstractRepositoryTest;
+import org.testng.annotations.Test;
+
+import java.util.List;
+
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+/*
+ * @author Shengzhao Li
+ */
+public class UserRepositoryMongoTest extends AbstractRepositoryTest {
+
+
+ private UserRepositoryMongo userRepository;
+
+ private void prepTest() {
+ if (userRepository == null) {
+ userRepository = new UserRepositoryMongo();
+ userRepository.setMongoTemplate(mongoTemplate());
+ }
+ }
+
+ @Test
+ public void testSaveUser() throws Exception {
+
+ prepTest();
+
+ User user = new User("user", "pass", "13302585", "ddedd@ddd.com");
+ user.privileges().add(Privilege.MOBILE);
+
+ userRepository.saveUser(user);
+
+ final User user1 = userRepository.findByGuid(user.guid());
+ assertNotNull(user1);
+ assertNotNull(user1.username());
+ assertNotNull(user1.createTime());
+
+
+ userRepository.removeUser(user1);
+
+
+ }
+
+
+ @Test
+ public void findByUsername() throws Exception {
+
+ prepTest();
+
+ User user = new User("user", "pass", "13302585", "ddedd@ddd.com");
+ user.privileges().add(Privilege.MOBILE);
+
+ userRepository.saveUser(user);
+
+ final User user1 = userRepository.findByUsername(user.username());
+ assertNotNull(user1);
+ assertNotNull(user1.username());
+ assertNotNull(user1.createTime());
+
+
+ userRepository.removeUser(user1);
+
+
+ }
+
+ @Test
+ public void findAllUsers() throws Exception {
+
+ prepTest();
+
+ final List list = userRepository.findAllUsers();
+ assertNotNull(list);
+
+ assertTrue(list.isEmpty());
+
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/test.properties b/src/test/resources/test.properties
index adaaba2..d375b2f 100644
--- a/src/test/resources/test.properties
+++ b/src/test/resources/test.properties
@@ -1,8 +1,11 @@
-#JDBC configuration information
-jdbc.driverClassName=com.mysql.jdbc.Driver
-############
-# localhost
-############
-jdbc.url=jdbc:mysql://localhost:3306/oauth2_test?autoReconnect=true&autoReconnectForPools=true&useUnicode=true&characterEncoding=utf8
-jdbc.username=andaily
-jdbc.password=andaily
\ No newline at end of file
+
+#MongoDB configuration
+
+mongo.host=127.0.0.1
+mongo.port=27017
+# DB name
+mongo.db=spring-oauth-server-test
+# Username, password
+mongo.username=mkk
+mongo.password=mkk
+