<commit_before>package org.ohmage.request;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.json.JSONObject;
import org.ohmage.annotator.ErrorCodes;
import org.ohmage.cache.UserBin;
import org.ohmage.domain.User;
import org.ohmage.service.AuthenticationService;
import org.ohmage.service.ServiceException;
import org.ohmage.util.CookieUtils;
import org.ohmage.validator.UserValidators;
import org.ohmage.validator.ValidationException;

/**
 * A request that contains a User object and a client String that represents
 * how the requester is making this request.
 * 
 * @author <NAME>
 */
public abstract class UserRequest extends Request {
	private static final Logger LOGGER = Logger.getLogger(UserRequest.class);
	
	private static final long MILLIS_IN_A_SECOND = 1000;
	
	protected final User user;
	protected final String client;
	
	/**
	 * Builds a request that contains a user based on a username and password.
	 * 
	 * @param username The username of the requester.
	 * 
	 * @param password The password of the <PASSWORD>.
	 * 
	 * @param hashPassword Whether or not the user's password should be hashed 
	 * 					   before being used.
	 * 
	 * @param client The name of the client requester is using to make the
	 * 				 request.
	 */
	public UserRequest(String username, String password, boolean hashPassword, String client) {
		// This will either be reset as a new User object or the request will 
		// have failed.
		User tempUser = null;
		
		try {
			// Validate the username.
			String tempUsername = UserValidators.validateUsername(this, username);
			
			// Validate the password using a validator based on whether or not
			// the password needs to be hashed.
			String tempPassword;
			if(hashPassword) {
				tempPassword = UserValidators.validatePlaintextPassword(this, password);
			}
			else {
				tempPassword = UserValidators.validateHashedPassword(this, password);
			}
			
			// Create the new User object for this request.
			tempUser = new User(tempUsername, tempPassword, hashPassword);
		}
		// If there is a problem validating one of the parameters.
		catch(ValidationException e) {
			LOGGER.info("Error while validating one of the parameters.", e);
		}
		// If user creation failed, set the request as failed.
		catch(IllegalArgumentException e) {
			LOGGER.info("The User could not be created because the username and/or password were missing.");
			setFailed(ErrorCodes.AUTHENTICATION_FAILED, "Missing username and/or password.");
		}
		
		user = tempUser;
		this.client = client;
	}

	/**
	 * Builds a request that contains a user based on their user token.
	 * 
	 * @param token The requester's current authentication / session token.
	 * 
	 * @param client The name of the client the requester is using to make the
	 * 				 request.
	 */
	public UserRequest(String token, String client) {
		// This will either be reset as a new User object or the request will 
		// have failed.
		User tempUser = null;
		
		try {
			// Validate the user's token.
			String tempToken = UserValidators.validateToken(this, token);
			
			// Attempt to retrieve the user.
			if(tempToken != null) {
				tempUser = UserBin.getUser(tempToken);
			}
			
			// If the bin doesn't know about the user, set the request as 
			// failed.
			if(tempUser == null) {
				LOGGER.info("The user could not be created because the token was unknown.");
				setFailed(ErrorCodes.AUTHENTICATION_FAILED, "Unkown token.");
			}
		}
		catch(ValidationException e) {
			LOGGER.error("There was a problem validating the token.", e);
		}
		
		user = tempUser;
		this.client = client;
	}
	
	/**
	 * Build a request that contains first a username and password, but if that
	 * fails attempt to create them from a token. If both fail, then set the
	 * request as failed.
	 * 
	 * For a successful login, either the username and the password should be
	 * valid or the token should be valid.
	 * 
	 * @param username The username of the requester.
	 * 
	 * @param password The password of the requester.
	 * 
	 * @param hashPassword Whether or not the password should be hashed before
	 * 					   being used.
	 * 
	 * @param token The requester's authentication / session token.
	 * 
	 * @param client The name of the client the requester is using to make the
	 * 				 request.
	 */
	public UserRequest(String username, String password, boolean hashPassword, String token, String client) {
		// This will either be reset as a new User object or the request will 
		// have failed.
		User tempUser = null;
		
		try {
			// Validate the username.
			String tempUsername = UserValidators.validateUsername(this, username);
			
			// Validate the password using a validator based on whether or not
			// the password needs to be hashed.
			String tempPassword;
			if(hashPassword) {
				tempPassword = UserValidators.validatePlaintextPassword(this, password);
			}
			else {
				tempPassword = UserValidators.validateHashedPassword(this, password);
			}
			
			// Create the new User object for this request.
			tempUser = new User(tempUsername, tempPassword, hashPassword);
		}
		// If there is a problem validating one of the parameters.
		catch(ValidationException e) {
			LOGGER.info("Error while validating one of the parameters.", e);
		}
		// If user creation failed, try to lookup a user with the token.
		catch(IllegalArgumentException illegalArgumentException) {
			try {
				LOGGER.info("The username and/or password were missing. Attempting to validate the user with a token.");
				
				// Validate the user's token.
				String tempToken = UserValidators.validateToken(this, token);
				
				// Attempt to retrieve the user.
				tempUser = UserBin.getUser(tempToken);
				
				// If the bin doesn't know about the user, set the request as 
				// failed.
				if(tempUser == null) {
					LOGGER.info("The user could not be created because the token was unknown.");
					setFailed(ErrorCodes.AUTHENTICATION_FAILED, "Unkown token.");
				}
			}
			catch(ValidationException validationException) {
				LOGGER.error("There was a problem validating the token.", validationException);
			}
		}
		
		user = tempUser;
		this.client = client;
	}
	
