/******************************************************************************* *Copyright (c) 2009 Eucalyptus Systems, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, only version 3 of the License. * * * This file is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see <http://www.gnu.org/licenses/>. * * Please contact Eucalyptus Systems, Inc., 130 Castilian * Dr., Goleta, CA 93101 USA or visit <http://www.eucalyptus.com/licenses/> * if you need additional information or have any questions. * * This file may incorporate work covered under the following copyright and * permission notice: * * Software License Agreement (BSD License) * * Copyright (c) 2008, Regents of the University of California * All rights reserved. * * Redistribution and use of this software in source and binary forms, with * or without modification, are permitted provided that the following * conditions are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. USERS OF * THIS SOFTWARE ACKNOWLEDGE THE POSSIBLE PRESENCE OF OTHER OPEN SOURCE * LICENSED MATERIAL, COPYRIGHTED MATERIAL OR PATENTED MATERIAL IN THIS * SOFTWARE, AND IF ANY SUCH MATERIAL IS DISCOVERED THE PARTY DISCOVERING * IT MAY INFORM DR. RICH WOLSKI AT THE UNIVERSITY OF CALIFORNIA, SANTA * BARBARA WHO WILL THEN ASCERTAIN THE MOST APPROPRIATE REMEDY, WHICH IN * THE REGENTS’ DISCRETION MAY INCLUDE, WITHOUT LIMITATION, REPLACEMENT * OF THE CODE SO IDENTIFIED, LICENSING OF THE CODE SO IDENTIFIED, OR * WITHDRAWAL OF THE CODE CAPABILITY TO THE EXTENT NEEDED TO COMPLY WITH * ANY SUCH LICENSES OR RIGHTS. *******************************************************************************/ /* * Author: Dmitrii Zagorodnov dmitrii@cs.ucsb.edu */ package edu.ucsb.eucalyptus.admin.client; import com.google.gwt.core.client.EntryPoint; import com.google.gwt.core.client.GWT; import com.google.gwt.http.client.URL; import com.google.gwt.user.client.Cookies; import com.google.gwt.user.client.History; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.*; import edu.ucsb.eucalyptus.admin.client.extensions.store.ImageStoreClient; import edu.ucsb.eucalyptus.admin.client.extensions.store.ImageStoreWidget; import java.util.Date; import java.util.HashMap; import java.util.List; /******************************************************************************* * Copyright (c) 2009 Eucalyptus Systems, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, only version 3 of the License. * * * This file is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see <http://www.gnu.org/licenses/>. * * Please contact Eucalyptus Systems, Inc., 130 Castilian * Dr., Goleta, CA 93101 USA or visit <http://www.eucalyptus.com/licenses/> * if you need additional information or have any questions. * * This file may incorporate work covered under the following copyright and * permission notice: * * SOFTWARE, AND IF ANY SUCH MATERIAL IS DISCOVERED THE PARTY DISCOVERING * IT MAY INFORM DR. RICH WOLSKI AT THE UNIVERSITY OF CALIFORNIA, SANTA * BARBARA WHO WILL THEN ASCERTAIN THE MOST APPROPRIATE REMEDY, WHICH IN * THE REGENTS' DISCRETION MAY INCLUDE, WITHOUT LIMITATION, REPLACEMENT * OF THE CODE SO IDENTIFIED, LICENSING OF THE CODE SO IDENTIFIED, OR * WITHDRAWAL OF THE CODE CAPABILITY TO THE EXTENT NEEDED TO COMPLY WITH * ANY SUCH LICENSES OR RIGHTS. ******************************************************************************/ public class EucalyptusWebInterface implements EntryPoint { private static final AppMessages MSG = (AppMessages) GWT.create(AppMessages.class); private static String cookie_name = "eucalyptus-session-id"; private static int minPasswordLength = 5; /* TODO: put into config? */ /* configuration parameters to be set from the server */ private static Boolean server_ready = new Boolean(false); private static String signup_greeting; private static String version; private static String cloud_name; private static String certificate_download_text; private static String rest_credentials_text; private static String user_account_text; private static String admin_first_time_config_text; private static String admin_email_change_text; private static String admin_cloud_ip_setup_text; private static boolean enable_signups; private static boolean request_telephone; private static boolean request_project_leader; private static boolean request_affiliation; private static boolean request_project_description; private static boolean show_cloud_registration; private static String cloud_registration_text; private static Image logo = null; private static Image textless_logo = null; private static String rightscale_base_url = null; private static String rightscaleUrl = null; private static String extensions = null; /* global variables */ private static HashMap props; private static HashMap urlParams; private static String sessionId; private static String currentAction; private static UserInfoWeb loggedInUser; private static CloudInfoWeb cloudInfo; private static TabBar allTabs; private static int currentTabIndex = 0; private static int credsTabIndex = -1; private static int imgTabIndex = -1; private static int usrTabIndex = -1; private static int confTabIndex = -1; private static int downTabIndex = -1; private static int storeTabIndex = -1; private static boolean sortUsersLastFirst = true; /* UI selections remembered for future use */ private static boolean previousSkipConfirmation = false; // do not skip email confirmation by default /* globally visible UI widgets */ private Label label_box = new Label(); private CheckBox check_box = new CheckBox("", false); private Label remember_label = new Label(MSG.rememberMe()); private static Label statusMessage = new Label(); public void onModuleLoad() { sessionId = Cookies.getCookie( cookie_name ); urlParams = GWTUtils.parseParamString( GWTUtils.getParamString() ); /* if specified, 'page' will tell us which tab to select */ String page = ( String ) urlParams.get( "page" ); if (page!=null) { currentTabIndex = Integer.parseInt(page); } currentAction = ( String ) urlParams.get( "action" ); displayStatusPage("Loading data from server..."); EucalyptusWebBackend.App.getInstance().getProperties( new AsyncCallback() { public void onSuccess( Object result ) { props = ( HashMap ) result; try { load_props(); /* verify properties */ /* these don't need sessions */ if ( currentAction!=null && (currentAction.equals ("confirm") || currentAction.equals ("recover")) ) { executeAction( currentAction ); } else { /* if we have don't have sessionId saved in a cookie */ if ( sessionId == null ) { displayLoginPage(); } else /* we have a cookie - try using it */ { check_box.setChecked(true); attemptLogin(); } } } catch (Exception e) { displayErrorPageFinal ("Internal error (1): " + e.getMessage()); } } public void onFailure( Throwable caught ) { displayErrorPageFinal ("Internal error (2): " + caught.getMessage()); } } ); } void load_props() throws Exception { if (props == null) { throw new Exception("Invalid server configuration"); } version = (String)props.get("version"); cloud_name = (String)props.get("cloud-name"); signup_greeting = (String)props.get("signup-greeting"); certificate_download_text = (String)props.get("certificate-download-text"); rest_credentials_text = (String)props.get("rest-credentials-text"); user_account_text = (String)props.get("user-account-text"); admin_first_time_config_text = (String)props.get("admin-first-time-config-text"); admin_email_change_text = (String)props.get("admin-email-change-text"); admin_cloud_ip_setup_text = (String)props.get("admin-cloud-ip-setup-text"); server_ready = (Boolean)props.get("ready"); if (server_ready==null) { throw new Exception("Internal server error (cannot determine server readiness)"); } if (cloud_name==null) { throw new Exception("Server configuration is missing 'cloud-name' value"); } if (signup_greeting==null) { throw new Exception("Server configuration is missing 'signup-greeting' value"); } if (certificate_download_text==null) { throw new Exception("Server configuration is missing 'certificate-dowload-text' value"); } if (rest_credentials_text==null) { throw new Exception("Server configuration is missing 'rest-credentials-text' value"); } if (user_account_text==null) { throw new Exception("Server configuration is missing 'user-account-text' value"); } if (admin_first_time_config_text==null) { throw new Exception("Server configuration is missing 'admin-first-time-config-text' value"); } if (admin_email_change_text==null) { throw new Exception("Server configuration is missing 'admin-email-change-text' value"); } if (admin_cloud_ip_setup_text==null) { throw new Exception("Server configuration is missing 'admin-cloud-ip-setup-text' value"); } /* optional parameters (booleans will be 'yes' if not specified) */ enable_signups = str2bool((String)props.get("enable-signups")); request_telephone = str2bool((String)props.get("request-telephone")); request_project_leader = str2bool((String)props.get("request-project-leader")); request_affiliation = str2bool((String)props.get("request-affiliation")); request_project_description = str2bool((String)props.get("request-project-description")); String file = (String)props.get("logo-file"); if (file!=null) { logo = new Image(file); } file = (String)props.get("logo-textless-file"); if (file!=null) { textless_logo = new Image(file); } show_cloud_registration = str2bool((String)props.get("show-cloud-registration")); cloud_registration_text = (String)props.get("cloud-registration-text"); rightscale_base_url = (String)props.get("rightscale-registration-base-url"); if (cloud_registration_text==null || rightscale_base_url==null) { show_cloud_registration = false; } extensions = (String)props.get("extensions"); } private boolean str2bool(String s) { if (s==null) { return true; } if (s.equalsIgnoreCase("no") || s.equalsIgnoreCase("n") || s.equalsIgnoreCase("0")) { return false; } else { return true; } } public void displayLoginPage() { if ( currentAction == null ) { displayLoginPage(MSG.pleaseSignIn() + ":"); } else { if ( currentAction.equals( "approve" ) || currentAction.equals( "reject" ) || currentAction.equals( "disable" ) || currentAction.equals( "delete" )) { displayLoginPage("Please, log into Eucalyptus to " + currentAction + " the user"); } else if ( currentAction.equals( "delete_image")) { displayLoginPage("Please, log into Eucalyptus to delete the image"); } else if ( currentAction.equals( "confirm" ) ) { displayLoginPage("Please, log into Eucalyptus to confirm your acccount"); } else { /* unknown action - will be caught upon login */ displayLoginPage(MSG.pleaseSignIn() + ":"); } label_box.setStyleName ("euca-greeting-warning"); /* highlight the message */ } } public void displayLoginPage(String greeting) { History.newItem("login"); label_box.setText( greeting ); label_box.setStyleName("euca-greeting-normal"); final TextBox login_box = new TextBox(); login_box.setFocus(true); // this box gets focus first final PasswordTextBox pass_box = new PasswordTextBox(); ClickListener LoginButtonListener = new ClickListener() { public void onClick( Widget sender ) { /* perform checks */ if ( login_box.getText().length() < 1 ) { displayLoginErrorPage("Username is empty!"); return; } if ( pass_box.getText().length() < 1 ) { displayLoginErrorPage("Password is empty!"); return; } label_box.setText("Contacting the server..."); label_box.setStyleName("euca-greeting-pending"); EucalyptusWebBackend.App.getInstance().getNewSessionID( login_box.getText(), GWTUtils.md5(pass_box.getText()), new AsyncCallback() { public void onSuccess( Object result ) { sessionId = ( String ) result; long expiresMs = System.currentTimeMillis() + (7 * 24 * 60 * 60 * 1000); /* week */ Date expires = new Date(expiresMs); if (check_box.isChecked()) { Cookies.setCookie( cookie_name, sessionId, expires); } else { /* this cookie should expire at the end of the session */ /* TODO: does this work right in all browsers? */ Cookies.setCookie( cookie_name, sessionId, new Date(0)); } attemptLogin(); } public void onFailure( Throwable caught ) { displayLoginErrorPage((String)caught.getMessage()); } } ); } }; ClickListener RecoverButtonListener = new ClickListener() { public void onClick( Widget sender ) { displayInitiatePasswordRecoveryPage(); } }; Button submit_button = new Button( MSG.signInButton(), LoginButtonListener ); Hyperlink signup_button = new Hyperlink( MSG.applyButton(), "apply" ); signup_button.addClickListener( AddUserButtonListener ); Hyperlink recover_button = new Hyperlink( MSG.recoverButton(), "recover" ); recover_button.addClickListener( RecoverButtonListener ); remember_label.setStyleName("euca-remember-text"); /* enable login by pressing Enter */ EucalyptusKeyboardListener sl = new EucalyptusKeyboardListener(submit_button); submit_button.addKeyboardListener(sl); login_box.addKeyboardListener(sl); pass_box.addKeyboardListener(sl); Grid g = new Grid( 4, 2 ); g.setCellSpacing(4); g.setWidget(0, 0, new Label(MSG.usernameField()+":")); g.getCellFormatter().setHorizontalAlignment(0, 0, HasHorizontalAlignment.ALIGN_RIGHT); g.setWidget(1, 0, new Label(MSG.passwordField()+":")); g.getCellFormatter().setHorizontalAlignment(1, 0, HasHorizontalAlignment.ALIGN_RIGHT); g.setWidget(0, 1, login_box ); g.setWidget(1, 1, pass_box ); g.setWidget(2, 0, check_box); g.getCellFormatter().setHorizontalAlignment(2, 0, HasHorizontalAlignment.ALIGN_RIGHT); g.setWidget(2, 1, remember_label); g.setWidget(3, 1, submit_button); VerticalPanel panel = new VerticalPanel(); panel.add (g); panel.setStyleName("euca-login-panel"); panel.setCellHorizontalAlignment(g, HasHorizontalAlignment.ALIGN_CENTER); panel.setCellVerticalAlignment(g, HasVerticalAlignment.ALIGN_MIDDLE); HorizontalPanel hpanel = new HorizontalPanel(); hpanel.setSpacing(2); if (enable_signups) { hpanel.add( signup_button ); hpanel.add( new HTML(" " + MSG.forAccount() + "  |  ") ); } hpanel.add( recover_button ); hpanel.add( new HTML(" " + MSG.thePassword()) ); VerticalPanel vpanel = new VerticalPanel(); vpanel.setSpacing(15); vpanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER); if (logo!=null) { vpanel.add (logo); } if (version!=null) { Label version_label = new Label ("Version " + version); version_label.setStyleName ("euca-small-text"); vpanel.add (version_label); } vpanel.add (label_box); vpanel.add (panel); if (server_ready.booleanValue()) { vpanel.add (hpanel); } VerticalPanel wrapper = new VerticalPanel(); wrapper.add (vpanel); wrapper.setSize("100%", "100%"); wrapper.setCellHorizontalAlignment(vpanel, VerticalPanel.ALIGN_CENTER); wrapper.setCellVerticalAlignment(vpanel, VerticalPanel.ALIGN_MIDDLE); RootPanel.get().clear(); RootPanel.get().add( wrapper ); } public void displayLoginErrorPage ( String message ) { if (message.equals("Earlier session not found") || message.equals("Earlier session expired")) { displayLoginPage(); } else { displayLoginPage("Error: " + message); label_box.setStyleName("euca-greeting-warning"); } } /* this handles sign-ups, adding of users by admin, and editing of users */ public void displayUserRecordPage( Panel parent, UserInfoWeb userToEdit) { final String oldPassword; final boolean admin; final boolean newUser; final boolean showSkipConfirmed; boolean isAdminChecked = false; // not admin by default boolean skipConfirmationChecked = previousSkipConfirmation; if (loggedInUser != null && (loggedInUser.isAdministrator() != null && loggedInUser.isAdministrator())) { admin = true; } else { admin = false; } if (userToEdit==null) { newUser = true; showSkipConfirmed = true; userToEdit = new UserInfoWeb(); oldPassword = ""; if ( admin ) { label_box.setText ("Please, fill out the form to add a user"); } else { label_box.setText ( signup_greeting ); // Please, fill out the form: } } else { newUser = false; oldPassword = userToEdit.getPassword(); isAdminChecked = userToEdit.isAdministrator() != null && userToEdit.isAdministrator(); showSkipConfirmed = userToEdit.isConfirmed() == null || !userToEdit.isConfirmed(); skipConfirmationChecked = userToEdit.isConfirmed() != null && userToEdit.isConfirmed(); String status; if (userToEdit.isApproved() == null || !userToEdit.isApproved()) { status = "unapproved"; } else if (userToEdit.isEnabled() == null || !userToEdit.isEnabled()) { status = "disabled"; } else if (userToEdit.isConfirmed() == null || !userToEdit.isConfirmed()) { status = "unconfirmed"; } else { status = "active"; } if (userToEdit.isAdministrator() != null && userToEdit.isAdministrator()) { status += " & admin"; } label_box.setText ("Editing information for user '" + userToEdit.getUserName() +"' (" + status + ")" ); } label_box.setStyleName("euca-greeting-normal"); int rowsMandatory = 5; if (admin) { rowsMandatory++; // for admin checkbox if (showSkipConfirmed) { rowsMandatory++; // for skip confirmation checkbox } } final Grid g1 = new Grid ( rowsMandatory, 3 ); g1.getColumnFormatter().setWidth(0, "180"); g1.getColumnFormatter().setWidth(1, "180"); g1.getColumnFormatter().setWidth(2, "180"); int i = 0; final Label label_mandatory = new Label( "Mandatory fields:" ); label_mandatory.setStyleName("euca-section-header"); final int userName_row = i; g1.setWidget( i, 0, new Label( "Username:" ) ); g1.getCellFormatter().setHorizontalAlignment(i, 0, HasHorizontalAlignment.ALIGN_RIGHT); final TextBox userName_box = new TextBox(); userName_box.setText (userToEdit.getUserName()); userName_box.setWidth("180"); if ( ! newUser ) { userName_box.setEnabled (false); } g1.setWidget( i++, 1, userName_box ); // optional row final CheckBox userIsAdmin = new CheckBox("Administrator"); userIsAdmin.setChecked(isAdminChecked); userIsAdmin.setStyleName("euca-remember-text"); if (admin) { g1.setWidget ( i++, 1, userIsAdmin); } final int password1_row = i; g1.setWidget( i, 0, new Label( "Password:" ) ); g1.getCellFormatter().setHorizontalAlignment(i, 0, HasHorizontalAlignment.ALIGN_RIGHT); final PasswordTextBox cleartextPassword1_box = new PasswordTextBox(); cleartextPassword1_box.setText (userToEdit.getPassword()); cleartextPassword1_box.setWidth ("180"); if ( (! admin && ! newUser ) || (userToEdit.isAdministrator() != null && userToEdit.isAdministrator().booleanValue())) { cleartextPassword1_box.setEnabled (false); } g1.setWidget( i++, 1, cleartextPassword1_box ); final int password2_row = i; g1.setWidget( i, 0, new Label( "Password, again:" ) ); g1.getCellFormatter().setHorizontalAlignment(i, 0, HasHorizontalAlignment.ALIGN_RIGHT); final PasswordTextBox cleartextPassword2_box = new PasswordTextBox(); cleartextPassword2_box.setText (userToEdit.getPassword()); cleartextPassword2_box.setWidth("180"); if ( ( ! admin && ! newUser ) || (userToEdit.isAdministrator() != null && userToEdit.isAdministrator().booleanValue())) { cleartextPassword2_box.setEnabled (false); } g1.setWidget( i++, 1, cleartextPassword2_box ); final int realName_row = i; g1.setWidget( i, 0, new Label( "Full Name:" ) ); g1.getCellFormatter().setHorizontalAlignment(i, 0, HasHorizontalAlignment.ALIGN_RIGHT); final TextBox realName_box = new TextBox(); realName_box.setText (userToEdit.getRealName()); realName_box.setWidth("180"); g1.setWidget( i++, 1, realName_box ); final int emailAddress_row = i; g1.setWidget( i, 0, new Label( "Email address:" ) ); g1.getCellFormatter().setHorizontalAlignment(i, 0, HasHorizontalAlignment.ALIGN_RIGHT); final TextBox emailAddress_box = new TextBox(); emailAddress_box.setText (userToEdit.getEmail()); emailAddress_box.setWidth("180"); g1.setWidget( i++, 1, emailAddress_box ); // optional row final CheckBox skipConfirmation = new CheckBox("Skip email confirmation"); skipConfirmation.setChecked(skipConfirmationChecked); skipConfirmation.setStyleName("euca-remember-text"); if (admin && showSkipConfirmed) { g1.setWidget ( i++, 1, skipConfirmation); } /* these widgets are allocated, but not necessarily used */ final Grid g2 = new Grid(); final Label label_optional = new Label( "Optional fields:" ); label_optional.setStyleName("euca-section-header"); final TextBox telephoneNumber_box = new TextBox(); final TextBox projectPIName_box = new TextBox(); final TextBox affiliation_box = new TextBox(); final TextArea projectDescription_box = new TextArea(); int extra_fields = 0; if (request_telephone) { extra_fields++; } if (request_project_leader) { extra_fields++; } if (request_affiliation) { extra_fields++; } if (request_project_description) { extra_fields++; } if (extra_fields > 0) { g2.resize(extra_fields, 2); g2.getColumnFormatter().setWidth(0, "180"); g2.getColumnFormatter().setWidth(1, "360"); i = 0; if (request_telephone) { g2.setWidget( i, 0, new Label( "Telephone Number:" )); g2.getCellFormatter().setHorizontalAlignment(i, 0, HasHorizontalAlignment.ALIGN_RIGHT); telephoneNumber_box.setWidth("180"); telephoneNumber_box.setText (userToEdit.getTelephoneNumber()); g2.setWidget( i++, 1, telephoneNumber_box ); } if (request_project_leader) { g2.setWidget( i, 0, new Label( "Project Leader:" ) ); g2.getCellFormatter().setHorizontalAlignment(i, 0, HasHorizontalAlignment.ALIGN_RIGHT); projectPIName_box.setText (userToEdit.getProjectPIName()); projectPIName_box.setWidth("180"); g2.setWidget( i++, 1, projectPIName_box ); } if (request_affiliation) { g2.setWidget( i, 0, new Label( "Affiliation:" ) ); g2.getCellFormatter().setHorizontalAlignment(i, 0, HasHorizontalAlignment.ALIGN_RIGHT); affiliation_box.setText (userToEdit.getAffiliation()); affiliation_box.setWidth("360"); g2.setWidget( i++, 1, affiliation_box ); } if (request_project_description) { g2.setWidget( i, 0, new Label( "Project Description:" ) ); g2.getCellFormatter().setHorizontalAlignment(i, 0, HasHorizontalAlignment.ALIGN_RIGHT); projectDescription_box.setText (userToEdit.getProjectDescription()); projectDescription_box.setWidth("360"); projectDescription_box.setHeight("50"); g2.setWidget( i++, 1, projectDescription_box ); } } ClickListener SignupButtonListener = new ClickListener() { public void onClick( Widget sender ) { boolean formOk = true; for ( int j = 0; j < 4; j++ ) { g1.clearCell( j, 2 ); /* clear previous right-hand-side annotations */ } // perform checks if ( userName_box.getText().length() < 1 ) { Label l = new Label( "Username is empty!" ); l.setStyleName("euca-error-hint"); g1.setWidget( userName_row, 2, l); formOk = false; } else { // do this in the else-clause so the empty username doesn't match here if ( cleartextPassword1_box.getText().toLowerCase().matches(".*" + userName_box.getText().toLowerCase() + ".*")) { Label l = new Label ( "Password may not contain the username!"); l.setStyleName("euca-error-hint"); g1.setWidget( password1_row, 2, l ); formOk = false; } } if ( userName_box.getText().matches(".*[^\\w\\-\\.@]+.*") ) { Label l = new Label ("Invalid characters in the username!"); l.setStyleName ("euca-error-hint"); g1.setWidget (userName_row, 2, l); formOk = false; } if ( userName_box.getText().length() > 30) { Label l = new Label( "Username is too long, sorry!" ); l.setStyleName("euca-error-hint"); g1.setWidget( userName_row, 2, l); formOk = false; } if ( cleartextPassword1_box.getText().length() < minPasswordLength ) { Label l = new Label( "Password must be at least " + minPasswordLength + " characters long!" ); l.setStyleName("euca-error-hint"); g1.setWidget( password1_row, 2, l ); formOk = false; } if ( !cleartextPassword1_box.getText().equals( cleartextPassword2_box.getText() ) ) { Label l = new Label( "Passwords do not match!" ); l.setStyleName("euca-error-hint"); g1.setWidget( password2_row, 2, l ); formOk = false; } if ( realName_box.getText().equalsIgnoreCase(cleartextPassword1_box.getText()) || userName_box.getText().equalsIgnoreCase(cleartextPassword1_box.getText())) { Label l = new Label ( "Password may not be your name or username!"); l.setStyleName("euca-error-hint"); g1.setWidget( password1_row, 2, l ); formOk = false; } if ( realName_box.getText().length() < 1 ) { Label l = new Label( "Name is empty!" ); l.setStyleName("euca-error-hint"); g1.setWidget( realName_row, 2, l ); formOk = false; } if ( emailAddress_box.getText().length() < 1 ) { Label l = new Label( "Email address is empty!" ); l.setStyleName("euca-error-hint"); g1.setWidget( emailAddress_row, 2, l ); formOk = false; } if ( formOk ) { label_box.setText( "Checking with the server..." ); label_box.setStyleName("euca-greeting-pending"); String enteredPassword = cleartextPassword1_box.getText(); String encryptedPassword = GWTUtils.md5(enteredPassword); if ( enteredPassword.equals(oldPassword)) { encryptedPassword = enteredPassword; // it was not changed in the edit } final UserInfoWeb userToSave = new UserInfoWeb( userName_box.getText(), realName_box.getText(), emailAddress_box.getText(), encryptedPassword); if ( admin ) { userToSave.setAdministrator( userIsAdmin.isChecked()); if ( showSkipConfirmed ) { previousSkipConfirmation = skipConfirmation.isChecked(); // remember value for the future userToSave.setConfirmed(previousSkipConfirmation); } } if ( telephoneNumber_box.getText().length() > 0 ) { userToSave.setTelephoneNumber( telephoneNumber_box.getText() ); } if ( affiliation_box.getText().length() > 0 ) { userToSave.setAffiliation( affiliation_box.getText() ); } if ( projectDescription_box.getText().length() > 0 ) { userToSave.setProjectDescription( projectDescription_box.getText() ); } if ( projectPIName_box.getText().length() > 0 ) { userToSave.setProjectPIName( projectPIName_box.getText() ); } if (newUser) { EucalyptusWebBackend.App.getInstance().addUserRecord( sessionId, /* will be null if anonymous user signs up */ userToSave, new AsyncCallback() { public void onSuccess( Object result ) { displayDialog( "Thank you!", ( String ) result ); } public void onFailure( Throwable caught ) { String m = caught.getMessage(); if ( m.equals( "User already exists" ) ) { g1.setWidget( userName_row, 2, new Label( "Username is taken!" ) ); label_box.setText( "Please, fix the error and resubmit:" ); label_box.setStyleName("euca-greeting-warning"); } else { displayErrorPage(m); } } } ); } else { EucalyptusWebBackend.App.getInstance().updateUserRecord( sessionId, userToSave, new AsyncCallback() { public void onSuccess(Object result) { if (loggedInUser.getUserName().equals(userToSave.getUserName())) { loggedInUser.setRealName(userToSave.getRealName()); loggedInUser.setEmail(userToSave.getEmail()); loggedInUser.setPassword(userToSave.getPassword()); loggedInUser.setTelephoneNumber(userToSave.getTelephoneNumber()); loggedInUser.setAffiliation(userToSave.getAffiliation()); loggedInUser.setProjectDescription(userToSave.getProjectDescription()); loggedInUser.setProjectPIName(userToSave.getProjectPIName()); displayDialog("", (String) result); } else { // admin updating a user displayBarAndTabs(""); statusMessage.setText( ( String ) result ); } } public void onFailure( Throwable caught ) { String m = caught.getMessage(); displayErrorPage(m); } } ); } } else { label_box.setText( "Please, fix the errors and resubmit:" ); label_box.setStyleName("euca-greeting-warning"); } } }; Button submit_button; if (newUser) { if (admin) { submit_button = new Button ( "Add user", SignupButtonListener); } else { submit_button = new Button ( "Sign up", SignupButtonListener); } } else { submit_button = new Button ( "Update Record", SignupButtonListener ); } Button cancel_button = new Button( "Cancel", DefaultPageButtonListener ); VerticalPanel mpanel = new VerticalPanel(); mpanel.add( label_mandatory ); mpanel.add( g1 ); VerticalPanel opanel = new VerticalPanel(); if (extra_fields > 0) { opanel.add( label_optional ); opanel.add( g2 ); } HorizontalPanel bpanel = new HorizontalPanel(); bpanel.add( submit_button ); bpanel.add( new HTML( "  or  " ) ); bpanel.add( cancel_button ); VerticalPanel vpanel = new VerticalPanel(); vpanel.setSpacing(15); vpanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER); vpanel.add(new HTML("<br/>")); if (logo!=null) { addLogoWithText(vpanel); vpanel.add(new HTML("<br/>"));}; vpanel.add (label_box); vpanel.add (mpanel); vpanel.add (opanel); vpanel.add (bpanel); VerticalPanel wrapper = new VerticalPanel(); wrapper.add (vpanel); wrapper.setSize("100%", "100%"); wrapper.setCellHorizontalAlignment(vpanel, VerticalPanel.ALIGN_CENTER); // wrapper.setCellVerticalAlignment(vpanel, VerticalPanel.ALIGN_MIDDLE); parent.clear(); parent.add( wrapper ); } public void displayInitiatePasswordRecoveryPage() { label_box.setText ("Enter the following to reset your password"); label_box.setStyleName("euca-greeting-normal"); final Grid g1 = new Grid ( 2, 3 ); // rows, cols g1.getColumnFormatter().setWidth(0, "230"); g1.getColumnFormatter().setWidth(1, "180"); g1.getColumnFormatter().setWidth(2, "180"); int i = 0; final int username_row = i; g1.setWidget( i, 0, new Label( "Username:" ) ); g1.getCellFormatter().setHorizontalAlignment(i, 0, HasHorizontalAlignment.ALIGN_RIGHT); final TextBox username_box = new TextBox(); username_box.setWidth("180"); g1.setWidget( i++, 1, username_box ); final int email_row = i; g1.setWidget( i, 0, new Label( "Email address:" ) ); g1.getCellFormatter().setHorizontalAlignment(i, 0, HasHorizontalAlignment.ALIGN_RIGHT); final TextBox email_box = new TextBox(); email_box.setWidth("180"); g1.setWidget( i++, 1, email_box ); ClickListener RecoverButtonListener = new ClickListener() { public void onClick( Widget sender ) { boolean formOk = true; for ( int j = 0; j < 2; j++ ) { g1.clearCell( j, 2 ); // clear previous right-hand-side annotations } // perform checks if ( username_box.getText().length() < 1 ) { Label l = new Label( "Username is empty!" ); l.setStyleName("euca-error-hint"); g1.setWidget( username_row, 2, l); formOk = false; } if ( username_box.getText().matches(".*[ \t]+.*") ) { Label l = new Label ("Username cannot have spaces, sorry!"); l.setStyleName ("euca-error-hint"); g1.setWidget (username_row, 2, l); formOk = false; } if ( ! email_box.getText().contains("@") ) { Label l = new Label( "Valid email is mandatory!" ); l.setStyleName("euca-error-hint"); g1.setWidget( email_row, 2, l ); formOk = false; } if ( formOk ) { label_box.setText( "Checking with the server..." ); label_box.setStyleName("euca-greeting-pending"); UserInfoWeb user = new UserInfoWeb( username_box.getText(), "", // don't care about real name email_box.getText(), null ); // null => reset requested EucalyptusWebBackend.App.getInstance().recoverPassword( user, new AsyncCallback() { public void onSuccess( Object result ) { displayDialog( "Thank you!", ( String ) result ); } public void onFailure( Throwable caught ) { String m = caught.getMessage(); displayErrorPage(m); } } ); } else { label_box.setText( "Please, fix the errors and resubmit:" ); label_box.setStyleName("euca-greeting-warning"); } } }; Button submit_button = new Button ( "Recover Password", RecoverButtonListener ); Button cancel_button = new Button ( "Cancel", DefaultPageButtonListener ); VerticalPanel mpanel = new VerticalPanel(); mpanel.add( g1 ); HorizontalPanel bpanel = new HorizontalPanel(); bpanel.add( submit_button ); bpanel.add( new HTML( "  or  " ) ); bpanel.add( cancel_button ); VerticalPanel vpanel = new VerticalPanel(); vpanel.setSpacing(15); vpanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER); if (logo!=null) { vpanel.add (logo); } vpanel.add (label_box); vpanel.add (mpanel); vpanel.add (bpanel); VerticalPanel wrapper = new VerticalPanel(); wrapper.add (vpanel); wrapper.setSize("100%", "100%"); wrapper.setCellHorizontalAlignment(vpanel, VerticalPanel.ALIGN_CENTER); wrapper.setCellVerticalAlignment(vpanel, VerticalPanel.ALIGN_MIDDLE); RootPanel.get().clear(); RootPanel.get().add( wrapper ); } public void displayCompletePasswordRecoveryPage(final String code) { label_box.setText ("Please, choose the new password"); label_box.setStyleName("euca-greeting-normal"); final Grid g1 = new Grid ( 2, 3 ); // rows, cols g1.getColumnFormatter().setWidth(0, "230"); g1.getColumnFormatter().setWidth(1, "180"); g1.getColumnFormatter().setWidth(2, "180"); int i = 0; final int password1_row = i; g1.setWidget( i, 0, new Label( "New password:" ) ); g1.getCellFormatter().setHorizontalAlignment(i, 0, HasHorizontalAlignment.ALIGN_RIGHT); final PasswordTextBox cleartextPassword1_box = new PasswordTextBox(); cleartextPassword1_box.setWidth("180"); g1.setWidget( i++, 1, cleartextPassword1_box ); final int password2_row = i; g1.setWidget( i, 0, new Label( "The password, again:" ) ); g1.getCellFormatter().setHorizontalAlignment(i, 0, HasHorizontalAlignment.ALIGN_RIGHT); final PasswordTextBox cleartextPassword2_box = new PasswordTextBox(); cleartextPassword2_box.setWidth("180"); g1.setWidget( i++, 1, cleartextPassword2_box ); ClickListener RecoverButtonListener = new ClickListener() { public void onClick( Widget sender ) { boolean formOk = true; for ( int j = 0; j < 2; j++ ) { g1.clearCell( j, 2 ); // clear previous right-hand-side annotations } if ( cleartextPassword1_box.getText().length() < minPasswordLength ) { Label l = new Label( "Password must be at least " + minPasswordLength + " characters long!" ); l.setStyleName("euca-error-hint"); g1.setWidget( password1_row, 2, l ); formOk = false; } if ( !cleartextPassword1_box.getText().equals( cleartextPassword2_box.getText() ) ) { Label l = new Label( "Passwords do not match!" ); l.setStyleName("euca-error-hint"); g1.setWidget( password2_row, 2, l ); formOk = false; } if ( formOk ) { label_box.setText( "Checking with the server..." ); label_box.setStyleName("euca-greeting-pending"); UserInfoWeb user = new UserInfoWeb(); user.setConfirmationCode(code); user.setPassword(GWTUtils.md5(cleartextPassword1_box.getText())); EucalyptusWebBackend.App.getInstance().recoverPassword( user, new AsyncCallback() { public void onSuccess( Object result ) { displayDialog( "Thank you!", ( String ) result ); } public void onFailure( Throwable caught ) { String m = caught.getMessage(); displayErrorPage(m); } } ); } else { label_box.setText( "Please, fix the errors and resubmit:" ); label_box.setStyleName("euca-greeting-warning"); } } }; Button submit_button = new Button ( "Change Password", RecoverButtonListener ); Button cancel_button = new Button ( "Cancel", DefaultPageButtonListener ); VerticalPanel mpanel = new VerticalPanel(); mpanel.add( g1 ); HorizontalPanel bpanel = new HorizontalPanel(); bpanel.add( submit_button ); bpanel.add( new HTML( "  or  " ) ); bpanel.add( cancel_button ); VerticalPanel vpanel = new VerticalPanel(); vpanel.setSpacing(15); vpanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER); if (logo!=null) { vpanel.add (logo); } vpanel.add (label_box); vpanel.add (mpanel); vpanel.add (bpanel); VerticalPanel wrapper = new VerticalPanel(); wrapper.add (vpanel); wrapper.setSize("100%", "100%"); wrapper.setCellHorizontalAlignment(vpanel, VerticalPanel.ALIGN_CENTER); wrapper.setCellVerticalAlignment(vpanel, VerticalPanel.ALIGN_MIDDLE); RootPanel.get().clear(); RootPanel.get().add( wrapper ); } private Button displayDialog ( String greeting, String message ) { return displayDialog (greeting, message, null); } private Button displayDialog ( String greeting, String message, Button firstButton ) { if ( message==null || message.equalsIgnoreCase("") ) { message = "Server is not accessible!"; // TODO: any other reasons why message would be empty? } label_box.setText( greeting ); label_box.setStyleName("euca-greeting-normal"); Label m = new Label ( message ); m.setWidth("300"); VerticalPanel panel = new VerticalPanel(); panel.add(m); panel.setStyleName("euca-login-panel"); panel.setCellHorizontalAlignment(m, HasHorizontalAlignment.ALIGN_CENTER); panel.setCellVerticalAlignment(m, HasVerticalAlignment.ALIGN_MIDDLE); Button ok_button = new Button( "Ok", DefaultPageButtonListener ); HorizontalPanel hpanel = new HorizontalPanel(); hpanel.setSpacing (10); if (firstButton!=null) { hpanel.add (firstButton); } hpanel.add (ok_button); VerticalPanel vpanel = new VerticalPanel(); vpanel.setSpacing(15); vpanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER); if (logo!=null) { vpanel.add (logo); } vpanel.add (label_box); vpanel.add (panel); vpanel.add (hpanel); VerticalPanel wrapper = new VerticalPanel(); wrapper.add (vpanel); wrapper.setSize("100%", "100%"); wrapper.setCellHorizontalAlignment(vpanel, VerticalPanel.ALIGN_CENTER); wrapper.setCellVerticalAlignment(vpanel, VerticalPanel.ALIGN_MIDDLE); RootPanel.get().clear(); RootPanel.get().add( wrapper ); return ok_button; } public void attemptLogin() { displayStatusPage("Logging into the server..."); EucalyptusWebBackend.App.getInstance().getUserRecord( sessionId, null, /* get user record associated with this sessionId */ new AsyncCallback() { public void onSuccess( Object result ) { loggedInUser = ( UserInfoWeb ) ( (List) result).get(0); if ( currentAction == null ) { displayDefaultPage (""); } else { executeAction( currentAction ); } } public void onFailure( Throwable caught ) { if (caught.getMessage().equals("Password expired")) { displayPasswordChangePage( true ); } else { displayLoginErrorPage( caught.getMessage() ); } } } ); } public void attemptAction( String action, String param ) { displayStatusPage( "Contacting the server..." ); EucalyptusWebBackend.App.getInstance().performAction( sessionId, action, param, new AsyncCallback() { public void onSuccess( Object result ) { displayMessagePage( ( String ) result ); } public void onFailure( Throwable caught ) { displayErrorPage( caught.getMessage() ); } } ); } public void attemptActionNoReload( String action, String param, final VerticalPanel parent ) { statusMessage.setText( "Contacting the server..." ); EucalyptusWebBackend.App.getInstance().performAction( sessionId, action, param, new AsyncCallback() { public void onSuccess( Object result ) { displayBarAndTabs(""); statusMessage.setText( ( String ) result ); } public void onFailure( Throwable caught ) { displayErrorPage( caught.getMessage() ); } } ); } public void executeAction( String action ) { /* NOTE: some of the checks are repeated by the server, * this is just to avoid unnecessary RPCs */ if ( action.equals ( "approve" ) || action.equals ( "reject" ) || action.equals ( "delete" ) || action.equals ( "disable" ) || action.equals ( "enable" ) ) { String userName = ( String ) urlParams.get( "user" ); if ( loggedInUser.isAdministrator() == null || !loggedInUser.isAdministrator().booleanValue() ) { displayErrorPage( "Administrative privileges required" ); } else if ( userName == null ) { displayErrorPage( "Username not specified" ); } else { attemptAction( action, userName ); } } else if ( action.equals ( "delete_image") || action.equals ( "disable_image") || action.equals ( "enable_image") ) { String imageId = ( String ) urlParams.get ("id"); if ( loggedInUser.isAdministrator() == null || !loggedInUser.isAdministrator().booleanValue() ) { displayErrorPage( "Administrative privileges required" ); } else if ( imageId == null ) { displayErrorPage( "Image ID not specified" ); } else { attemptAction( action, imageId ); } } else if ( action.equals( "confirm" ) || action.equals ("recover") ) { String code = ( String ) urlParams.get( "code" ); if ( code == null ) { displayErrorPage( "Confirmation code not specified" ); } else { if (action.equals( "confirm" )) { attemptAction( action, code ); } else if (action.equals( "recover")) { displayCompletePasswordRecoveryPage(code); } } } else { displayErrorPage( "Action '" + action + "' not recognized" ); } } public void displayDefaultPage (String message) { displayStatusPage("Loading default page..."); /* If there is an action encoded in the URL, then redirect to * a URL without that action, so it is not repeated upon a reload * However, reserve the currently selected tab in URL. */ if (currentAction!=null) { String extra = ""; if (currentTabIndex!=0) { extra = "?page=" + currentTabIndex; } GWTUtils.redirect (GWT.getModuleBaseURL() + extra); } if (loggedInUser!=null) { if ( loggedInUser.isAdministrator() != null && loggedInUser.isAdministrator().booleanValue() ) { if (loggedInUser.getEmail().equalsIgnoreCase( UserInfoWeb.BOGUS_ENTRY ) ) { displayFirstTimeConfiguration(); } else { displayBarAndTabs(message); } } else { displayBarAndTabs(message); } } else { displayLoginPage(); } } ClickListener AddUserButtonListener = new ClickListener() { public void onClick( Widget sender ) { displayUserRecordPage (RootPanel.get(), null); } }; ClickListener DefaultPageButtonListener = new ClickListener() { public void onClick( Widget sender ) { displayDefaultPage (""); } }; public void displayErrorPage( String message ) { displayDialog("Error!", message); label_box.setStyleName("euca-greeting-error"); } public void displayErrorPageFinal( String message ) { Button ok_button = displayDialog("Error!", message); label_box.setStyleName("euca-greeting-error"); ok_button.setVisible(false); } public void displayMessagePage( String message ) { displayDialog("", message); label_box.setStyleName("euca-greeting-normal"); } ClickListener LogoutButtonListener = new ClickListener() { public void onClick( Widget sender ) { EucalyptusWebBackend.App.getInstance().logoutSession( sessionId, new AsyncCallback() { public void onSuccess( Object result ) { displayLoginPage(); } public void onFailure( Throwable caught ) { displayLoginPage(); } } ); sessionId = null; /* invalidate sessionId */ loggedInUser = null; /* invalidate user */ Cookies.removeCookie( cookie_name ); // TODO: this isn't working for some reason } }; public void displayBarAndTabs(String message) { /* top bar */ displayStatusPage("Drawing the tabs..."); HorizontalPanel top_bar = new HorizontalPanel(); top_bar.getElement().setClassName("euca-top-bar"); HorizontalPanel name_panel = new HorizontalPanel(); name_panel.getElement().setClassName("euca-top-bar-left"); name_panel.setSpacing (5); name_panel.add (new HTML(Theme.draw_header())); top_bar.add (name_panel); top_bar.setCellHorizontalAlignment(name_panel, HorizontalPanel.ALIGN_LEFT); top_bar.setCellVerticalAlignment(name_panel, HorizontalPanel.ALIGN_TOP); // michael left this as MIDDLE HorizontalPanel upanel = new HorizontalPanel(); upanel.getElement().setClassName("euca-top-bar-right"); Label user_name = new HTML("Logged in as <b>" + loggedInUser.getUserName() + "</b>  |  "); Hyperlink logout_button = new Hyperlink("Logout", "logout"); logout_button.addClickListener(LogoutButtonListener); upanel.add(user_name); upanel.add(logout_button); top_bar.add(upanel); top_bar.setCellHorizontalAlignment(upanel, HorizontalPanel.ALIGN_RIGHT); top_bar.setCellVerticalAlignment(upanel, HorizontalPanel.ALIGN_TOP); final HorizontalPanel messageBox = new HorizontalPanel(); messageBox.setStyleName("euca-message-bar"); messageBox.setSpacing(3); messageBox.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT); messageBox.add (statusMessage); statusMessage.setStyleName("euca-small-text"); final VerticalPanel wrapper = new VerticalPanel(); wrapper.setStyleName("euca-tab-contents"); // wrapper.setSize("100%", "80%"); // wrapper.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER); // wrapper.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE); // set up tab layout so that *TabIndex variables are set in the beginning int nTabs = 0; allTabs = new TabBar(); allTabs.addTab ("Credentials"); credsTabIndex = nTabs++; allTabs.addTab ("Images"); imgTabIndex = nTabs++; /////allTabs.addTab ("Instances"); instTabIndex = nTabs++; if (loggedInUser.isAdministrator() != null && loggedInUser.isAdministrator().booleanValue()) { allTabs.addTab ("Users"); usrTabIndex = nTabs++; allTabs.addTab ("Configuration"); confTabIndex = nTabs++; allTabs.addTab ("Extras"); downTabIndex = nTabs++; if (extensions!=null && extensions.contains ("store") ) { allTabs.addTab ("Store"); storeTabIndex = nTabs++; } } // can happen if admin user re-logs in as regular without reloading if (currentTabIndex > (nTabs-1) ) { currentTabIndex = 0; } allTabs.addTabListener(new TabListener() { public void onTabSelected(SourcesTabEvents sender, int tabIndex) { String error = "This tab is not implemented yet, sorry!"; statusMessage.setText(""); wrapper.clear(); currentTabIndex = tabIndex; if (tabIndex==credsTabIndex) { displayCredentialsTab(wrapper); } else if (tabIndex==imgTabIndex) { displayImagesTab(wrapper); } else if (tabIndex==usrTabIndex) { displayUsersTab(wrapper); } else if (tabIndex==confTabIndex) { displayConfTab(wrapper); } else if (tabIndex==downTabIndex) { displayDownloadsTab(wrapper); } else if (tabIndex==storeTabIndex) { displayStoreTab(wrapper); } else { displayErrorPage("Invalid tab!"); } } public boolean onBeforeTabSelected(SourcesTabEvents sender, int tabIndex) { return true; /* here we could do checking for clicks on disabled tabs */ } }); RootPanel.get().clear(); RootPanel.get().add( top_bar ); RootPanel.get().add( allTabs ); RootPanel.get().add( messageBox ); RootPanel.get().add( wrapper ); allTabs.selectTab(currentTabIndex); } private Image addLogoWithText(CellPanel name_panel) { logo.getElement().setAttribute("alt", cloud_name); name_panel.add(logo); return logo; } private void addTextlessLogoAndHeading(HorizontalPanel name_panel) { Label welcome = new Label( cloud_name); if (textless_logo!=null) { name_panel.add (textless_logo); } name_panel.add(welcome); name_panel.setCellVerticalAlignment(welcome, HorizontalPanel.ALIGN_MIDDLE); } public void displayCredentialsTab (final VerticalPanel parent) { EucalyptusWebBackend.App.getInstance().getCloudInfo( sessionId, false, // do not check external IP for now new AsyncCallback() { public void onSuccess( Object result ) { cloudInfo = ( CloudInfoWeb ) result; actuallyDisplayCredentialsTab (parent); } public void onFailure( Throwable caught ) { displayErrorPage( caught.getMessage() ); } } ); } private class RightscaleDialog extends DialogBox { private boolean cancelled; public RightscaleDialog () { cancelled = false; setHTML ("<img src=\"themes/share/pending-FFCC33.gif\" align=\"middle\">   Checking the external IP address..."); final Button okButton = new Button("OK", new ClickListener() { public void onClick(Widget sender) { RightscaleDialog.this.hide(); if (rightscaleUrl!=null) { Window.open (rightscaleUrl, "_blank", ""); } } }); okButton.setEnabled (false); Button cancelButton = new Button("Cancel", new ClickListener() { public void onClick(Widget sender) { RightscaleDialog.this.hide(); cancelled = true; } }); HorizontalPanel buttonPanel = new HorizontalPanel(); buttonPanel.add (okButton); buttonPanel.add (cancelButton); setWidget (buttonPanel); EucalyptusWebBackend.App.getInstance().getCloudInfo( sessionId, true, // DO check external IP new AsyncCallback () { public void onSuccess( Object result ) { if (cancelled) { return; } cloudInfo = ( CloudInfoWeb ) result; String ex = cloudInfo.getExternalHostPort(); String in = cloudInfo.getInternalHostPort(); String text = ""; String ip; if (ex==null) { ip = in; text = "<b>Warning:</b> Rightscale could not discover the external IP address of your cloud. Hence, the pre-filled cloud URL <i>may</i> be incorrect. Check your firewall settings.</p> "; } else if (!ex.equals(in)) { ip = ex; text = "<b>Warning:</b> The external cloud IP discovered by Rightscale (" + ex + ") is different from the IP found by Eucalyptus (" + in + "). Hence, the pre-filled cloud URL <i>may</i> be incorrect. Check your firewall settings.</p> "; } else { ip = ex; } String callbackUrl = "https://" + ip + cloudInfo.getServicePath(); rightscaleUrl = rightscale_base_url + GWTUtils.escape (callbackUrl) // URL.encode() wasn't quite right + "®istration_version=1.0&retry=1&secret_token=" + GWTUtils.escape (cloudInfo.getCloudId()); String pre = "<h3>Cloud registration</h3> You are about to open a new window to Rightscale's Web site, on which you will be able to complete registraton. </p> "; setHTML (pre + text); okButton.setEnabled (true); center(); } public void onFailure( Throwable caught ) { displayErrorPage( caught.getMessage() ); } } ); } } public void actuallyDisplayCredentialsTab (VerticalPanel parent) { History.newItem("credentials"); VerticalPanel credspanel = new VerticalPanel (); credspanel.setSpacing(5); parent.add (credspanel); credspanel.getElement().setClassName ("euca-tab-with-text"); VerticalPanel ppanel = new VerticalPanel(); ppanel.add (new HTML ("<h3>User account Information</h3>")); Grid userGrid = new Grid(3,2); userGrid.setText(0, 0, "Login:"); userGrid.setHTML(0, 1, "<b>" + loggedInUser.getUserName() +"</b>"); userGrid.setText(1, 0, "Name:"); userGrid.setHTML(1, 1, "<b>" + loggedInUser.getRealName() +"</b>"); userGrid.setText(2, 0, "Email:"); userGrid.setHTML(2, 1, "<b>" + loggedInUser.getEmail() +"</b>"); ppanel.add(userGrid); ppanel.add (new HTML ("<p>" + user_account_text + "</p>")); ppanel.setStyleName("euca-text"); ppanel.addStyleName("content"); Button passwordButton = new Button ( "Change Password", new ClickListener() { public void onClick(Widget sender) { displayPasswordChangePage (false); } }); Button editButton = new Button ( "Edit Account Information", new ClickListener() { public void onClick (Widget sender) { displayUserRecordPage (RootPanel.get(), loggedInUser); } }); ppanel.setSpacing( 0 ); ppanel.add(editButton); ppanel.add(passwordButton); VerticalPanel cpanel = new VerticalPanel(); cpanel.add ( new HTML (certificate_download_text) ); cpanel.setStyleName( "euca-text" ); cpanel.addStyleName("content"); Button certButton = new Button ("Download Credentials", new ClickListener() { public void onClick (Widget sender) { Window.open(GWT.getModuleBaseURL() + "getX509?user=" + loggedInUser.getUserName() + "&keyValue=" + loggedInUser.getUserName() + "&code=" + loggedInUser.getToken(), "_self", ""); } }); VerticalPanel rpanel = new VerticalPanel(); rpanel.setSpacing (0); HTML credentials_html = new HTML (rest_credentials_text); credentials_html.setStyleName("content"); rpanel.add( credentials_html ); Grid g0 = new Grid (2, 2); g0.setWidget (0, 0, new HTML ("<b><font size=\"2\">Query ID:</font></b>")); final HTML queryId = new HTML ("<font color=#666666 size=\"2\">" + loggedInUser.getQueryId() + "</font>"); queryId.setVisible (false); g0.setWidget (0, 1, queryId); g0.setWidget (1, 0, new HTML ("<b><font size=\"2\">Secret Key:</font></b>")); final HTML secretKey = new HTML ("<font color=#666666 size=\"2\">" + loggedInUser.getSecretKey() + "</font>"); secretKey.setVisible (false); g0.setWidget (1, 1, secretKey); rpanel.add (g0); rpanel.setStyleName( "euca-text" ); final Button secretButton = new Button ( "Show keys" ); secretButton.addClickListener(new ClickListener() { public void onClick(Widget sender) { if (secretKey.isVisible()) { secretKey.setVisible(false); queryId.setVisible(false); secretButton.setText ("Show keys"); } else { secretKey.setVisible(true); queryId.setVisible(true); secretButton.setText ("Hide keys"); } } }); int gridRows = 3; if (loggedInUser.isAdministrator() != null && loggedInUser.isAdministrator() && show_cloud_registration) { gridRows++; } credspanel.add(ppanel); credspanel.add(cpanel); credspanel.add(certButton); credspanel.add(rpanel); credspanel.add(secretButton); // final Grid g = new Grid( gridRows, 2 ); // g.getColumnFormatter().setWidth(0, "400"); // g.getColumnFormatter().setWidth(1, "200"); // g.setCellSpacing( 30 ); // // g.setWidget( 0, 0, ppanel ); g.getCellFormatter().setVerticalAlignment(0, 0, HasVerticalAlignment.ALIGN_TOP); // // g.setWidget( 0, 1, ppanel2); g.getCellFormatter().setVerticalAlignment(0, 1, HasVerticalAlignment.ALIGN_TOP); // // g.setWidget( 1, 0, cpanel ); g.getCellFormatter().setVerticalAlignment(1, 0, HasVerticalAlignment.ALIGN_TOP); // g.setWidget( 1, 1, certButton ); g.getCellFormatter().setVerticalAlignment(1, 1, HasVerticalAlignment.ALIGN_TOP); // // g.setWidget( 2, 0, rpanel ); g.getCellFormatter().setVerticalAlignment(2, 0, HasVerticalAlignment.ALIGN_TOP); // g.setWidget( 2, 1, secretButton ); g.getCellFormatter().setVerticalAlignment(2, 1, HasVerticalAlignment.ALIGN_TOP); if (loggedInUser.isAdministrator() != null && loggedInUser.isAdministrator() && show_cloud_registration) { VerticalPanel cloud_panel = new VerticalPanel(); cloud_panel.setSpacing (0); cloud_panel.add( new HTML (cloud_registration_text) ); Grid g1 = new Grid (2, 2); g1.setWidget (0, 0, new HTML ("<b><font size=\"2\">Cloud URL:</font></b>")); final HTML cloudUrl = new HTML ("<font color=#666666 size=\"2\">https://" + cloudInfo.getInternalHostPort() + cloudInfo.getServicePath() + "</font>"); g1.setWidget (0, 1, cloudUrl); g1.setWidget (1, 0, new HTML ("<b><font size=\"2\">Cloud ID:</font></b>")); final HTML cloudId = new HTML ("<font color=#666666 size=\"2\">" + cloudInfo.getCloudId() + "</font>"); g1.setWidget (1, 1, cloudId); cloud_panel.add (g1); cloud_panel.setStyleName( "euca-text" ); final Button cloudButton = new Button ( "Register" ); cloudButton.addClickListener(new ClickListener() { public void onClick(Widget sender) { new RightscaleDialog().center(); } }); // g.setWidget (3, 0, cloud_panel ); // g.getCellFormatter().setVerticalAlignment(3, 0, HasVerticalAlignment.ALIGN_TOP); credspanel.add(cloud_panel); VerticalPanel vp = new VerticalPanel(); vp.setSpacing (0); HorizontalPanel hp = new HorizontalPanel(); hp.setSpacing (0); hp.add (cloudButton); hp.add (new HTML ("with")); Image logo = new Image ("themes/share/rightscale-logo-blue.gif"); logo.setStyleName("euca-inline-image"); hp.add (logo); vp.add (hp); // g.setWidget( 3, 1, vp ); // g.getCellFormatter().setVerticalAlignment(3, 1, HasVerticalAlignment.ALIGN_TOP); credspanel.add(vp); } //credspanel.add(g); } public void displayErrorTab(VerticalPanel parent, String message) { parent.add(new Label(message)); } public void displayTestingTab(VerticalPanel parent) { parent.add(new Label("truth = [" + props.get("truth") + "]")); } public void displayStatusPage(String message) { label_box.setText( message ); label_box.setStyleName("euca-greeting-pending"); final VerticalPanel wrapper = new VerticalPanel(); wrapper.setSize("100%", "100%"); wrapper.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER); wrapper.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE); wrapper.add(label_box); RootPanel.get().clear(); RootPanel.get().add(wrapper); } public void displayPasswordChangePage(boolean mustChange) { if (mustChange) { label_box.setText( "You are required to change your password" ); label_box.setStyleName("euca-greeting-error"); } else { label_box.setText( "Please, change your password" ); label_box.setStyleName("euca-greeting-normal"); } final Grid g1 = new Grid ( 3, 3 ); g1.getColumnFormatter().setWidth(0, "180"); g1.getColumnFormatter().setWidth(1, "180"); g1.getColumnFormatter().setWidth(2, "180"); int i = 0; final int oldPassword_row = i; g1.setWidget( i, 0, new Label( "Old password:" ) ); g1.getCellFormatter().setHorizontalAlignment(i, 0, HasHorizontalAlignment.ALIGN_RIGHT); final PasswordTextBox oldPassword_box = new PasswordTextBox(); oldPassword_box.setWidth("180"); if (!mustChange) { // don't ask for old password if the change is involuntary g1.setWidget( i++, 1, oldPassword_box ); } final int newPassword1_row = i; g1.setWidget( i, 0, new Label( "New password:" ) ); g1.getCellFormatter().setHorizontalAlignment(i, 0, HasHorizontalAlignment.ALIGN_RIGHT); final PasswordTextBox newCleartextPassword1_box = new PasswordTextBox(); newCleartextPassword1_box.setWidth("180"); g1.setWidget( i++, 1, newCleartextPassword1_box ); final int newPassword2_row = i; g1.setWidget( i, 0, new Label( "New password, again:" ) ); g1.getCellFormatter().setHorizontalAlignment(i, 0, HasHorizontalAlignment.ALIGN_RIGHT); final PasswordTextBox newCleartextPassword2_box = new PasswordTextBox(); newCleartextPassword2_box.setWidth("180"); g1.setWidget( i++, 1, newCleartextPassword2_box ); ClickListener ChangeButtonListener = new ClickListener() { public void onClick( Widget sender ) { boolean formOk = true; for ( int j = 0; j < 3; j++ ) { g1.clearCell( j, 2 ); // clear previous right-hand-side annotations } // perform checks if ( newCleartextPassword1_box.getText().length() < minPasswordLength ) { Label l = new Label( "Password is too short!" ); l.setStyleName("euca-error-hint"); g1.setWidget( newPassword1_row, 2, l ); formOk = false; } if ( !newCleartextPassword1_box.getText().equals( newCleartextPassword2_box.getText() ) ) { Label l = new Label( "Passwords do not match!" ); l.setStyleName("euca-error-hint"); g1.setWidget( newPassword2_row, 2, l ); formOk = false; } if ( formOk ) { label_box.setText( "Checking with the server..." ); label_box.setStyleName("euca-greeting-pending"); EucalyptusWebBackend.App.getInstance().changePassword( sessionId, GWTUtils.md5(oldPassword_box.getText()), GWTUtils.md5(newCleartextPassword1_box.getText()), new AsyncCallback<String>() { public void onSuccess( final String result ) { // password change succeded - pull in the new user record label_box.setText( "Refreshing user data..." ); EucalyptusWebBackend.App.getInstance().getUserRecord( sessionId, null, new AsyncCallback<List<UserInfoWeb>>() { public void onSuccess( List<UserInfoWeb> users ) { loggedInUser = users.get(0); displayMessagePage ( ( String ) result ); } public void onFailure( Throwable caught ) { displayLoginErrorPage( caught.getMessage() ); } }); } public void onFailure( Throwable caught ) { String m = caught.getMessage(); label_box.setText( m ); label_box.setStyleName("euca-greeting-warning"); } } ); } else { label_box.setText( "Please, fix the errors and try again:" ); label_box.setStyleName("euca-greeting-warning"); } } }; Button change_button = new Button( "Change password", ChangeButtonListener ); Button cancel_button = new Button( "Cancel", DefaultPageButtonListener ); HorizontalPanel bpanel = new HorizontalPanel(); bpanel.add( change_button ); if (!mustChange) { bpanel.add( new HTML( "  or  " ) ); bpanel.add( cancel_button ); } VerticalPanel vpanel = new VerticalPanel(); vpanel.setSpacing(15); vpanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER); if (logo!=null) { vpanel.add (logo); } vpanel.add (label_box); vpanel.add (g1); vpanel.add (bpanel); VerticalPanel wrapper = new VerticalPanel(); wrapper.add (vpanel); wrapper.setSize("100%", "100%"); wrapper.setCellHorizontalAlignment(vpanel, VerticalPanel.ALIGN_CENTER); wrapper.setCellVerticalAlignment(vpanel, VerticalPanel.ALIGN_MIDDLE); RootPanel.get().clear(); RootPanel.get().add( wrapper ); } public void displayAdminEmailChangePage() { label_box.setText( "One more thing!" ); label_box.setStyleName("euca-greeting-error"); final Grid g1 = new Grid ( 2, 3 ); g1.getColumnFormatter().setWidth(0, "180"); g1.getColumnFormatter().setWidth(1, "180"); g1.getColumnFormatter().setWidth(2, "180"); int i = 0; g1.setWidget( i, 0, new Label( "Email address:" ) ); g1.getCellFormatter().setHorizontalAlignment(i, 0, HasHorizontalAlignment.ALIGN_RIGHT); final TextBox emailAddress1_box = new TextBox(); emailAddress1_box.setWidth("180"); g1.setWidget( i++, 1, emailAddress1_box ); g1.setWidget( i, 0, new Label( "The address, again:" ) ); g1.getCellFormatter().setHorizontalAlignment(i, 0, HasHorizontalAlignment.ALIGN_RIGHT); final TextBox emailAddress2_box = new TextBox(); emailAddress2_box.setWidth("180"); g1.setWidget( i++, 1, emailAddress2_box ); ClickListener ChangeButtonListener = new ClickListener() { public void onClick( Widget sender ) { boolean formOk = true; for ( int j = 0; j < 2; j++ ) { g1.clearCell( j, 2 ); /* clear previous right-hand-side annotations */ } /* perform checks */ if ( emailAddress1_box.getText().length() < 3 ) { Label l = new Label( "Invalid address!" ); l.setStyleName("euca-error-hint"); g1.setWidget( 0, 2, l ); formOk = false; } if ( !emailAddress1_box.getText().equals( emailAddress2_box.getText() ) ) { Label l = new Label( "Addresses do not match!" ); l.setStyleName("euca-error-hint"); g1.setWidget( 1, 2, l ); formOk = false; } if ( formOk ) { loggedInUser.setEmail( emailAddress1_box.getText() ); label_box.setText( "Checking with the server..." ); label_box.setStyleName("euca-greeting-pending"); EucalyptusWebBackend.App.getInstance().updateUserRecord( sessionId, loggedInUser, new AsyncCallback() { public void onSuccess( final Object result ) { displayWalrusURLChangePage (); } public void onFailure( Throwable caught ) { loggedInUser.setEmail( UserInfoWeb.BOGUS_ENTRY ); displayLoginErrorPage( caught.getMessage() ); } }); } else { label_box.setText( "Please, fix the errors and try again:" ); label_box.setStyleName("euca-greeting-warning"); } } }; Button change_button = new Button( "Change address", ChangeButtonListener ); HTML message = new HTML (admin_email_change_text); message.setWidth( "460" ); VerticalPanel vpanel = new VerticalPanel(); vpanel.setSpacing(15); // vpanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER); if (logo!=null) { vpanel.add (logo); } vpanel.add (label_box); vpanel.add (message); vpanel.add (g1); vpanel.add (change_button); VerticalPanel wrapper = new VerticalPanel(); wrapper.add (vpanel); wrapper.setSize("100%", "100%"); wrapper.setCellHorizontalAlignment(vpanel, VerticalPanel.ALIGN_CENTER); // michael commented out wrapper.setCellVerticalAlignment(vpanel, VerticalPanel.ALIGN_MIDDLE); RootPanel.get().clear(); RootPanel.get().add( wrapper ); } public static SystemConfigWeb conf = new SystemConfigWeb (); public void displayWalrusURLChangePage() { label_box.setText( "One last thing! Really!!!" ); label_box.setStyleName("euca-greeting-error"); HorizontalPanel hpanel = new HorizontalPanel(); hpanel.add (new Label ("Walrus URL:")); final TextBox box = new TextBox (); box.setVisibleLength (55); hpanel.add (box); EucalyptusWebBackend.App.getInstance().getSystemConfig(sessionId, new AsyncCallback( ) { public void onSuccess ( final Object result ) { conf = (SystemConfigWeb) result; box.setText (conf.getCloudHost()); } public void onFailure ( Throwable caught ) { } } ); Button change_button = new Button( "Confirm URL", new ClickListener() { public void onClick( Widget sender ) { conf.setCloudHost(box.getText()); EucalyptusWebBackend.App.getInstance().setSystemConfig(sessionId, conf, new AsyncCallback() { public void onSuccess ( final Object result ) { currentTabIndex = 3; // TODO: change this to confTabIndex displayDefaultPage (""); } public void onFailure ( Throwable caught ) { displayErrorPage ("Failed to save the URL (check 'Configuration' tab)."); } } ); } } ); HTML message = new HTML (admin_cloud_ip_setup_text); message.setWidth( "460" ); VerticalPanel vpanel = new VerticalPanel(); vpanel.setSpacing(15); vpanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER); if (logo!=null) { vpanel.add (logo); } vpanel.add (label_box); vpanel.add (message); vpanel.add (hpanel); vpanel.add (change_button); VerticalPanel wrapper = new VerticalPanel(); wrapper.add (vpanel); wrapper.setSize("100%", "100%"); wrapper.setCellHorizontalAlignment(vpanel, VerticalPanel.ALIGN_CENTER); wrapper.setCellVerticalAlignment(vpanel, VerticalPanel.ALIGN_MIDDLE); RootPanel.get().clear(); RootPanel.get().add (wrapper); } public void displayUsersTab(final VerticalPanel parent) { History.newItem("users"); final HTML msg = new HTML("Contacting the server..."); EucalyptusWebBackend.App.getInstance().getUserRecord( sessionId, "*", /* we want all user records */ new AsyncCallback() { public void onSuccess( Object result ) { List usersList = (List)result; displayUsersList (usersList, parent); } public void onFailure( Throwable caught ) { displayErrorPage (caught.getMessage()); } }); parent.add(msg); } public void displayImagesTab (final VerticalPanel parent) { History.newItem("images"); final HTML msg = new HTML ("Contacting the server..."); EucalyptusWebBackend.App.getInstance().getImageInfo( sessionId, loggedInUser.getUserName(), new AsyncCallback() { public void onSuccess (Object result) { List imagesList = (List)result; displayImagesList (imagesList, parent); } public void onFailure (Throwable caught) { displayErrorPage (caught.getMessage()); } }); parent.add(msg); } private class EucalyptusDialog extends DialogBox { private boolean cancelled; public EucalyptusDialog (String mainMsg, String extraMsg, Button okButton) { super(true); cancelled = false; setHTML (mainMsg); Button cancelButton = new Button ("Cancel", new ClickListener() { public void onClick(Widget sender) { EucalyptusDialog.this.hide(); cancelled = true; } }); HorizontalPanel buttonPanel = new HorizontalPanel(); buttonPanel.add (okButton); buttonPanel.add (cancelButton); setWidget (buttonPanel); center(); } } public void displayConfirmDeletePage( final String userName ) { Button deleteButton = new Button ("Delete", new ClickListener() { public void onClick(Widget sender) { GWTUtils.redirect (GWT.getModuleBaseURL() + "?action=delete" + "&user=" + userName + "&page=" + currentTabIndex); } }); Button okButton = displayDialog ("Sure?", "Do you want to delete user '" + userName + "'?", deleteButton); okButton.setText ("Cancel"); label_box.setStyleName("euca-greeting-warning"); } public void displayConfirmDeletePageNoReload ( final String userName, final VerticalPanel parent ) { Button deleteButton = new Button ("Delete", new ClickListener() { public void onClick(Widget sender) { attemptActionNoReload("delete", userName, parent); } }); Button okButton = displayDialog ("Sure?", "Do you want to delete user '" + userName + "'?", deleteButton); okButton.setText ("Cancel"); label_box.setStyleName("euca-greeting-warning"); } private HTML userActionButton (String action, UserInfoWeb user) { return new HTML ("<a class=\"euca-action-link\" href=\"" + GWT.getModuleBaseURL() + "?action=" + action.toLowerCase() + "&user=" + user.getUserName() + "&page=" + currentTabIndex + "\">" + action + "</a>"); } private HTML userActionButtonNoReload (final String action, final UserInfoWeb user, final VerticalPanel parent) { HTML link = new HTML (action); link.setStyleName("euca-action-link"); link.addClickListener(new ClickListener() { public void onClick (Widget sender) { attemptActionNoReload(action.toLowerCase(), user.getUserName(), parent); } }); return link; } class EditCallback implements ClickListener { private EucalyptusWebInterface parent; private UserInfoWeb u; EditCallback ( final EucalyptusWebInterface parent, UserInfoWeb u ) { this.parent = parent; this.u = u; } public void onClick( final Widget widget ) { displayUserRecordPage (RootPanel.get(), u); } } public void displayUsersList(final List usersList, final VerticalPanel parent) { String sortSymbol = "↓"; // HTML down arrow if (sortUsersLastFirst) { sortSymbol = "↑"; // HTML up arrow } parent.clear(); VerticalPanel vpanel = new VerticalPanel(); vpanel.setSpacing(5); parent.add(new HTML("<h3>Users</h3>")); parent.add(vpanel); int nusers = usersList.size(); if (nusers>0) { Anchor sort_button = new Anchor( sortSymbol, true); sort_button.setStyleName ("euca-small-text"); sort_button.addClickListener( new ClickListener() { public void onClick(Widget sender) { sortUsersLastFirst = !sortUsersLastFirst; displayUsersList (usersList, parent); } }); final Grid g = new Grid(nusers + 1, 6); g.setStyleName("euca-table"); g.setCellPadding(6); g.setWidget(0, 0, sort_button); g.setWidget(0, 1, new Label("Username")); g.setWidget(0, 2, new Label("Email")); g.setWidget(0, 3, new Label("Name")); g.setWidget(0, 4, new Label("Status")); g.setWidget(0, 5, new Label("Actions")); g.getRowFormatter().setStyleName(0, "euca-table-heading-row"); for (int i=0; i<nusers; i++) { int userIndex = i; if (sortUsersLastFirst) { userIndex = nusers - i - 1; } final UserInfoWeb u = (UserInfoWeb) usersList.get(userIndex); int row = i+1; if ((row%2)==1) { g.getRowFormatter().setStyleName(row, "euca-table-odd-row"); } else { g.getRowFormatter().setStyleName(row, "euca-table-even-row"); } Label indexLabel = new Label(Integer.toString(userIndex)); indexLabel.setStyleName("euca-small-text"); g.setWidget(row, 0, indexLabel); Label userLabel = new Label(u.getUserName()); g.setWidget(row, 1, userLabel); Label emailLabel = new Label(u.getEmail()); g.setWidget(row, 2, emailLabel); Label nameLabel = new Label(u.getRealName()); g.setWidget(row, 3, nameLabel); String status; if (u.isApproved() == null || !u.isApproved().booleanValue()) { status = "unapproved"; } else if (u.isEnabled() == null || !u.isEnabled().booleanValue()) { status = "disabled"; } else if (u.isConfirmed() == null || !u.isConfirmed().booleanValue()) { status = "unconfirmed"; } else { status = "active"; } if (u.isAdministrator() != null && u.isAdministrator().booleanValue()) { status += " & admin"; } g.setWidget(row, 4, new Label(status) ); // actions HorizontalPanel ops = new HorizontalPanel(); ops.setSpacing (3); Label editLabel = new Label ("Edit"); editLabel.addClickListener (new EditCallback(this, u)); editLabel.setStyleName ("euca-action-link"); ops.add(editLabel); // admin can't be disabled or deleted (that breaks things) if (u.isAdministrator() == null || !u.isAdministrator().booleanValue()) { HTML act_button = userActionButtonNoReload ("Disable", u, parent); if (u.isApproved() == null || !u.isApproved().booleanValue()) { act_button = userActionButtonNoReload ("Approve", u, parent); } else if (u.isEnabled() == null || !u.isEnabled().booleanValue()) { act_button = userActionButtonNoReload ("Enable", u, parent); } ops.add(act_button); Anchor del_button = new Anchor ( "Delete" ); del_button.setStyleName ("euca-action-link"); del_button.addClickListener( new ClickListener() { public void onClick(Widget sender) { displayConfirmDeletePageNoReload (u.getUserName(), parent); } }); ops.add(del_button); } g.setWidget(row, 5, ops ); // view HorizontalPanel views = new HorizontalPanel(); views.setSpacing (3); HTML inst_button = userActionButton ("Instances", u); views.add(inst_button); HTML img_button = userActionButton ("Images", u); views.add(img_button); //g.setWidget(row, 5, views); TODO: implement 'views' } vpanel.add(g); } else { vpanel.add(new Label("No users found")); } vpanel.add(new Button ("Add user", AddUserButtonListener)); } private HTML imageActionButton (String action, ImageInfoWeb img) { return new HTML ("<a class=\"euca-action-link\" href=\"" + GWT.getModuleBaseURL() + "?action=" + action.toLowerCase() + "_image" + "&id=" + img.getImageId() + "&page=" + currentTabIndex + "\">" + action + "</a>"); } public void displayImagesList(List imagesList, final VerticalPanel parent) { parent.clear(); int nimages = imagesList.size(); boolean showActions = false; if (loggedInUser.isAdministrator() != null && loggedInUser.isAdministrator().booleanValue()) { showActions = true; } if (nimages>0) { final Grid g = new Grid(nimages + 1, 6); g.setStyleName("euca-table"); g.setCellPadding(6); g.setWidget(0, 0, new Label("Id")); g.setWidget(0, 1, new Label("Name")); g.setWidget(0, 2, new Label("Kernel")); g.setWidget(0, 3, new Label("Ramdisk")); g.setWidget(0, 4, new Label("State")); if ( showActions ) g.setWidget(0, 5, new Label("Actions")); g.getRowFormatter().setStyleName(0, "euca-table-heading-row"); for (int i=0; i<nimages; i++) { ImageInfoWeb img = (ImageInfoWeb) imagesList.get(i); int row = i+1; if ((row%2)==1) { g.getRowFormatter().setStyleName(row, "euca-table-odd-row"); } else { g.getRowFormatter().setStyleName(row, "euca-table-even-row"); } g.setWidget(row, 0, new Label (img.getImageId()) ); g.setWidget(row, 1, new Label (img.getImageLocation()) ); g.setWidget(row, 2, new Label (img.getKernelId()) ); g.setWidget(row, 3, new Label (img.getRamdiskId()) ); g.setWidget(row, 4, new Label (img.getImageState())); if ( showActions ) { HorizontalPanel ops = new HorizontalPanel(); ops.setSpacing (3); HTML act_button = imageActionButton ("Disable", img); if (img.getImageState().equalsIgnoreCase("deregistered")) { act_button = imageActionButton ("Enable", img); } ops.add(act_button); // TODO: uncomment when deletion is implemented //HTML del_button = imageActionButton ("Delete", img); //ops.add(del_button); g.setWidget(row, 5, ops ); } } parent.add(g); } else { parent.add(new Label("No images found")); } } public void displayConfTab (final VerticalPanel parent) { History.newItem("conf"); VerticalPanel vpanel = new VerticalPanel(); vpanel.setSpacing(15); //vpanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER); // michael had this commented out vpanel.add (new SystemConfigTable (sessionId)); vpanel.add (new WalrusInfoTable (sessionId)); vpanel.add (new ClusterInfoTable (sessionId)); vpanel.add (new VmTypeTable (sessionId)); parent.clear(); parent.add (vpanel); } public void displayDownloadsTab (final VerticalPanel parent) { History.newItem("extras"); VerticalPanel vpanel = new VerticalPanel(); vpanel.setSpacing(15); //vpanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER); vpanel.add (new DownloadsTable(sessionId, "http://www.eucalyptussoftware.com/downloads/eucalyptus-images/list.php?version=" + URL.encode(version), "http://open.eucalyptus.com/wiki/EucalyptusUserImageCreatorGuide_v1.6", "Eucalyptus-certified Images", 50)); vpanel.add (new DownloadsTable(sessionId, "http://www.eucalyptussoftware.com/downloads/eucalyptus-tools/list.php?version=" + URL.encode(version), "http://open.eucalyptus.com/wiki/ToolsEcosystem", "Eucalyptus-compatible Tools", 50)); parent.clear(); parent.add (vpanel); } public void displayStoreTab (final VerticalPanel parent) { History.newItem ("store"); ImageStoreClient imageStoreClient = new ImageStoreClient(sessionId); ImageStoreWidget imageStore = new ImageStoreWidget(imageStoreClient); parent.clear(); parent.add(imageStore); } public void displayFirstTimeConfiguration() { displayStatusPage("Loading first-time configuration page..."); VerticalPanel gpanel = new VerticalPanel(); gpanel.setSpacing(25); gpanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER); // password grid final Grid g1 = new Grid ( 2, 3 ); g1.getColumnFormatter().setWidth(0, "240"); g1.getColumnFormatter().setWidth(1, "180"); g1.getColumnFormatter().setWidth(2, "180"); int i = 0; final int newPassword1_row = i; g1.setWidget( i, 0, new Label( "Administrator's new password:" ) ); g1.getCellFormatter().setHorizontalAlignment(i, 0, HasHorizontalAlignment.ALIGN_RIGHT); final PasswordTextBox newCleartextPassword1_box = new PasswordTextBox(); newCleartextPassword1_box.setFocus(true); // this box gets focus first newCleartextPassword1_box.setWidth("180"); g1.setWidget( i++, 1, newCleartextPassword1_box ); final int newPassword2_row = i; g1.setWidget( i, 0, new Label( "The password, again:" ) ); g1.getCellFormatter().setHorizontalAlignment(i, 0, HasHorizontalAlignment.ALIGN_RIGHT); final PasswordTextBox newCleartextPassword2_box = new PasswordTextBox(); newCleartextPassword2_box.setWidth("180"); g1.setWidget( i++, 1, newCleartextPassword2_box ); gpanel.add(g1); // email address grid final Grid g2 = new Grid ( 1, 3 ); g2.getColumnFormatter().setWidth(0, "240"); g2.getColumnFormatter().setWidth(1, "180"); g2.getColumnFormatter().setWidth(2, "180"); i = 0; final int emailAddress_row = i; g2.setWidget( i, 0, new Label( "Administrator's email address:" ) ); g2.getCellFormatter().setHorizontalAlignment(i, 0, HasHorizontalAlignment.ALIGN_RIGHT); final TextBox emailAddress_box = new TextBox(); emailAddress_box.setWidth("180"); g2.setWidget( i++, 1, emailAddress_box ); VerticalPanel epanel = new VerticalPanel(); epanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER); epanel.setSpacing(5); epanel.add(g2); HTML emailChangeMsg = new HTML( admin_email_change_text ); emailChangeMsg.setWidth ("300"); emailChangeMsg.setStyleName("euca-small-text"); epanel.add(emailChangeMsg); gpanel.add(epanel); // cloud URL grid final Grid g3 = new Grid ( 1, 3 ); g3.getColumnFormatter().setWidth(0, "240"); g3.getColumnFormatter().setWidth(1, "180"); g3.getColumnFormatter().setWidth(2, "180"); i = 0; final int cloudUrl_row = i; g3.setWidget( i, 0, new Label( "Cloud Host:" ) ); g3.getCellFormatter().setHorizontalAlignment(i, 0, HasHorizontalAlignment.ALIGN_RIGHT); final TextBox cloudUrl_box = new TextBox(); cloudUrl_box.setWidth("180"); g3.setWidget( i++, 1, cloudUrl_box ); VerticalPanel cpanel = new VerticalPanel(); cpanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER); cpanel.setSpacing(5); cpanel.add(g3); HTML cloudUrlMsg = new HTML ( admin_cloud_ip_setup_text ); cloudUrlMsg.setWidth ("300"); cloudUrlMsg.setStyleName("euca-small-text"); cpanel.add (cloudUrlMsg); gpanel.add(cpanel); // pull in guessed cloud URL EucalyptusWebBackend.App.getInstance().getSystemConfig(sessionId, new AsyncCallback( ) { public void onSuccess ( final Object result ) { conf = (SystemConfigWeb) result; cloudUrl_box.setText (conf.getCloudHost()); } public void onFailure ( Throwable caught ) { } } ); // user clicked submit Button change_button = new Button( "Submit", new ClickListener() { public void onClick( Widget sender ) { boolean formOk = true; g1.clearCell( 0, 2 ); // clear previous right-hand-side annotations g1.clearCell( 1, 2 ); // clear previous right-hand-side annotations g2.clearCell( 0, 2 ); // clear previous right-hand-side annotations g3.clearCell( 0, 2 ); // clear previous right-hand-side annotations // perform checks if ( newCleartextPassword1_box.getText().length() < minPasswordLength ) { Label l = new Label( "Password is too short!" ); l.setStyleName("euca-error-hint"); g1.setWidget( newPassword1_row, 2, l ); formOk = false; } if ( !newCleartextPassword1_box.getText().equals( newCleartextPassword2_box.getText() ) ) { Label l = new Label( "Passwords do not match!" ); l.setStyleName("euca-error-hint"); g1.setWidget( newPassword2_row, 2, l ); formOk = false; } if ( emailAddress_box.getText().length() < 1 ) { Label l = new Label( "Email address is empty!" ); l.setStyleName("euca-error-hint"); g2.setWidget( emailAddress_row, 2, l ); formOk = false; } if ( cloudUrl_box.getText().length() < 1 ) { Label l = new Label( "Cloud URL is empty!" ); l.setStyleName("euca-error-hint"); g3.setWidget( cloudUrl_row, 2, l ); formOk = false; } if ( !formOk ) { label_box.setText( "Please, fix the errors and try again:" ); label_box.setStyleName("euca-greeting-warning"); return; } label_box.setText( "Checking with the server..." ); label_box.setStyleName("euca-greeting-pending"); loggedInUser.setEmail( emailAddress_box.getText() ); loggedInUser.setPassword(GWTUtils.md5(newCleartextPassword1_box.getText())); EucalyptusWebBackend.App.getInstance().updateUserRecord( sessionId, loggedInUser, new AsyncCallback() { public void onSuccess( final Object result ) { // password change succeded - pull in the new user record label_box.setText( "Refreshing user data..." ); EucalyptusWebBackend.App.getInstance().getUserRecord( sessionId, null, new AsyncCallback() { public void onSuccess( Object result2 ) { loggedInUser = ( UserInfoWeb ) ( (List) result2).get(0); // update cloud URL conf.setCloudHost(cloudUrl_box.getText()); EucalyptusWebBackend.App.getInstance().setSystemConfig(sessionId, conf, new AsyncCallback() { public void onSuccess ( final Object result ) { currentTabIndex = 3; // TODO: change this to confTabIndex when it's available displayDefaultPage (""); } public void onFailure ( Throwable caught ) { displayErrorPage ("Failed to save the cloud URL (check 'Configuration' tab)."); } } ); } public void onFailure( Throwable caught ) { displayLoginErrorPage( caught.getMessage() ); } }); } public void onFailure( Throwable caught ) { loggedInUser.setEmail( UserInfoWeb.BOGUS_ENTRY ); String m = caught.getMessage(); label_box.setText( m ); label_box.setStyleName("euca-greeting-warning"); } }); } } ); EucalyptusKeyboardListener sl = new EucalyptusKeyboardListener(change_button); change_button.addKeyboardListener(sl); newCleartextPassword1_box.addKeyboardListener(sl); newCleartextPassword2_box.addKeyboardListener(sl); emailAddress_box.addKeyboardListener(sl); cloudUrl_box.addKeyboardListener(sl); HTML message = new HTML (admin_first_time_config_text); message.setWidth( "600" ); VerticalPanel vpanel = new VerticalPanel(); vpanel.setSpacing(15); vpanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER); if (logo!=null) { vpanel.add (logo); } label_box.setText( "First-time Configuration" ); label_box.setStyleName("euca-greeting-normal"); vpanel.add (label_box); vpanel.add (message); vpanel.add (gpanel); vpanel.add (change_button); VerticalPanel wrapper = new VerticalPanel(); wrapper.add (vpanel); wrapper.setSize("100%", "100%"); wrapper.setCellHorizontalAlignment(vpanel, VerticalPanel.ALIGN_CENTER); wrapper.setCellVerticalAlignment(vpanel, VerticalPanel.ALIGN_MIDDLE); // michael commented out RootPanel.get().clear(); RootPanel.get().add (wrapper); } }