package org.apache.struts.util;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

public class TokenProcessor {
  private static TokenProcessor instance = new TokenProcessor();
  
  public static TokenProcessor getInstance() {
    return instance;
  }
  
  public synchronized boolean isTokenValid(HttpServletRequest request) {
    return isTokenValid(request, false);
  }
  
  public synchronized boolean isTokenValid(HttpServletRequest request, boolean reset) {
    HttpSession session = request.getSession(false);
    if (session == null)
      return false; 
    String saved = (String)session.getAttribute("org.apache.struts.action.TOKEN");
    if (saved == null)
      return false; 
    if (reset)
      resetToken(request); 
    String token = request.getParameter("org.apache.struts.taglib.html.TOKEN");
    if (token == null)
      return false; 
    return saved.equals(token);
  }
  
  public synchronized void resetToken(HttpServletRequest request) {
    HttpSession session = request.getSession(false);
    if (session == null)
      return; 
    session.removeAttribute("org.apache.struts.action.TOKEN");
  }
  
  public synchronized void saveToken(HttpServletRequest request) {
    HttpSession session = request.getSession();
    String token = generateToken(request);
    if (token != null)
      session.setAttribute("org.apache.struts.action.TOKEN", token); 
  }
  
  public String generateToken(HttpServletRequest request) {
    HttpSession session = request.getSession();
    try {
      byte[] id = session.getId().getBytes();
      byte[] now = (new Long(System.currentTimeMillis())).toString().getBytes();
      MessageDigest md = MessageDigest.getInstance("MD5");
      md.update(id);
      md.update(now);
      return toHex(md.digest());
    } catch (IllegalStateException e) {
      return null;
    } catch (NoSuchAlgorithmException e) {
      return null;
    } 
  }
  
  public String toHex(byte[] buffer) {
    StringBuffer sb = new StringBuffer();
    String s = null;
    for (int i = 0; i < buffer.length; i++) {
      s = Integer.toHexString(buffer[i] & 0xFF);
      if (s.length() < 2)
        sb.append('0'); 
      sb.append(s);
    } 
    return sb.toString();
  }
}
