org.eclipse.team.internal.ccvs.ui.WorkbenchUserAuthenticator.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.team.internal.ccvs.ui.WorkbenchUserAuthenticator.java

Source

/*******************************************************************************
 * Copyright (c) 2000, 2007 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Atsuhiko Yamanaka, JCraft,Inc. - implementation of promptForKeyboradInteractive
 *******************************************************************************/
package org.eclipse.team.internal.ccvs.ui;

import java.util.Map;

import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.jface.dialogs.*;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.team.core.*;
import org.eclipse.team.internal.ccvs.core.*;

/**
 * An authenticator that prompts the user for authentication info,
 * and stores the results in the Platform's authentication key-ring.
 */
public class WorkbenchUserAuthenticator implements IUserAuthenticator {
    public static boolean USE_ALTERNATE_PROMPTER = false;

    /**
     * WorkbenchUserAuthenticator constructor.
     */
    public WorkbenchUserAuthenticator() {
        super();
        // Initialize USE_ALTERNATE_PROMPTER
        IIgnoreInfo[] ignores = Team.getAllIgnores();
        boolean found = false;
        for (int i = 0; i < ignores.length; i++) {
            if (ignores[i].getPattern().equals("*.notes")) { //$NON-NLS-1$
                found = true;
            }
        }
        if (!found)
            return;
        IStringMapping[] mappings = Team.getFileContentManager().getExtensionMappings();
        for (int i = 0; i < mappings.length; i++) {
            if (mappings[i].getString().equals("notes")) { //$NON-NLS-1$
                USE_ALTERNATE_PROMPTER = true;
                return;
            }
        }
        USE_ALTERNATE_PROMPTER = false;
    }

    /**
     * @see IUserAuthenticator#authenticateUser
     */
    public void promptForUserInfo(final ICVSRepositoryLocation location, final IUserInfo userinfo,
            final String message) throws CVSException {
        if (!userinfo.isUsernameMutable() && USE_ALTERNATE_PROMPTER) {
            alternatePromptForUserInfo(userinfo);
            return;
        }
        // ask the user for a password
        final String[] result = new String[2];
        Display display = Display.getCurrent();
        final boolean allowCaching[] = { false };
        if (display != null) {
            allowCaching[0] = promptForPassword(location, userinfo.getUsername(), message,
                    userinfo.isUsernameMutable(), result);
        } else {
            // sync exec in default thread
            final CVSException[] exception = new CVSException[] { null };
            Display.getDefault().syncExec(new Runnable() {
                public void run() {
                    try {
                        allowCaching[0] = promptForPassword(location, userinfo.getUsername(), message,
                                userinfo.isUsernameMutable(), result);
                    } catch (CVSException e) {
                        exception[0] = e;
                    }
                }
            });
            if (exception[0] != null) {
                throw exception[0];
            }
        }

        if (result[0] == null) {
            throw new OperationCanceledException(CVSUIMessages.WorkbenchUserAuthenticator_cancelled);
        }

        if (userinfo.isUsernameMutable()) {
            userinfo.setUsername(result[0]);

        }
        userinfo.setPassword(result[1]);

        if (location != null) {
            if (userinfo.isUsernameMutable()) {
                location.setUsername(result[0]);
            }
            location.setPassword(result[1]);
            location.setAllowCaching(allowCaching[0]);
        }
    }

