package jp.troter.servlet.httpsession.spi.impl;

import jp.troter.servlet.httpsession.UserHttpSession;
import jp.troter.servlet.httpsession.UserHttpSessionHttpServletRequestWrapper;
import jp.troter.servlet.httpsession.spi.SessionValidator;

import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;

public class DefaultSessionValidator extends SessionValidator {

    protected static final String HTTPSESSION_REMOTE_ADDR
        = "jp.troter.servlet.httpsession.spi.impl.DefaultSessionValidator.REMOTE_ADDR";
    protected static final String HTTPSESSION_USER_AGENT
        = "jp.troter.servlet.httpsession.spi.impl.DefaultSessionValidator.USER_AGENT";

    protected String getMakerNameRemoteAddr() {
        return HTTPSESSION_REMOTE_ADDR;
    }

    protected String getMakerNameUserAgent() {
        return HTTPSESSION_USER_AGENT;
    }

    @Override
    public boolean isExistsMarker(UserHttpSession session) {
        return session.getAttribute(getMakerNameRemoteAddr()) != null
            || session.getAttribute(getMakerNameUserAgent()) != null;
    }

    @Override
    public void setupMarker(UserHttpSession session, UserHttpSessionHttpServletRequestWrapper request) {
        if (session.getAttribute(getMakerNameRemoteAddr()) == null) {
            session.setAttribute(getMakerNameRemoteAddr(),
                    ObjectUtils.toString(request.getRemoteAddr(), ""));
        }
        if (session.getAttribute(getMakerNameUserAgent()) == null) {
            session.setAttribute(getMakerNameUserAgent(),
                    ObjectUtils.toString(request.getHeader("User-Agent"), ""));
        }
    }

    @Override
    public boolean isValid(UserHttpSession session, UserHttpSessionHttpServletRequestWrapper request) {
        String requestRemoteAddr = ObjectUtils.toString(request.getRemoteAddr(), "");
        String requestUserAgent  = ObjectUtils.toString(request.getHeader("User-Agent"), "");
        String sessionRemoteAddr = ObjectUtils.toString(session.getAttribute(getMakerNameRemoteAddr()), "");
        String sessionUserAgent  = ObjectUtils.toString(session.getAttribute(getMakerNameUserAgent()), "");

        boolean hasPossibilityOfSessionHijack
            =  ! StringUtils.equals(sessionRemoteAddr, requestRemoteAddr)
            || ! StringUtils.equals(sessionUserAgent, requestUserAgent);
        if (hasPossibilityOfSessionHijack) {
            trace("Hijacked session.");
            trace("Request url is " + request.getRequestURI());
            trace("Session id is " + session.getId());
            trace("REQUEST: remote_addr[" + requestRemoteAddr + "] user_agent[" + requestUserAgent + "]");
            trace("SESSION: remote_addr[" + sessionRemoteAddr + "] user_agent[" + sessionUserAgent + "]");
        }

        return ! hasPossibilityOfSessionHijack;
    }

    public void trace(String message) {
        //TODO
    }
}

@@ -322,16 +322,73 @@
 ngUtils;
+%0Aimport org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;
 %0A%0Apublic
@@ -446,16 +446,105 @@
 ator %7B%0A%0A
+    private static Logger log = LoggerFactory.getLogger(DefaultSessionValidator.class);%0A%0A
     prot
@@ -2560,112 +2560,559 @@
     
+S
 tr
-ace(%22Hijacked session.%22);%0A            trace(%22Request url is %22 + request.getRequestURI());
+ing message = getHijackSessionMessage(%0A                    request.getRequestURI(), session.getId(),%0A                    requestRemoteAddr, requestUserAgent,%0A                    sessionRemoteAddr, sessionUserAgent);%0A            log.warn(message);%0A        %7D%0A%0A        return ! hasPossibilityOfSessionHijack;%0A    %7D%0A%0A    protected String getHijackSessionMessage(%0A            String requestUrl, String sessionId,%0A            String requestRemoteAddr, String requestUserAgent,%0A            String sessionRemoteAddr, String sessionUserAgent)
 %0A    
+%7B%0A
         
 trac
@@ -3111,133 +3111,406 @@
     
+S
 tr
-ace(%22Session id is %22 + session.getId());%0A            trace(%22REQUEST: remote_addr%5B%22 + requestRemoteAddr + %22%5D user_agent%5B%22 + 
+ingBuilder m = new StringBuilder();%0A        m.append(%22Session hijack occured!%22);%0A        m.append(%22%5B%22);%0A        m.append(%22request_url=%22).append(requestUrl);%0A        m.append(%22, %22);%0A        m.append(%22session_id=%22).append(sessionId);%0A        m.append(%22, %22);%0A        m.append(%22request_remote_addr=%22).append(requestRemoteAddr);%0A        m.append(%22, %22);%0A        m.append(%22request_user_agent=%22).append(
 requ
@@ -3513,38 +3513,32 @@
 requestUserAgent
- + %22%5D%22
 );%0A            t
@@ -3536,82 +3536,163 @@
     
-    trace(%22SESSION: remote_addr%5B%22 + sessionRemoteAddr + %22%5D user_agent%5B%22 + 
+m.append(%22, %22);%0A        m.append(%22session_remote_addr=%22).append(sessionRemoteAddr);%0A        m.append(%22, %22);%0A        m.append(%22session_user_agent=%22).append(
 sess
@@ -3707,14 +3707,8 @@
 gent
- + %22%5D%22
 );%0A 
@@ -3706,34 +3706,46 @@
 Agent);%0A        
-%7D%0A
+m.append(%22%5D%22);
 %0A        return 
@@ -3748,102 +3748,21 @@
 urn 
-! hasPossibilityOfSessionHijack;%0A    %7D%0A%0A    public void trace(String message) %7B%0A        //TODO
+m.toString();
 %0A   

add log