001/*
002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 *
009 * Contributors:
010 *     Nuxeo - initial API and implementation
011 *
012 * $Id$
013 */
014
015package org.nuxeo.runtime.api.login;
016
017import java.io.IOException;
018import java.security.Principal;
019import java.util.Map;
020
021import javax.security.auth.Subject;
022import javax.security.auth.callback.Callback;
023import javax.security.auth.callback.CallbackHandler;
024import javax.security.auth.callback.UnsupportedCallbackException;
025import javax.security.auth.login.LoginException;
026import javax.security.auth.spi.LoginModule;
027
028import org.apache.commons.logging.Log;
029import org.apache.commons.logging.LogFactory;
030import org.nuxeo.runtime.api.Framework;
031
032/**
033 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
034 */
035public class SystemLoginModule implements LoginModule {
036
037    private static final Log log = LogFactory.getLog(SystemLoginModule.class);
038
039    protected Subject subject;
040
041    protected CallbackHandler callbackHandler;
042
043    protected Map sharedState;
044
045    protected boolean trace;
046
047    @Override
048    public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) {
049        this.subject = subject;
050        this.sharedState = sharedState;
051        this.callbackHandler = callbackHandler;
052        trace = log.isTraceEnabled();
053    }
054
055    @Override
056    @SuppressWarnings("unchecked")
057    public boolean login() throws LoginException {
058        if (trace) {
059            log.trace("begin system login");
060        }
061        LoginService loginService = Framework.getLocalService(LoginService.class);
062        if (loginService == null) {
063            throw new LoginException("Nuxeo Login Service is not running - cannot do system login");
064        }
065        CredentialsCallback cb = new CredentialsCallback();
066        try {
067            callbackHandler.handle(new Callback[] { cb });
068        } catch (RuntimeException | IOException | UnsupportedCallbackException e) {
069            LoginException ee = new LoginException("System login failed - callback failed");
070            ee.initCause(e);
071            throw ee;
072        }
073        Object credential = cb.getCredentials();
074        if (LoginComponent.isSystemLogin(credential)) {
075            Principal principal = (Principal) credential;
076            sharedState.put("javax.security.auth.login.name", principal);
077            sharedState.put("javax.security.auth.login.password", null);
078            if (trace) {
079                log.trace("System Login Succeded");
080            }
081            return true;
082        }
083        if (trace) {
084            log.trace("System Login Failed");
085        }
086        return false;
087    }
088
089    @Override
090    public boolean commit() throws LoginException {
091        if (trace) {
092            log.trace("commit, subject=" + subject);
093        }
094        return true;
095    }
096
097    @Override
098    public boolean abort() throws LoginException {
099        if (trace) {
100            log.trace("abort, subject=" + subject);
101        }
102        return true;
103    }
104
105    @Override
106    public boolean logout() throws LoginException {
107        if (trace) {
108            log.trace("logout, subject=" + subject);
109        }
110        return true;
111    }
112
113}