    /**
     * Asks the user to enter a password. Places the
     * results in the supplied string[].  result[0] must
     * contain the username, result[1] must contain the password.
     * If the user canceled, both values must be zero.
     * 
     * @param location  the location to obtain the password for
     * @param username  the username
     * @param message  a message to display to the user
     * @param userMutable  whether the user can be changed in the dialog
     * @param result  a String array of length two in which to put the result
     * @throws CVSException 
     */
    private boolean promptForPassword(final ICVSRepositoryLocation location, final String username,
            final String message, final boolean userMutable, final String[] result) throws CVSException {
        String domain = location == null ? null : location.getLocation(true);
        boolean cachingCheckbox = true;

        if (location != null && location.getMethod().getName().equals("pserverssh2")) { //$NON-NLS-1$
            /**
             * If this method 'promptForPassword' is invoked for ssh2 connection,
             * we want to disable the checkbox for password caching, because it will
             * overwrite the password for pserver with the password for ssh2.
             * 
             * In pserverssh2 connection type, its location name will be like
             *    pserverssh2:pserver_username@ssh2_username@ssh2_host@pserver_host
             *    
             * The problem is that there is not a method to know if we are invoked from ssh2 or pserver.
             * The following code will guess that if 'username' is equals to 'ssh2_userver' we are from ssh2,
             * but if 'pserver2_username' is equals to 'ssh2_username', this guess will not be correct.
             */
            String host = location.getHost(); // ssh2_username@ssh2_host@pserver_host
            int index = host.indexOf("@"); //$NON-NLS-1$
            if (index != -1) {
                cachingCheckbox = false;
                if (index != 0) {
                    if (!username.equals(host.substring(0, index))) {
                        cachingCheckbox = true;
                    }
                }
            }
        }

        UserValidationDialog dialog = new UserValidationDialog(null, domain, (username == null) ? "" : username, //$NON-NLS-1$
                message, cachingCheckbox);
        dialog.setUsernameMutable(userMutable);
        dialog.open();
        result[0] = dialog.getUsername();
        result[1] = dialog.getPassword();
        return dialog.getAllowCaching();
    }

    /**
     * Asks the user to enter values. 
     * 
     * @param location  the location to obtain the password for
     * @param destication the location
     * @param name the name
     * @param instruction the instruction
     * @param prompt the titles for text fields
     * @param echo '*' should be used or not
     * @param result the entered values, or null if user canceled.
     */
    public String[] promptForKeyboradInteractive(final ICVSRepositoryLocation location, final String destination,
            final String name, final String instruction, final String[] prompt, final boolean[] echo)
            throws CVSException {
        final String[][] result = new String[1][];
        final boolean[] allowCaching = new boolean[1];
        Display display = Display.getCurrent();
        if (display != null) {
            result[0] = _promptForUserInteractive(location, destination, name, instruction, prompt, echo,
                    allowCaching);
        } else {
            // sync exec in default thread
            Display.getDefault().syncExec(new Runnable() {
                public void run() {
                    result[0] = _promptForUserInteractive(location, destination, name, instruction, prompt, echo,
                            allowCaching);
                }
            });
        }
        if (result[0] != null && location != null && KeyboardInteractiveDialog.isPasswordAuth(prompt)) {
            location.setPassword(result[0][0]);
            location.setAllowCaching(allowCaching[0]);
        }
        return result[0];
    }

    private String[] _promptForUserInteractive(final ICVSRepositoryLocation location, final String destination,
            final String name, final String instruction, final String[] prompt, final boolean[] echo,
            final boolean[] allowCaching) {

        String domain = location == null ? null : location.getLocation(true);
        String userName = location == null ? null : location.getUsername();
        boolean cachingCheckbox = true;

        if (location != null && location.getMethod().getName().equals("pserverssh2")) { //$NON-NLS-1$
            /**
             * We want to disable the checkbox for password caching, because it will
             * overwrite the password for pserver with the password for ssh2.
             * 
             * In pserverssh2 connection type, its location name will be like
             *    pserverssh2:pserver_username@ssh2_username@ssh2_host@pserver_host
             * 
             * 'userName' is 'pserver_username', so we also have to change it to 'ssh2_username'.
             */
            String host = location.getHost(); // ssh2_username@ssh2_host@pserver_host
            int index = host.indexOf("@"); //$NON-NLS-1$
            if (index != -1) {
                if (index != 0) {
                    userName = host.substring(0, index);
                }
                cachingCheckbox = false;
            }
        }

        KeyboardInteractiveDialog dialog = new KeyboardInteractiveDialog(null, domain, destination, name, userName,
                instruction, prompt, echo, cachingCheckbox);
        dialog.open();
        String[] _result = dialog.getResult();
        if (_result != null)
            allowCaching[0] = dialog.getAllowCaching();
        return _result;
    }

    /**
     * Special alternate prompting. Returns the password. Username must be fixed.
     */
    private String alternatePromptForPassword(final String username) {
        AlternateUserValidationDialog dialog = new AlternateUserValidationDialog(null,
                (username == null) ? "" : username); //$NON-NLS-1$
        dialog.setUsername(username);
        int result = dialog.open();
        if (result == Window.CANCEL)
            return null;
        return dialog.getPassword();
    }

