GamigoAuthServiceImpl
package com.tgi.platform.account.service.impl;
import com.tgi.platform.account.dao.AccountHistoryDao;
import com.tgi.platform.account.domain.RegisteredUser;
import com.tgi.platform.account.dto.AuthenticatedUserResponse;
import com.tgi.platform.account.dto.ReserveUserResponse;
import com.tgi.platform.account.service.AuthService;
import com.tgi.platform.account.service.GamigoAuthService;
import com.tgi.platform.account.service.UserReservationService;
import com.tgi.platform.account.service.UserService;
import com.tgi.platform.account.service.impl.gamigoauth.GamigoAuthenticationExceptionWrapper;
import com.tgi.platform.account.service.impl.gamigoauth.GamigoAuthenticationResult;
import com.tgi.platform.account.service.impl.gamigoauth.TestAuthenticationServiceService;
import com.tgi.platform.dto.ErrorResponse;
import com.tgi.platform.dto.ResponseI;
import com.tgi.platform.exceptions.ExceptionCode;
import com.tgi.platform.exceptions.GeneralException;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.concurrent.*;
import static com.tgi.platform.PlatformConstants.FAILURE;
import static com.tgi.platform.PlatformConstants.SUCCESS;
import static com.tgi.platform.exceptions.ExceptionCode.*;
import static com.tgi.platform.messages.UserMessages.*;
public class GamigoAuthServiceImpl
implements AuthService {
private static Logger log = Logger.getLogger(GamigoAuthServiceImpl.class);
@Autowired
AccountHistoryDao accountHistoryDao;
@Autowired
UserService userService;
@Autowired
private UserReservationService userReservationService;
private final TestAuthenticationServiceService service = new TestAuthenticationServiceService();
private static final ThreadGroup group = new ThreadGroup(GamigoAuthServiceImpl.class.getName());
private static int threadCount = 0;
private final ExecutorService executorService = Executors.newFixedThreadPool(10, new ThreadFactory() {
public Thread newThread(Runnable r) {
return new Thread(group, r, group.getName() + " " + threadCount++);
}
});
public ResponseI authenticateUser(String ipAddr,
final String userName,
String password,
String gameSKU,
String getDisplayName) {
log.info("Executing service authenticateUser with params:" + " userName=" + userName + " password=**** gameSku=" + gameSKU);
if (StringUtils.isBlank(gameSKU)) {
return new ErrorResponse(Missing_Game_SKU, missing_GameSku);
}
if (StringUtils.isBlank(ipAddr)) {
return new ErrorResponse(Missing_Value, missing_IpAddr);
}
if (StringUtils.isBlank(userName)) {
return new ErrorResponse(Missing_Value, missing_UserName);
}
if (StringUtils.isBlank(password)) {
return new ErrorResponse(Missing_Value, missing_PWD);
}
String opResult;
String opDesc = "";
final String encodedPassword;
GamigoAuthenticationResult gamigoAuthResult;
ResponseI theResponse;
try {
encodedPassword = Hex.encodeHexString(MessageDigest.getInstance("SHA-256").digest(password.getBytes("UTF-8")));
Callable<GamigoAuthenticationResult> callable = new Callable<GamigoAuthenticationResult>() {
public GamigoAuthenticationResult call() throws Exception {
return service.getTestAuthenticationServicePort().authenticate(userName, encodedPassword);
}
};
Future<GamigoAuthenticationResult> authenticationResultFuture = executorService.submit(callable);
gamigoAuthResult = authenticationResultFuture.get(10, TimeUnit.SECONDS);// blocking call
// Handle codes
switch (gamigoAuthResult.getCode()) {
case SUCCESS:
opResult = SUCCESS;
theResponse = new AuthenticatedUserResponse();
((AuthenticatedUserResponse) theResponse).setUid(gamigoAuthResult.getGameAccountId());
if (getDisplayName != null && getDisplayName.equalsIgnoreCase("yes")) {
((AuthenticatedUserResponse) theResponse).setDisplayName(gamigoAuthResult.getUsername());
}
// theResponse.setTgt(gamigoAuthResult.get); Don't have anything from Gamigo for this at the moment.
// Create a user in LDAP
ResponseI reservationResponse = userService.reserveUser(userName,
GamigoAuthService.GAMIGO_PWD_PLACEHOLDER,
GamigoAuthService.GAMIGO_DATE_PLACEHOLDER,
userName + GamigoAuthService.GAMIGO_EMAILDOMAIN_PLACEHOLDER,
ipAddr,
"",
"",
gameSKU,
userName);
if (reservationResponse instanceof ReserveUserResponse) { // Success case
String reservationCode = ((ReserveUserResponse) reservationResponse).getReservationCode();
// Handle setting the UID on the account. This is a special case because Gamigo supplies the UID, whereas in other cases
// we create one ourselves.
RegisteredUser registeredUser;
synchronized (this) {
registeredUser = userReservationService.getUserReservation(reservationCode);
}
if (registeredUser == null) {
throw new GeneralException(Reservation_Not_Found, "Unable to find reservation associated with " + reservationCode);
}
registeredUser.getTgiAccount().setUid(gamigoAuthResult.getGameAccountId());
// Now create the user with that reservationCode
userService.createUser(reservationCode);
}
else if (reservationResponse instanceof ErrorResponse) { // error case
// If an error occurs here, it's incidental to authentication. Log it, but otherwise, do nothing.
ErrorResponse errorResponse = (ErrorResponse) reservationResponse;
boolean duplicateAccount = errorResponse.getCode() == User_Name_Taken.getCode() ||
errorResponse.getCode() == Email_Taken.getCode() || errorResponse.getCode() == Display_Name_Taken.getCode();
if (duplicateAccount) {
log.error("LDAP account for " + userName + " already existed. Odd.");
}
if (errorResponse.getCode() == ExceptionCode.Reservation_Not_Found.getCode()) {
log.error("Failed to create LDAP account for " + userName + " : " + errorResponse.getErrorMessage());
}
}
break;
case UNKNOWN_USERNAME:
theResponse = new ErrorResponse(User_Not_Found, auth_deny_user_passwd);
opResult = FAILURE;
break;
case USER_BANNED:
theResponse = new ErrorResponse(User_Banned, auth_deny_ban);
opResult = FAILURE;
break;
case AUTHENTICATION_FAILED:
theResponse = new ErrorResponse(User_Pwd_Not_Found, auth_deny_user_passwd);
opResult = FAILURE;
break;
default:
theResponse = new ErrorResponse(External_Error, External_Error.getCode() + ": Unknown error code from Gamigo auth server: [" + gamigoAuthResult.getCode() + "]");
opResult = FAILURE;
break;
}
} catch (TimeoutException e) {
opDesc = "Timeout while authenticating with Gamigo.";
log.error(opDesc);
theResponse = new ErrorResponse(Operation_Timout, opDesc);
opResult = FAILURE;
} catch (NoSuchAlgorithmException e) {
opDesc = "Failure to encode password. This is a programming error and should not happen.";
log.error(opDesc);
theResponse = new ErrorResponse(Operation_Error, opDesc);
opResult = FAILURE;
} catch (UnsupportedEncodingException e) {
opDesc = "Failure to encode password. This is a programming error and should not happen.";
log.error(opDesc);
theResponse = new ErrorResponse(Operation_Error, opDesc);
opResult = FAILURE;
} catch (Exception e) {
if (e.getCause() instanceof GamigoAuthenticationExceptionWrapper) {
opDesc = "GamigoAuthenticationException: " + e.getMessage();
log.error(opDesc);
theResponse = new ErrorResponse(External_Error, opDesc);
opResult = FAILURE;
}
else {
opDesc = "Unknown failure while authenticating with Gamigo: " + e.getMessage();
log.error(opDesc);
theResponse = new ErrorResponse(External_Error, opDesc);
opResult = FAILURE;
}
}
accountHistoryDao.createAuthenticationRecord(ipAddr, userName, opResult, opDesc, gameSKU);
return theResponse;
}
}