Skip to content

Commit

Permalink
Support Authorization Token and drop use of Sessions
Browse files Browse the repository at this point in the history
  • Loading branch information
iainporter committed Jun 22, 2014
1 parent 131063a commit e0920d5
Show file tree
Hide file tree
Showing 24 changed files with 108 additions and 350 deletions.
53 changes: 0 additions & 53 deletions src/main/java/com/porterhead/rest/authorization/UserSession.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import com.porterhead.rest.user.UserRepository;
import com.porterhead.rest.user.UserService;
import com.porterhead.rest.user.api.ExternalUser;
import com.porterhead.rest.user.domain.SessionToken;
import com.porterhead.rest.user.domain.AuthorizationToken;
import com.porterhead.rest.user.domain.User;
import com.porterhead.rest.user.exception.AuthorizationException;
import com.porterhead.rest.util.DateUtil;
Expand Down Expand Up @@ -169,16 +169,11 @@ private boolean isAuthorized(User user, AuthorizationRequestContext authorizatio
Assert.notNull(user);
Assert.notNull(authorizationRequest.getAuthorizationToken());
String unEncodedString = composeUnEncodedRequest(authorizationRequest);
Set<SessionToken> sessionTokens = user.getSessions();
String userTokenHash = null;
for (SessionToken token : sessionTokens) {
userTokenHash = encodeAuthToken(token.getToken(), unEncodedString);
AuthorizationToken authorizationToken = user.getAuthorizationToken();
String userTokenHash = encodeAuthToken(authorizationToken.getToken(), unEncodedString);
if (hashedToken.equals(userTokenHash)) {
token.setLastUpdated(new Date());
userRepository.save(user);
return true;
}
}
LOG.error("Hash check failed for hashed token: {} for the following request: {} for user: {}",
new Object[]{authorizationRequest.getAuthorizationToken(), unEncodedString, user.getId()});
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import com.porterhead.rest.authorization.AuthorizationService;
import com.porterhead.rest.user.UserRepository;
import com.porterhead.rest.user.api.ExternalUser;
import com.porterhead.rest.user.domain.SessionToken;
import com.porterhead.rest.user.domain.AuthorizationToken;
import com.porterhead.rest.user.domain.User;
import com.porterhead.rest.user.exception.AuthorizationException;

Expand Down Expand Up @@ -40,13 +40,10 @@ public ExternalUser authorize(AuthorizationRequestContext securityContext) {
if(user == null) {
throw new AuthorizationException("Session token not valid");
}
for (SessionToken sessionToken : user.getSessions()) {
if (sessionToken.getToken().equals(token)) {
sessionToken.setLastUpdated(new Date());
userRepository.save(user);
AuthorizationToken authorizationToken = user.getAuthorizationToken();
if (authorizationToken.getToken().equals(token)) {
externalUser = new ExternalUser(user);
}
}
return externalUser;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class ApplicationConfig {
private final static String HOSTNAME_PROPERTY = "hostNameUrl";

private final static String SECURITY_AUTHORIZATION_REQUIRE_SIGNED_REQUESTS = "security.authorization.requireSignedRequests";
private final static String SESSION_EXPIRY_DURATION = "session.timeToLive.inMinutes";
private final static String AUTHORIZATION_EXPIRY_DURATION = "authorization.timeToLive.inSeconds";
private final static String SESSION_DATE_OFFSET_IN_MINUTES = "session.date.offset.inMinutes";
private final static String TOKEN_EMAIL_REGISTRATION_DURATION = "token.emailRegistration.timeToLive.inMinutes";
private final static String TOKEN_EMAIL_VERIFICATION_DURATION = "token.emailVerification.timeToLive.inMinutes";
Expand All @@ -44,8 +44,8 @@ public String getFacebookClientSecret() {
return environment.getProperty("facebook.clientSecret");
}

public int getSessionExpiryTimeInMinutes() {
return Integer.parseInt(environment.getProperty(SESSION_EXPIRY_DURATION));
public int getAuthorizationExpiryTimeInSeconds() {
return Integer.parseInt(environment.getProperty(AUTHORIZATION_EXPIRY_DURATION));
}

public int getSessionDateOffsetInMinutes() {
Expand Down
36 changes: 0 additions & 36 deletions src/main/java/com/porterhead/rest/user/SessionReaper.java

This file was deleted.

4 changes: 2 additions & 2 deletions src/main/java/com/porterhead/rest/user/UserRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ public interface UserRepository extends JpaRepository<User, Long> {
@Query("select u from User u where uuid = ?")
User findByUuid(String uuid);

@Query("select u from User u where u in (select user from SessionToken where lastUpdated < ?)")
@Query("select u from User u where u in (select user from AuthorizationToken where lastUpdated < ?)")
List<User> findByExpiredSession(Date lastUpdated);

@Query("select u from User u where u = (select user from SessionToken where token = ?)")
@Query("select u from User u where u = (select user from AuthorizationToken where token = ?)")
User findBySession(String token);

}
10 changes: 6 additions & 4 deletions src/main/java/com/porterhead/rest/user/UserService.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.porterhead.rest.user;

import com.porterhead.rest.user.api.*;
import com.porterhead.rest.user.domain.AuthorizationToken;
import com.porterhead.rest.user.domain.Role;
import com.porterhead.rest.user.domain.User;
import org.springframework.social.connect.Connection;

/**
Expand Down Expand Up @@ -74,11 +76,11 @@ public interface UserService {
public ExternalUser saveUser(String userId, UpdateUserRequest request);

/**
* Delete all SessionToken objects that have not been accessed within the duration specified by the argument timeSinceLastUpdatedInMinutes
* Create an AuthorizationToken for the User
*
* @param timeSinceLastUpdatedInMinutes
* @return the number of sessions removed
* @return
*/
public Integer deleteExpiredSessions(int timeSinceLastUpdatedInMinutes);
public AuthorizationToken createAuthorizationToken(User user);


}
41 changes: 20 additions & 21 deletions src/main/java/com/porterhead/rest/user/UserServiceImpl.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.porterhead.rest.user;


import com.porterhead.rest.config.ApplicationConfig;
import com.porterhead.rest.service.BaseService;
import com.porterhead.rest.user.api.*;
import com.porterhead.rest.user.domain.AuthorizationToken;
import com.porterhead.rest.user.domain.Role;
import com.porterhead.rest.user.domain.User;
import com.porterhead.rest.user.exception.AuthenticationException;
Expand All @@ -11,7 +13,6 @@
import com.porterhead.rest.user.exception.UserNotFoundException;
import com.porterhead.rest.user.social.JpaUsersConnectionRepository;
import com.porterhead.rest.util.StringUtil;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
Expand Down Expand Up @@ -40,15 +41,19 @@ public class UserServiceImpl extends BaseService implements UserService {

private UserRepository userRepository;

private ApplicationConfig applicationConfig;

public UserServiceImpl(Validator validator) {
super(validator);
}

@Autowired
public UserServiceImpl(UsersConnectionRepository usersConnectionRepository, Validator validator) {
public UserServiceImpl(UsersConnectionRepository usersConnectionRepository,
Validator validator, ApplicationConfig applicationConfig) {
this(validator);
this.jpaUsersConnectionRepository = usersConnectionRepository;
((JpaUsersConnectionRepository)this.jpaUsersConnectionRepository).setUserService(this);
this.applicationConfig = applicationConfig;
}

private static final Logger LOG = LoggerFactory.getLogger(UserServiceImpl.class);
Expand All @@ -59,7 +64,7 @@ public UserServiceImpl(UsersConnectionRepository usersConnectionRepository, Vali
* This method creates a User with the given Role. A check is made to see if the username already exists and a duplication
* check is made on the email address if it is present in the request.
* <P></P>
* The password is hashed and a SessionToken generated for subsequent authorization of role-protected requests.
* The password is hashed and a AuthorizationToken generated for subsequent authorization of role-protected requests.
*
*/
@Transactional
Expand All @@ -71,7 +76,7 @@ public AuthenticatedUserToken createUser(CreateUserRequest request, Role role) {
}

User newUser = createNewUser(request, role);
AuthenticatedUserToken token = new AuthenticatedUserToken(newUser.getUuid().toString(), newUser.addSessionToken().getToken());
AuthenticatedUserToken token = new AuthenticatedUserToken(newUser.getUuid().toString(), createAuthorizationToken(newUser).getToken());
userRepository.save(newUser);
return token;
}
Expand All @@ -80,7 +85,8 @@ public AuthenticatedUserToken createUser(CreateUserRequest request, Role role) {
public AuthenticatedUserToken createUser(Role role) {
User user = new User();
user.setRole(role);
AuthenticatedUserToken token = new AuthenticatedUserToken(user.getUuid().toString(), user.addSessionToken().getToken());
AuthenticatedUserToken token = new AuthenticatedUserToken(user.getUuid().toString(),
createAuthorizationToken(user).getToken());
userRepository.save(user);
return token;
}
Expand All @@ -107,7 +113,7 @@ public AuthenticatedUserToken login(LoginRequest request) {
throw new AuthenticationException();
}
if (hashedPassword.equals(user.getHashedPassword())) {
return new AuthenticatedUserToken(user.getUuid().toString(), user.addSessionToken().getToken());
return new AuthenticatedUserToken(user.getUuid().toString(), createAuthorizationToken(user).getToken());
} else {
throw new AuthenticationException();
}
Expand All @@ -121,7 +127,7 @@ public AuthenticatedUserToken login(LoginRequest request) {
*
* <P></P>
*
* A SessionToken is generated and any Profile data that can be collected from the Social account is propagated to the User object.
* A AuthorizationToken is generated and any Profile data that can be collected from the Social account is propagated to the User object.
*
*/
@Transactional
Expand All @@ -136,7 +142,7 @@ public AuthenticatedUserToken socialLogin(Connection<?> connection) {
throw new AuthenticationException();
}
updateUserFromProfile(connection, user);
return new AuthenticatedUserToken(user.getUuid().toString(), user.addSessionToken().getToken());
return new AuthenticatedUserToken(user.getUuid().toString(), createAuthorizationToken(user).getToken());
}

/**
Expand Down Expand Up @@ -190,19 +196,12 @@ public ExternalUser saveUser(String userId, UpdateUserRequest request) {
return new ExternalUser(user);
}

@Transactional
public Integer deleteExpiredSessions(int timeSinceLastUpdatedInMinutes) {
DateTime date = new DateTime();
date = date.minusMinutes(timeSinceLastUpdatedInMinutes);
List<User> expiredUserSessions = userRepository.findByExpiredSession(date.toDate());
int count = expiredUserSessions.size();
for(User user : expiredUserSessions) {
user.removeExpiredSessions(date.toDate());
}
if(count > 0) {
userRepository.save(expiredUserSessions);
}
return count;
@Override
public AuthorizationToken createAuthorizationToken(User user) {
if(user.getAuthorizationToken() == null || user.getAuthorizationToken().hasExpired()) {
user.setAuthorizationToken(new AuthorizationToken(user, applicationConfig.getAuthorizationExpiryTimeInSeconds()));
}
return user.getAuthorizationToken();
}

private User createNewUser(CreateUserRequest request, Role role) {
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/porterhead/rest/user/api/ExternalUser.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.porterhead.rest.user.api;

import com.porterhead.rest.user.domain.SessionToken;
import com.porterhead.rest.user.domain.AuthorizationToken;
import com.porterhead.rest.user.domain.SocialUser;
import com.porterhead.rest.user.domain.User;
import org.codehaus.jackson.annotate.JsonIgnore;
Expand Down Expand Up @@ -64,7 +64,7 @@ public ExternalUser(User user) {
role = user.getRole().toString();
}

public ExternalUser(User user, SessionToken activeSession) {
public ExternalUser(User user, AuthorizationToken activeSession) {
this(user);
}

Expand Down
Loading

0 comments on commit e0920d5

Please sign in to comment.