001/*
002 * Copyright (c) 2006-2012 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 javax.security.auth.callback.Callback;
018import javax.security.auth.callback.CallbackHandler;
019import javax.security.auth.callback.NameCallback;
020import javax.security.auth.callback.PasswordCallback;
021import javax.security.auth.callback.UnsupportedCallbackException;
022
023/**
024 * The default callback handler used by Framework.login methods.
025 * <p>
026 * This callback handler supports 3 types of callbacks:
027 * <ul>
028 * <li>the standard name callback
029 * <li>the standard password callback
030 * <li>a custom credentials callback that can be used to pass specific login information.
031 * </ul>
032 *
033 * @author eionica@nuxeo.com
034 */
035public class CredentialsCallbackHandler implements CallbackHandler {
036
037    private final String name;
038
039    private final Object credentials;
040
041    public CredentialsCallbackHandler(String username, Object credentials) {
042        this.name = username;
043        this.credentials = credentials;
044    }
045
046    @Override
047    public void handle(Callback[] callbacks) throws UnsupportedCallbackException {
048        for (Callback cb : callbacks) {
049            if (cb instanceof NameCallback) {
050                ((NameCallback) cb).setName(name);
051            } else if (cb instanceof PasswordCallback) {
052                if (credentials instanceof CharSequence) {
053                    // TODO cache the password to avoid recomputing it?
054                    ((PasswordCallback) cb).setPassword(credentials.toString().toCharArray());
055                } else if (credentials instanceof char[]) {
056                    ((PasswordCallback) cb).setPassword((char[]) credentials);
057                } else {
058                    // the credentials are not in a password format. use null
059                    ((PasswordCallback) cb).setPassword(null);
060                }
061            } else if (cb instanceof CredentialsCallback) {
062                // if neither name or password callback are given use the generic credentials callback
063                ((CredentialsCallback) cb).setCredentials(credentials);
064            } else {
065                throw new UnsupportedCallbackException(cb, "Unsupported callback " + cb + ". "
066                        + "Only NameCallback, PasswordCallback and CredentialsCallback are supported by this handler.");
067            }
068        }
069    }
070
071}