modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RoleEditView.java
| 2
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RolesView.java
| 3
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UserEditView.java
| 6
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UsersDataSource.java
| 4
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UsersView.java
| 5
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/AbstractAlertDefinitionsView.java
| 13 +
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/GeneralPropertiesAlertDefinitionForm.java
| 4
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/deployment/BundleDeploymentListView.java
| 11 +
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/deployment/BundleDeploymentView.java
| 7
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/destination/BundleDestinationListView.java
| 16 +-
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/destination/BundleDestinationView.java
| 11 -
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/list/BundleView.java
| 5
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/list/BundlesListView.java
| 11 +
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/revert/GetRevertInfoStep.java
| 16 +-
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/tree/BundleTreeDataSource.java
| 10 -
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java
| 5
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/EnhancedDynamicForm.java
| 8 -
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/EscapedHtmlCellFormatter.java
| 19 ++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/IconField.java
| 73 ++++++++++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/TableSection.java
| 14 +
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/tree/EnhancedTreeNode.java
| 6
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/recent/problems/ProblemResourcesPortlet.java
| 6
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/util/MessagePortlet.java
| 11 -
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/operation/history/AbstractOperationHistoryDetailsView.java
| 2
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/operation/schedule/AbstractOperationScheduleDetailsView.java
| 4
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/summary/AbstractActivityView.java
| 2
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/ResourceGroupTreeView.java
| 10 -
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/AncestryUtil.java
| 58 ++++---
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceSearchView.java
| 23 +--
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTitleBar.java
| 3
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeDatasource.java
| 8 -
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/StringUtility.java
| 65 ++++++++
32 files changed, 343 insertions(+), 98 deletions(-)
New commits:
commit ce940eefcecc42c3a4c545dc17010d7773725a6c
Author: Ian Springer <ian.springer(a)redhat.com>
Date: Thu Mar 31 17:28:25 2011 -0400
...
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/StringUtility.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/StringUtility.java
index 0c93099..e14b9db 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/StringUtility.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/StringUtility.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright 2011, Red Hat Middleware LLC, and individual contributors
+ * Copyright 2010-2011, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
@@ -19,6 +19,9 @@
*/
package org.rhq.enterprise.gui.coregui.client.util;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* A collection of utility methods for working with Strings.
*
@@ -27,6 +30,41 @@ package org.rhq.enterprise.gui.coregui.client.util;
public class StringUtility {
/**
+ * Split a string on delimiter boundaries, and place each element into a List.
+ *
+ * @param s String to split up
+ * @param delim Delimiting token, ala StringTokenizer
+ *
+ * @return a List comprised of elements split by the tokenizing
+ */
+ public static List<String> explode(String s, String delim) {
+ List<String> res = new ArrayList<String>();
+ if (s == null)
+ return res;
+
+ String[] tokens = s.split(delim);
+ for (String token : tokens) {
+ res.add(token);
+ }
+
+ return res;
+ }
+
+ // TODO: I18N. The logic here may need to be pluggable for different localizations.
+ public static String pluralize(String singularNoun) {
+ String pluralNoun;
+ if (singularNoun.endsWith("y") &&
!singularNoun.endsWith("ay") && !singularNoun.endsWith("ey")
+ && !singularNoun.endsWith("oy")) {
+ pluralNoun = singularNoun.substring(0, singularNoun.length() - 1) +
"ies";
+ } else if (!singularNoun.endsWith("s")) {
+ pluralNoun = singularNoun + "s";
+ } else {
+ pluralNoun = singularNoun;
+ }
+ return pluralNoun;
+ }
+
+ /**
* Escapes HTML in a string to eliminate cross site scripting (XSS) vulnerabilities.
Note, this impl is designed
* to be highly efficient to minimize the impact on performance.
*
commit 170b9a147fce855f8196a7e13803e5a0e3d2f7bb
Author: Ian Springer <ian.springer(a)redhat.com>
Date: Thu Mar 31 17:25:56 2011 -0400
escape or sanitize HTML in user-controlled text, which could be used for XSS attacks
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RoleEditView.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RoleEditView.java
index 58cde04..178acd0 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RoleEditView.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RoleEditView.java
@@ -305,11 +305,13 @@ public class RoleEditView extends
AbstractRecordEditor<RolesDataSource> implemen
TextItem nameItem = new TextItem(RolesDataSource.Field.NAME);
nameItem.setShowTitle(true);
+ nameItem.setAttribute(EnhancedDynamicForm.OUTPUT_AS_HTML_ATTRIBUTE, true);
items.add(nameItem);
TextItem descriptionItem = new TextItem(RolesDataSource.Field.DESCRIPTION);
descriptionItem.setShowTitle(true);
descriptionItem.setColSpan(form.getNumCols());
+ descriptionItem.setAttribute(EnhancedDynamicForm.OUTPUT_AS_HTML_ATTRIBUTE,
true);
items.add(descriptionItem);
return items;
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RolesView.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RolesView.java
index 46fa148..6aaf418 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RolesView.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RolesView.java
@@ -34,6 +34,7 @@ import org.rhq.enterprise.gui.coregui.client.BookmarkableView;
import org.rhq.enterprise.gui.coregui.client.PermissionsLoadedListener;
import org.rhq.enterprise.gui.coregui.client.PermissionsLoader;
import org.rhq.enterprise.gui.coregui.client.admin.AdministrationView;
+import org.rhq.enterprise.gui.coregui.client.components.table.EscapedHtmlCellFormatter;
import org.rhq.enterprise.gui.coregui.client.components.table.TableAction;
import org.rhq.enterprise.gui.coregui.client.components.table.TableSection;
import org.rhq.enterprise.gui.coregui.client.components.view.ViewName;
@@ -62,6 +63,7 @@ public class RolesView extends TableSection<RolesDataSource>
implements Bookmark
final RolesDataSource datasource = RolesDataSource.getInstance();
setDataSource(datasource);
setHeaderIcon(HEADER_ICON);
+ setEscapeHtmlInDetailsLinkColumn(true);
}
@Override
@@ -108,6 +110,7 @@ public class RolesView extends TableSection<RolesDataSource>
implements Bookmark
fields.add(nameField);
ListGridField descriptionField = new
ListGridField(RolesDataSource.Field.DESCRIPTION);
+ descriptionField.setCellFormatter(new EscapedHtmlCellFormatter());
fields.add(descriptionField);
return fields;
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UserEditView.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UserEditView.java
index 4ce9950..ba10fef 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UserEditView.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UserEditView.java
@@ -137,6 +137,7 @@ public class UserEditView extends
AbstractRecordEditor<UsersDataSource> {
nameItem = new TextItem(UsersDataSource.Field.NAME);
} else {
nameItem = new StaticTextItem(UsersDataSource.Field.NAME);
+ ((StaticTextItem)nameItem).setOutputAsHTML(true);
}
items.add(nameItem);
@@ -167,20 +168,25 @@ public class UserEditView extends
AbstractRecordEditor<UsersDataSource> {
TextItem firstNameItem = new TextItem(UsersDataSource.Field.FIRST_NAME);
firstNameItem.setShowTitle(true);
+ firstNameItem.setAttribute(EnhancedDynamicForm.OUTPUT_AS_HTML_ATTRIBUTE, true);
items.add(firstNameItem);
TextItem lastNameItem = new TextItem(UsersDataSource.Field.LAST_NAME);
lastNameItem.setShowTitle(true);
+ lastNameItem.setAttribute(EnhancedDynamicForm.OUTPUT_AS_HTML_ATTRIBUTE, true);
items.add(lastNameItem);
TextItem emailAddressItem = new TextItem(UsersDataSource.Field.EMAIL_ADDRESS);
emailAddressItem.setShowTitle(true);
+ emailAddressItem.setAttribute(EnhancedDynamicForm.OUTPUT_AS_HTML_ATTRIBUTE,
true);
items.add(emailAddressItem);
TextItem phoneNumberItem = new TextItem(UsersDataSource.Field.PHONE_NUMBER);
+ phoneNumberItem.setAttribute(EnhancedDynamicForm.OUTPUT_AS_HTML_ATTRIBUTE,
true);
items.add(phoneNumberItem);
TextItem departmentItem = new TextItem(UsersDataSource.Field.DEPARTMENT);
+ departmentItem.setAttribute(EnhancedDynamicForm.OUTPUT_AS_HTML_ATTRIBUTE, true);
items.add(departmentItem);
boolean userBeingEditedIsRhqadmin = (getRecordId() == SUBJECT_ID_RHQADMIN);
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UsersDataSource.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UsersDataSource.java
index d6f536b..6bdf6a5 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UsersDataSource.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UsersDataSource.java
@@ -107,7 +107,9 @@ public class UsersDataSource extends RPCDataSource<Subject,
SubjectCriteria> {
fields.add(idDataField);
DataSourceTextField usernameField = createTextField(Field.NAME,
MSG.dataSource_users_field_name(), 3, 100, true);
-
+ // Don't allow characters that could be used in HTML intended for an XSS
attack.
+ RegExpValidator regExpValidator = new
RegExpValidator("[^&<]*");
+ usernameField.setValidators(regExpValidator);
fields.add(usernameField);
DataSourceTextField ldapField = createBooleanField(Field.LDAP,
MSG.dataSource_users_field_ldap(), true);
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UsersView.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UsersView.java
index f124703..4fae91e 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UsersView.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UsersView.java
@@ -33,6 +33,7 @@ import org.rhq.core.domain.authz.Permission;
import org.rhq.enterprise.gui.coregui.client.PermissionsLoadedListener;
import org.rhq.enterprise.gui.coregui.client.PermissionsLoader;
import org.rhq.enterprise.gui.coregui.client.admin.AdministrationView;
+import org.rhq.enterprise.gui.coregui.client.components.table.EscapedHtmlCellFormatter;
import org.rhq.enterprise.gui.coregui.client.components.table.TableAction;
import org.rhq.enterprise.gui.coregui.client.components.table.TableSection;
import org.rhq.enterprise.gui.coregui.client.components.view.ViewName;
@@ -64,6 +65,7 @@ public class UsersView extends TableSection<UsersDataSource> {
setDataSource(dataSource);
setHeaderIcon(HEADER_ICON);
+ setEscapeHtmlInDetailsLinkColumn(true);
fetchManageSecurityPermissionAsync();
}
@@ -131,12 +133,15 @@ public class UsersView extends TableSection<UsersDataSource>
{
fields.add(ldapField);
ListGridField firstNameField = new
ListGridField(UsersDataSource.Field.FIRST_NAME, 150);
+ firstNameField.setCellFormatter(new EscapedHtmlCellFormatter());
fields.add(firstNameField);
ListGridField lastNameField = new ListGridField(UsersDataSource.Field.LAST_NAME,
150);
+ lastNameField.setCellFormatter(new EscapedHtmlCellFormatter());
fields.add(lastNameField);
ListGridField departmentField = new
ListGridField(UsersDataSource.Field.DEPARTMENT, 150);
+ departmentField.setCellFormatter(new EscapedHtmlCellFormatter());
fields.add(departmentField);
// TODO: instead of fetching roles, use a composite object that will pull the
role count across the wire.
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/AbstractAlertDefinitionsView.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/AbstractAlertDefinitionsView.java
index 376d659..4d8b846 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/AbstractAlertDefinitionsView.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/AbstractAlertDefinitionsView.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2010 Red Hat, Inc.
+ * Copyright (C) 2005-2011 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -21,6 +21,7 @@ package org.rhq.enterprise.gui.coregui.client.alert.definitions;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.smartgwt.client.data.Criteria;
import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.grid.CellFormatter;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;
@@ -34,9 +35,11 @@ import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.gui.coregui.client.CoreGUI;
import org.rhq.enterprise.gui.coregui.client.components.table.AbstractTableAction;
+import org.rhq.enterprise.gui.coregui.client.components.table.EscapedHtmlCellFormatter;
import org.rhq.enterprise.gui.coregui.client.components.table.TableActionEnablement;
import org.rhq.enterprise.gui.coregui.client.components.table.TableSection;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
+import org.rhq.enterprise.gui.coregui.client.util.StringUtility;
/**
* Superclass to the different alert definition views. This should be subclassed
@@ -48,6 +51,8 @@ public abstract class AbstractAlertDefinitionsView extends
TableSection<Abstract
public AbstractAlertDefinitionsView(String locatorId, String tableTitle) {
super(locatorId, tableTitle);
+
+ setEscapeHtmlInDetailsLinkColumn(true);
}
@Override
@@ -66,6 +71,12 @@ public abstract class AbstractAlertDefinitionsView extends
TableSection<Abstract
listGrid.setFixedRecordHeights(false);
//listGrid.getField("id").setWidth(55);
+ // name and description are user-editable, so escape HTML to prevent XSS attacks
+ ListGridField nameField =
listGrid.getField(AbstractAlertDefinitionsDataSource.FIELD_NAME);
+ nameField.setCellFormatter(new EscapedHtmlCellFormatter());
+ ListGridField descriptionField =
listGrid.getField(AbstractAlertDefinitionsDataSource.FIELD_DESCRIPTION);
+ descriptionField.setCellFormatter(new EscapedHtmlCellFormatter());
+
boolean permitted = isAllowedToModifyAlertDefinitions();
TableActionEnablement enablement = (permitted) ? TableActionEnablement.ALWAYS :
TableActionEnablement.NEVER;
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/GeneralPropertiesAlertDefinitionForm.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/GeneralPropertiesAlertDefinitionForm.java
index 90f09f4..7d6b0d5 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/GeneralPropertiesAlertDefinitionForm.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/GeneralPropertiesAlertDefinitionForm.java
@@ -209,11 +209,15 @@ public class GeneralPropertiesAlertDefinitionForm extends
LocatableDynamicForm i
nameTextField.setWidth(300);
nameTextField.setDefaultValue("");
nameStatic = new StaticTextItem("nameStatic",
MSG.common_title_name());
+ // name is user-editable, so escape HTML to prevent XSS attacks
+ nameStatic.setOutputAsHTML(true);
descriptionTextField = new TextAreaItem("description",
MSG.common_title_description());
descriptionTextField.setWidth(300);
descriptionTextField.setDefaultValue("");
descriptionStatic = new StaticTextItem("descriptionStatic",
MSG.common_title_description());
+ // description is user-editable, so escape HTML to prevent XSS attacks
+ descriptionStatic.setOutputAsHTML(true);
prioritySelection = new SelectItem("priority",
MSG.view_alerts_field_priority());
LinkedHashMap<String, String> priorities = new LinkedHashMap<String,
String>(3);
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/deployment/BundleDeploymentListView.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/deployment/BundleDeploymentListView.java
index 42711b6..b2763d9 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/deployment/BundleDeploymentListView.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/deployment/BundleDeploymentListView.java
@@ -40,8 +40,10 @@ import org.rhq.enterprise.gui.coregui.client.CoreGUI;
import org.rhq.enterprise.gui.coregui.client.ErrorMessageWindow;
import org.rhq.enterprise.gui.coregui.client.LinkManager;
import org.rhq.enterprise.gui.coregui.client.bundle.list.BundleVersionDataSource;
+import org.rhq.enterprise.gui.coregui.client.components.table.EscapedHtmlCellFormatter;
import org.rhq.enterprise.gui.coregui.client.components.table.Table;
import org.rhq.enterprise.gui.coregui.client.components.table.TimestampCellFormatter;
+import org.rhq.enterprise.gui.coregui.client.util.StringUtility;
/**
* @author Greg Hinkle
@@ -76,16 +78,21 @@ public class BundleDeploymentListView extends
Table<BundleDeploymentDataSource>
// only users that are authorized can see deployments
if (canManageBundles) {
nameField.setCellFormatter(new CellFormatter() {
- public String format(Object o, ListGridRecord record, int i, int i1) {
+ public String format(Object value, ListGridRecord record, int i, int i1)
{
return "<a href=\""
+ LinkManager.getBundleDeploymentLink(record
.getAttributeAsInt(BundleDeploymentDataSource.FIELD_BUNDLE_ID), record
- .getAttributeAsInt(BundleDeploymentDataSource.FIELD_ID)) +
"\">" + String.valueOf(o)
+ .getAttributeAsInt(BundleDeploymentDataSource.FIELD_ID)) +
"\">"
+ + StringUtility.escapeHtml(String.valueOf(value))
+ "</a>";
}
});
+ } else {
+ nameField.setCellFormatter(new EscapedHtmlCellFormatter());
}
+ descriptionField.setCellFormatter(new EscapedHtmlCellFormatter());
+
bundleVersionField.setCellFormatter(new CellFormatter() {
public String format(Object o, ListGridRecord record, int i, int i1) {
return "<a href=\""
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/deployment/BundleDeploymentView.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/deployment/BundleDeploymentView.java
index c00a454..62bf4ed 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/deployment/BundleDeploymentView.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/deployment/BundleDeploymentView.java
@@ -77,6 +77,7 @@ import
org.rhq.enterprise.gui.coregui.client.components.tagging.TagEditorView;
import org.rhq.enterprise.gui.coregui.client.components.tagging.TagsChangedCallback;
import org.rhq.enterprise.gui.coregui.client.gwt.BundleGWTServiceAsync;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
+import org.rhq.enterprise.gui.coregui.client.util.StringUtility;
import org.rhq.enterprise.gui.coregui.client.util.message.Message;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableDynamicForm;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableIButton;
@@ -146,7 +147,7 @@ public class BundleDeploymentView extends LocatableVLayout implements
Bookmarkab
LinkItem bundleName = new LinkItem("bundle");
bundleName.setTitle(MSG.view_bundle_bundle());
bundleName.setValue(LinkManager.getBundleLink(bundle.getId()));
- bundleName.setLinkTitle(bundle.getName());
+ bundleName.setLinkTitle(StringUtility.escapeHtml(bundle.getName()));
bundleName.setTarget("_self");
CanvasItem actionItem = new CanvasItem("actions");
@@ -172,14 +173,14 @@ public class BundleDeploymentView extends LocatableVLayout
implements Bookmarkab
LinkItem destinationGroup = new LinkItem("group");
destinationGroup.setTitle(MSG.common_title_resource_group());
destinationGroup.setValue(LinkManager.getResourceGroupLink(deployment.getDestination().getGroup().getId()));
- destinationGroup.setLinkTitle(deployment.getDestination().getGroup().getName());
+
destinationGroup.setLinkTitle(StringUtility.escapeHtml((deployment.getDestination().getGroup().getName())));
destinationGroup.setTarget("_self");
StaticTextItem path = new StaticTextItem("path",
MSG.view_bundle_deployDir());
path.setValue(deployment.getDestination().getDeployDir());
StaticTextItem description = new StaticTextItem("description",
MSG.common_title_description());
- description.setValue(deployment.getDescription());
+ description.setValue(StringUtility.escapeHtml(deployment.getDescription()));
StaticTextItem status = new StaticTextItem("status",
MSG.common_title_status());
status.setValue(deployment.getStatus().name());
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/destination/BundleDestinationListView.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/destination/BundleDestinationListView.java
index d3ca12c..bbd20f6 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/destination/BundleDestinationListView.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/destination/BundleDestinationListView.java
@@ -38,6 +38,7 @@ import org.rhq.enterprise.gui.coregui.client.CoreGUI;
import org.rhq.enterprise.gui.coregui.client.LinkManager;
import org.rhq.enterprise.gui.coregui.client.components.table.Table;
import org.rhq.enterprise.gui.coregui.client.components.table.TimestampCellFormatter;
+import org.rhq.enterprise.gui.coregui.client.util.StringUtility;
/**
* @author Greg Hinkle
@@ -77,24 +78,27 @@ public class BundleDestinationListView extends
Table<BundleDestinationDataSource
TimestampCellFormatter.prepareDateField(latestDeploymentDateField);
nameField.setCellFormatter(new CellFormatter() {
- public String format(Object o, ListGridRecord listGridRecord, int i, int i1)
{
+ public String format(Object value, ListGridRecord listGridRecord, int i, int
i1) {
Integer bundleId =
listGridRecord.getAttributeAsInt(BundleDestinationDataSource.FIELD_BUNDLE_ID);
Integer bundleDestId =
listGridRecord.getAttributeAsInt(BundleDestinationDataSource.FIELD_ID);
- return "<a href=\"" +
LinkManager.getBundleDestinationLink(bundleId, bundleDestId) + "\">" + o
+ "</a>";
+ return "<a href=\"" +
LinkManager.getBundleDestinationLink(bundleId, bundleDestId) + "\">"
+ + StringUtility.escapeHtml(value.toString()) +
"</a>";
}
});
groupNameField.setCellFormatter(new CellFormatter() {
- public String format(Object o, ListGridRecord listGridRecord, int i, int i1)
{
+ public String format(Object value, ListGridRecord listGridRecord, int i, int
i1) {
Integer groupId =
listGridRecord.getAttributeAsInt(BundleDestinationDataSource.FIELD_GROUP_ID);
- return "<a href=\"" +
LinkManager.getResourceGroupLink(groupId) + "\">" + o +
"</a>";
+ return "<a href=\"" +
LinkManager.getResourceGroupLink(groupId) + "\">"
+ + StringUtility.escapeHtml(value.toString()) +
"</a>";
}
});
bundleNameField.setCellFormatter(new CellFormatter() {
- public String format(Object o, ListGridRecord listGridRecord, int i, int i1)
{
+ public String format(Object value, ListGridRecord listGridRecord, int i, int
i1) {
Integer bid =
listGridRecord.getAttributeAsInt(BundleDestinationDataSource.FIELD_BUNDLE_ID);
- return "<a href=\"" + LinkManager.getBundleLink(bid) +
"\">" + o + "</a>";
+ return "<a href=\"" + LinkManager.getBundleLink(bid) +
"\">"
+ + StringUtility.escapeHtml(value.toString()) +
"</a>";
}
});
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/destination/BundleDestinationView.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/destination/BundleDestinationView.java
index da52896..0a805e0 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/destination/BundleDestinationView.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/destination/BundleDestinationView.java
@@ -57,6 +57,7 @@ import
org.rhq.enterprise.gui.coregui.client.components.tagging.TagEditorView;
import org.rhq.enterprise.gui.coregui.client.components.tagging.TagsChangedCallback;
import org.rhq.enterprise.gui.coregui.client.gwt.BundleGWTServiceAsync;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
+import org.rhq.enterprise.gui.coregui.client.util.StringUtility;
import org.rhq.enterprise.gui.coregui.client.util.message.Message;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableDynamicForm;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableIButton;
@@ -89,10 +90,10 @@ public class BundleDestinationView extends LocatableVLayout implements
Bookmarka
this.bundle = bundleDestination.getBundle();
BackButton backButton = new BackButton(extendLocatorId("BackButton"),
MSG.view_bundle_dest_backToBundle()
- + ": " + bundle.getName(), "Bundles/Bundle/" +
bundle.getId());
+ + ": " + StringUtility.escapeHtml(bundle.getName()),
"Bundles/Bundle/" + bundle.getId());
HeaderLabel header = new
HeaderLabel(Canvas.getImgURL("subsystems/bundle/BundleDestination_24.png"),
- destination.getName());
+ StringUtility.escapeHtml(destination.getName()));
detail = new Canvas();
detail.setHeight("50%");
@@ -121,7 +122,7 @@ public class BundleDestinationView extends LocatableVLayout implements
Bookmarka
LinkItem bundleName = new LinkItem("bundle");
bundleName.setTitle(MSG.view_bundle_bundle());
bundleName.setValue(LinkManager.getBundleLink(bundle.getId()));
- bundleName.setLinkTitle(bundle.getName());
+ bundleName.setLinkTitle(StringUtility.escapeHtml(bundle.getName()));
bundleName.setTarget("_self");
CanvasItem actionItem = new CanvasItem("actions");
@@ -136,14 +137,14 @@ public class BundleDestinationView extends LocatableVLayout
implements Bookmarka
LinkItem destinationGroup = new LinkItem("group");
destinationGroup.setTitle(MSG.view_bundle_dest_group());
destinationGroup.setValue(LinkManager.getResourceGroupLink(destination.getGroup().getId()));
- destinationGroup.setLinkTitle(destination.getGroup().getName());
+
destinationGroup.setLinkTitle(StringUtility.escapeHtml(destination.getGroup().getName()));
destinationGroup.setTarget("_self");
StaticTextItem path = new StaticTextItem("path",
MSG.view_bundle_dest_deployDir());
path.setValue(destination.getDeployDir());
StaticTextItem description = new StaticTextItem("description",
MSG.common_title_description());
- description.setValue(destination.getDescription());
+ description.setValue(StringUtility.escapeHtml(destination.getDescription()));
form.setFields(bundleName, actionItem, created, destinationGroup, path,
description);
return form;
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/list/BundleView.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/list/BundleView.java
index f4801ea..74eaa68 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/list/BundleView.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/list/BundleView.java
@@ -60,6 +60,7 @@ import
org.rhq.enterprise.gui.coregui.client.components.tagging.TagEditorView;
import org.rhq.enterprise.gui.coregui.client.components.tagging.TagsChangedCallback;
import org.rhq.enterprise.gui.coregui.client.gwt.BundleGWTServiceAsync;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
+import org.rhq.enterprise.gui.coregui.client.util.StringUtility;
import org.rhq.enterprise.gui.coregui.client.util.message.Message;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableDynamicForm;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableIButton;
@@ -98,7 +99,7 @@ public class BundleView extends LocatableVLayout implements
BookmarkableView {
BackButton backButton = new BackButton(extendLocatorId("BackButton"),
MSG.view_bundle_list_backToAll(),
BundleTopView.VIEW_ID.getTitle());
- headerLabel = new HeaderLabel("subsystems/bundle/Bundle_24.png",
bundle.getName());
+ headerLabel = new HeaderLabel("subsystems/bundle/Bundle_24.png",
StringUtility.escapeHtml(bundle.getName()));
tabs = new LocatableTabSet(getLocatorId());
versionsTab = createVersionsTab();
destinationsTab = createDestinationsTab();
@@ -188,7 +189,7 @@ public class BundleView extends LocatableVLayout implements
BookmarkableView {
destinationsCountItem.setValue(bundle.getDestinations() != null ?
bundle.getDestinations().size() : 0);
StaticTextItem descriptionItem = new StaticTextItem("description",
MSG.common_title_description());
- descriptionItem.setValue(bundle.getDescription());
+ descriptionItem.setValue(StringUtility.escapeHtml(bundle.getDescription()));
form.setFields(versionCountItem, actionItem, destinationsCountItem,
descriptionItem);
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/list/BundlesListView.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/list/BundlesListView.java
index 023fd1f..ea25046 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/list/BundlesListView.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/list/BundlesListView.java
@@ -47,6 +47,7 @@ import
org.rhq.enterprise.gui.coregui.client.components.table.TableActionEnablem
import org.rhq.enterprise.gui.coregui.client.gwt.BundleGWTServiceAsync;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
import org.rhq.enterprise.gui.coregui.client.util.ErrorHandler;
+import org.rhq.enterprise.gui.coregui.client.util.StringUtility;
import org.rhq.enterprise.gui.coregui.client.util.message.Message;
import org.rhq.enterprise.gui.coregui.client.util.message.Message.Severity;
@@ -80,7 +81,6 @@ public class BundlesListView extends
Table<BundlesWithLatestVersionDataSource> {
@Override
protected void configureTable() {
-
ListGridField idField = new
ListGridField(BundlesWithLatestVersionDataSource.FIELD_ID, MSG.common_title_id());
idField.setType(ListGridFieldType.INTEGER);
idField.setWidth("50");
@@ -89,15 +89,20 @@ public class BundlesListView extends
Table<BundlesWithLatestVersionDataSource> {
.common_title_name());
nameField.setWidth("33%");
nameField.setCellFormatter(new CellFormatter() {
- public String format(Object o, ListGridRecord record, int i, int i1) {
+ public String format(Object value, ListGridRecord record, int i, int i1) {
return "<a href=\"" +
record.getAttribute(BundlesWithLatestVersionDataSource.FIELD_NAMELINK) +
"\">"
- + String.valueOf(o) + "</a>";
+ + StringUtility.escapeHtml(String.valueOf(value)) +
"</a>";
}
});
ListGridField descField = new
ListGridField(BundlesWithLatestVersionDataSource.FIELD_DESCRIPTION, MSG
.common_title_description());
descField.setWidth("33%");
+ descField.setCellFormatter(new CellFormatter() {
+ public String format(Object value, ListGridRecord record, int i, int i1) {
+ return StringUtility.escapeHtml(String.valueOf(value));
+ }
+ });
ListGridField latestVersionField = new
ListGridField(BundlesWithLatestVersionDataSource.FIELD_LATEST_VERSION,
MSG.view_bundle_latestVersion());
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/revert/GetRevertInfoStep.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/revert/GetRevertInfoStep.java
index 552ab4d..33d20e2 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/revert/GetRevertInfoStep.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/revert/GetRevertInfoStep.java
@@ -31,6 +31,7 @@ import org.rhq.enterprise.gui.coregui.client.CoreGUI;
import org.rhq.enterprise.gui.coregui.client.components.wizard.AbstractWizardStep;
import org.rhq.enterprise.gui.coregui.client.gwt.BundleGWTServiceAsync;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
+import org.rhq.enterprise.gui.coregui.client.util.StringUtility;
import org.rhq.enterprise.gui.coregui.client.util.selenium.Locatable;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableDynamicForm;
@@ -68,24 +69,27 @@ public class GetRevertInfoStep extends AbstractWizardStep {
.getId(), //
new AsyncCallback<String>() {
- public void onSuccess(String result) {
+ public void onSuccess(String bundleDeploymentName) {
final StaticTextItem nameTextItem = new
StaticTextItem("name", MSG
.view_bundle_revertWizard_getInfoStep_revertDeployName());
nameTextItem.setWidth(300);
- wizard.setSubtitle(result);
- nameTextItem.setValue(result);
+ String escapedBundleDeploymentName =
StringUtility.escapeHtml(bundleDeploymentName);
+ wizard.setSubtitle(escapedBundleDeploymentName);
+ nameTextItem.setValue(escapedBundleDeploymentName);
final TextAreaItem descriptionTextAreaItem = new
TextAreaItem("description", MSG
.view_bundle_revertWizard_getInfoStep_revertDeployDesc());
descriptionTextAreaItem.setWidth(300);
String liveDesc = wizard.getLiveDeployment().getDescription();
liveDesc = (null == liveDesc) ?
wizard.getLiveDeployment().getName() : liveDesc;
+ String escapedLiveDesc = StringUtility.escapeHtml(liveDesc);
String prevDesc =
wizard.getPreviousDeployment().getDescription();
prevDesc = (null == prevDesc) ?
wizard.getPreviousDeployment().getName() : prevDesc;
- wizard.setDeploymentDescription("[REVERT From]\n" +
liveDesc + "\n\n[REVERT To]\n" + prevDesc);
+ String escapedPrevDesc = StringUtility.escapeHtml(prevDesc);
+ wizard.setDeploymentDescription("[REVERT From]\n" +
escapedLiveDesc + "\n\n[REVERT To]\n" + escapedPrevDesc);
wizard.setDeploymentDescription(MSG.view_bundle_revertWizard_getInfoStep_revertDeployDescFull(
- liveDesc, prevDesc));
-
descriptionTextAreaItem.setValue(wizard.getDeploymentDescription());
+ escapedLiveDesc, escapedPrevDesc));
+
descriptionTextAreaItem.setValue(StringUtility.escapeHtml(wizard.getDeploymentDescription()));
descriptionTextAreaItem.addChangedHandler(new ChangedHandler() {
public void onChanged(ChangedEvent event) {
Object value = event.getValue();
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/tree/BundleTreeDataSource.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/tree/BundleTreeDataSource.java
index 039bc3e..39b84e7 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/tree/BundleTreeDataSource.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/tree/BundleTreeDataSource.java
@@ -49,6 +49,7 @@ import org.rhq.enterprise.gui.coregui.client.CoreGUI;
import org.rhq.enterprise.gui.coregui.client.gwt.BundleGWTServiceAsync;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource;
+import org.rhq.enterprise.gui.coregui.client.util.StringUtility;
/**
* @author Greg Hinkle
@@ -244,7 +245,7 @@ public class BundleTreeDataSource extends RPCDataSource<Object,
Criteria> {
node.setIsFolder(true);
node.setIcon("subsystems/bundle/Bundle_16.png");
node.setID(String.valueOf(bundle.getId()));
- node.setName(bundle.getName());
+ node.setName(StringUtility.escapeHtml(bundle.getName()));
} else if (from instanceof BundleVersion) {
BundleVersion version = (BundleVersion) from;
@@ -262,10 +263,11 @@ public class BundleTreeDataSource extends RPCDataSource<Object,
Criteria> {
parentID = bundleId + "_destinations_" +
deployment.getDestination().getId();
node.setParentID(parentID);
node.setID(bundleId + "_deployments_" + deployment.getId());
+ String name = StringUtility.escapeHtml(deployment.getName());
if (deployment.isLive()) {
- node.setName("<span style=\"color: green; font-weight:
bold\">(live)</span> " + deployment.getName());
+ node.setName("<span style=\"color: green; font-weight:
bold\">(live)</span> " + name);
} else {
- node.setName(deployment.getName());
+ node.setName(name);
}
} else if (from instanceof BundleDestination) {
@@ -275,7 +277,7 @@ public class BundleTreeDataSource extends RPCDataSource<Object,
Criteria> {
parentID = destination.getBundle().getId() + "_destinations";
node.setParentID(parentID);
node.setID(parentID + '_' + destination.getId());
- node.setName(destination.getName());
+ node.setName(StringUtility.escapeHtml(destination.getName()));
}
return node;
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java
index ac2d132..35d61f2 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java
@@ -1261,7 +1261,10 @@ public class ConfigurationEditor extends LocatableVLayout {
// TODO (ips, 03/25/11): We eventually want to use StaticTextItems for read-only
PASSWORD props too, but we have
// to wait until we implement masking/unmasking of PASSWORD
props at the SLSB layer first.
if (propertyIsReadOnly && propertyDefinitionSimple.getType() !=
PropertySimpleType.PASSWORD) {
- valueItem = new StaticTextItem();
+ StaticTextItem staticItem = new StaticTextItem();
+ // Property values are user-editable, so escape HTML to prevent an XSS
attack.
+ staticItem.setOutputAsHTML(true);
+ valueItem = staticItem;
} else {
List<PropertyDefinitionEnumeration> enumeratedValues =
propertyDefinitionSimple.getEnumeratedValues();
if (enumeratedValues != null && !enumeratedValues.isEmpty()) {
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/EnhancedDynamicForm.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/EnhancedDynamicForm.java
index 59c8b9d..02c2752 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/EnhancedDynamicForm.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/EnhancedDynamicForm.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2010 Red Hat, Inc.
+ * Copyright (C) 2010-2011 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -45,6 +45,8 @@ import
org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableDynamicForm;
*/
public class EnhancedDynamicForm extends LocatableDynamicForm {
+ public static final String OUTPUT_AS_HTML_ATTRIBUTE = "outputAsHTML";
+
private static final String FIELD_ID = "id";
private boolean isReadOnly;
@@ -116,6 +118,10 @@ public class EnhancedDynamicForm extends LocatableDynamicForm {
staticItem.setTooltip(item.getTooltip());
staticItem.setValue(item.getDisplayValue());
staticItem.setColSpan(item.getAttribute("colSpan"));
+ Boolean outputAsHtml =
item.getAttributeAsBoolean(OUTPUT_AS_HTML_ATTRIBUTE);
+ if (Boolean.TRUE.equals(outputAsHtml)) {
+ staticItem.setOutputAsHTML(true);
+ }
// TODO: Any other fields we should copy? icons?
if ((item instanceof BooleanItem) || (item instanceof CheckboxItem))
{
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/EscapedHtmlCellFormatter.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/EscapedHtmlCellFormatter.java
new file mode 100644
index 0000000..c60236c
--- /dev/null
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/EscapedHtmlCellFormatter.java
@@ -0,0 +1,19 @@
+package org.rhq.enterprise.gui.coregui.client.components.table;
+
+import com.smartgwt.client.widgets.grid.CellFormatter;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+import org.rhq.enterprise.gui.coregui.client.ImageManager;
+import org.rhq.enterprise.gui.coregui.client.util.StringUtility;
+
+/**
+ * A cell formatter that escapes any HTML in the cell's value.
+ *
+ * @author Ian Springer
+ */
+public class EscapedHtmlCellFormatter implements CellFormatter {
+
+ public String format(Object value, ListGridRecord record, int rowNum, int colNum) {
+ return (value != null) ? StringUtility.escapeHtml(value.toString()) :
"";
+ }
+
+}
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/IconField.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/IconField.java
new file mode 100644
index 0000000..82d6071
--- /dev/null
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/IconField.java
@@ -0,0 +1,73 @@
+/*
+ * RHQ Management Platform
+ * Copyright 2011, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * 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 version 2 of the License.
+ *
+ * This program 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, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.rhq.enterprise.gui.coregui.client.components.table;
+
+import com.google.gwt.core.client.JavaScriptObject;
+import com.smartgwt.client.types.Alignment;
+import com.smartgwt.client.types.ListGridFieldType;
+import com.smartgwt.client.widgets.grid.ListGridField;
+
+/**
+ * @author Ian Springer
+ */
+public class IconField extends ListGridField {
+
+ private static final String DEFAULT_NAME = "icon";
+ private static final String DEFAULT_TITLE = " ";
+ private static final int DEFAULT_WIDTH = 25;
+
+ public IconField() {
+ super(DEFAULT_NAME, DEFAULT_TITLE, DEFAULT_WIDTH);
+ init();
+ }
+
+ public IconField(JavaScriptObject jsObj) {
+ super(DEFAULT_NAME, DEFAULT_TITLE, DEFAULT_WIDTH);
+ setJsObj(jsObj);
+ init();
+ }
+
+ public IconField(String name) {
+ super(name, DEFAULT_TITLE, DEFAULT_WIDTH);
+ init();
+ }
+
+ public IconField(String name, int width) {
+ super(name, DEFAULT_TITLE, width);
+ init();
+ }
+
+ public IconField(String name, String title) {
+ super(name, title, DEFAULT_WIDTH);
+ init();
+ }
+
+ public IconField(String name, String title, int width) {
+ super(name, title, width);
+ init();
+ }
+
+ private void init() {
+ setType(ListGridFieldType.IMAGE);
+ setAlign(Alignment.CENTER);
+ setShowDefaultContextMenu(false);
+ }
+
+}
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/TableSection.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/TableSection.java
index e551deb..b19abfd 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/TableSection.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/TableSection.java
@@ -44,6 +44,7 @@ import org.rhq.enterprise.gui.coregui.client.DetailsView;
import org.rhq.enterprise.gui.coregui.client.ViewPath;
import org.rhq.enterprise.gui.coregui.client.components.buttons.BackButton;
import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource;
+import org.rhq.enterprise.gui.coregui.client.util.StringUtility;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableVLayout;
import org.rhq.enterprise.gui.coregui.client.util.selenium.SeleniumUtility;
@@ -56,6 +57,7 @@ public abstract class TableSection<DS extends RPCDataSource>
extends Table<DS> i
private VLayout detailsHolder;
private Canvas detailsView;
private String basePath;
+ private boolean escapeHtmlInDetailsLinkColumn;
protected TableSection(String locatorId, String tableTitle) {
super(locatorId, tableTitle);
@@ -110,7 +112,7 @@ public abstract class TableSection<DS extends RPCDataSource>
extends Table<DS> i
/**
* The default implementation wraps the {@link getDetailsLinkColumnCellFormatter()}
column with the
- * {@link getDetailsLinkColumnCellFormatter()}. This is typically the 'name'
column linking to the detail
+ * {@link #getDetailsLinkColumnCellFormatter()}. This is typically the 'name'
column linking to the detail
* view, given the 'id'. Also, establishes a double click handler for the row
which invokes
* {@link showDetails()}</br>
* </br>
@@ -146,6 +148,10 @@ public abstract class TableSection<DS extends RPCDataSource>
extends Table<DS> i
return true;
}
+ public void setEscapeHtmlInDetailsLinkColumn(boolean escapeHtmlInDetailsLinkColumn)
{
+ this.escapeHtmlInDetailsLinkColumn = escapeHtmlInDetailsLinkColumn;
+ }
+
/**
* Override if you don't want FIELD_NAME to be wrapped ina link.
* @return the name of the field to be wrapped, or null if no field should be
wrapped.
@@ -161,9 +167,13 @@ public abstract class TableSection<DS extends RPCDataSource>
extends Table<DS> i
protected CellFormatter getDetailsLinkColumnCellFormatter() {
return new CellFormatter() {
public String format(Object value, ListGridRecord record, int i, int i1) {
+ if (value == null) {
+ return "";
+ }
Integer recordId = getId(record);
String detailsUrl = "#" + getBasePath() + "/" +
recordId;
- return SeleniumUtility.getLocatableHref(detailsUrl, value.toString(),
null);
+ String formattedValue = (escapeHtmlInDetailsLinkColumn) ?
StringUtility.escapeHtml(value.toString()) : value.toString();
+ return SeleniumUtility.getLocatableHref(detailsUrl, formattedValue,
null);
}
};
}
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/tree/EnhancedTreeNode.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/tree/EnhancedTreeNode.java
index 15e13fa..1bae1e2 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/tree/EnhancedTreeNode.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/tree/EnhancedTreeNode.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2010 Red Hat, Inc.
+ * Copyright (C) 2010-2011 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -24,6 +24,7 @@ import com.smartgwt.client.widgets.tree.TreeNode;
* @author Ian Springer
*/
public class EnhancedTreeNode extends TreeNode {
+
public EnhancedTreeNode() {
super();
}
@@ -55,7 +56,7 @@ public class EnhancedTreeNode extends TreeNode {
public void setName(String name) {
super.setName(name);
if (name != null && getTitle() == null) {
- setTitle(name);
+ super.setTitle(name);
}
}
@@ -110,4 +111,5 @@ public class EnhancedTreeNode extends TreeNode {
private Attributes() {
}
}
+
}
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/recent/problems/ProblemResourcesPortlet.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/recent/problems/ProblemResourcesPortlet.java
index 8fcaba0..f91c4cf 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/recent/problems/ProblemResourcesPortlet.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/recent/problems/ProblemResourcesPortlet.java
@@ -49,6 +49,7 @@ import
org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
import org.rhq.core.domain.configuration.definition.PropertySimpleType;
import org.rhq.core.domain.dashboard.DashboardPortlet;
import org.rhq.enterprise.gui.coregui.client.LinkManager;
+import org.rhq.enterprise.gui.coregui.client.components.table.IconField;
import org.rhq.enterprise.gui.coregui.client.components.table.Table;
import org.rhq.enterprise.gui.coregui.client.components.table.TableWidget;
import org.rhq.enterprise.gui.coregui.client.dashboard.AutoRefreshPortlet;
@@ -139,12 +140,9 @@ public class ProblemResourcesPortlet extends
Table<ProblemResourcesDataSource> i
ListGridField alertsField = new ListGridField(ALERTS.propertyName(),
ALERTS.title(), 70);
- ListGridField availabilityField = new ListGridField(AVAILABILITY.propertyName(),
AVAILABILITY.title(), 70);
- availabilityField.setType(ListGridFieldType.IMAGE);
- availabilityField.setAlign(Alignment.CENTER);
+ IconField availabilityField = new IconField(AVAILABILITY.propertyName(),
AVAILABILITY.title(), 70);
setListGridFields(resourceField, ancestryField, alertsField, availabilityField);
-
}
@Override
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/util/MessagePortlet.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/util/MessagePortlet.java
index 8da6a8b..ead9cc2 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/util/MessagePortlet.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/util/MessagePortlet.java
@@ -34,6 +34,7 @@ import
org.rhq.enterprise.gui.coregui.client.dashboard.ConfigurablePortlet;
import org.rhq.enterprise.gui.coregui.client.dashboard.Portlet;
import org.rhq.enterprise.gui.coregui.client.dashboard.PortletViewFactory;
import org.rhq.enterprise.gui.coregui.client.dashboard.PortletWindow;
+import org.rhq.enterprise.gui.coregui.client.util.StringUtility;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableHTMLPane;
/**
@@ -46,15 +47,17 @@ public class MessagePortlet extends LocatableHTMLPane implements
ConfigurablePor
// A default displayed, persisted name for the portlet
public static final String NAME = MSG.view_portlet_defaultName_message();
+ private static final String MESSAGE_PROPERTY = "message";
+
public MessagePortlet(String locatorId) {
super(locatorId);
setContentsType(ContentsType.PAGE);
}
public void configure(PortletWindow portletWindow, DashboardPortlet storedPortlet) {
- String contents =
storedPortlet.getConfiguration().getSimpleValue("message", null);
+ String contents =
storedPortlet.getConfiguration().getSimpleValue(MESSAGE_PROPERTY, null);
if (contents != null) {
- setContents(contents);
+ setContents(StringUtility.sanitizeHtml(contents));
} else {
setContents("<br/><i>" +
MSG.view_portlet_configure_needed() + "</i>");
}
@@ -68,7 +71,7 @@ public class MessagePortlet extends LocatableHTMLPane implements
ConfigurablePor
ConfigurationDefinition definition = new
ConfigurationDefinition(MSG.view_portlet_configure_definitionTitle(),
MSG.view_portlet_configure_definitionDesc());
- definition.put(new PropertyDefinitionSimple("message",
MSG.view_portlet_message_title(), true,
+ definition.put(new PropertyDefinitionSimple(MESSAGE_PROPERTY,
MSG.view_portlet_message_title(), true,
PropertySimpleType.LONG_STRING));
return definition;
@@ -78,8 +81,8 @@ public class MessagePortlet extends LocatableHTMLPane implements
ConfigurablePor
public static PortletViewFactory INSTANCE = new Factory();
public final Portlet getInstance(String locatorId) {
-
return new MessagePortlet(locatorId);
}
}
+
}
\ No newline at end of file
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/operation/history/AbstractOperationHistoryDetailsView.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/operation/history/AbstractOperationHistoryDetailsView.java
index 27b1040..236e994 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/operation/history/AbstractOperationHistoryDetailsView.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/operation/history/AbstractOperationHistoryDetailsView.java
@@ -167,6 +167,8 @@ public abstract class AbstractOperationHistoryDetailsView<T extends
OperationHis
StaticTextItem requesterItem = new
StaticTextItem(AbstractOperationHistoryDataSource.Field.SUBJECT, MSG
.view_operationHistoryDetails_requestor());
+
+ requesterItem.setOutputAsHTML(true);
requesterItem.setValue(operationHistory.getSubjectName());
items.add(requesterItem);
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/operation/schedule/AbstractOperationScheduleDetailsView.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/operation/schedule/AbstractOperationScheduleDetailsView.java
index ff577d0..387c4d5 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/operation/schedule/AbstractOperationScheduleDetailsView.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/operation/schedule/AbstractOperationScheduleDetailsView.java
@@ -263,7 +263,9 @@ public abstract class AbstractOperationScheduleDetailsView extends
AbstractRecor
Integer integerValue = TypeConversionUtility.toInteger(value);
timeoutItem.setValue(integerValue, UnitType.TIME);
- FormItem notesItem =
this.notesForm.getField(AbstractOperationScheduleDataSource.Field.DESCRIPTION);
+ StaticTextItem notesItem = (StaticTextItem)
this.notesForm.getField(AbstractOperationScheduleDataSource.Field.DESCRIPTION);
+ // Notes field is user-editable, so escape HTML to prevent an XSS attack.
+ notesItem.setOutputAsHTML(true);
notesItem.setValue(getForm().getValue(AbstractOperationScheduleDataSource.Field.DESCRIPTION));
this.parameters = (Configuration)
record.getAttributeAsObject(AbstractOperationScheduleDataSource.Field.PARAMETERS);
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/summary/AbstractActivityView.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/summary/AbstractActivityView.java
index 82ac645..5fec813 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/summary/AbstractActivityView.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/summary/AbstractActivityView.java
@@ -401,7 +401,7 @@ public abstract class AbstractActivityView extends LocatableVLayout
implements R
/** Create empty display row(LocatableDynamicForm) that is constently defined and
displayed.
*
- * @param column Locatable parent colum.
+ * @param locatorId locator ID of Locatable parent column
* @param emptyMessage Contents of the empty region
* @return
*/
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/ResourceGroupTreeView.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/ResourceGroupTreeView.java
index 04fbfbd..a469fa9 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/ResourceGroupTreeView.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/ResourceGroupTreeView.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2010 Red Hat, Inc.
+ * Copyright (C) 2005-2011 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -281,7 +281,9 @@ public class ResourceGroupTreeView extends LocatableVLayout implements
Bookmarka
ResourceGroupTreeView.this.rootResourceGroup = group;
ResourceGroupTreeView.this.rootGroupId =
rootResourceGroup.getId();
ResourceGroupEnhancedTreeNode fakeRoot = new
ResourceGroupEnhancedTreeNode("fakeRootNode");
- ResourceGroupEnhancedTreeNode rootNode = new
ResourceGroupEnhancedTreeNode(group.getName());
+ String groupName = group.getName();
+ String escapedGroupName = StringUtility.escapeHtml(groupName);
+ ResourceGroupEnhancedTreeNode rootNode = new
ResourceGroupEnhancedTreeNode(escapedGroupName);
String icon = ImageManager.getGroupIcon(GroupCategory.MIXED);
rootNode.setIcon(icon);
rootNode.setID(String.valueOf(rootResourceGroup.getId()));
@@ -387,7 +389,9 @@ public class ResourceGroupTreeView extends LocatableVLayout implements
Bookmarka
ResourceGroupEnhancedTreeNode fakeRoot = new
ResourceGroupEnhancedTreeNode("fakeRootNode");
fakeRoot.setID(FAKE_ROOT_ID);
- ResourceGroupEnhancedTreeNode rootNode = new
ResourceGroupEnhancedTreeNode(rootResourceGroup.getName());
+ String groupName = rootResourceGroup.getName();
+ String escapedGroupName = StringUtility.escapeHtml(groupName);
+ ResourceGroupEnhancedTreeNode rootNode = new
ResourceGroupEnhancedTreeNode(escapedGroupName);
rootNode.setID(rootKey.getKey());
rootNode.setParentID(fakeRoot.getID());
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/AncestryUtil.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/AncestryUtil.java
index 2393132..ba890d4 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/AncestryUtil.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/AncestryUtil.java
@@ -34,6 +34,7 @@ import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.enterprise.gui.coregui.client.CoreGUI;
import org.rhq.enterprise.gui.coregui.client.LinkManager;
+import org.rhq.enterprise.gui.coregui.client.util.StringUtility;
import org.rhq.enterprise.gui.coregui.client.util.selenium.SeleniumUtility;
/**
@@ -42,6 +43,7 @@ import
org.rhq.enterprise.gui.coregui.client.util.selenium.SeleniumUtility;
* @author Jay Shaughnessy
*/
public abstract class AncestryUtil {
+
// ListGrid Record attribute names expected to be set on records processed by the
utility
public static final String RESOURCE_ANCESTRY = "resourceAncestry";
public static final String RESOURCE_ANCESTRY_VALUE =
"resourceAncestryDecoded";
@@ -115,8 +117,8 @@ public abstract class AncestryUtil {
continue;
}
String[] ancestryEntries = ancestry.split(Resource.ANCESTRY_DELIM);
- for (int i = 0; i < ancestryEntries.length; ++i) {
- String[] entryTokens =
ancestryEntries[i].split(Resource.ANCESTRY_ENTRY_DELIM);
+ for (String ancestryEntry : ancestryEntries) {
+ String[] entryTokens =
ancestryEntry.split(Resource.ANCESTRY_ENTRY_DELIM);
int rtId = Integer.valueOf(entryTokens[0]);
result.add(rtId);
}
@@ -148,7 +150,7 @@ public abstract class AncestryUtil {
String[] entryTokens =
ancestryEntries[i].split(Resource.ANCESTRY_ENTRY_DELIM);
int ancestorTypeId = Integer.valueOf(entryTokens[0]);
int ancestorResourceId = Integer.valueOf(entryTokens[1]);
- String ancestorName = entryTokens[2];
+ String ancestorName = StringUtility.escapeHtml(entryTokens[2]);
sbResources.append((i > 0) ? " < " : "");
//sbResources.append(" < ");
@@ -201,17 +203,15 @@ public abstract class AncestryUtil {
return "";
}
- Integer resourceId = record.getAttributeAsInt(RESOURCE_ID);
- // if not set assume the standard "id" attr is a resourceId
- resourceId = (null != resourceId) ? resourceId :
record.getAttributeAsInt("id");
+ Integer resourceId = getResourceId(record);
StringBuilder sbResources = new StringBuilder();
String[] ancestryEntries = ancestry.split(Resource.ANCESTRY_DELIM);
for (int i = 0; i < ancestryEntries.length; ++i) {
String[] entryTokens =
ancestryEntries[i].split(Resource.ANCESTRY_ENTRY_DELIM);
int ancestorResourceId = Integer.valueOf(entryTokens[1]);
- String ancestorName = entryTokens[2];
+ String ancestorName = StringUtility.escapeHtml(entryTokens[2]);
- sbResources.append((i > 0) ? " < " : "");
+ sbResources.append((i > 0) ? " < " : "");
if (generateLinks) {
String url = LinkManager.getResourceLink(ancestorResourceId);
String suffix = resourceId + "_" + entryTokens[1];
@@ -231,18 +231,14 @@ public abstract class AncestryUtil {
return ancestryHover;
}
- Integer resourceId = listGridRecord.getAttributeAsInt(RESOURCE_ID);
- // if not set assume the standard "id" attr is a resourceId
- resourceId = (null != resourceId) ? resourceId :
listGridRecord.getAttributeAsInt("id");
- String resourceName = listGridRecord.getAttribute(RESOURCE_NAME);
- // if not set assume the standard "name" attr is a resourceName
- resourceName = (null != resourceName) ? resourceName :
listGridRecord.getAttribute("name");
+ String resourceName = getResourceName(listGridRecord);
+
Map<Integer, ResourceType> types = ((MapWrapper)
listGridRecord.getAttributeAsObject(RESOURCE_ANCESTRY_TYPES))
.getMap();
Integer resourceTypeId = listGridRecord.getAttributeAsInt(RESOURCE_TYPE_ID);
String ancestry = listGridRecord.getAttributeAsString(RESOURCE_ANCESTRY);
- String result = getAncestryHoverHTMLString(resourceId, resourceName, ancestry,
resourceTypeId, types, width);
+ String result = getAncestryHoverHTMLString(resourceName, ancestry,
resourceTypeId, types, width);
listGridRecord.setAttribute(RESOURCE_ANCESTRY_HOVER, result);
return result;
@@ -250,12 +246,12 @@ public abstract class AncestryUtil {
public static String getAncestryHoverHTMLForResource(Resource resource,
Map<Integer, ResourceType> types, int width) {
- return getAncestryHoverHTMLString(resource.getId(), resource.getName(),
resource.getAncestry(), resource
+ return getAncestryHoverHTMLString(resource.getName(), resource.getAncestry(),
resource
.getResourceType().getId(), types, width);
}
- private static String getAncestryHoverHTMLString(int resourceId, String resourceName,
String ancestry,
- int resourceTypeId, Map<Integer, ResourceType> types, int width) {
+ private static String getAncestryHoverHTMLString(String resourceName, String
ancestry,
+ int resourceTypeId, Map<Integer,
ResourceType> types, int width) {
ResourceType type = types.get(resourceTypeId);
String resourceLongName = getResourceLongName(resourceName, type);
@@ -282,7 +278,7 @@ public abstract class AncestryUtil {
for (int i = ancestryEntries.length - 1, j = 0; i >= 0; --i, ++j) {
String[] entryTokens =
ancestryEntries[i].split(Resource.ANCESTRY_ENTRY_DELIM);
int ancestorTypeId = Integer.valueOf(entryTokens[0]);
- String ancestorName = entryTokens[2];
+ String ancestorName = StringUtility.escapeHtml(entryTokens[2]);
// indent with spaces
if (j > 0) {
@@ -323,9 +319,10 @@ public abstract class AncestryUtil {
/**
* Get a resource name that combines type and resource information. This is useful
for when we want to
- * use a single column for dispay of the resource "name". The name is
wrapped in a navigable link.
+ * use a single column for display of the resource "name". The name is
wrapped in a navigable link.
*
- * @param resource The resource
+ * @param record the resource record
+ * @param width the width, in pixels, of the returned HTML <code>p</code>
tag
*
* @return the long name for the resource
*/
@@ -335,9 +332,7 @@ public abstract class AncestryUtil {
return resourceHover;
}
- String resourceName = record.getAttribute(RESOURCE_NAME);
- // if not set assume the standard "name" attr is a resourceName
- resourceName = (null != resourceName) ? resourceName :
record.getAttribute("name");
+ String resourceName = getResourceName(record);
Map<Integer, ResourceType> types = ((MapWrapper)
record.getAttributeAsObject(RESOURCE_ANCESTRY_TYPES)).getMap();
Integer resourceTypeId = record.getAttributeAsInt(RESOURCE_TYPE_ID);
ResourceType type = types.get(resourceTypeId);
@@ -365,6 +360,21 @@ public abstract class AncestryUtil {
return result;
}
+ private static Integer getResourceId(Record record) {
+ Integer resourceId = record.getAttributeAsInt(RESOURCE_ID);
+ // if not set assume the standard "id" attr is a resourceId
+ resourceId = (null != resourceId) ? resourceId :
record.getAttributeAsInt("id");
+ return resourceId;
+ }
+
+ private static String getResourceName(Record record) {
+ String resourceName = record.getAttribute(RESOURCE_NAME);
+ // if not set assume the standard "name" attr is a resourceName
+ resourceName = (null != resourceName) ? resourceName :
record.getAttribute("name");
+ resourceName = StringUtility.escapeHtml(resourceName);
+ return resourceName;
+ }
+
// We do not want smargwt to see we are storing our map into an attribute because it
barfs on our key/value pairs
// so instead we have to wrap it in a non-Map POJO Object so smartgwt just handles it
as a java.lang.Object.
public static class MapWrapper {
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceSearchView.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceSearchView.java
index 32a6227..b53a127 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceSearchView.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceSearchView.java
@@ -33,8 +33,6 @@ import com.google.gwt.user.client.rpc.AsyncCallback;
import com.smartgwt.client.data.Criteria;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.data.SortSpecifier;
-import com.smartgwt.client.types.Alignment;
-import com.smartgwt.client.types.ListGridFieldType;
import com.smartgwt.client.widgets.events.DoubleClickEvent;
import com.smartgwt.client.widgets.events.DoubleClickHandler;
import com.smartgwt.client.widgets.grid.CellFormatter;
@@ -52,12 +50,14 @@ import org.rhq.enterprise.gui.coregui.client.CoreGUI;
import org.rhq.enterprise.gui.coregui.client.LinkManager;
import org.rhq.enterprise.gui.coregui.client.components.table.RecordExtractor;
import
org.rhq.enterprise.gui.coregui.client.components.table.ResourceAuthorizedTableAction;
+import org.rhq.enterprise.gui.coregui.client.components.table.IconField;
import
org.rhq.enterprise.gui.coregui.client.components.table.ResourceCategoryCellFormatter;
import org.rhq.enterprise.gui.coregui.client.components.table.Table;
import org.rhq.enterprise.gui.coregui.client.components.table.TableActionEnablement;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGWTServiceAsync;
import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource;
+import org.rhq.enterprise.gui.coregui.client.util.StringUtility;
import org.rhq.enterprise.gui.coregui.client.util.TableUtility;
import org.rhq.enterprise.gui.coregui.client.util.message.Message;
import org.rhq.enterprise.gui.coregui.client.util.message.Message.Severity;
@@ -125,14 +125,9 @@ public class ResourceSearchView extends Table {
@Override
protected void configureTable() {
- ListGridField iconField = new ListGridField("icon",
MSG.common_title_icon(), 25);
- iconField.setType(ListGridFieldType.IMAGE);
- iconField.setShowDefaultContextMenu(false);
- iconField.setCanSort(false);
- iconField.setTitle(" ");
+ IconField iconField = new IconField();
iconField.setShowHover(true);
iconField.setHoverCustomizer(new HoverCustomizer() {
- @Override
public String hoverHTML(Object value, ListGridRecord record, int rowNum, int
colNum) {
String resCat = record.getAttribute(CATEGORY.propertyName());
switch (ResourceCategory.valueOf(resCat)) {
@@ -149,14 +144,14 @@ public class ResourceSearchView extends Table {
ListGridField nameField = new ListGridField(NAME.propertyName(), NAME.title(),
250);
nameField.setCellFormatter(new CellFormatter() {
- public String format(Object o, ListGridRecord listGridRecord, int i, int i1)
{
- String url =
LinkManager.getResourceLink(listGridRecord.getAttributeAsInt("id"));
- return SeleniumUtility.getLocatableHref(url, o.toString(), null);
+ public String format(Object value, ListGridRecord record, int rowNum, int
colNum) {
+ String url =
LinkManager.getResourceLink(record.getAttributeAsInt("id"));
+ String name = StringUtility.escapeHtml(value.toString());
+ return SeleniumUtility.getLocatableHref(url, name, null);
}
});
nameField.setShowHover(true);
nameField.setHoverCustomizer(new HoverCustomizer() {
-
public String hoverHTML(Object value, ListGridRecord listGridRecord, int
rowNum, int colNum) {
return AncestryUtil.getResourceHoverHTML(listGridRecord, 0);
}
@@ -174,9 +169,7 @@ public class ResourceSearchView extends Table {
categoryField.setCellFormatter(new ResourceCategoryCellFormatter());
categoryField.setHidden(true); // the icon field already shows us this, no need
to show it in another column
- ListGridField availabilityField = new ListGridField(AVAILABILITY.propertyName(),
AVAILABILITY.title(), 70);
- availabilityField.setType(ListGridFieldType.IMAGE);
- availabilityField.setAlign(Alignment.CENTER);
+ IconField availabilityField = new IconField(AVAILABILITY.propertyName(),
AVAILABILITY.title(), 70);
setListGridFields(iconField, nameField, ancestryField, descriptionField,
typeNameField, pluginNameField,
categoryField, availabilityField);
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTitleBar.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTitleBar.java
index bd86104..dcdffd9 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTitleBar.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTitleBar.java
@@ -49,6 +49,7 @@ import org.rhq.enterprise.gui.coregui.client.UserSessionManager;
import org.rhq.enterprise.gui.coregui.client.components.tagging.TagEditorView;
import org.rhq.enterprise.gui.coregui.client.components.tagging.TagsChangedCallback;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
+import org.rhq.enterprise.gui.coregui.client.util.StringUtility;
import org.rhq.enterprise.gui.coregui.client.util.message.Message;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableHLayout;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableImg;
@@ -310,7 +311,7 @@ public class ResourceTitleBar extends LocatableVLayout {
if (!resource.getName().equals(resourceName)) {
resource.setName(resourceName); // the name must have been changed by the
user via the editable field
}
- this.title.setContents("<span class=\"SectionHeader\">"
+ resource.getName()
+ this.title.setContents("<span class=\"SectionHeader\">"
+ StringUtility.escapeHtml(resourceName)
+ "</span> <span
class=\"subtitle\">" + resource.getResourceType().getName() +
"</span>");
this.title.markForRedraw();
}
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeDatasource.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeDatasource.java
index 336e12e..6a38008 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeDatasource.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeDatasource.java
@@ -334,10 +334,14 @@ public class ResourceTreeDatasource extends DataSource {
}
this.setParentID(parentId);
+ // name and description are user-editable, so escape HTML to prevent XSS
attacks
String name = resource.getName();
- setName(name);
+ String escapedName = StringUtility.escapeHtml(name);
+ setName(escapedName);
- setAttribute(Attributes.DESCRIPTION, resource.getDescription());
+ String description = resource.getDescription();
+ String escapedDescription = StringUtility.escapeHtml(description);
+ setAttribute(Attributes.DESCRIPTION, escapedDescription);
Set<ResourceType> childTypes =
resource.getResourceType().getChildResourceTypes();
setIsFolder((childTypes != null && !childTypes.isEmpty()));
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/StringUtility.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/StringUtility.java
index 984ca22..0c93099 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/StringUtility.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/StringUtility.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * Copyright 2011, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
@@ -19,53 +19,72 @@
*/
package org.rhq.enterprise.gui.coregui.client.util;
-import java.util.ArrayList;
-import java.util.List;
-
/**
* A collection of utility methods for working with Strings.
- *
- * TODO: I18N. The logic here may need to be pluggable for different localizations.
*
* @author Ian Springer
*/
public class StringUtility {
/**
- * Split a string on delimiter boundaries, and place each element into a List.
+ * Escapes HTML in a string to eliminate cross site scripting (XSS) vulnerabilities.
Note, this impl is designed
+ * to be highly efficient to minimize the impact on performance.
*
- * @param s String to split up
- * @param delim Delimiting token, ala StringTokenizer
+ * @param string the string to be escaped
*
- * @return a List comprised of elements split by the tokenizing
+ * @return the escaped string
*/
-
- public static List<String> explode(String s, String delim) {
- List<String> res = new ArrayList<String>();
- if (s == null)
- return res;
-
- String[] tokens = s.split(delim);
- for (String token : tokens) {
- res.add(token);
+ public static String escapeHtml(String string) {
+ if (string == null) {
+ return null;
}
-
- return res;
+ StringBuilder buffer = null;
+ for (int i = 0; i < string.length(); i++) {
+ char c = string.charAt(i);
+ if (c == '&') {
+ if (buffer == null) {
+ buffer = new StringBuilder(string.substring(0, i));
+ }
+ buffer.append("&");
+ } else if (c == '<') {
+ if (buffer == null) {
+ buffer = new StringBuilder(string.substring(0, i));
+ }
+ buffer.append("<");
+ } else if (c == '>') {
+ if (buffer == null) {
+ buffer = new StringBuilder(string.substring(0, i));
+ }
+ buffer.append(">");
+ } else {
+ if (buffer != null) {
+ buffer.append(c);
+ }
+ }
+ }
+ return (buffer != null) ? buffer.toString() : string;
}
- public static String pluralize(String singularNoun) {
- String pluralNoun;
- if (singularNoun.endsWith("y") &&
!singularNoun.endsWith("ay") && !singularNoun.endsWith("ey")
- && !singularNoun.endsWith("oy")) {
- pluralNoun = singularNoun.substring(0, singularNoun.length() - 1) +
"ies";
- } else if (!singularNoun.endsWith("s")) {
- pluralNoun = singularNoun + "s";
- } else {
- pluralNoun = singularNoun;
+ /**
+ * Sanitizes HTML (i.e. removes unsafe HTML such as SCRIPT tags) in a string to
eliminate cross site scripting (XSS)
+ * vulnerabilities.
+ *
+ * @param string the string to be sanitized
+ *
+ * @return the sanitized string
+ */
+ // TODO (ips, 03/31/11): Replace this lame impl with a much more robust one - easiest
way would be to upgrade to GWT
+ // 2.1 or later and use the new Safe HTML APIs. See also
+ //
http://tomerdoron.blogspot.com/2011/03/less-simple-safe-html-sanitizer.html.
+ public static String sanitizeHtml(String string) {
+ if (string == null) {
+ return null;
}
- return pluralNoun;
+
+ return string.replaceAll("<script",
"<script").replaceAll("<SCRIPT",
"<SCRIPT");
}
private StringUtility() {
}
+
}