Allon Mureinik has uploaded a new change for review. Change subject: core: QueriesCommandBase public query validation ......................................................................
core: QueriesCommandBase public query validation The Backend bean is just a wrapper used to call queries and actions, and should not have any security logic in it. This patch moves the exiting validation inside QueriesCommandBase, which provides a couple of improvements: 1. QueriesCommandBase is more self contained, and does not rely on the caller (Backend) for some of the validations. 2. All the security validations are done in the same place, both for logged in and not logged in callers. This patch contains: 1. Adding another authorization type, Public, to the VdcQueryAuthType enum to handle Public Queries, which do not require a log in. 2. Adding the proper handling for it in QueriesCommandBase. 3. Adding a new Public value to the ConfigAuthType enum, since configuration values permissions are handled per key. 4. Removing the specific Public Query logic from Backend.runQueryImpl. This is a step towards removing Backend.runPublicQuery, which would be done in a subsequent patch. Note that this patch does NOT leave the system in a vulnerable state - The validation removed from the Backend were added to QueriesCommandBase, and even though Backend.runPublicQuery still exists, it has become a meaningless wrapper method. 5. Updating QueriesCommandBaseTest, GetConfigurationValueQueryTest and AbstractUserQueryTest to test this new functionality. Change-Id: I6f428c6449873054f3d7d291eef6caf4c9b09bb2 Signed-off-by: Allon Mureinik <amure...@redhat.com> --- M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/Backend.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetConfigurationValueQuery.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/QueriesCommandBase.java M backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/AbstractUserQueryTest.java M backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/GetConfigurationValueQueryTest.java M backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/QueriesCommandBaseTest.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/ConfigurationValues.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java M backend/manager/modules/common/src/test/java/org/ovirt/engine/core/common/queries/VdcQueryTypeTest.java 9 files changed, 90 insertions(+), 63 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/01/23001/1 diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/Backend.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/Backend.java index 675ba69..e1b3c95 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/Backend.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/Backend.java @@ -461,11 +461,7 @@ protected VdcQueryReturnValue runQueryImpl(VdcQueryType actionType, VdcQueryParametersBase parameters, boolean isPerformUserCheck) { if (isPerformUserCheck) { - String sessionId = addSessionToContext(parameters); - if (StringUtils.isEmpty(sessionId) - || SessionDataContainer.getInstance().getUser(sessionId, parameters.getRefresh()) == null) { - return getErrorQueryReturnValue(VdcBllMessages.USER_IS_NOT_LOGGED_IN); - } + addSessionToContext(parameters); } Class<CommandBase<? extends VdcActionParametersBase>> clazz = CommandsFactory.getQueryClass(actionType.name()); diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetConfigurationValueQuery.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetConfigurationValueQuery.java index 48c8267..868bf74 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetConfigurationValueQuery.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/GetConfigurationValueQuery.java @@ -4,6 +4,7 @@ import org.ovirt.engine.core.common.config.ConfigCommon; import org.ovirt.engine.core.common.config.ConfigValues; import org.ovirt.engine.core.common.queries.GetConfigurationValueParameters; +import org.ovirt.engine.core.common.queries.VdcQueryType; public class GetConfigurationValueQuery<P extends GetConfigurationValueParameters> extends QueriesCommandBase<P> { public GetConfigurationValueQuery(P parameters) { @@ -13,34 +14,25 @@ @Override protected void executeQueryCommand() { Object returnValue = null; - if (shouldReturnValue()) { - try { - final GetConfigurationValueParameters params = getParameters(); - final ConfigValues value = ConfigValues.valueOf(params.getConfigValue().toString()); - String version = params.getVersion(); - if (version == null) { - log.warnFormat("calling {0} ({2}) with null version, using default {1} for version", - GetConfigurationValueQuery.class.getSimpleName(), ConfigCommon.defaultConfigurationVersion, value); - version = ConfigCommon.defaultConfigurationVersion; - } - returnValue = Config.<Object> getValue(value, version); - } catch (Exception e) { - log.error("Unable to return config parameter: " + getParameters(), e); + try { + final GetConfigurationValueParameters params = getParameters(); + final ConfigValues value = ConfigValues.valueOf(params.getConfigValue().toString()); + String version = params.getVersion(); + if (version == null) { + log.warnFormat("calling {0} ({2}) with null version, using default {1} for version", + GetConfigurationValueQuery.class.getSimpleName(), ConfigCommon.defaultConfigurationVersion, value); + version = ConfigCommon.defaultConfigurationVersion; } + returnValue = Config.<Object> getValue(value, version); + } catch (Exception e) { + log.error("Unable to return config parameter: " + getParameters(), e); } getQueryReturnValue().setReturnValue(returnValue); } - /** - * Validates if the query should return anything or not, according to the user's permissions: - * <ul> - * <li>If the query is run as an administrator (note that since we've reached the {@link #executeQueryCommand()} method, - * we've already validated that the use is indeed an administrator), the results from the database queries should be returned.</li> - * <li>If the query is run as a user, it may return results <b>ONLY</b> if the configuration value has {@link org.ovirt.engine.core.common.queries.ConfigurationValues.ConfigAuthType#User}.</li> - * </ul> - */ - private boolean shouldReturnValue() { - return !getParameters().isFiltered() || !getParameters().getConfigValue().isAdmin(); + @Override + protected VdcQueryType.VdcQueryAuthType getAuthType() { + return VdcQueryType.VdcQueryAuthType.valueOf(getParameters().getConfigValue().getConfigAuthType().toString()); } } diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/QueriesCommandBase.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/QueriesCommandBase.java index 44c2b8a..3f9c4a1 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/QueriesCommandBase.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/QueriesCommandBase.java @@ -1,5 +1,7 @@ package org.ovirt.engine.core.bll; +import static org.ovirt.engine.core.common.queries.VdcQueryType.VdcQueryAuthType; + import java.util.Set; import javax.validation.ConstraintViolation; @@ -88,7 +90,9 @@ log.error("Query execution failed due to invalid inputs. " + returnValue.getExceptionString()); } } else { - String errMessage = VdcBllMessages.USER_CANNOT_RUN_QUERY_NO_PERMISSION.name(); + String errMessage = getUser() == null ? + VdcBllMessages.USER_CANNOT_RUN_QUERY_NOT_PUBLIC.name() : + VdcBllMessages.USER_CANNOT_RUN_QUERY_NO_PERMISSION.name(); log.error(errMessage); returnValue.setExceptionString(errMessage); } @@ -101,15 +105,25 @@ * <code>false</code> otherwise. */ private final boolean validatePermissions() { - // If the user requests filtered execution, his permissions are inconsequential. - // If the query supports filtering it should be allowed, and if not - not. - if (parameters.isFiltered()) { - return !queryType.isAdmin(); - } - // If the query was executed internally, it should be allowed in any event. if (isInternalExecution) { return true; + } + + // If the query is public, it should always be allowed + if (getAuthType().isPublic()) { + return true; + } + + // If the query is not public, the user must be logged on + if (getUser() == null) { + return false; + } + + // If the user requests filtered execution, his permissions are inconsequential. + // If the query supports filtering it should be allowed, and if not - not. + if (parameters.isFiltered()) { + return !getAuthType().isAdmin(); } // In any other event, we have admin execution, which should only be allowed according to the user's @@ -118,6 +132,10 @@ return getUser().isAdmin(); } + protected VdcQueryAuthType getAuthType() { + return queryType.getAuthType(); + } + /** * @return true if all parameters class and its inner members passed * validation diff --git a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/AbstractUserQueryTest.java b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/AbstractUserQueryTest.java index 5731df1..a70951d 100644 --- a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/AbstractUserQueryTest.java +++ b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/AbstractUserQueryTest.java @@ -29,7 +29,7 @@ } /** Sets up a mock for {@link #user} */ - private void setUpMockUser() { + protected void setUpMockUser() { userID = new Guid(UUID.randomUUID()); user = mock(DbUser.class); when(user.getId()).thenReturn(userID); @@ -56,6 +56,6 @@ @Test public void testQueryIsAUserQuery() throws IllegalArgumentException, IllegalAccessException { assertFalse("A query tested for filtered access should not be an admin query", - TestHelperQueriesCommandType.getQueryTypeFieldValue(getQuery()).isAdmin()); + TestHelperQueriesCommandType.getQueryTypeFieldValue(getQuery()).getAuthType().isAdmin()); } } diff --git a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/GetConfigurationValueQueryTest.java b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/GetConfigurationValueQueryTest.java index 723b8c5..cd55c01 100644 --- a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/GetConfigurationValueQueryTest.java +++ b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/GetConfigurationValueQueryTest.java @@ -25,12 +25,21 @@ private ConfigurationValues configValue; private boolean isFiltered; + private boolean isLoggedIn; private boolean shouldSucceed; - public GetConfigurationValueQueryTest(ConfigurationValues configValue, boolean isFiltered, boolean shouldSucceed) { + public GetConfigurationValueQueryTest(ConfigurationValues configValue, boolean isFiltered, boolean isLoggedIn, boolean shouldSucceed) { this.configValue = configValue; this.isFiltered = isFiltered; + this.isLoggedIn = isLoggedIn; this.shouldSucceed = shouldSucceed; + } + + @Override + protected void setUpMockUser() { + if (isLoggedIn) { + super.setUpMockUser(); + } } /** @@ -38,16 +47,21 @@ * <ol> * <li>The {@link ConfigurationValues} constant to test</li> * <li>Testing in filtered/unfiltered mode</li> + * <li>Whether the user logged in or not</li> * <li>Whether this query should succeed or not</li> * </ol> */ @Parameterized.Parameters public static Collection<Object[]> data() { return Arrays.asList(new Object[][] - { { ConfigurationValues.MaxVmsInPool, true, true }, // A user config value - { ConfigurationValues.MaxVmsInPool, false, false }, - { ConfigurationValues.AdUserName, true, false}, // An admin config value - { ConfigurationValues.AdUserName, false, false} + { { ConfigurationValues.MaxVmsInPool, true, true, true }, // A user config value + { ConfigurationValues.MaxVmsInPool, true, false, false }, + { ConfigurationValues.MaxVmsInPool, false, true, false }, + { ConfigurationValues.MaxVmsInPool, false, false, false }, + { ConfigurationValues.AdUserName, true, true, false}, // An admin config value + { ConfigurationValues.AdUserName, true, false, false}, + { ConfigurationValues.AdUserName, false, true, false}, + { ConfigurationValues.AdUserName, false, false, false} }); } @@ -67,9 +81,10 @@ Object actual = getQuery().getQueryReturnValue().getReturnValue(); if (shouldSucceed) { - assertEquals("Got wrong value for " + configValue, expected, actual); + assertEquals("[loggedin=" + isLoggedIn + "] Got wrong value for " + configValue, expected, actual); } else { - assertNull("Should get null result for " + configValue + " but got " + actual, actual); + assertNull("[loggedin=" + isLoggedIn + "] Should get null result for " + configValue + " but got " + + actual, actual); } } diff --git a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/QueriesCommandBaseTest.java b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/QueriesCommandBaseTest.java index 61f6b85..61a3721 100644 --- a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/QueriesCommandBaseTest.java +++ b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/QueriesCommandBaseTest.java @@ -66,11 +66,11 @@ for (boolean isFiltered : booleans) { for (boolean isUserAdmin : booleans) { for (boolean isInternalExecution : booleans) { - boolean shouldBeAbleToRunQuery; + boolean shouldBeAbleToRunQuery = isInternalExecution || queryType.getAuthType().isPublic(); if (isFiltered) { - shouldBeAbleToRunQuery = !queryType.isAdmin(); + shouldBeAbleToRunQuery = shouldBeAbleToRunQuery || !queryType.getAuthType().isAdmin(); } else { - shouldBeAbleToRunQuery = isInternalExecution || isUserAdmin; + shouldBeAbleToRunQuery = shouldBeAbleToRunQuery || isUserAdmin; } log.debug("Running on query: " + toString()); diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/ConfigurationValues.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/ConfigurationValues.java index a3a239a..727b447 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/ConfigurationValues.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/ConfigurationValues.java @@ -4,7 +4,7 @@ MaxNumOfVmCpus(ConfigAuthType.User), MaxNumOfVmSockets(ConfigAuthType.User), MaxNumOfCpuPerSocket(ConfigAuthType.User), - VdcVersion(ConfigAuthType.User), + VdcVersion(ConfigAuthType.Public), // GetAllAdDomains, SSLEnabled(ConfigAuthType.User), CipherSuite(ConfigAuthType.User), @@ -64,13 +64,13 @@ SupportedClusterLevels(ConfigAuthType.User), OvfUpdateIntervalInMinutes, OvfItemsCountPerUpdate, - ProductRPMVersion(ConfigAuthType.User), + ProductRPMVersion(ConfigAuthType.Public), RhevhLocalFSPath, HotPlugEnabled(ConfigAuthType.User), NetworkLinkingSupported(ConfigAuthType.User), SupportBridgesReportByVDSM(ConfigAuthType.User), ManagementNetwork, - ApplicationMode(ConfigAuthType.User), + ApplicationMode(ConfigAuthType.Public), ShareableDiskEnabled(ConfigAuthType.User), DirectLUNDiskEnabled(ConfigAuthType.User), WANDisableEffects(ConfigAuthType.User), @@ -96,7 +96,7 @@ MaxAverageNetworkQoSValue, MaxPeakNetworkQoSValue, MaxBurstNetworkQoSValue, - UserMessageOfTheDay(ConfigAuthType.User), + UserMessageOfTheDay(ConfigAuthType.Public), QoSInboundAverageDefaultValue, QoSInboundPeakDefaultValue, QoSInboundBurstDefaultValue, @@ -114,7 +114,8 @@ public static enum ConfigAuthType { Admin, - User + User, + Public } private ConfigAuthType authType; diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java index 7c5d7e5..5fddbc3 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java @@ -156,7 +156,7 @@ GetAllBookmarks, // Configuration values - GetConfigurationValue(VdcQueryAuthType.User), + GetConfigurationValue(VdcQueryAuthType.Public), GetConfigurationValues(VdcQueryAuthType.User), GetDefaultTimeZone(VdcQueryAuthType.User), GetAvailableStoragePoolVersions(VdcQueryAuthType.User), @@ -174,10 +174,10 @@ AdGroupsSearch(VdcQueryAuthType.User), // Public services - GetDomainList(VdcQueryAuthType.User), - RegisterVds(VdcQueryAuthType.User), - CheckDBConnection(VdcQueryAuthType.User), - ValidateSession(VdcQueryAuthType.User), + GetDomainList(VdcQueryAuthType.Public), + RegisterVds(VdcQueryAuthType.Public), + CheckDBConnection(VdcQueryAuthType.Public), + ValidateSession(VdcQueryAuthType.Public), // License queries GetAllServerCpuList, @@ -312,7 +312,16 @@ */ public static enum VdcQueryAuthType { Admin, - User + User, + Public; + + public boolean isAdmin() { + return this == Admin; + } + + public boolean isPublic() { + return this == Public; + } } private static final String DEFAULT_PACKAGE_NAME = "org.ovirt.engine.core.bll"; @@ -350,9 +359,5 @@ public VdcQueryAuthType getAuthType() { return authType; - } - - public boolean isAdmin() { - return authType == VdcQueryAuthType.Admin; } } diff --git a/backend/manager/modules/common/src/test/java/org/ovirt/engine/core/common/queries/VdcQueryTypeTest.java b/backend/manager/modules/common/src/test/java/org/ovirt/engine/core/common/queries/VdcQueryTypeTest.java index b4620c5..b208b50 100644 --- a/backend/manager/modules/common/src/test/java/org/ovirt/engine/core/common/queries/VdcQueryTypeTest.java +++ b/backend/manager/modules/common/src/test/java/org/ovirt/engine/core/common/queries/VdcQueryTypeTest.java @@ -19,6 +19,6 @@ @Test public void testAuthTypes() { assertEquals("Unknown should not be an admin query", VdcQueryAuthType.User, VdcQueryType.Unknown.getAuthType()); - assertFalse("Unknown should not be an admin query", VdcQueryType.Unknown.isAdmin()); + assertFalse("Unknown should not be an admin query", VdcQueryType.Unknown.getAuthType().isAdmin()); } } -- To view, visit http://gerrit.ovirt.org/23001 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I6f428c6449873054f3d7d291eef6caf4c9b09bb2 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Allon Mureinik <amure...@redhat.com> _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches