com.google.gerrit.client.auth.openid.OpenIdSignInDialog.java Source code

Java tutorial

Introduction

Here is the source code for com.google.gerrit.client.auth.openid.OpenIdSignInDialog.java

Source

// Copyright (C) 2009 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.gerrit.client.auth.openid;

import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.SignInDialog;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.ui.SmallHeading;
import com.google.gerrit.common.auth.SignInMode;
import com.google.gerrit.common.auth.openid.DiscoveryResult;
import com.google.gerrit.common.auth.openid.OpenIdProviderPattern;
import com.google.gerrit.common.auth.openid.OpenIdUrls;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.FormElement;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.FormPanel.SubmitEvent;
import com.google.gwt.user.client.ui.FormSubmitCompleteEvent;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Hidden;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.InlineLabel;
import com.google.gwtexpui.globalkey.client.NpTextBox;

import java.util.Map;

public class OpenIdSignInDialog extends SignInDialog implements FormPanel.SubmitHandler {
    static {
        OpenIdResources.I.css().ensureInjected();
    }

    private final FlowPanel panelWidget;
    private final FormPanel form;
    private final FlowPanel formBody;
    private final FormPanel redirectForm;
    private final FlowPanel redirectBody;

    private FlowPanel errorLine;
    private InlineLabel errorMsg;

    private Button login;
    private NpTextBox providerId;
    private CheckBox rememberId;
    private boolean discovering;

    public OpenIdSignInDialog(final SignInMode requestedMode, final String token, final String initialErrorMsg) {
        super(requestedMode, token);

        formBody = new FlowPanel();
        formBody.setStyleName(OpenIdResources.I.css().loginForm());

        form = new FormPanel();
        form.setMethod(FormPanel.METHOD_GET);
        form.addSubmitHandler(this);
        form.add(formBody);

        redirectBody = new FlowPanel();
        redirectBody.setVisible(false);
        redirectForm = new FormPanel();
        redirectForm.add(redirectBody);

        panelWidget = new FlowPanel();
        panelWidget.add(form);
        panelWidget.add(redirectForm);
        add(panelWidget);

        createHeaderLogo();
        createHeaderText();
        createErrorBox();
        createIdentBox();

        link(OpenIdUrls.URL_GOOGLE, OpenIdUtil.C.nameGoogle(), OpenIdResources.I.iconGoogle());
        link(OpenIdUrls.URL_YAHOO, OpenIdUtil.C.nameYahoo(), OpenIdResources.I.iconYahoo());

        if (initialErrorMsg != null) {
            showError(initialErrorMsg);
        }
        formBody.add(new HTML(OpenIdUtil.C.whatIsOpenIDHtml()));
    }

    @Override
    public void show() {
        super.show();
        providerId.selectAll();
        Scheduler.get().scheduleDeferred(new ScheduledCommand() {
            @Override
            public void execute() {
                providerId.setFocus(true);
            }
        });
    }

    private void createHeaderLogo() {
        final FlowPanel headerLogo = new FlowPanel();
        headerLogo.setStyleName(OpenIdResources.I.css().logo());
        headerLogo.add(new Image(OpenIdResources.I.openidLogo()));
        formBody.add(headerLogo);
    }

    private void createHeaderText() {
        final FlowPanel headerText = new FlowPanel();
        final String me = Window.Location.getHostName();
        final SmallHeading headerLabel = new SmallHeading();
        switch (mode) {
        case LINK_IDENTIY:
            headerLabel.setText(OpenIdUtil.M.linkAt(me));
            break;
        case REGISTER:
            headerLabel.setText(OpenIdUtil.M.registerAt(me));
            break;
        case SIGN_IN:
        default:
            headerLabel.setText(OpenIdUtil.M.signInAt(me));
            break;
        }
        headerText.add(headerLabel);
        formBody.add(headerText);
    }

    private void createErrorBox() {
        errorLine = new FlowPanel();
        DOM.setStyleAttribute(errorLine.getElement(), "visibility", "hidden");
        errorLine.setStyleName(OpenIdResources.I.css().error());

        errorMsg = new InlineLabel();
        errorLine.add(errorMsg);
        formBody.add(errorLine);
    }

    private void showError(final String msgText) {
        errorMsg.setText(msgText);
        DOM.setStyleAttribute(errorLine.getElement(), "visibility", "");
    }

    private void hideError() {
        DOM.setStyleAttribute(errorLine.getElement(), "visibility", "hidden");
    }

    private void createIdentBox() {
        boolean remember = mode == SignInMode.SIGN_IN || mode == SignInMode.REGISTER;

        final FlowPanel group = new FlowPanel();
        group.setStyleName(OpenIdResources.I.css().loginLine());

        final FlowPanel line1 = new FlowPanel();
        group.add(line1);

        providerId = new NpTextBox();
        providerId.setVisibleLength(60);
        providerId.setStyleName(OpenIdResources.I.css().identifier());
        providerId.setTabIndex(0);
        providerId.addKeyPressHandler(new KeyPressHandler() {
            @Override
            public void onKeyPress(final KeyPressEvent event) {
                if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) {
                    event.preventDefault();
                    form.submit();
                }
            }
        });
        line1.add(providerId);

