/*
 * Copyright 2008-2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.broadleafcommerce.openadmin.server.service;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.broadleafcommerce.openadmin.client.service.ServiceException;
import org.broadleafcommerce.openadmin.server.service.exception.XSRFException;
import org.owasp.validator.html.AntiSamy;
import org.owasp.validator.html.Policy;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;

import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;

/**
 * @author jfischer
 */
@Service("blExploitProtectionService")
public class ExploitProtectionServiceImpl implements ExploitProtectionService {

    private static final Log LOG = LogFactory.getLog(ExploitProtectionServiceImpl.class);

    private static class Handler extends URLStreamHandler {
        /** The classloader to find resources from. */
        private final ClassLoader classLoader;

        public Handler() {
            classLoader = getClass().getClassLoader();
        }

        public Handler(ClassLoader classLoader) {
            this.classLoader = classLoader;
        }

        @Override
        protected URLConnection openConnection(URL u) throws IOException {
            URL resourceUrl = classLoader.getResource(u.getPath());
            return resourceUrl.openConnection();
        }
    }

    private static Policy getAntiSamyPolicy(String policyFileLocation) {
        try {
            URL url = new URL(null, policyFileLocation, new Handler(ExploitProtectionServiceImpl.class.getClassLoader()));
            return Policy.getInstance(url);
        } catch (Exception e) {
            throw new RuntimeException("Unable to create URL", e);
        }
    }

    private static final String DEFAULTANTISAMYPOLICYFILELOCATION = "classpath:antisamy-tinymce-1.4.4.xml";

    protected String antiSamyPolicyFileLocation = DEFAULTANTISAMYPOLICYFILELOCATION;
    //this is thread safe
    private Policy antiSamyPolicy = getAntiSamyPolicy(antiSamyPolicyFileLocation);
    //this is thread safe for the usage of scan()
    private AntiSamy as = new AntiSamy();

    /**
     * Detect and remove possible XSS threats from the passed in string. This
     * includes {@code <script>} tags, and the like.
     *
     * @param string The possibly dirty string
     * @return The cleansed version of the string
     * @throws ServiceException
     */
    @Override
    public String cleanString(String string) throws ServiceException {
        if (StringUtils.isEmpty(string)) {
            return string;
        }
        try {
            //TODO antisamy is currently removing img tags, which we don't want
            //figure out what's going wrong an re-enable

            //CleanResults results = as.scan(string, antiSamyPolicy);
            //return results.getCleanHTML();
            return string;
        } catch (Exception e) {
            LOG.error("Unable to clean the passed in entity values", e);
            throw new ServiceException("Unable to clean the passed in entity values", e);
        }
    }

    /**
     * Detect possible XSRF attacks by comparing the session token included
     * in the request against the true session for this user. If they are
     * different, then the exception is thrown.
     *
     * @param passedToken The session id token that was passed in the request
     * @throws XSRFException
     */
    @Override
    public void compareSessionToken(String passedToken) throws XSRFException {
        String mySessionId = RequestContextHolder.currentRequestAttributes().getSessionId();
        if (!mySessionId.equals(passedToken)) {
            throw new XSRFException("Session ID mismatch. Possible XSRF attack.");
        }
    }

    @Override
    public String getAntiSamyPolicyFileLocation() {
        return antiSamyPolicyFileLocation;
    }

    @Override
    public void setAntiSamyPolicyFileLocation(String antiSamyPolicyFileLocation) {
        this.antiSamyPolicyFileLocation = antiSamyPolicyFileLocation;
        antiSamyPolicy = getAntiSamyPolicy(antiSamyPolicyFileLocation);
    }
}

@@ -2859,24 +2859,128 @@
 amy();%0A%0A
+    protected boolean xsrfProtectionEnabled = true;%0A    protected boolean xssProtectionEnabled = true;%0A%0A
     /**%0A
      * D
@@ -2963,32 +2963,32 @@
  true;%0A%0A    /**%0A
-
      * Detect an
@@ -3343,16 +3343,41 @@
     if (
+!xssProtectionEnabled %7C%7C 
 StringUt
@@ -4355,32 +4355,73 @@
 XSRFException %7B%0A
+        if (xsrfProtectionEnabled) %7B%0A    
         String m
@@ -4501,24 +4501,28 @@
 ();%0A        
+    
 if (!mySessi
@@ -4553,32 +4553,36 @@
 ) %7B%0A            
+   
+ 
 throw new XSRFEx
@@ -4636,16 +4636,30 @@
 ack.%22);%0A
+            %7D%0A
         
@@ -4946,24 +4946,24 @@
 leLocation;%0A
-
         anti
@@ -5027,11 +5027,471 @@
 );%0A    %7D
+%0A%0A    public boolean isXsrfProtectionEnabled() %7B%0A        return xsrfProtectionEnabled;%0A    %7D%0A%0A    public void setXsrfProtectionEnabled(boolean xsrfProtectionEnabled) %7B%0A        this.xsrfProtectionEnabled = xsrfProtectionEnabled;%0A    %7D%0A%0A    public boolean isXssProtectionEnabled() %7B%0A        return xssProtectionEnabled;%0A    %7D%0A%0A    public void setXssProtectionEnabled(boolean xssProtectionEnabled) %7B%0A        this.xssProtectionEnabled = xssProtectionEnabled;%0A    %7D
 %0A%7D%0A

Add some config options for the exploit protection service