	/**
	 * Returns the user in the request.
	 * 
	 * @return The user in the request.
	 */
	public final User getUser() {
		return user;
	}

	/**
	 * Authenticates the user in the request.
	 * 
	 * @param newAccountsAllowed Whether or not new accounts are allowed to
	 * 							 make this call.
	 */
	public final boolean authenticate(boolean newAccountsAllowed) {
		try {
			// Validate that the username and password are valid.
			LOGGER.info("Authenticating the user.");
			return AuthenticationService.authenticate(this, newAccountsAllowed);
		}
		catch(ServiceException e) {
			LOGGER.error("There is a bug in the system.", e);
			return false;
		}
	}
	<commit_msg>Added a function to retrieve the cookie even if it is a parameter not in the header.<commit_after>package org.ohmage.request;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.json.JSONObject;
import org.ohmage.annotator.ErrorCodes;
import org.ohmage.cache.UserBin;
import org.ohmage.domain.User;
import org.ohmage.service.AuthenticationService;
import org.ohmage.service.ServiceException;
import org.ohmage.util.CookieUtils;
import org.ohmage.validator.UserValidators;
import org.ohmage.validator.ValidationException;

/**
 * A request that contains a User object and a client String that represents
 * how the requester is making this request.
 * 
 * @author <NAME>
 */
public abstract class UserRequest extends Request {
	private static final Logger LOGGER = Logger.getLogger(UserRequest.class);
	
	private static final long MILLIS_IN_A_SECOND = 1000;
	
	protected final User user;
	protected final String client;
	
	/**
	 * Builds a request that contains a user based on a username and password.
	 * 
	 * @param username The username of the requester.
	 * 
	 * @param password The password of the requester.
	 * 
	 * @param hashPassword Whether or not the user's password should be hashed 
	 * 					   before being used.
	 * 
	 * @param client The name of the client requester is using to make the
	 * 				 request.
	 */
	public UserRequest(String username, String password, boolean hashPassword, String client) {
		// This will either be reset as a new User object or the request will 
		// have failed.
		User tempUser = null;
		
		try {
			// Validate the username.
			String tempUsername = UserValidators.validateUsername(this, username);
			
			// Validate the password using a validator based on whether or not
			// the password needs to be hashed.
			String tempPassword;
			if(hashPassword) {
				tempPassword = UserValidators.validatePlaintextPassword(this, password);
			}
			else {
				tempPassword = UserValidators.validateHashedPassword(this, password);
			}
			
			// Create the new User object for this request.
			tempUser = new User(tempUsername, tempPassword, hashPassword);
		}
		// If there is a problem validating one of the parameters.
		catch(ValidationException e) {
			LOGGER.info("Error while validating one of the parameters.", e);
		}
		// If user creation failed, set the request as failed.
		catch(IllegalArgumentException e) {
			LOGGER.info("The User could not be created because the username and/or password were missing.");
			setFailed(ErrorCodes.AUTHENTICATION_FAILED, "Missing username and/or password.");
		}
		
		user = tempUser;
		this.client = client;
	}

