Author: orudyy
Date: Tue Jul 19 13:45:19 2016
New Revision: 1753388
URL: http://svn.apache.org/viewvc?rev=1753388&view=rev
Log:
QPID-7247: Prevent modification of other user preference
Modified:
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/preferences/UserPreferencesImpl.java
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/singleton/PreferencesTest.java
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/QueryWidget.js
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/query/QueryWidget.html
qpid/java/trunk/systests/src/test/java/org/apache/qpid/systest/rest/UserPreferencesRestTest.java
Modified:
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/preferences/UserPreferencesImpl.java
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/preferences/UserPreferencesImpl.java?rev=1753388&r1=1753387&r2=1753388&view=diff
==============================================================================
---
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/preferences/UserPreferencesImpl.java
(original)
+++
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/preferences/UserPreferencesImpl.java
Tue Jul 19 13:45:19 2016
@@ -442,6 +442,18 @@ public class UserPreferencesImpl impleme
throw new SecurityException(String.format("Preference '%s' not
owned by current user.",
preference.getId().toString()));
}
+
+ if (preference.getId() != null)
+ {
+ Preference oldPreference =
_preferences.get(preference.getId());
+ if (oldPreference != null &&
!principalsEqual(oldPreference.getOwner(), preference.getOwner()))
+ {
+ throw new SecurityException(String.format(
+ "Ownership of other user preference having id '%s'
and name '%s' cannot be changed to current user",
+ preference.getId().toString(),
+ preference.getName()));
+ }
+ }
}
}
Modified:
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/singleton/PreferencesTest.java
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/singleton/PreferencesTest.java?rev=1753388&r1=1753387&r2=1753388&view=diff
==============================================================================
---
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/singleton/PreferencesTest.java
(original)
+++
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/singleton/PreferencesTest.java
Tue Jul 19 13:45:19 2016
@@ -1255,6 +1255,37 @@ public class PreferencesTest extends Qpi
assertEquals("Unexpected preference attributes", expectedAttributes,
p.getAttributes());
}
+ public void testSavingOtherUserPreference() throws Exception
+ {
+ final String testGroupName = "testGroup";
+ Subject user1Subject =
TestPrincipalUtils.createTestSubject(TEST_USERNAME, testGroupName);
+
+ Map<String, Object> preferenceAttributes =
PreferenceTestHelper.createPreferenceAttributes(
+ _testObject.getId(),
+ UUID.randomUUID(),
+ "X-PREF",
+ "prefname",
+ null,
+ TEST_USERNAME,
+ Collections.singleton(testGroupName),
+ Collections.<String,Object>emptyMap());
+ updateOrAppendAs(user1Subject, PreferenceFactory.recover(_testObject,
preferenceAttributes));
+
+ Subject user2Subject =
TestPrincipalUtils.createTestSubject(TEST_USERNAME2, testGroupName);
+ preferenceAttributes.put(Preference.OWNER_ATTRIBUTE, TEST_USERNAME2);
+ Preference stolenPreference = PreferenceFactory.recover(_testObject,
preferenceAttributes);
+
+ try
+ {
+ updateOrAppendAs(user2Subject, stolenPreference);
+ fail("Steeling of other user preferences should not be allowed");
+ }
+ catch (SecurityException e)
+ {
+ // pass
+ }
+ }
+
private void updateOrAppendAs(final Subject testSubject, final
Preference... testUserPreference)
{
Subject.doAs(testSubject, new PrivilegedAction<Void>()
Modified:
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java?rev=1753388&r1=1753387&r2=1753388&view=diff
==============================================================================
---
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java
(original)
+++
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java
Tue Jul 19 13:45:19 2016
@@ -560,7 +560,7 @@ public class RestServlet extends Abstrac
{
super.service(request, response);
}
- catch (IllegalArgumentException | IllegalConfigurationException |
IllegalStateException | AccessControlException
+ catch (IllegalArgumentException | IllegalConfigurationException |
IllegalStateException | SecurityException
| IntegrityViolationException |
IllegalStateTransitionException | NoClassDefFoundError e)
{
setResponseStatus(request, response, e);
@@ -1101,9 +1101,9 @@ public class RestServlet extends Abstrac
private void setResponseStatus(HttpServletRequest request,
HttpServletResponse response, Throwable e)
throws IOException
{
- if (e instanceof AccessControlException)
+ if (e instanceof SecurityException)
{
- LOGGER.debug("AccessControlException, sending {}",
HttpServletResponse.SC_FORBIDDEN, e);
+ LOGGER.debug("{}, sending {}", e.getClass().getName(),
HttpServletResponse.SC_FORBIDDEN, e);
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
}
else
Modified:
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/QueryWidget.js
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/QueryWidget.js?rev=1753388&r1=1753387&r2=1753388&view=diff
==============================================================================
---
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/QueryWidget.js
(original)
+++
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/js/qpid/management/query/QueryWidget.js
Tue Jul 19 13:45:19 2016
@@ -293,6 +293,9 @@ define(["dojo/_base/declare",
saveButton: null,
cloneButton: null,
deleteButton: null,
+ saveButtonTooltip: null,
+ cloneButtonTooltip: null,
+ deleteButtonTooltip: null,
/**
* constructor parameter
@@ -310,6 +313,7 @@ define(["dojo/_base/declare",
_lastStandardModeSelect: null,
_lastHeaders: null,
_queryCloneDialogForm: null,
+ _ownQuery: false,
postCreate: function ()
{
@@ -351,6 +355,20 @@ define(["dojo/_base/declare",
this.cloneButton.on("click", lang.hitch(this,
this._cloneQuery));
this.deleteButton.on("click", lang.hitch(this,
this._deleteQuery));
+ this._ownQuery = !this.preference ||
!this.preference.owner || this.preference.owner ===
this.management.getAuthenticatedUser();
+ this.saveButton.set("disabled", !this._ownQuery);
+ this.deleteButton.set("disabled", !this._ownQuery ||
!(this.preference && this.preference.id));
+
+ if (!this._ownQuery)
+ {
+ this.saveButtonTooltip.set("label", "Shared query
owned by someone else cannot be saved!"
+ + "<br/>"
+ + "Please clone
query to make your own one.");
+ this.deleteButtonTooltip.set("label", "Shared query
owned by someone else cannot be deleted!"
+ + "<br/>"
+ + "Please clone
query to make your own one.");
+ }
+
// advanced mode widgets
this.advancedSelect.on("change", lang.hitch(this,
this._advancedModeSelectChanged));
this.advancedWhere.on("change", lang.hitch(this,
this._advancedModeWhereChanged));
@@ -394,9 +412,6 @@ define(["dojo/_base/declare",
{
this._toggleSearchButton(true);
}
-
- // if the preference has an id, then we know it is in the
store
- this.deleteButton.set("disabled", this.preference != null
&& this.preference.id != null ? false : true);
},
search: function ()
{
@@ -1045,6 +1060,10 @@ define(["dojo/_base/declare",
{
delete preference.id;
}
+ if (preference.owner)
+ {
+ delete preference.owner;
+ }
preference.value = this._getQuery();
this._queryCloneDialog.hide();
this.emit("clone", {preference: preference, parentObject:
e.parentObject});
@@ -1085,10 +1104,13 @@ define(["dojo/_base/declare",
},
_queryChanged: function(query)
{
- var queryParameters = this._getQuery(query);
- var pref = lang.clone(this.preference);
- pref.value = queryParameters;
- this.emit("change", {preference: pref});
+ if (this._ownQuery)
+ {
+ var queryParameters = this._getQuery(query);
+ var pref = lang.clone(this.preference);
+ pref.value = queryParameters;
+ this.emit("change", {preference: pref});
+ }
}
});
Modified:
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/query/QueryWidget.html
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/query/QueryWidget.html?rev=1753388&r1=1753387&r2=1753388&view=diff
==============================================================================
---
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/query/QueryWidget.html
(original)
+++
qpid/java/trunk/broker-plugins/management-http/src/main/java/resources/query/QueryWidget.html
Tue Jul 19 13:45:19 2016
@@ -19,15 +19,27 @@
<div>
<div data-dojo-type="dijit/Toolbar">
- <div data-dojo-type="dijit/form/Button"
+ <div id="saveButton_${id}"
+ data-dojo-type="dijit/form/Button"
data-dojo-attach-point="saveButton"
data-dojo-props="iconClass: 'dijitIconSave'">Save</div>
- <div data-dojo-type="dijit/form/Button"
+ <div data-dojo-attach-point="saveButtonTooltip"
+ data-dojo-type="dijit/Tooltip"
+
data-dojo-props="connectId:'saveButton_${id}',position:['below']">Save and
share query</div>
+ <div id="cloneButton_${id}"
+ data-dojo-type="dijit/form/Button"
data-dojo-attach-point="cloneButton"
data-dojo-props="iconClass: 'dijitIconCopy'">Clone</div>
- <div data-dojo-type="dijit/form/Button"
+ <div data-dojo-attach-point="cloneButtonTooltip"
+ data-dojo-type="dijit/Tooltip"
+
data-dojo-props="connectId:'cloneButton_${id}',position:['below']">Clone query
into new one<br/>Note, group information is not cloned into new query.</div>
+ <div id="deleteButton_${id}"
+ data-dojo-type="dijit/form/Button"
data-dojo-attach-point="deleteButton"
data-dojo-props="iconClass: 'trashIcon ui-icon'">Delete</div>
+ <div data-dojo-attach-point="deleteButtonTooltip"
+ data-dojo-type="dijit/Tooltip"
+
data-dojo-props="connectId:'deleteButton_${id}',position:['below']">Delete
query from preferences and close the tab</div>
<div data-dojo-type="dijit/form/Button"
data-dojo-attach-point="modeButton"
data-dojo-props="iconClass: 'advancedViewIcon ui-icon',
title:'Switch to \'Advanced View\' search using SQL-like expressions'"
Modified:
qpid/java/trunk/systests/src/test/java/org/apache/qpid/systest/rest/UserPreferencesRestTest.java
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/systests/src/test/java/org/apache/qpid/systest/rest/UserPreferencesRestTest.java?rev=1753388&r1=1753387&r2=1753388&view=diff
==============================================================================
---
qpid/java/trunk/systests/src/test/java/org/apache/qpid/systest/rest/UserPreferencesRestTest.java
(original)
+++
qpid/java/trunk/systests/src/test/java/org/apache/qpid/systest/rest/UserPreferencesRestTest.java
Tue Jul 19 13:45:19 2016
@@ -25,6 +25,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.UUID;
import javax.servlet.http.HttpServletResponse;
@@ -33,7 +34,9 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import
org.apache.qpid.server.management.plugin.preferences.QueryPreferenceValue;
+import org.apache.qpid.server.model.GroupProvider;
import org.apache.qpid.server.model.preferences.Preference;
+import org.apache.qpid.server.security.group.GroupProviderImpl;
public class UserPreferencesRestTest extends QpidRestTestCase
{
@@ -78,6 +81,33 @@ public class UserPreferencesRestTest ext
assertEquals("Unexpected preference returned from all url",
prefDetails, prefs.get(0));
}
+ public void testSavingOtherUserPreference() throws Exception
+ {
+ getRestTestHelper().submitRequest("groupprovider/temp", "PUT",
Collections.singletonMap(GroupProvider.TYPE, GroupProviderImpl.CONFIG_TYPE),
HttpServletResponse.SC_CREATED);
+ getRestTestHelper().createGroup("test", "temp");
+ getRestTestHelper().createNewGroupMember("temp", "test", "webadmin");
+ getRestTestHelper().createNewGroupMember("temp", "test", "admin");
+
+ String preferenceType = "X-Type-" + getTestName();
+ String preferenceName = getTestName();
+ Map<String, Object> preferenceAttributes = new HashMap<>();
+ preferenceAttributes.put(Preference.ID_ATTRIBUTE, UUID.randomUUID());
+ preferenceAttributes.put(Preference.TYPE_ATTRIBUTE, preferenceType);
+ preferenceAttributes.put(Preference.NAME_ATTRIBUTE, preferenceName);
+ preferenceAttributes.put(Preference.DESCRIPTION_ATTRIBUTE, "");
+ preferenceAttributes.put(Preference.OWNER_ATTRIBUTE, "webadmin");
+ preferenceAttributes.put(Preference.VISIBILITY_LIST_ATTRIBUTE,
Collections.singletonList("test"));
+ preferenceAttributes.put(Preference.VALUE_ATTRIBUTE,
Collections.emptyMap());
+
+ String fullUrl = String.format("broker/userpreferences/%s/%s",
preferenceType, preferenceName);
+ getRestTestHelper().submitRequest(fullUrl, "PUT",
preferenceAttributes, HttpServletResponse.SC_OK);
+
+ getRestTestHelper().setUsernameAndPassword("admin", "admin");
+
+ preferenceAttributes.put(Preference.OWNER_ATTRIBUTE, "admin");
+ getRestTestHelper().submitRequest(fullUrl, "PUT",
preferenceAttributes, HttpServletResponse.SC_FORBIDDEN);
+ }
+
public void testPutQueryPreferenceRoundTrip() throws Exception
{
final String prefName = "myquery";
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]