    /**
     * Special alternate prompting.
     */
    public void alternatePromptForUserInfo(final IUserInfo userinfo) {
        // ask the user for a password
        final String[] result = new String[1];
        Display display = Display.getCurrent();
        if (display != null) {
            result[0] = alternatePromptForPassword(userinfo.getUsername());
        } else {
            // sync exec in default thread
            Display.getDefault().syncExec(new Runnable() {
                public void run() {
                    result[0] = alternatePromptForPassword(userinfo.getUsername());
                }
            });
        }

        if (result[0] == null) {
            throw new OperationCanceledException(
                    CVSUIMessages.WorkbenchUserAuthenticator_The_operation_was_canceled_by_the_user_1);
        }

        userinfo.setPassword(result[0]);
    }

    /* (non-Javadoc)
     * @see org.eclipse.team.internal.ccvs.core.IUserAuthenticator#prompt(org.eclipse.team.internal.ccvs.core.ICVSRepositoryLocation, int, java.lang.String, java.lang.String, int[], int)
     */
    public int prompt(final ICVSRepositoryLocation location, final int promptType, final String title,
            final String message, final int[] promptResponses, final int defaultResponse) {
        final Display display = CVSUIPlugin.getStandardDisplay();
        final int[] retval = new int[1];
        final String[] buttons = new String[promptResponses.length];
        for (int i = 0; i < promptResponses.length; i++) {
            int prompt = promptResponses[i];
            switch (prompt) {
            case IUserAuthenticator.OK_ID:
                buttons[i] = IDialogConstants.OK_LABEL;
                break;
            case IUserAuthenticator.CANCEL_ID:
                buttons[i] = IDialogConstants.CANCEL_LABEL;
                break;
            case IUserAuthenticator.NO_ID:
                buttons[i] = IDialogConstants.NO_LABEL;
                break;
            case IUserAuthenticator.YES_ID:
                buttons[i] = IDialogConstants.YES_LABEL;
                break;
            }
        }

        display.syncExec(new Runnable() {
            public void run() {
                final MessageDialog dialog = new MessageDialog(new Shell(display), title, null /* title image */,
                        NLS.bind(CVSUIMessages.WorkbenchUserAuthenticator_0, message, location.getLocation(true)),
                        promptType, buttons, 1);
                retval[0] = dialog.open();
            }
        });
        return retval[0];
    }

    public boolean promptForHostKeyChange(final ICVSRepositoryLocation location) {
        final boolean[] openConfirm = new boolean[] { false };
        final Display display = CVSUIPlugin.getStandardDisplay();
        display.syncExec(new Runnable() {
            public void run() {
                openConfirm[0] = MessageDialog.openConfirm(null, CVSUIMessages.WorkbenchUserAuthenticator_1,
                        NLS.bind(CVSUIMessages.WorkbenchUserAuthenticator_2, new String[] { location.getHost() })); // 
            }
        });
        if (!openConfirm[0]) {
            throw new OperationCanceledException();
        }
        return openConfirm[0];
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.team.internal.ccvs.core.IUserAuthenticator#promptToConfigureRepositoryLocations(java.util.Map)
     */
    public Map promptToConfigureRepositoryLocations(final Map alternativeMap) {
        final Map[] result = new Map[1];
        Display display = Display.getCurrent();
        if (display != null) {
            result[0] = openAlternativeRepositoryDialog(alternativeMap);
        } else {
            // sync exec in default thread
            Display.getDefault().syncExec(new Runnable() {
                public void run() {
                    result[0] = openAlternativeRepositoryDialog(alternativeMap);
                }
            });
        }
        return result[0];
    }

    /**
     * Opens the Alternative Repository Selection dialog.
     * 
     * @param alternativeMap
     * @return a map with selected repositories to use or <code>null</code>
     *         when canceled.
     */
    private Map openAlternativeRepositoryDialog(Map alternativeMap) {
        ConfigureRepositoryLocationsDialog dialog = new ConfigureRepositoryLocationsDialog(null, alternativeMap);
        int result = dialog.open();
        return result == IDialogConstants.CANCEL_ID ? null : dialog.getSelected();
    }
}