//
//  ========================================================================
//  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.security;

import java.util.Properties;

import javax.security.auth.Subject;

import org.eclipse.jetty.server.UserIdentity;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.security.B64Code;
import org.ietf.jgss.GSSContext;
import org.ietf.jgss.GSSCredential;
import org.ietf.jgss.GSSException;
import org.ietf.jgss.GSSManager;
import org.ietf.jgss.GSSName;
import org.ietf.jgss.Oid;

public class SpnegoLoginService extends AbstractLifeCycle implements LoginService
{
    private static final Logger LOG = Log.getLogger(SpnegoLoginService.class);

    protected IdentityService _identityService;// = new LdapIdentityService();
    protected String _name;
    private String _config;
    
    private String _targetName;

    public SpnegoLoginService()
    {
        
    }
    
    public SpnegoLoginService( String name )
    {
        setName(name);
    }
    
    public SpnegoLoginService( String name, String config )
    {
        setName(name);
        setConfig(config);
    }
    
    public String getName()
    {
        return _name;
    }

    public void setName(String name)
    {
        if (isRunning())
        {
            throw new IllegalStateException("Running");
        }
        
        _name = name;
    }
    
    public String getConfig()
    {
        return _config;
    }
    
    public void setConfig( String config )
    {
        if (isRunning())
        {
            throw new IllegalStateException("Running");
        }
        
        _config = config;
    }
    
    
    
    @Override
    protected void doStart() throws Exception
    {
        Properties properties = new Properties();
        Resource resource = Resource.newResource(_config);
        properties.load(resource.getInputStream());
        
        _targetName = properties.getProperty("targetName");
        
        LOG.debug("Target Name {}", _targetName);
        
        super.doStart();
    }

    /**
     * username will be null since the credentials will contain all the relevant info
     */
    public UserIdentity login(String username, Object credentials)
    {
        String encodedAuthToken = (String)credentials;
        
        byte[] authToken = B64Code.decode(encodedAuthToken);
        
        GSSManager manager = GSSManager.getInstance();
        try
        {
            Oid krb5Oid = new Oid("1.3.6.1.5.5.2"); // http://java.sun.com/javase/6/docs/technotes/guides/security/jgss/jgss-features.html
            GSSName gssName = manager.createName(_targetName,null);
            GSSCredential serverCreds = manager.createCredential(gssName,GSSCredential.INDEFINITE_LIFETIME,krb5Oid,GSSCredential.ACCEPT_ONLY);
            GSSContext gContext = manager.createContext(serverCreds);

            if (gContext == null)
            {
                LOG.debug("SpnegoUserRealm: failed to establish GSSContext");
            }
            else
            {
                while (!gContext.isEstablished())
                {
                    authToken = gContext.acceptSecContext(authToken,0,authToken.length);
                }
                if (gContext.isEstablished())
                {
                    String clientName = gContext.getSrcName().toString();
                    String role = clientName.substring(clientName.indexOf('@') + 1);
                    
                    LOG.debug("SpnegoUserRealm: established a security context");
                    LOG.debug("Client Principal is: " + gContext.getSrcName());
                    LOG.debug("Server Principal is: " + gContext.getTargName());
                    LOG.debug("Client Default Role: " + role);

                    SpnegoUserPrincipal user = new SpnegoUserPrincipal(clientName,authToken);

                    Subject subject = new Subject();
                    subject.getPrincipals().add(user);
                    
                    return _identityService.newUserIdentity(subject,user, new String[]{role});
                }
            }

        }
        catch (GSSException gsse)
        {
            LOG.warn(gsse);
        }

        return null;
    }

    public boolean validate(UserIdentity user)
    {
        return false;
    }

    public IdentityService getIdentityService()
    {
        return _identityService;
    }

    public void setIdentityService(IdentityService service)
    {
        _identityService = service;
    }

	public void logout(UserIdentity user) {
		// TODO Auto-generated method stub
		
	}

}
