RestBean.java 3.03 KB
package fi.codecrew.moya.beans;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.LocalBean;
import javax.ejb.SessionContext;
import javax.ejb.Singleton;
import javax.ejb.Timeout;
import javax.ejb.Timer;
import javax.ejb.TimerService;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import fi.codecrew.moya.facade.ApiApplicationFacade;
import fi.codecrew.moya.facade.ApiApplicationInstanceFacade;
import fi.codecrew.moya.utilities.PasswordFunctions;

/**
 * Session Bean implementation class RestAuthBean
 */
@Singleton
@LocalBean
public class RestBean implements RestBeanLocal {

	/**
	 * Default constructor.
	 */
	public RestBean() {
		// TODO Auto-generated constructor stub
	}

	@Resource
	private TimerService ts;

	@Resource
	private SessionContext context;

	private static final Logger logger = LoggerFactory.getLogger(RestBean.class);

	@PostConstruct
	public void initialize() {
		ts.createTimer(60 * 1000, 60 * 1000, null);
	}

	@EJB
	private ApiApplicationFacade appfacade;
	@EJB
	private ApiApplicationInstanceFacade apiInstanceFacade;

	@Timeout
	public void timeoutNonces(Timer timer) {
		int count = 0;
		long now = System.currentTimeMillis();
		synchronized (userRestAuths) {
			for (Map<String, Long> ua : userRestAuths.values()) {
				for (Entry<String, Long> no : ua.entrySet()) {
					if (no != null && now > no.getValue()) {
						ua.remove(no.getKey());
						++count;
					}
				}
			}
		}
		logger.info("Timeouted {} nonces", count);

	}

	// Username -> Nonce -> expiration
	private Map<String, Map<String, Long>> userRestAuths = Collections.synchronizedMap(new HashMap<String, Map<String, Long>>());

	@Override
	public String getLoggedinUserRestNonce()
	{
		String username = context.getCallerPrincipal().getName();
		if (username == null) {
			return null;
		}
		Map<String, Long> userAuthMap = userRestAuths.get(username);
		if (userAuthMap == null) {
			synchronized (userRestAuths) {
				if (!userRestAuths.containsKey(username)) {
					userAuthMap = Collections.synchronizedMap(new HashMap<String, Long>());
					userRestAuths.put(username, userAuthMap);
				}
			}
		}

		Random random = new Random();

		int charcount = 20 + random.nextInt(10);
		String nonce = null;

		do {
			nonce = PasswordFunctions.generateRandomString(charcount, PasswordFunctions.ALL_CHARS);
		} while (userAuthMap.containsKey(nonce));
		userAuthMap.put(nonce, System.currentTimeMillis() + 120 * 1000); // Timeout in 60 seconds.
		return nonce;
	}

	@Override
	public boolean validateUserNonce(String nonce) {
		String username = context.getCallerPrincipal().getName();
		boolean ret = false;

		// Validation is successfull if user exists, nonce exists and timeout has not passed. 
		if (username != null && userRestAuths.containsKey(username)) {
			Long time = userRestAuths.get(username).remove(nonce);
			ret = time != null && time > System.currentTimeMillis();
		}
		return ret;
	}

}