GamigoAuthServiceImpl.java

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; } }