	/**
	 * Builds a request that contains a user based on their user token.
	 * 
	 * @param token The requester's current authentication / session token.
	 * 
	 * @param client The name of the client the requester is using to make the
	 * 				 request.
	 */
	public UserRequest(String token, String client) {
		// This will either be reset as a new User object or the request will 
		// have failed.
		User tempUser = null;
		
		try {
			// Validate the user's token.
			String tempToken = UserValidators.validateToken(this, token);
			
			// Attempt to retrieve the user.
			if(tempToken != null) {
				tempUser = UserBin.getUser(tempToken);
			}
			
			// If the bin doesn't know about the user, set the request as 
			// failed.
			if(tempUser == null) {
				LOGGER.info("The user could not be created because the token was unknown.");
				setFailed(ErrorCodes.AUTHENTICATION_FAILED, "Unkown token.");
			}
		}
		catch(ValidationException e) {
			LOGGER.error("There was a problem validating the token.", e);
		}
		
		user = tempUser;
		this.client = client;
	}
	
	/**
	 * Build a request that contains first a username and password, but if that
	 * fails attempt to create them from a token. If both fail, then set the
	 * request as failed.
	 * 
	 * For a successful login, either the username and the password should be
	 * valid or the token should be valid.
	 * 
	 * @param username The username of the requester.
	 * 
	 * @param password The password of the requester.
	 * 
	 * @param hashPassword Whether or not the password should be hashed before
	 * 					   being used.
	 * 
	 * @param token The requester's authentication / session token.
	 * 
	 * @param client The name of the client the requester is using to make the
	 * 				 request.
	 */
	public UserRequest(String username, String password, boolean hashPassword, String token, String client) {
		// This will either be reset as a new User object or the request will 
		// have failed.
		User tempUser = null;
		
		try {
			// Validate the username.
			String tempUsername = UserValidators.validateUsername(this, username);
			
			// Validate the password using a validator based on whether or not
			// the password needs to be hashed.
			String tempPassword;
			if(hashPassword) {
				tempPassword = UserValidators.validatePlaintextPassword(this, password);
			}
			else {
				tempPassword = UserValidators.validateHashedPassword(this, password);
			}
			
			// Create the new User object for this request.
			tempUser = new User(tempUsername, tempPassword, hashPassword);
		}
		// If there is a problem validating one of the parameters.
		catch(ValidationException e) {
			LOGGER.info("Error while validating one of the parameters.", e);
		}
		// If user creation failed, try to lookup a user with the token.
		catch(IllegalArgumentException illegalArgumentException) {
			try {
				LOGGER.info("The username and/or password were missing. Attempting to validate the user with a token.");
				
				// Validate the user's token.
				String tempToken = UserValidators.validateToken(this, token);
				
				// Attempt to retrieve the user.
				tempUser = UserBin.getUser(tempToken);
				
				// If the bin doesn't know about the user, set the request as 
				// failed.
				if(tempUser == null) {
					LOGGER.info("The user could not be created because the token was unknown.");
					setFailed(ErrorCodes.AUTHENTICATION_FAILED, "Unkown token.");
				}
			}
			catch(ValidationException validationException) {
				LOGGER.error("There was a problem validating the token.", validationException);
			}
		}
		
		user = tempUser;
		this.client = client;
	}
	
	/**
	 * Returns the user in the request.
	 * 
	 * @return The user in the request.
	 */
	public final User getUser() {
		return user;
	}
	
	/**
	 * Retrieves the authentication / session token from the request. It first
	 * attempts to retrieve it as a cookie and, if it doesn't exist there,
	 * attempts to retrieve it as a parameter. If it didn't exist there either,
	 * null is returned.
	 *  
	 * @param httpRequest The request that contains the cookie in either its
	 * 					  header or as a parameter.
	 * 
	 * @return The authentication / session token from this request or null if
	 * 		   no such cookie or parameter exists.
	 */
	public String getToken(HttpServletRequest httpRequest) {
		String token;
		
		token = CookieUtils.getCookieValue(httpRequest.getCookies(), InputKeys.AUTH_TOKEN);
		if(token == null) {
			token = httpRequest.getParameter(InputKeys.AUTH_TOKEN);
		}
		
		return token;
	}

	/**
	 * Authenticates the user in the request.
	 * 
	 * @param newAccountsAllowed Whether or not new accounts are allowed to
	 * 							 make this call.
	 */
	public final boolean authenticate(boolean newAccountsAllowed) {
		try {
			// Validate that the username and password are valid.
			LOGGER.info("Authenticating the user.");
			return AuthenticationService.authenticate(this, newAccountsAllowed);
		}
		catch(ServiceException e) {
			LOGGER.error("There is a bug in the system.", e);
			return false;
		}
	}
	
{'fraction_non_alphanumeric': 0.08147641831852358, 'fraction_numerical': 0.000683526999316473, 'mean_word_length': 3.2322823257159388, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3211005', 'n_tokens_mistral': 4674, 'n_tokens_neox': 3976, 'n_words': 1563}