        login = new Button();
        switch (mode) {
        case LINK_IDENTIY:
            login.setText(OpenIdUtil.C.buttonLinkId());
            break;
        case REGISTER:
            login.setText(OpenIdUtil.C.buttonRegister());
            break;
        case SIGN_IN:
        default:
            login.setText(OpenIdUtil.C.buttonSignIn());
            break;
        }
        login.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(final ClickEvent event) {
                form.submit();
            }
        });
        login.setTabIndex(remember ? 2 : 1);
        line1.add(login);

        Button close = new Button(Gerrit.C.signInDialogClose());
        close.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                hide();
            }
        });
        close.setTabIndex(remember ? 3 : 2);
        line1.add(close);

        if (remember) {
            rememberId = new CheckBox(OpenIdUtil.C.rememberMe());
            rememberId.setTabIndex(1);
            group.add(rememberId);

            String last = Cookies.getCookie(OpenIdUrls.LASTID_COOKIE);
            if (last != null && !"".equals(last)) {
                if (last.startsWith("\"") && last.endsWith("\"")) {
                    // Dequote the value. We shouldn't have to do this, but
                    // something is causing some Google Account tokens to get
                    // wrapped up in double quotes when obtained from the cookie.
                    //
                    last = last.substring(1, last.length() - 2);
                }
                providerId.setText(last);
                rememberId.setValue(true);
            }
        }

        formBody.add(group);
    }

    private void link(final String identUrl, final String who, final ImageResource icon) {
        if (!isAllowedProvider(identUrl)) {
            return;
        }

        final ClickHandler i = new ClickHandler() {
            @Override
            public void onClick(final ClickEvent event) {
                event.preventDefault();
                if (!discovering) {
                    providerId.setText(identUrl);
                    form.submit();
                }
            }
        };

        final FlowPanel line = new FlowPanel();
        line.addStyleName(OpenIdResources.I.css().directLink());

        final Image img = new Image(icon);
        img.addClickHandler(i);
        line.add(img);

        final Anchor text = new Anchor();
        switch (mode) {
        case LINK_IDENTIY:
            text.setText(OpenIdUtil.M.linkWith(who));
            break;
        case REGISTER:
            text.setText(OpenIdUtil.M.registerWith(who));
            break;
        case SIGN_IN:
        default:
            text.setText(OpenIdUtil.M.signInWith(who));
            break;
        }
        text.setHref(identUrl);
        text.addClickHandler(i);
        line.add(text);

        formBody.add(line);
    }

    private static boolean isAllowedProvider(final String identUrl) {
        for (OpenIdProviderPattern p : Gerrit.getConfig().getAllowedOpenIDs()) {
            if (p.matches(identUrl)) {
                return true;
            }
        }
        return false;
    }

    private void enable(final boolean on) {
        providerId.setEnabled(on);
        login.setEnabled(on);
    }

    private void onDiscovery(final DiscoveryResult result) {
        discovering = false;

        switch (result.status) {
        case VALID:
            // The provider won't support operation inside an IFRAME,
            // so we replace our entire application.
            //
            redirectForm.setMethod(FormPanel.METHOD_POST);
            redirectForm.setAction(result.providerUrl);
            redirectBody.clear();
            for (final Map.Entry<String, String> e : result.providerArgs.entrySet()) {
                redirectBody.add(new Hidden(e.getKey(), e.getValue()));
            }
            FormElement.as(redirectForm.getElement()).setTarget("_top");
            redirectForm.submit();
            break;

        case NOT_ALLOWED:
            showError(OpenIdUtil.C.notAllowed());
            enableRetryDiscovery();
            break;

        case NO_PROVIDER:
            showError(OpenIdUtil.C.noProvider());
            enableRetryDiscovery();
            break;

        case ERROR:
        default:
            showError(OpenIdUtil.C.error());
            enableRetryDiscovery();
            break;
        }
    }

    private void enableRetryDiscovery() {
        enable(true);
        providerId.selectAll();
        providerId.setFocus(true);
    }

    @Override
    public void onSubmit(final SubmitEvent event) {
        event.cancel();

        String openidIdentifier = providerId.getText();
        if (openidIdentifier == null || openidIdentifier.equals("")) {
            enable(true);
            return;
        }

        if (!openidIdentifier.startsWith("http://") && !openidIdentifier.startsWith("https://")) {
            openidIdentifier = "http://" + openidIdentifier;
        }

        if (!isAllowedProvider(openidIdentifier)) {
            showError(OpenIdUtil.C.notAllowed());
            enableRetryDiscovery();
            return;
        }

        discovering = true;
        enable(false);
        hideError();

        final boolean remember = rememberId != null && rememberId.getValue();
        OpenIdUtil.SVC.discover(openidIdentifier, mode, remember, token, new GerritCallback<DiscoveryResult>() {
            public void onSuccess(final DiscoveryResult result) {
                onDiscovery(result);
            }

            @Override
            public void onFailure(final Throwable caught) {
                super.onFailure(caught);
                enableRetryDiscovery();
            }
        });
    }

    public void onSubmitComplete(final FormSubmitCompleteEvent event) {
    }
}