package org.slc.sli.api.security;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.GenericFilterBean;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * A security filter responsible for checking SLI session
 *
 * @author dkornishev
 */
@Component
public class SliRequestFilter extends GenericFilterBean {

    private static final Logger LOG = LoggerFactory.getLogger(SliRequestFilter.class);
    private static final String PARAM_SESSION = "sessionId";
    private static final String HEADER_SESSION_NAME = "sessionId";

    @Resource(name = "openamRestTokenResolver")
    private SecurityTokenResolver resolver;

    @Value("${sli.security.noSession.landing.url}")
    private String realmSelectionUrl;

    /**
     * Intercepter method called by spring
     * Checks cookies to see if SLI session id exists
     * If session does exist, resolution will be attempted
     */
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        String sessionId = getSessionIdFromRequest((HttpServletRequest) request);
        
        if (sessionId != null) {
            SecurityContextHolder.getContext().setAuthentication(resolver.resolve(sessionId));
        }
        else {
            LOG.warn("Unauthorized access");
            if (!(((HttpServletRequest) request).getRequestURL().toString().contains("system/session/check"))) {

                ((HttpServletResponse)response).setStatus(HttpServletResponse.SC_UNAUTHORIZED);

                ((HttpServletResponse)response).setHeader("WWW-Authenticate", this.realmSelectionUrl);
                return;
            }

        }

        chain.doFilter(request, response);
    }

    private String getSessionIdFromRequest(HttpServletRequest req) {

        String sessionId = "";

        if (requestContainsSessionParam(req)) {
            sessionId = req.getParameter(PARAM_SESSION);
        } else {
            sessionId = req.getHeader(HEADER_SESSION_NAME);
        }

        return sessionId;
    }

    private boolean requestContainsSessionParam(HttpServletRequest req) {
        return req.getParameter(PARAM_SESSION) != null;
    }

    public void setResolver(SecurityTokenResolver resolver) {
        this.resolver = resolver;
    }
}

@@ -691,17 +691,18 @@
 ssion%0A *
+ 
 %0A
-
  * @auth
@@ -784,24 +784,28 @@
 ilterBean %7B%0A
+    
 %0A    private
@@ -829,12 +829,30 @@
 ger 
+  
 LOG 
+                
 = Lo
@@ -930,16 +930,18 @@
  String 
+  
 PARAM_SE
@@ -946,16 +946,22 @@
 SESSION 
+      
 = %22sessi
@@ -999,16 +999,18 @@
  String 
+  
 HEADER_S
@@ -1036,16 +1036,20 @@
 ionId%22;%0A
+    
 %0A    @Re
@@ -1133,17 +1133,21 @@
 solver;%0A
+    
 %0A
-
     @Val
@@ -1209,16 +1209,31 @@
  String 
+               
 realmSel
@@ -1243,16 +1243,20 @@
 ionUrl;%0A
+    
 %0A    /**
@@ -1567,17 +1567,25 @@
 ption %7B%0A
+        
 %0A
-
         
@@ -1696,16 +1696,41 @@
  != null
+ && !%22%22.equals(sessionId)
 ) %7B%0A    
@@ -1829,24 +1829,16 @@
        %7D
-%0A       
  else %7B%0A
@@ -1991,24 +1991,40 @@
 check%22))) %7B%0A
+                
 %0A           
@@ -2042,32 +2042,33 @@
 ServletResponse)
+ 
 response).setSta
@@ -2109,17 +2109,16 @@
 RIZED);%0A
-%0A
         
@@ -2147,16 +2147,17 @@
 esponse)
+ 
 response
@@ -2243,33 +2243,45 @@
 ;%0A            %7D%0A
+            
 %0A
-
         %7D%0A%0A     
@@ -2266,33 +2266,41 @@
      %0A        %7D%0A
+        
 %0A
-
         chain.do
@@ -2324,33 +2324,37 @@
 esponse);%0A    %7D%0A
+    
 %0A
-
     private Stri
@@ -2406,17 +2406,25 @@
  req) %7B%0A
+        
 %0A
-
         
@@ -2446,17 +2446,25 @@
 d = %22%22;%0A
+        
 %0A
-
         
@@ -2643,25 +2643,33 @@
 ;%0A        %7D%0A
+        
 %0A
-
         retu
@@ -2684,25 +2684,29 @@
 onId;%0A    %7D%0A
+    
 %0A
-
     private 
@@ -2829,16 +2829,20 @@
 ;%0A    %7D%0A
+    
 %0A    pub

fix for empty string as sessionId