/**
 * Copyright 2005 JBoss Inc
 *
 * 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.drools.guvnor.server.files;



import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.security.auth.login.LoginException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.drools.util.codec.Base64;
import org.drools.guvnor.server.util.TestEnvironmentSessionHelper;
import org.drools.repository.RulesRepository;
import org.jboss.seam.Component;
import org.jboss.seam.security.Identity;
import org.jboss.seam.contexts.Contexts;

import java.io.IOException;
import java.util.Locale;

/**
 * This is a base servlet that all repo servlets inherit behaviour from. 
 * 
 * @author Michael Neale
 */
public class RepositoryServlet extends HttpServlet {

    private static final long  serialVersionUID = 510l;
    //    protected final FileManagerUtils uploadHelper = new FileManagerUtils();
    public static final Logger log              = LoggerFactory.getLogger( RepositoryServlet.class );

    //    protected RulesRepository getRepository() {
    //
    //        if ( Contexts.isApplicationContextActive() ) {
    //            return (RulesRepository) Component.getInstance( "repository" );
    //        } else {
    //            //MN: NOTE THIS IS MY HACKERY TO GET IT WORKING IN GWT HOSTED MODE.
    //            //THIS IS ALL THAT IS NEEDED FOR THE SERVLETS.
    //            log.debug( "WARNING: RUNNING IN NON SEAM MODE SINGLE USER MODE - ONLY FOR TESTING AND DEBUGGING !!!!!" );
    //
    //            try {
    //                return new RulesRepository( TestEnvironmentSessionHelper.getSession( false ) );
    //            } catch ( Exception e ) {
    //                throw new IllegalStateException( "Unable to launch debug mode..." );
    //            }
    //        }
    //    }   

    public FileManagerUtils getFileManager() {
        if ( Contexts.isApplicationContextActive() ) {
            return (FileManagerUtils) Component.getInstance( "fileManager" );
        } else {
            //MN: NOTE THIS IS MY HACKERY TO GET IT WORKING IN GWT HOSTED MODE.
            //THIS IS ALL THAT IS NEEDED FOR THE SERVLETS.
            log.debug( "WARNING: RUNNING IN NON SEAM MODE SINGLE USER MODE - ONLY FOR TESTING AND DEBUGGING !!!!!" );
            FileManagerUtils manager = new FileManagerUtils();
            try {
                manager.setRepository(new RulesRepository( TestEnvironmentSessionHelper.getSession( false ) ));
                return manager;
            } catch ( Exception e ) {
                throw new IllegalStateException();
            }
            
        }
    }


    /**
     * Here we perform the action in the appropriate security context.
     */
	void doAuthorizedAction(HttpServletRequest req, HttpServletResponse res, A action) throws IOException {
        String auth = req.getHeader("Authorization");

        if (!allowUser(auth)) {
          res.setHeader("WWW-Authenticate", "BASIC realm=\"users\"");
          res.sendError(HttpServletResponse.SC_UNAUTHORIZED);
        }
        else {
        	try {
        		action.a();
        	} catch (RuntimeException e) {
        		log.error(e.getMessage(), e);
        		throw e;
        	} catch (Exception e) {
                log.error(e.getMessage(), e);
                throw new RuntimeException(e);
            }
        }
	}


    /**
     * Check the users credentials.
     * This takes the Authorization string from the HTTP request header (the whole lot).
     * uses Seam Identity component to set the user up.
     */
    public static boolean allowUser(String auth) {
        String usr = null;
        String pwd = null;

        if ( Contexts.isApplicationContextActive() ) {
        	//If the request is from same session, the user should be logged already.
        	if (Identity.instance().isLoggedIn()) {
        		return true;
        	}
        	
            Identity ids = Identity.instance();
            if(auth != null && auth.toUpperCase(Locale.ENGLISH).startsWith("BASIC ")) {
                String[] a = unpack(auth);
                usr = a[0];
                pwd = a[1];
                ids.getCredentials().setUsername(usr);
                ids.getCredentials().setPassword(pwd);
            }
            try {
                ids.authenticate();
                log.info(usr + " authenticated for rest api");
               
                return true;
            } catch (LoginException e) {
                log.warn("Unable to authenticate for rest api: " + usr);
                return false;
            }
        } else {
            //MN: NOTE THIS IS MY HACKERY TO GET IT WORKING IN GWT HOSTED MODE.
            String[] a = unpack(auth);
            usr = a[0];
            pwd = a[1];
      	
            return usr.equals("test") && pwd.equals("password");
        }

    }

    /**
     * For closures. Damn you java when will you catch up with the 70s.
     */
    static interface A {
        public void a() throws Exception;
    }


    static String[] unpack(String auth) {

        // Get encoded user and password, comes after "BASIC "
        String userpassEncoded = auth.substring(6);
        String userpassDecoded = new String(Base64.decodeBase64(userpassEncoded.getBytes()));

        String[] a = userpassDecoded.split(":");
        a[0] = a[0].trim();
        a[1] = a[1].trim();
		return a;
	}
}

@@ -5924,18 +5924,57 @@
     
+for(int i=0;i%3Ca.length;i++) %7B%0A        %09
 a%5B
-0
+i
 %5D = a%5B
-0
+i
 %5D.tr
@@ -5991,39 +5991,263 @@
     
-a%5B1%5D = a%5B1%5D.trim();%0A%09%09return a;
+%09%0A        %7D%0A        if (a.length == 2) %7B%0A%09%09    return a;%0A        %7D else if (a.length == 1) %7B%0A        %09//pwd is empty%0A        %09String%5B%5D b = new String%5B%5D%7Ba%5B0%5D, %22%22%7D;%0A        %09return b;        %09%0A        %7D else %7B%0A        %09return new String%5B%5D%7B%22%22, %22%22%7D;%0A        %7D
 %0A%09%7D%0A

fix BASIC authorization problem