/*
 * Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
 *
 * The contents of this file are subject to the CCM Public
 * License (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.redhat.com/licenses/ccmpl.html.
 *
 * Software distributed under the License is distributed on an
 * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
 * or implied. See the License for the specific language
 * governing rights and limitations under the License.
 *
 */
package com.arsdigita.kernel.security;

import java.util.Map;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.FailedLoginException;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
import org.apache.log4j.Logger;

/**
 * Supports login as an aribtrary user by checking whether a user ID has
 * been set for the Subject.  If so, <code>login</code> succeeds, so
 * <code>commit</code> is called on all login modules to log the user in.
 * If no user ID is set, <code>login</code> fails.  This module should
 * appear at the beginning of a login context with the "sufficient" control
 * flag.  Note that this module does not check the privileges of the current
 * user; this must be done by the code that runs the login context.
 *
 * @author Sameer Ajmani
 *
 * @see UserContext#login(com.arsdigita.kernel.User)
 **/
public class AdminLoginModule implements LoginModule {

    public static final String versionId = "$Id: //core-platform/dev/src/com/arsdigita/kernel/security/AdminLoginModule.java#9 $ by $Author: dennis $, $DateTime: 2004/04/07 16:07:11 $";
    private static final Logger s_log =
        Logger.getLogger(AdminLoginModule.class.getName());

    private Subject m_subject;

    public void initialize(Subject subject,
                           CallbackHandler handler,
                           Map shared,
                           Map options) {
        m_subject = subject;
        // TODO: support "debug" option
    }

    /**
     * Checks whether a user ID has been assigned to the Subject.
     *
     * @return <code>true</code>.
     *
     * @throws FailedLoginException if no user ID has been assigned.
     **/
    public boolean login() throws LoginException {
        if (m_subject.getPrincipals(PartyPrincipal.class).isEmpty()) {
            throw new FailedLoginException("no existing principal");
        }
        return true;
    }

    /**
     * Trivial implementation; does nothing.
     *
     * @return <code>true</code>.
     **/
    public boolean commit() throws LoginException {
        return true;
    }

    /**
     * Trivial implementation; does nothing.
     *
     * @return <code>true</code>.
     **/
    public boolean abort() throws LoginException {
        return true;
    }

    /**
     * Trivial implementation; does nothing.
     *
     * @return <code>true</code>.
     **/
    public boolean logout() throws LoginException {
        return true;
    }
}
