modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java | 25
modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleCriteria.java | 11
modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleResourceDeploymentCriteria.java | 9
modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleVersionCriteria.java | 10
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/deployment/BundleDeploymentDataSource.java | 3
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/list/BundleView.java | 4
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/version/BundleVersionView.java | 4
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/BundleGWTService.java | 9
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/BundleGWTServiceImpl.java | 44
modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java | 14
modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBeanTest.java | 2
modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/tagging/TagManagerBeanTest.java | 2
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerBean.java | 445 ++++++----
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java | 149 ++-
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerRemote.java | 159 ++-
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleServerServiceImpl.java | 2
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java | 50 -
17 files changed, 583 insertions(+), 359 deletions(-)
New commits:
commit c0adb33418b870b168d72d682225744664bea1b7
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed Jul 31 14:19:18 2013 -0400
Fine-grained bundle perms : checkpoint check-in
- finished initial work-through of remote/local API methods and
the associated coding to support the updated permission scheme
- Global.MANAGE_BUNDLE is no longer used as an explicit permission but
now only as a convenience for setting all of the new permissions.
- merged the "FindXxxByCriteriaWithDestinationFilter" local methods into
their respective "FindXxxByCriteria" methods. The base methods should be
handling this filtering, otherwise they basically have a security hole.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java
index 3a8569f..5af51af 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java
@@ -57,7 +57,7 @@ import org.rhq.core.domain.tagging.Tag;
* @author John Mazzitelli
*/
@Entity
-@NamedQueries( {
+@NamedQueries({
// Below queries primarily used for domain test code.
@NamedQuery(name = Bundle.QUERY_FIND_ALL, query = "SELECT b FROM Bundle b"), //
@NamedQuery(name = Bundle.QUERY_FIND_BY_NAME, query = "SELECT b FROM Bundle b WHERE :name = b.name"),
@@ -182,6 +182,29 @@ public class Bundle implements Serializable {
this.bundleVersions = bundleVersions;
}
+ public Set<BundleGroup> getBundleGroups() {
+ return bundleGroups;
+ }
+
+ public void setBundleGroups(Set<BundleGroup> bundleGroups) {
+ this.bundleGroups = bundleGroups;
+ }
+
+ public void addBundleGroup(BundleGroup bundleGroup) {
+ if (this.bundleGroups == null) {
+ this.bundleGroups = new HashSet<BundleGroup>();
+ }
+ this.bundleGroups.add(bundleGroup);
+ }
+
+ public boolean removeBundleGroup(BundleGroup bundleGroup) {
+ if (this.bundleGroups != null) {
+ return this.bundleGroups.remove(bundleGroup);
+ } else {
+ return false;
+ }
+ }
+
public List<BundleDestination> getDestinations() {
return destinations;
}
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleCriteria.java
index 5e6f8c1..32f2f9d 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleCriteria.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleCriteria.java
@@ -145,6 +145,12 @@ public class BundleCriteria extends TaggedCriteria {
this.fetchBundleVersions = fetchBundleVersions;
}
+ /**
+ * Unless called by an InventoryManager the destinations will be filtered to those the caller can view, based
+ * on the resource groups associated with his roles and the group associated wuth the destination.
+ *
+ * @param fetchDestinations
+ */
public void fetchDestinations(boolean fetchDestinations) {
this.fetchDestinations = fetchDestinations;
}
@@ -166,4 +172,9 @@ public class BundleCriteria extends TaggedCriteria {
addSortField("description");
this.sortDescription = sortDescription;
}
+
+ public boolean isInventoryManagerRequired() {
+ return fetchDestinations;
+ }
+
}
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleResourceDeploymentCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleResourceDeploymentCriteria.java
index 7ec26d7..4924d6f 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleResourceDeploymentCriteria.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleResourceDeploymentCriteria.java
@@ -18,15 +18,12 @@
*/
package org.rhq.core.domain.criteria;
-import java.util.List;
-
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import org.rhq.core.domain.bundle.BundleDeploymentStatus;
import org.rhq.core.domain.bundle.BundleResourceDeployment;
-import org.rhq.core.domain.util.CriteriaUtils;
/**
* @author Jay Shaughnessy
@@ -85,11 +82,7 @@ public class BundleResourceDeploymentCriteria extends Criteria {
/**
* By setting this fetch to true, it will cause {@link #isInventoryManagerRequired()} to return true as well.
- *
- * In practice, however, MANAGE_INVENTORY is too restrictive; a bundle manager who has MANAGE_BUNDLE but not
- * MANAGE_INVENTORY would not be able to see any resource deployments. So, until it is possible to handle granular
- * authorization checks on optionally fetched criteria data, a bundle manager will be allowed to see resource
- * deployments to any platform.
+ * Without Inventory Manager permission results will be limited to only the resources viewable to the caller.
*
* @see org.rhq.enterprise.server.bundle.BundleManagerBean#findBundleResourceDeploymentsByCriteria(org.rhq.core.domain.auth.Subject, BundleResourceDeploymentCriteria)
*/
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleVersionCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleVersionCriteria.java
index 0bc999f..b5dd0e4 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleVersionCriteria.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleVersionCriteria.java
@@ -79,6 +79,12 @@ public class BundleVersionCriteria extends TaggedCriteria {
this.fetchBundle = fetchBundle;
}
+ /**
+ * Unless called by an InventoryManager the deployments will be filtered to those the caller can view, based
+ * on the resource groups associated with his roles and the destination associated with the deployments.
+ *
+ * @param fetchDestinations
+ */
public void fetchBundleDeployments(boolean fetchBundleDeployments) {
this.fetchBundleDeployments = fetchBundleDeployments;
}
@@ -91,4 +97,8 @@ public class BundleVersionCriteria extends TaggedCriteria {
this.fetchConfigurationDefinition = fetchConfigurationDefinition;
}
+ public boolean isInventoryManagerRequired() {
+ return fetchBundleDeployments;
+ }
+
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/deployment/BundleDeploymentDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/deployment/BundleDeploymentDataSource.java
index 3f71fb1..576f8a8 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/deployment/BundleDeploymentDataSource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/deployment/BundleDeploymentDataSource.java
@@ -99,7 +99,7 @@ public class BundleDeploymentDataSource extends RPCDataSource<BundleDeployment,
@Override
protected void executeFetch(final DSRequest request, final DSResponse response,
final BundleDeploymentCriteria criteria) {
- bundleService.findBundleDeploymentsByCriteriaWithDestinationFilter(criteria, new AsyncCallback<PageList<BundleDeployment>>() {
+ bundleService.findBundleDeploymentsByCriteria(criteria, new AsyncCallback<PageList<BundleDeployment>>() {
public void onFailure(Throwable caught) {
CoreGUI.getErrorHandler().handleError(MSG.view_bundle_deploy_loadDeployFailure(), caught);
}
@@ -109,7 +109,6 @@ public class BundleDeploymentDataSource extends RPCDataSource<BundleDeployment,
processResponse(request.getRequestId(), response);
}
});
-
}
@Override
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 bd54a07..a3bc0d8 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
@@ -62,9 +62,9 @@ import org.rhq.enterprise.gui.coregui.client.components.tagging.TagsChangedCallb
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.enhanced.EnhancedIButton;
import org.rhq.enterprise.gui.coregui.client.util.enhanced.EnhancedVLayout;
+import org.rhq.enterprise.gui.coregui.client.util.message.Message;
public class BundleView extends EnhancedVLayout implements BookmarkableView {
private DynamicForm form;
@@ -277,7 +277,7 @@ public class BundleView extends EnhancedVLayout implements BookmarkableView {
criteria.fetchDestinations(true);
criteria.fetchTags(true);
- GWTServiceLookup.getBundleService().findBundlesByCriteriaWithDestinationFilter(criteria,
+ GWTServiceLookup.getBundleService().findBundlesByCriteria(criteria,
new AsyncCallback<PageList<Bundle>>() {
public void onFailure(Throwable caught) {
CoreGUI.getErrorHandler().handleError(MSG.view_bundle_list_error3(), caught);
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/version/BundleVersionView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/version/BundleVersionView.java
index 52f73f3..3ac67dd 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/version/BundleVersionView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/version/BundleVersionView.java
@@ -58,9 +58,9 @@ 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.message.Message;
import org.rhq.enterprise.gui.coregui.client.util.enhanced.EnhancedIButton;
import org.rhq.enterprise.gui.coregui.client.util.enhanced.EnhancedVLayout;
+import org.rhq.enterprise.gui.coregui.client.util.message.Message;
/**
* @author Greg Hinkle
@@ -268,7 +268,7 @@ public class BundleVersionView extends EnhancedVLayout implements BookmarkableVi
criteria.fetchConfigurationDefinition(true);
criteria.fetchTags(true);
- bundleManager.findBundleVersionsByCriteriaWithDestinationFilter(criteria,
+ bundleManager.findBundleVersionsByCriteria(criteria,
new AsyncCallback<PageList<BundleVersion>>() {
public void onFailure(Throwable caught) {
CoreGUI.getErrorHandler().handleError(MSG.view_bundle_version_loadFailure(), caught);
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/BundleGWTService.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/BundleGWTService.java
index cd108b7..2a45f65 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/BundleGWTService.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/BundleGWTService.java
@@ -47,8 +47,6 @@ public interface BundleGWTService extends RemoteService {
ResourceTypeBundleConfiguration getResourceTypeBundleConfiguration(int compatGroupId) throws RuntimeException;
- BundleVersion createBundleVersion(int bundleId, String name, String version, String recipe) throws RuntimeException;
-
BundleVersion createBundleVersionViaURL(String url, String username, String password) throws RuntimeException;
BundleVersion createBundleVersionViaRecipe(String recipe) throws RuntimeException;
@@ -74,14 +72,9 @@ public interface BundleGWTService extends RemoteService {
PageList<BundleGroup> findBundleGroupsByCriteria(BundleGroupCriteria criteria) throws RuntimeException;
- PageList<Bundle> findBundlesByCriteriaWithDestinationFilter(BundleCriteria criteria) throws RuntimeException;
-
PageList<BundleDeployment> findBundleDeploymentsByCriteria(BundleDeploymentCriteria criteria)
throws RuntimeException;
- PageList<BundleDeployment> findBundleDeploymentsByCriteriaWithDestinationFilter(BundleDeploymentCriteria criteria)
- throws RuntimeException;
-
PageList<BundleDestination> findBundleDestinationsByCriteria(BundleDestinationCriteria criteria)
throws RuntimeException;
@@ -92,8 +85,6 @@ public interface BundleGWTService extends RemoteService {
PageList<BundleVersion> findBundleVersionsByCriteria(BundleVersionCriteria criteria) throws RuntimeException;
- PageList<BundleVersion> findBundleVersionsByCriteriaWithDestinationFilter(BundleVersionCriteria criteria) throws RuntimeException;
-
PageList<BundleWithLatestVersionComposite> findBundlesWithLatestVersionCompositesByCriteria(BundleCriteria criteria)
throws RuntimeException;
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/BundleGWTServiceImpl.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/BundleGWTServiceImpl.java
index 88458b8..01b17a1 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/BundleGWTServiceImpl.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/BundleGWTServiceImpl.java
@@ -110,18 +110,6 @@ public class BundleGWTServiceImpl extends AbstractGWTServiceImpl implements Bund
}
@Override
- public BundleVersion createBundleVersion(int bundleId, String name, String version, String recipe)
- throws RuntimeException {
- try {
- BundleVersion results = bundleManager.createBundleVersion(getSessionSubject(), bundleId, name, null,
- version, recipe);
- return SerialUtility.prepare(results, "createBundleVersion");
- } catch (Throwable t) {
- throw getExceptionToThrowToClient(t);
- }
- }
-
- @Override
public void deleteBundles(int[] bundleIds) throws RuntimeException {
try {
bundleManager.deleteBundles(getSessionSubject(), bundleIds);
@@ -246,16 +234,6 @@ public class BundleGWTServiceImpl extends AbstractGWTServiceImpl implements Bund
}
@Override
- public PageList<Bundle> findBundlesByCriteriaWithDestinationFilter(BundleCriteria criteria) throws RuntimeException {
- try {
- PageList<Bundle> results = bundleManager.findBundlesByCriteriaWithDestinationFilter(getSessionSubject(), criteria);
- return SerialUtility.prepare(results, "findBundlesByCriteriaWithDestinationFilter");
- } catch (Throwable t) {
- throw getExceptionToThrowToClient(t);
- }
- }
-
- @Override
public PageList<BundleDeployment> findBundleDeploymentsByCriteria(BundleDeploymentCriteria criteria)
throws RuntimeException {
try {
@@ -268,18 +246,6 @@ public class BundleGWTServiceImpl extends AbstractGWTServiceImpl implements Bund
}
@Override
- public PageList<BundleDeployment> findBundleDeploymentsByCriteriaWithDestinationFilter(BundleDeploymentCriteria criteria)
- throws RuntimeException {
- try {
- PageList<BundleDeployment> result = bundleManager.findBundleDeploymentsByCriteriaWithDestinationFilter(getSessionSubject(),
- criteria);
- return SerialUtility.prepare(result, "BundleService.findBundleDeploymentsByCriteriaWithDestinationFilter");
- } catch (Throwable t) {
- throw getExceptionToThrowToClient(t);
- }
- }
-
- @Override
public PageList<BundleDestination> findBundleDestinationsByCriteria(BundleDestinationCriteria criteria)
throws RuntimeException {
try {
@@ -324,16 +290,6 @@ public class BundleGWTServiceImpl extends AbstractGWTServiceImpl implements Bund
}
@Override
- public PageList<BundleVersion> findBundleVersionsByCriteriaWithDestinationFilter(BundleVersionCriteria criteria) throws RuntimeException {
- try {
- PageList<BundleVersion> results = bundleManager.findBundleVersionsByCriteriaWithDestinationFilter(getSessionSubject(), criteria);
- return SerialUtility.prepare(results, "findBundleVersionsByCriteriaWithDestinationFilter");
- } catch (Throwable t) {
- throw getExceptionToThrowToClient(t);
- }
- }
-
- @Override
public PageList<BundleWithLatestVersionComposite> findBundlesWithLatestVersionCompositesByCriteria(
BundleCriteria criteria) throws RuntimeException {
try {
diff --git a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
index f60d426..c4d9a79 100644
--- a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
+++ b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
@@ -860,7 +860,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
int size = brd.getBundleResourceDeploymentHistories().size();
assertTrue(size > 0);
String auditMessage = "BundleTest-Message";
- bundleManager.addBundleResourceDeploymentHistory(overlord, brd.getId(), new BundleResourceDeploymentHistory(
+ bundleManager.addBundleResourceDeploymentHistoryInNewTrans(overlord, brd.getId(), new BundleResourceDeploymentHistory(
overlord.getName(), auditMessage, auditMessage, BundleResourceDeploymentHistory.Category.DEPLOY_STEP,
BundleResourceDeploymentHistory.Status.SUCCESS, auditMessage, auditMessage));
@@ -1242,7 +1242,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
final BundleType type = createBundleType(name);
final String recipe = "deploy -f " + TEST_PREFIX + ".zip -d @@ test.path @@";
final BundleVersion bundleVerison = bundleManager.createBundleAndBundleVersion(overlord, fullName,
- "description", type.getId(), fullName, fullName + "-desc", "3.0", recipe);
+ "description", type.getId(), 0, fullName, fullName + "-desc", "3.0", recipe);
assertNotNull(bundleVerison);
// find the previously created bundle
@@ -1272,7 +1272,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
final String fullName = TEST_PREFIX + "-bundle-" + name;
final String recipe = "deploy -f " + TEST_PREFIX + ".zip -d @@ test.path @@";
final BundleVersion bundleVerison = bundleManager.createBundleAndBundleVersion(overlord, fullName,
- "description", bundle.getBundleType().getId(), fullName, fullName + "-desc", "3.0", recipe);
+ "description", bundle.getBundleType().getId(), 0, fullName, fullName + "-desc", "3.0", recipe);
// find the newly created bundle
BundleCriteria c = new BundleCriteria();
@@ -1284,6 +1284,12 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
assertEquals(1, bundles.size());
}
+ @Test(enabled = false)
+ public void testNoAuthz() throws Exception {
+ // create
+
+ }
+
// helper methods
private BundleType createBundleType(String name) throws Exception {
final String fullName = TEST_PREFIX + "-type-" + name;
@@ -1302,7 +1308,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
private Bundle createBundle(String name, BundleType bt) throws Exception {
final String fullName = TEST_PREFIX + "-bundle-" + name;
- Bundle b = bundleManager.createBundle(overlord, fullName, fullName + "-desc", bt.getId());
+ Bundle b = bundleManager.createBundle(overlord, fullName, fullName + "-desc", bt.getId(), 0);
assert b.getId() > 0;
assert b.getName().endsWith(fullName);
diff --git a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBeanTest.java b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBeanTest.java
index 48649d2..46f2bef 100644
--- a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBeanTest.java
+++ b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBeanTest.java
@@ -684,7 +684,7 @@ public class ResourceMetadataManagerBeanTest extends MetadataBeanTest {
BundleType bundleType = bundleMgr.getBundleType(subjectMgr.getOverlord(), bundleTypeName);
assertNotNull("Cannot create bundle. Unable to find bundle type for [name: " + bundleTypeName + "]", bundleType);
Bundle bundle = bundleMgr.createBundle(subjectMgr.getOverlord(), bundleName, "test bundle: " + bundleName,
- bundleType.getId());
+ bundleType.getId(), 0);
assertNotNull("Failed create bundle for [name: " + bundleName + "]", bundle);
}
diff --git a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/tagging/TagManagerBeanTest.java b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/tagging/TagManagerBeanTest.java
index 83a5dfe..bef8921 100644
--- a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/tagging/TagManagerBeanTest.java
+++ b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/tagging/TagManagerBeanTest.java
@@ -259,7 +259,7 @@ public class TagManagerBeanTest extends AbstractEJB3Test {
private Bundle createBundle() throws Exception {
ResourceType resourceType = SessionTestHelper.createNewResourceType(em);
BundleType bundleType = bundleManager.createBundleType(overlord, getRandomString(), resourceType.getId());
- return bundleManager.createBundle(overlord, getRandomString(), getRandomString(), bundleType.getId());
+ return bundleManager.createBundle(overlord, getRandomString(), getRandomString(), bundleType.getId(), 0);
}
private BundleVersion createBundleVersion() throws Exception {
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerBean.java
index 51e59ff..a9882c4 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerBean.java
@@ -30,6 +30,7 @@ import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -197,9 +198,8 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
@Override
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
- @RequiredPermission(Permission.MANAGE_BUNDLE)
- public BundleResourceDeploymentHistory addBundleResourceDeploymentHistory(Subject subject, int bundleDeploymentId,
- BundleResourceDeploymentHistory history) throws Exception {
+ public BundleResourceDeploymentHistory addBundleResourceDeploymentHistoryInNewTrans(Subject subject,
+ int bundleDeploymentId, BundleResourceDeploymentHistory history) throws Exception {
BundleResourceDeployment resourceDeployment = entityManager.find(BundleResourceDeployment.class,
bundleDeploymentId);
@@ -214,8 +214,8 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
}
@Override
- @RequiredPermission(Permission.MANAGE_BUNDLE)
- public Bundle createBundle(Subject subject, String name, String description, int bundleTypeId) throws Exception {
+ public Bundle createBundle(Subject subject, String name, String description, int bundleTypeId, int bundleGroupId)
+ throws Exception {
if (null == name || "".equals(name.trim())) {
throw new IllegalArgumentException("Invalid bundleName: " + name);
}
@@ -225,8 +225,15 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
throw new IllegalArgumentException("Invalid bundleTypeId: " + bundleTypeId);
}
- // create and add the required Repo. the Repo is a detached object which helps in its eventual
- // removal.
+ BundleGroup bundleGroup = null;
+ if (bundleGroupId > 0) {
+ bundleGroup = entityManager.find(BundleGroup.class, bundleGroupId);
+ if (null == bundleGroup) {
+ throw new IllegalArgumentException("Invalid bundleGroupId: " + bundleGroupId);
+ }
+ }
+
+ // create and add the required Repo. the Repo is a detached object which helps in its eventual removal.
Repo repo = new Repo(name);
repo.setCandidate(false);
repo.setSyncSchedule(null);
@@ -249,6 +256,9 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
Bundle bundle = new Bundle(name, bundleType, repo, packageType);
bundle.setDescription(description);
bundle.setPackageType(packageType);
+ if (null != bundleGroup) {
+ bundle.addBundleGroup(bundleGroup);
+ }
log.info("Creating bundle: " + bundle);
entityManager.persist(bundle);
@@ -258,7 +268,6 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
@Override
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
- @RequiredPermission(Permission.MANAGE_BUNDLE)
public BundleDeployment createBundleDeploymentInNewTrans(Subject subject, int bundleVersionId,
int bundleDestinationId, String name, String description, Configuration configuration) throws Exception {
@@ -287,7 +296,7 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
throw new IllegalArgumentException("Invalid bundleDestinationId: " + bundleDestinationId);
}
- checkBundleDeploymentAuthz(subject, bundleVersion.getBundle().getId(), bundleDestination.getGroup().getId());
+ checkDeployBundleAuthz(subject, bundleVersion.getBundle().getId(), bundleDestination.getGroup().getId());
String name = getBundleDeploymentNameImpl(subject, bundleDestination, bundleVersion, null);
return this.createBundleDeploymentImpl(subject, bundleVersion, bundleDestination, name, description,
@@ -348,7 +357,7 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
}
ResourceGroup group = entityManager.find(ResourceGroup.class, groups.get(0).getId());
- checkBundleDeploymentAuthz(subject, bundle.getId(), groupId);
+ checkDeployBundleAuthz(subject, bundle.getId(), groupId);
BundleDestination dest = new BundleDestination(bundle, name, group, destBaseDirName, deployDir);
dest.setDescription(description);
@@ -383,6 +392,8 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
+ "] or prevDeploymentId [" + prevDeploymentId + "]");
}
+ checkDeployBundleAuthz(subject, bundleVersion.getBundle().getId(), bundleDestination.getGroup().getId());
+
return getBundleDeploymentNameImpl(subject, bundleDestination, bundleVersion, prevDeployment);
}
@@ -442,7 +453,7 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
}
@Override
- @RequiredPermission(Permission.MANAGE_BUNDLE)
+ @RequiredPermission(Permission.CREATE_BUNDLES)
public BundleType createBundleType(Subject subject, String name, int resourceTypeId) throws Exception {
if (null == name || "".equals(name.trim())) {
throw new IllegalArgumentException("Invalid bundleTypeName: " + name);
@@ -459,22 +470,21 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
}
@Override
- @RequiredPermission(Permission.MANAGE_BUNDLE)
public BundleVersion createBundleAndBundleVersion(Subject subject, String bundleName, String bundleDescription,
- int bundleTypeId, String bundleVersionName, String bundleVersionDescription, String version, String recipe)
- throws Exception {
+ int bundleTypeId, int bundleGroupId, String bundleVersionName, String bundleVersionDescription, String version,
+ String recipe) throws Exception {
// first see if the bundle exists or not; if not, create one
BundleCriteria criteria = new BundleCriteria();
criteria.setStrict(true);
criteria.addFilterBundleTypeId(Integer.valueOf(bundleTypeId));
criteria.addFilterName(bundleName);
- criteria.clearPaging();//disable paging as the code assumes all the results will be returned.
+ criteria.clearPaging(); //disable paging as the code assumes all the results will be returned.
PageList<Bundle> bundles = findBundlesByCriteria(subject, criteria);
Bundle bundle;
if (bundles.getTotalSize() == 0) {
- bundle = createBundle(subject, bundleName, bundleDescription, bundleTypeId);
+ bundle = createBundle(subject, bundleName, bundleDescription, bundleTypeId, bundleGroupId);
} else {
bundle = bundles.get(0);
}
@@ -487,7 +497,6 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
@Override
@SuppressWarnings("unchecked")
- @RequiredPermission(Permission.MANAGE_BUNDLE)
public BundleVersion createBundleVersion(Subject subject, int bundleId, String name, String description,
String version, String recipe) throws Exception {
if (null == name || "".equals(name.trim())) {
@@ -533,7 +542,7 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
versionOrder = ((Number) bv[1]).intValue();
needToUpdateOrder = true;
} else {
- break; // comparision > 0, means our new version is higher than what's in the DB, because we DESC ordered, we can stop
+ break; // Comparison > 0, means our new version is higher than what's in the DB, because we DESC ordered, we can stop
}
}
@@ -753,7 +762,8 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
if (isInitialVersion) {
checkCreateInitialBundleVersionAuthz(subject, initialBundleGroupId);
- bundle = bundleManager.createBundle(subject, bundleName, bundleDescription, bundleType.getId());
+ bundle = bundleManager.createBundle(subject, bundleName, bundleDescription, bundleType.getId(),
+ initialBundleGroupId);
createdBundle = true;
} else {
bundle = bundles.get(0);
@@ -762,8 +772,8 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
}
// now create the bundle version with the bundle we either found or created
- BundleVersion bundleVersion = bundleManager.createBundleVersion(subject, bundle.getId(), name, description,
- version, recipe);
+ BundleVersion bundleVersion = bundleManager.createBundleVersion(subjectManager.getOverlord(), bundle.getId(),
+ name, description, version, recipe);
// now that we have the bundle version we can actually create the bundle files that were provided in
// the bundle distribution
@@ -979,7 +989,6 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
}
@Override
- @RequiredPermission(Permission.MANAGE_BUNDLE)
public BundleFile addBundleFileViaPackageVersion(Subject subject, int bundleVersionId, String name,
int packageVersionId) throws Exception {
@@ -1010,7 +1019,6 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
}
@Override
- @RequiredPermission(Permission.MANAGE_BUNDLE)
@TransactionAttribute(TransactionAttributeType.NEVER)
public void purgeBundleDestination(final Subject subject, int bundleDestinationId) throws Exception {
// find the live bundle deployment for this destination, and get all the resource deployments for that live deployment
@@ -1031,6 +1039,13 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
return; // nothing to do
}
+ // Although they likely will, the actual resource deployments may no longer match the members of the destination's
+ // resource group (if group membership has changed). We still use the group for authz because that is the more
+ // intuitive, manageable way to do this. Otherwise the subject would need view perms on each of the previously
+ // deployed-to resources, and that may be tricky to provide.
+ checkDeployBundleAuthz(subject, liveDeployment.getBundleVersion().getBundle().getId(), liveDeployment
+ .getDestination().getGroup().getId());
+
// we need to obtain the bundle type (the remote plugin container needs it). our first criteria can't fetch this deep, we have to do another query.
BundleVersionCriteria bvc = new BundleVersionCriteria();
bvc.addFilterId(liveDeployment.getBundleVersion().getId());
@@ -1082,7 +1097,8 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
BundleResourceDeploymentHistory history = new BundleResourceDeploymentHistory(subject.getName(),
"Purge Requested", "User [" + subject.getName() + "] requested to purge this deployment", null,
BundleResourceDeploymentHistory.Status.SUCCESS, null, null);
- bundleManager.addBundleResourceDeploymentHistory(subject, resourceDeploy.getId(), history);
+ bundleManager.addBundleResourceDeploymentHistoryInNewTrans(subjectManager.getOverlord(),
+ resourceDeploy.getId(), history);
// get a connection to the agent and tell it to purge the bundle from the file system
Subject overlord = subjectManager.getOverlord();
@@ -1116,8 +1132,6 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
}
@Override
- @RequiredPermission(Permission.MANAGE_SECURITY)
- // no one should be calling us except overlord
public void _finalizePurge(Subject subject, BundleDeployment bundleDeployment,
Map<BundleResourceDeployment, String> failedToPurge) throws Exception {
@@ -1154,14 +1168,12 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
}
@Override
- @RequiredPermission(Permission.MANAGE_BUNDLE)
public BundleDeployment scheduleBundleDeployment(Subject subject, int bundleDeploymentId, boolean isCleanDeployment)
throws Exception {
return scheduleBundleDeploymentImpl(subject, bundleDeploymentId, isCleanDeployment, false, null);
}
@Override
- @RequiredPermission(Permission.MANAGE_BUNDLE)
public BundleDeployment scheduleRevertBundleDeployment(Subject subject, int bundleDestinationId,
String deploymentDescription, boolean isCleanDeployment) throws Exception {
@@ -1189,6 +1201,9 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
+ "] can not be reverted. There is no prior deployment for destinationId [" + bundleDestinationId + "]");
}
+ checkDeployBundleAuthz(subject, liveDeployment.getBundleVersion().getBundle().getId(), liveDeployment
+ .getDestination().getGroup().getId());
+
// A revert is done by deploying a new deployment that mirrors "prevDeployment". It uses the same
// bundleVersion, destination and config as prevDeployment. It can have a new name and new desc, and
// may opt to clean the deploy dir. It must be a new deployment so that all status/auditing/history starts
@@ -1225,6 +1240,8 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
+ "] group has no members. Invalid deployment destination");
}
+ checkDeployBundleAuthz(subject, newDeployment.getBundleVersion().getBundle().getId(), group.getId());
+
for (Resource groupMember : groupMembers) {
try {
scheduleBundleResourceDeployment(subject, newDeployment, groupMember, isCleanDeployment, isRevert);
@@ -1277,8 +1294,8 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
// The BundleResourceDeployment record must exist in the db before the agent request because the agent may try
// to add History to it during immediate deployments. So, create and persist it (requires a new trans).
- BundleResourceDeployment resourceDeployment = bundleManager.createBundleResourceDeployment(subject,
- deployment.getId(), bundleTargetResourceId);
+ BundleResourceDeployment resourceDeployment = bundleManager.createBundleResourceDeploymentInNewTrans(
+ subjectManager.getOverlord(), deployment.getId(), bundleTargetResourceId);
if (null != bundleTarget.getResourceType().getResourceTypeBundleConfiguration()) {
@@ -1292,7 +1309,8 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
AUDIT_ACTION_DEPLOYMENT_REQUESTED, deployment.getName(), null,
BundleResourceDeploymentHistory.Status.SUCCESS, "Requested deployment time: "
+ request.getRequestedDeployTimeAsString(), null);
- bundleManager.addBundleResourceDeploymentHistory(subject, resourceDeployment.getId(), history);
+ bundleManager.addBundleResourceDeploymentHistoryInNewTrans(subjectManager.getOverlord(),
+ resourceDeployment.getId(), history);
BundleScheduleResponse response = bundleAgentService.schedule(request);
@@ -1303,7 +1321,8 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
history = new BundleResourceDeploymentHistory(subject.getName(), AUDIT_ACTION_DEPLOYMENT,
deployment.getName(), null, BundleResourceDeploymentHistory.Status.FAILURE,
response.getErrorMessage(), null);
- bundleManager.addBundleResourceDeploymentHistory(subject, resourceDeployment.getId(), history);
+ bundleManager.addBundleResourceDeploymentHistoryInNewTrans(subject, resourceDeployment.getId(),
+ history);
}
} catch (Throwable t) {
// fail the unlaunched resource deployment
@@ -1311,7 +1330,8 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
this.AUDIT_ACTION_DEPLOYMENT, deployment.getName(), null,
BundleResourceDeploymentHistory.Status.FAILURE, "Failed to schedule, agent on [" + bundleTarget
+ "] may be down: " + t, null);
- bundleManager.addBundleResourceDeploymentHistory(subject, resourceDeployment.getId(), failureHistory);
+ bundleManager.addBundleResourceDeploymentHistoryInNewTrans(subject, resourceDeployment.getId(),
+ failureHistory);
bundleManager.setBundleResourceDeploymentStatus(subject, resourceDeployment.getId(),
BundleDeploymentStatus.FAILURE);
}
@@ -1324,7 +1344,7 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
"Target resource is not of a type that can have bundles deployed to it [resource="
+ bundleTarget.getName() + "; id=" + bundleTarget.getId() + "]. Fix target group for destination ["
+ deployment.getDestination().getName() + "]", null);
- bundleManager.addBundleResourceDeploymentHistory(subject, resourceDeployment.getId(), history);
+ bundleManager.addBundleResourceDeploymentHistoryInNewTrans(subject, resourceDeployment.getId(), history);
}
return resourceDeployment;
@@ -1332,7 +1352,6 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
@Override
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
- @RequiredPermission(Permission.MANAGE_BUNDLE)
public BundleScheduleRequest getScheduleRequest(Subject subject, int resourceDeploymentId,
boolean isCleanDeployment, boolean isRevert) throws Exception {
@@ -1391,8 +1410,7 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
@Override
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
- @RequiredPermission(Permission.MANAGE_BUNDLE)
- public BundleResourceDeployment createBundleResourceDeployment(Subject subject, int bundleDeploymentId,
+ public BundleResourceDeployment createBundleResourceDeploymentInNewTrans(Subject subject, int bundleDeploymentId,
int resourceId) throws Exception {
BundleDeployment deployment = entityManager.find(BundleDeployment.class, bundleDeploymentId);
@@ -1411,7 +1429,6 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
}
@Override
- @RequiredPermission(Permission.MANAGE_BUNDLE)
public BundleResourceDeployment setBundleResourceDeploymentStatus(Subject subject, int resourceDeploymentId,
BundleDeploymentStatus status) throws Exception {
@@ -1456,14 +1473,7 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
return resourceDeployment;
}
- // @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
- // public BundleGroupDeployment createBundleGroupDeployment(BundleGroupDeployment groupDeployment) throws Exception {
- // entityManager.persist(groupDeployment);
- // return groupDeployment;
- //}
-
@Override
- @RequiredPermission(Permission.MANAGE_BUNDLE)
public Set<String> getBundleVersionFilenames(Subject subject, int bundleVersionId, boolean withoutBundleFileOnly)
throws Exception {
@@ -1472,6 +1482,8 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
throw new IllegalArgumentException("Invalid bundleVersionId: " + bundleVersionId);
}
+ checkCreateBundleVersionAuthz(subject, bundleVersion.getBundle().getId());
+
// parse the recipe (validation occurs here) and get the config def and list of files
BundleType bundleType = bundleVersion.getBundle().getBundleType();
RecipeParseResults parseResults = BundleManagerHelper.getPluginContainer().getBundleServerPluginManager()
@@ -1499,11 +1511,9 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
}
return result;
-
}
@Override
- @RequiredPermission(Permission.MANAGE_BUNDLE)
public HashMap<String, Boolean> getAllBundleVersionFilenames(Subject subject, int bundleVersionId) throws Exception {
BundleVersion bundleVersion = entityManager.find(BundleVersion.class, bundleVersionId);
@@ -1511,6 +1521,8 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
throw new IllegalArgumentException("Invalid bundleVersionId: " + bundleVersionId);
}
+ checkCreateBundleVersionAuthz(subject, bundleVersion.getBundle().getId());
+
// parse the recipe (validation occurs here) and get the config def and list of files
BundleType bundleType = bundleVersion.getBundle().getBundleType();
RecipeParseResults parseResults = BundleManagerHelper.getPluginContainer().getBundleServerPluginManager()
@@ -1533,7 +1545,6 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
}
return result;
-
}
@Override
@@ -1557,44 +1568,40 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
@Override
public PageList<BundleDeployment> findBundleDeploymentsByCriteria(Subject subject, BundleDeploymentCriteria criteria) {
CriteriaQueryGenerator generator = new CriteriaQueryGenerator(subject, criteria);
- CriteriaQueryRunner<BundleDeployment> queryRunner = new CriteriaQueryRunner<BundleDeployment>(criteria,
- generator, entityManager);
- return queryRunner.execute();
- }
-
- /**
- * Fetch bundle deployments by criteria and then filter on destinations on the result objects to limit what the user can see
- * @param subject Caller
- * @param criteria criteria to fetch the deployments
- * @return List of deployments with destinations filtered.
- */
- @Override
- public PageList<BundleDeployment> findBundleDeploymentsByCriteriaWithDestinationFilter(Subject subject,
- BundleDeploymentCriteria criteria) {
-
- PageList<BundleDeployment> deployments = findBundleDeploymentsByCriteria(subject, criteria);
- if (authorizationManager.isInventoryManager(subject))
- return deployments;
- PageList<BundleDeployment> resultingDeployments = new PageList<BundleDeployment>(deployments.getPageControl());
- // We now have visible destinations - go over the resultingDeployments and only include the ones with vis. destinations
- for (BundleDeployment deployment : deployments) {
+ // filter by bundles that are viewable
+ if (!authorizationManager.hasGlobalPermission(subject, Permission.VIEW_BUNDLES)) {
+ generator.setAuthorizationResourceFragment(CriteriaQueryGenerator.AuthorizationTokenType.BUNDLE, null,
+ subject.getId());
+ }
- int bundleId = deployment.getBundleVersion().getBundle().getId();
- BundleDestinationCriteria destinationCriteria = new BundleDestinationCriteria();
- destinationCriteria.addFilterBundleId(bundleId);
- List<BundleDestination> destinations = findBundleDestinationsByCriteria(subject, destinationCriteria);
- if (destinationsContains(destinations, deployment.getDestination()))
- resultingDeployments.add(deployment);
+ CriteriaQueryRunner<BundleDeployment> queryRunner = new CriteriaQueryRunner<BundleDeployment>(criteria,
+ generator, entityManager);
+ PageList<BundleDeployment> result = queryRunner.execute();
+
+ // The result currently holds bundle deployments for bundles viewable by the caller, but we must remove
+ // those bundle deployments for destinations not viewable by the user. In essence we wanted two authz tokens,
+ // one for bundle and one for resource group, but we can only supply one.
+ if (!(result.isEmpty() || authorizationManager.isInventoryManager(subject))) {
+
+ for (Iterator<BundleDeployment> i = result.iterator(); i.hasNext();) {
+ BundleDeployment bd = i.next();
+ int groupId = bd.getDestination().getGroup().getId();
+ if (!authorizationManager.canViewGroup(subject, groupId)) {
+ i.remove();
+ }
+ }
}
- return resultingDeployments;
+
+ return result;
}
@Override
public PageList<BundleDestination> findBundleDestinationsByCriteria(Subject subject,
BundleDestinationCriteria criteria) {
CriteriaQueryGenerator generator = new CriteriaQueryGenerator(subject, criteria);
- // Filter by destinations that are viewable
+
+ // Filter by destinations (resource groups) that are viewable
if (!authorizationManager.isInventoryManager(subject)) {
generator.setAuthorizationResourceFragment(CriteriaQueryGenerator.AuthorizationTokenType.GROUP,
subject.getId());
@@ -1610,74 +1617,95 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
CriteriaQueryGenerator generator = new CriteriaQueryGenerator(subject, criteria);
- if (!authorizationManager.isInventoryManager(subject)) {
- if (criteria.isInventoryManagerRequired()) {
- // TODO: MANAGE_INVENTORY was too restrictive as a bundle manager could not then
- // see his resource deployments. Until we can handle granular authorization checks on
- // optionally fetched resource member data, allow a bundle manager to see
- // resource deployments to any resource.
- if (!authorizationManager.hasGlobalPermission(subject, Permission.MANAGE_BUNDLE)) {
- throw new PermissionException("Subject [" + subject.getName()
- + "] requires InventoryManager or BundleManager permission for requested query criteria.");
- }
- }
- // TODO limit target groups according to visibility
+ // filter by bundles that are viewable
+ if (!authorizationManager.hasGlobalPermission(subject, Permission.VIEW_BUNDLES)) {
+ generator.setAuthorizationResourceFragment(CriteriaQueryGenerator.AuthorizationTokenType.BUNDLE, null,
+ subject.getId());
}
CriteriaQueryRunner<BundleResourceDeployment> queryRunner = new CriteriaQueryRunner<BundleResourceDeployment>(
criteria, generator, entityManager);
+ PageList<BundleResourceDeployment> result = queryRunner.execute();
- return queryRunner.execute();
+ // if necessary, filter results to resources that are viewable
+ if (!result.isEmpty() && criteria.isInventoryManagerRequired()
+ && !authorizationManager.isInventoryManager(subject)) {
+
+ // try to authorize in one call, if that fails then go (slow) fine-grained
+ List<Integer> resourceIds = new ArrayList<Integer>(result.size());
+ for (BundleResourceDeployment brd : result) {
+ int resourceId = brd.getResource().getId();
+ resourceIds.add(resourceId);
+ }
+
+ if (!authorizationManager.canViewResources(subject, resourceIds)) {
+ for (Integer resourceId : resourceIds) {
+ if (!authorizationManager.canViewResource(subject, resourceId)) {
+ for (Iterator<BundleResourceDeployment> i = result.iterator(); i.hasNext();) {
+ BundleResourceDeployment brd = i.next();
+ if (brd.getResource().getId() == resourceId.intValue()) {
+ i.remove();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return result;
}
@Override
public PageList<BundleVersion> findBundleVersionsByCriteria(Subject subject, BundleVersionCriteria criteria) {
CriteriaQueryGenerator generator = new CriteriaQueryGenerator(subject, criteria);
- CriteriaQueryRunner<BundleVersion> queryRunner = new CriteriaQueryRunner<BundleVersion>(criteria, generator,
- entityManager);
- return queryRunner.execute();
- }
-
- /**
- * Fetch bundle versions by criteria and then filter destination on the result objects to limit what the user can see
- * @param subject Caller
- * @param criteria criteria to fetch the bundles
- * @return List of versions with destinations filtered.
- */
- @Override
- public PageList<BundleVersion> findBundleVersionsByCriteriaWithDestinationFilter(Subject subject,
- BundleVersionCriteria criteria) {
- PageList<BundleVersion> versions = findBundleVersionsByCriteria(subject, criteria);
- if (authorizationManager.isInventoryManager(subject)) {
- return versions;
+ if (!authorizationManager.hasGlobalPermission(subject, Permission.VIEW_BUNDLES)) {
+ generator.setAuthorizationResourceFragment(CriteriaQueryGenerator.AuthorizationTokenType.BUNDLE, null,
+ subject.getId());
}
- // Not inv manager -> restrict visible deployments by visible destinations
- for (BundleVersion version : versions) {
+ CriteriaQueryRunner<BundleVersion> queryRunner = new CriteriaQueryRunner<BundleVersion>(criteria, generator,
+ entityManager);
+ PageList<BundleVersion> result = queryRunner.execute();
+
+ // If asking for optional data that the subject may not be able to see then ensure that the optional
+ // data is filtered appropriately. In this case only deployments to destinations viewable by the subject
+ // can be returned. The result currently holds bundle versions viewable by the caller, but the bundle version
+ // may have been deployed to destinations for which the user does not have access to the destination's
+ // resource group. (BZ 694741)
+ if (!result.isEmpty() && criteria.isInventoryManagerRequired()
+ && !authorizationManager.isInventoryManager(subject)) {
+
+ // this works because findBundleDestinationsByCriteria() authorizes against resource group associations
+
+ for (BundleVersion bundleVersion : result) {
+ int numDeployments = bundleVersion.getBundleDeployments().size();
+ if (0 == numDeployments) {
+ continue;
+ }
- Bundle bundle = version.getBundle();
- BundleDestinationCriteria destinationCriteria = new BundleDestinationCriteria();
- destinationCriteria.addFilterBundleId(bundle.getId());
- destinationCriteria.clearPaging();//disable paging as the code assumes all the results will be returned.
+ Bundle bundle = bundleVersion.getBundle();
+ BundleDestinationCriteria destinationCriteria = new BundleDestinationCriteria();
+ destinationCriteria.clearPaging(); //disable paging as the code assumes all the results will be returned.
+ destinationCriteria.addFilterBundleId(bundle.getId());
+
+ // get the viewable destinations and use to filter the deployments
+ List<BundleDestination> destinations = findBundleDestinationsByCriteria(subject, destinationCriteria);
+ List<BundleDeployment> filteredDeployments = new ArrayList<BundleDeployment>(numDeployments);
+ entityManager.detach(bundleVersion); // make sure we don't persist the filtered data
+ for (BundleDeployment deployment : bundleVersion.getBundleDeployments()) {
+ if (containsDestination(destinations, deployment.getDestination()))
+ filteredDeployments.add(deployment);
+ }
- List<BundleDestination> destinations = findBundleDestinationsByCriteria(subject, destinationCriteria);
- List<BundleDeployment> resultingDeployments = new ArrayList<BundleDeployment>(version
- .getBundleDeployments().size());
- // We now have visible destinations - go over the resultingDeployments and only include the ones with vis. destinations
- for (BundleDeployment deployment : version.getBundleDeployments()) {
- if (destinationsContains(destinations, deployment.getDestination()))
- resultingDeployments.add(deployment);
+ bundleVersion.setBundleDeployments(filteredDeployments);
}
-
- version.setBundleDeployments(resultingDeployments);
}
- return versions;
-
+ return result;
}
- private boolean destinationsContains(List<BundleDestination> list, BundleDestination dest) {
+ private boolean containsDestination(List<BundleDestination> list, BundleDestination dest) {
int id = dest.getId();
for (BundleDestination destination : list) {
if (destination.getId() == id)
@@ -1689,6 +1717,13 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
@Override
public PageList<BundleFile> findBundleFilesByCriteria(Subject subject, BundleFileCriteria criteria) {
CriteriaQueryGenerator generator = new CriteriaQueryGenerator(subject, criteria);
+
+ // filter by bundles that are viewable
+ if (!authorizationManager.hasGlobalPermission(subject, Permission.VIEW_BUNDLES)) {
+ generator.setAuthorizationResourceFragment(CriteriaQueryGenerator.AuthorizationTokenType.BUNDLE, null,
+ subject.getId());
+ }
+
CriteriaQueryRunner<BundleFile> queryRunner = new CriteriaQueryRunner<BundleFile>(criteria, generator,
entityManager);
return queryRunner.execute();
@@ -1700,40 +1735,35 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
CriteriaQueryGenerator generator = new CriteriaQueryGenerator(subject, criteria);
if (!authorizationManager.hasGlobalPermission(subject, Permission.VIEW_BUNDLES)) {
-
generator.setAuthorizationResourceFragment(CriteriaQueryGenerator.AuthorizationTokenType.BUNDLE, null,
subject.getId());
}
CriteriaQueryRunner<Bundle> queryRunner = new CriteriaQueryRunner<Bundle>(criteria, generator, entityManager);
- return queryRunner.execute();
- }
-
- /**
- * Fetch bundles by criteria and then filter destination on the result objects to limit what the user can see
- * @param subject Caller
- * @param criteria criteria to fetch the bundles
- * @return List of bundles with destinations filtered.
- */
- @Override
- public PageList<Bundle> findBundlesByCriteriaWithDestinationFilter(Subject subject, BundleCriteria criteria) {
- // First get the bundles
- PageList<Bundle> bundles = findBundlesByCriteria(subject, criteria);
- if (authorizationManager.isInventoryManager(subject)) {
- return bundles;
- }
- // Not inv manager -> restrict visible destinations
- PageList<Bundle> result = new PageList<Bundle>(bundles.size(), bundles.getPageControl());
- for (Bundle bundle : bundles.getValues()) { // TODO clone the bundle and return the modified clones
- BundleDestinationCriteria destinationCriteria = new BundleDestinationCriteria();
- destinationCriteria.addFilterBundleId(bundle.getId());
- destinationCriteria.clearPaging();//disable paging as the code assumes all the results will be returned.
-
- List<BundleDestination> destinations = findBundleDestinationsByCriteria(subject, destinationCriteria);
- bundle.setDestinations(destinations);
+ PageList<Bundle> result = queryRunner.execute();
+
+ // If asking for optional data that the subject may not be able to see then ensure that the optional
+ // data is filtered appropriately. In this case only destinations viewable by the subject can be returned.
+ // The result currently holds bundles viewable by the caller, but the bundle may have been deployed to
+ // destinations for which the user does not have access to the destination's resource group. (BZ 694741)
+ if (!result.isEmpty() && criteria.isInventoryManagerRequired()
+ && !authorizationManager.isInventoryManager(subject)) {
+
+ // this works because findBundleDestinationsByCriteria() authorizes against resource group associations
+ for (Bundle bundle : result) {
+ if (bundle.getDestinations().isEmpty()) {
+ continue;
+ }
+ BundleDestinationCriteria destinationCriteria = new BundleDestinationCriteria();
+ destinationCriteria.clearPaging(); //disable paging as the code assumes all the results will be returned.
+ destinationCriteria.addFilterBundleId(bundle.getId());
+ List<BundleDestination> destinations = findBundleDestinationsByCriteria(subject, destinationCriteria);
+ entityManager.detach(bundle); // make sure the narrowed set of destinations does not get persisted
+ bundle.setDestinations(destinations);
+ }
}
- return bundles;
+ return result;
}
@Override
@@ -1750,6 +1780,11 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
+ " ( SELECT COUNT(bv3) FROM bundle.bundleVersions bv3 WHERE bv3.bundle.id = bundle.id) AS deploymentCount ) ";
generator.alterProjection(replacementSelectList);
+ if (!authorizationManager.hasGlobalPermission(subject, Permission.VIEW_BUNDLES)) {
+ generator.setAuthorizationResourceFragment(CriteriaQueryGenerator.AuthorizationTokenType.BUNDLE, null,
+ subject.getId());
+ }
+
CriteriaQueryRunner<BundleWithLatestVersionComposite> queryRunner = new CriteriaQueryRunner<BundleWithLatestVersionComposite>(
criteria, generator, entityManager);
PageList<BundleWithLatestVersionComposite> results = queryRunner.execute();
@@ -1771,13 +1806,14 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
@Override
@SuppressWarnings("unchecked")
- @RequiredPermission(Permission.MANAGE_BUNDLE)
public void deleteBundle(Subject subject, int bundleId) throws Exception {
Bundle bundle = this.entityManager.find(Bundle.class, bundleId);
if (null == bundle) {
return;
}
+ checkDeleteBundleAuthz(subject, bundleId);
+
Query q = entityManager.createNamedQuery(BundleVersion.QUERY_FIND_BY_BUNDLE_ID);
q.setParameter("bundleId", bundleId);
List<BundleVersion> bvs = q.getResultList();
@@ -1797,12 +1833,15 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
}
@Override
- @RequiredPermission(Permission.MANAGE_BUNDLE)
public void deleteBundleDeployment(Subject subject, int bundleDeploymentId) throws Exception {
BundleDeployment doomed = this.entityManager.find(BundleDeployment.class, bundleDeploymentId);
if (null == doomed) {
return;
}
+
+ checkDeployBundleAuthz(subject, doomed.getBundleVersion().getBundle().getId(), doomed.getDestination()
+ .getGroup().getId());
+
// only allow deployments to be deleted if they are finished
if (BundleDeploymentStatus.SUCCESS == doomed.getStatus()
|| BundleDeploymentStatus.FAILURE == doomed.getStatus()
@@ -1814,13 +1853,14 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
}
@Override
- @RequiredPermission(Permission.MANAGE_BUNDLE)
public void deleteBundleDestination(Subject subject, int destinationId) throws Exception {
BundleDestination doomed = this.entityManager.find(BundleDestination.class, destinationId);
if (null == doomed) {
return;
}
+ checkDeployBundleAuthz(subject, doomed.getBundle().getId(), doomed.getGroup().getId());
+
// deployments replace other deployments and have a self-referring FK. The deployments
// need to be removed in a way that will ensure that a replaced deployment is not removed
// prior to the replacer. To do this we'll just blanket update all the doomed deployments
@@ -1834,26 +1874,26 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
}
@Override
- @RequiredPermission(Permission.MANAGE_BUNDLE)
public void deleteBundleVersion(Subject subject, int bundleVersionId, boolean deleteBundleIfEmpty) throws Exception {
BundleVersion bundleVersion = this.entityManager.find(BundleVersion.class, bundleVersionId);
if (null == bundleVersion) {
return;
}
+ int bundleId = bundleVersion.getBundle().getId();
+
+ checkDeleteBundleAuthz(subject, bundleId);
+
// After we delete this bundle version, this is the version order value that is being removed.
// Later we need to re-order the other bundles that are newer than this so their version orders are readjusted.
int doomedBundleVersionOrder = bundleVersion.getVersionOrder();
- int bundleId = bundleVersion.getBundle().getId();
-
// deployments replace other deployments and have a self-referring FK. The deployments
// need to be removed in a way that will ensure that a replaced deployment is not removed
// prior to the replacer. To do this we'll just blanket update all the doomed deployments
// to break the FK dependency with nulls.
Query q = entityManager.createNamedQuery(BundleDeployment.QUERY_UPDATE_FOR_VERSION_REMOVE);
q.setParameter("bundleVersionId", bundleVersionId);
- @SuppressWarnings("unused")
int rowsUpdated = q.executeUpdate();
entityManager.flush();
@@ -1970,10 +2010,10 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
public PageList<BundleGroup> findBundleGroupsByCriteria(Subject subject, BundleGroupCriteria criteria) {
CriteriaQueryGenerator generator = new CriteriaQueryGenerator(subject, criteria);
- if (!authorizationManager.hasGlobalPermission(subject, Permission.VIEW_BUNDLES)) {
-
- generator.setAuthorizationResourceFragment(CriteriaQueryGenerator.AuthorizationTokenType.BUNDLE, null,
- subject.getId());
+ // filter by bundle groups that are viewable
+ if (!authorizationManager.hasGlobalPermission(subject, Permission.MANAGE_BUNDLE_GROUPS)) {
+ generator.setAuthorizationResourceFragment(CriteriaQueryGenerator.AuthorizationTokenType.BUNDLE_GROUP,
+ null, subject.getId());
}
CriteriaQueryRunner<BundleGroup> queryRunner = new CriteriaQueryRunner<BundleGroup>(criteria, generator,
@@ -1983,11 +2023,29 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
@Override
public void unassignBundlesFromBundleGroup(Subject subject, int bundleGroupId, int[] bundleIds) {
- // TODO Auto-generated method stub
+ BundleGroup bundleGroup = entityManager.find(BundleGroup.class, bundleGroupId);
+ if (null == bundleGroup) {
+ throw new IllegalArgumentException("BundleGroup does not exist for bundleGroupId [" + bundleGroupId + "]");
+ }
+
+ checkAssignBundleGroupAuthz(subject, bundleGroupId, bundleIds);
+ for (int bundleId : bundleIds) {
+ Bundle bundle = entityManager.find(Bundle.class, bundleId);
+ if (null == bundle) {
+ throw new IllegalArgumentException("Bundle does not exist for bundleId [" + bundleId + "]");
+ }
+
+ bundleGroup.removeBundle(bundle);
+ }
}
/**
+ * Required Permissions: Either:
+ * - Global.CREATE_BUNDLES and Global.VIEW_BUNDLES
+ * - Global.CREATE_BUNDLES and BundleGroup.VIEW_BUNDLES_IN_GROUP for bundle group BG
+ * - BundleGroup.CREATE_BUNDLES_IN_GROUP for bundle group BG
+ *
* @param subject
* @param bundleGroupId null or 0 for unassigned initial bundle version creation
* @throws PermissionException
@@ -2026,6 +2084,11 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
}
/**
+ * Required Permissions: Either:
+ * - Global.CREATE_BUNDLES and Global.VIEW_BUNDLES
+ * - Global.CREATE_BUNDLES and BundleGroup.VIEW_BUNDLES_IN_GROUP for bundle group BG and the relevant bundle is assigned to BG
+ * - BundleGroup.CREATE_BUNDLES_IN_GROUP for bundle group BG and the relevant bundle is assigned to BG
+ *
* @param subject
* @param bundleId required, bundleId of bundle in which bundle version is being created/updated
* @throws PermissionException
@@ -2062,6 +2125,10 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
}
/**
+ * Requires VIEW permission for the relevant bundle and either:
+ * - Global.CREATE_BUNDLE
+ * - BundleGroup.CREATE_BUNDLES_IN_GROUP or BundleGroup.ASSIGN_BUNDLES_TO_GROUP for the relevant bundle group
+ *
* @param subject
* @param bundleGroupId an existing bundle group
* @param bundleIds existing bundles
@@ -2109,8 +2176,12 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
return;
}
- private void checkBundleDeploymentAuthz(Subject subject, int bundleId, int resourceGroupId)
- throws PermissionException {
+ /**
+ * Required Permissions: Either:
+ * - Global.DEPLOY_BUNDLES and a view of the relevant bundle and a view of the relevant resource group (may involve multiple roles)
+ * - Resource.DEPLOY_BUNDLES_TO_GROUP and a view of the relevant bundle and a view of the relevant resource group (may involve multiple roles)
+ */
+ private void checkDeployBundleAuthz(Subject subject, int bundleId, int resourceGroupId) throws PermissionException {
boolean hasResourceGroupView = authorizationManager.hasGroupPermission(subject, Permission.VIEW_RESOURCE,
resourceGroupId);
@@ -2143,4 +2214,46 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
return;
}
+
+ /**
+ * Required Permissions: Either:
+ * - Global.DELETE_BUNDLES and Global.VIEW_BUNDLES
+ * - Global.DELETE_BUNDLES and BundleGroup.VIEW_BUNDLES_IN_GROUP for bundle group BG and the relevant bundle is assigned to BG
+ * - BundleGroup.DELETE_BUNDLES_FROM_GROUP for bundle group BG and the relevant bundle is assigned to BG
+ *
+ * @param subject
+ * @param bundleId required, bundleId of bundle, or the bundle version, being deleted
+ * @throws PermissionException
+ */
+ private void checkDeleteBundleAuthz(Subject subject, int bundleId) throws PermissionException {
+
+ if (bundleId <= 0) {
+ throw new IllegalArgumentException(
+ "Must supply valid bundleId for bundle version being deleted. BundleId specified [" + bundleId + "]");
+ }
+
+ Set<Permission> globalPerms = authorizationManager.getExplicitGlobalPermissions(subject);
+ boolean hasGlobalDeleteBundles = globalPerms.contains(Permission.DELETE_BUNDLES);
+
+ if (hasGlobalDeleteBundles && globalPerms.contains(Permission.VIEW_BUNDLES)) {
+ return;
+ }
+
+ if (hasGlobalDeleteBundles) {
+ if (authorizationManager.hasBundlePermission(subject, Permission.VIEW_BUNDLES_IN_GROUP, bundleId)) {
+ return;
+ }
+ } else {
+ if (authorizationManager.hasBundlePermission(subject, Permission.DELETE_BUNDLES_FROM_GROUP, bundleId)) {
+ return;
+ }
+ }
+
+ String msg = "Subject ["
+ + subject.getName()
+ + "] requires either Global.DELETE_BUNDLES + BundleGroup.VIEW_BUNDLES_IN_GROUP, or BundleGroup.DELETE_BUNDLES_FROM_GROUP, to delete bundle ["
+ + bundleId + "].";
+ throw new PermissionException(msg);
+ }
+
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
index b4d7d1b..01ca620 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
@@ -33,10 +33,6 @@ import org.rhq.core.domain.bundle.BundleResourceDeploymentHistory;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
import org.rhq.core.domain.configuration.Configuration;
-import org.rhq.core.domain.criteria.BundleCriteria;
-import org.rhq.core.domain.criteria.BundleDeploymentCriteria;
-import org.rhq.core.domain.criteria.BundleVersionCriteria;
-import org.rhq.core.domain.util.PageList;
/**
* Local interface to the manager responsible for creating and managing bundles.
@@ -55,51 +51,64 @@ public interface BundleManagerLocal extends BundleManagerRemote {
// - legacy reasons
/**
+ * Internal use only
+ * </p>
* Called internally to add history when action is taken against a deployment. This executes
* in a New Transaction and supports deployBundle and Agent requests.
- *
+ * </p>
+ * This method performs NO AUTHZ!
+ * </p>
* @param subject
* @param resourceDeploymentId id of the deployment appending the history record
* @param history
* @return the persisted history
*/
- BundleResourceDeploymentHistory addBundleResourceDeploymentHistory(Subject subject, int resourceDeploymentId,
- BundleResourceDeploymentHistory history) throws Exception;
+ BundleResourceDeploymentHistory addBundleResourceDeploymentHistoryInNewTrans(Subject subject,
+ int resourceDeploymentId, BundleResourceDeploymentHistory history) throws Exception;
/**
- * Mainly Used For Testing
- *
+ * Internal use only, and test entry point.
+ * </p>
+ * This method performs NO AUTHZ!
+ * </p>
* @param subject user that must have proper permissions
* @param name not null or empty
* @param description optional long description of the bundle
* @param bundleTypeId valid bundleType
+ * @param bundleGroupId bundle group, existing bundle group for bundle assignment, or 0 for unassigned
* @return the persisted Bundle (id is assigned)
*/
- Bundle createBundle(Subject subject, String name, String description, int bundleTypeId) throws Exception;
+ Bundle createBundle(Subject subject, String name, String description, int bundleTypeId, int bundleGroupId)
+ throws Exception;
/**
- * Mainly Used For Testing
+ * Internal use only and test entry point.
*
- * Convienence method that combines {@link #createBundle(Subject, String, int)} and {@link #createBundleVersion(Subject, int, String, String, String)}.
+ * Convenience method that combines {@link #createBundle(Subject, String, int)} and {@link #createBundleVersion(Subject, int, String, String, String)}.
* This will first check to see if a bundle with the given type/name exists - if it doesn't, it will be created. If it does, it will be reused.
* This will then create the bundle version that will be associated with the bundle that was created or found.
- *
+ * </p>
+ * This method performs NO AUTHZ!
+ * </p>
* @param subject user that must have proper permissions
* @param bundleName name of the bundle to use (if not found, it will be created)
* @param bundleDescription optional long description of the bundle
* @param bundleTypeId the bundle type for the new bundle (if it is created) for which this will be the first version
+ * @param bundleGroupId the bundle group for the new bundle (if it is created) for which this will be the first version. 0 to leave unassigned.
* @param bundleVersionName name of the bundle version
* @param bundleVersionDescription optional long description of the bundle version
* @param version optional. If not supplied set to 1.0 for first version, or incremented (as best as possible) for subsequent version
* @return the persisted BundleVersion (id is assigned)
*/
BundleVersion createBundleAndBundleVersion(Subject subject, String bundleName, String bundleDescription,
- int bundleTypeId, String bundleVersionName, String bundleVersionDescription, String version, String recipe)
- throws Exception;
+ int bundleTypeId, int bundleGroupId, String bundleVersionName, String bundleVersionDescription, String version,
+ String recipe) throws Exception;
/**
- * Mainly Used For Testing
- *
+ * Internal use only, test entry point
+ * </p>
+ * This method performs NO AUTHZ!
+ * </p>
* @param subject user that must have proper permissions
* @param bundleId the bundle for which this will be the next version
* @param name not null or empty
@@ -112,8 +121,11 @@ public interface BundleManagerLocal extends BundleManagerRemote {
/**
* Not generally called. For use by Server Side Plugins when registering a Bundle Plugin.
- *
- * @param subject must be InventoryManager
+ * </p>
+ * Required Permissions:
+ * - Global.CREATE_BUNDLES
+ * </p>
+ * @param subject
* @param name not null or empty
* @param resourceTypeId id of the ResourceType that handles this BundleType
* @return the persisted BundleType (id is assigned)
@@ -121,26 +133,50 @@ public interface BundleManagerLocal extends BundleManagerRemote {
BundleType createBundleType(Subject subject, String name, int resourceTypeId) throws Exception;
/**
- * This is typically not called directly, typically scheduleBundleResourceDeployment() is called externally. This executes
- * in a New Transaction and supports scheduleBundleResourceDeployment.
+ * This is typically not called directly, typically scheduleBundleResourceDeployment() is called externally.
+ * This executes in a New Transaction and supports scheduleBundleResourceDeployment.
+ * </p>
+ * This method performs NO AUTHZ!
+ * </p>
*/
- BundleResourceDeployment createBundleResourceDeployment(Subject subject, int bundleDeploymentId, int resourceId)
- throws Exception;
+ BundleResourceDeployment createBundleResourceDeploymentInNewTrans(Subject subject, int bundleDeploymentId,
+ int resourceId) throws Exception;
/**
* Similar to {@link BundleManagerRemote#createBundleDeployment(Subject, int, int, String, Configuration)} but
* supplies the internally generated deploymentName and has different transaction semantics. Useful when an
* slsb method needs to both create a deployment and schedules it prior to returning to an external caller.
+ * </p>
+ * This method performs NO AUTHZ!
+ * </p>
*/
public BundleDeployment createBundleDeploymentInNewTrans(Subject subject, int bundleVersionId,
int bundleDestinationId, String name, String description, Configuration configuration) throws Exception;
- // added here because the same method in @Remote was commented out to bypass a WSProvide issue
+ /**
+ * Used by GUI
+ * </p>
+ * Required Permissions: Either:
+ * - Global.CREATE_BUNDLES and Global.VIEW_BUNDLES
+ * - Global.CREATE_BUNDLES and BundleGroup.VIEW_BUNDLES_IN_GROUP for bundle group BG and the relevant bundle is assigned to BG
+ * - BundleGroup.CREATE_BUNDLES_IN_GROUP for bundle group BG and the relevant bundle is assigned to BG
+ * </p>
+ *
+ * @param subject
+ * @param bundleVersionId
+ * @return Map, filename to foundInBundleVersion
+ * @throws Exception
+ */
HashMap<String, Boolean> getAllBundleVersionFilenames(Subject subject, int bundleVersionId) throws Exception;
/**
- * Needed by the Bundle Deploy and Revert wizards GUI to generate a deployment name for display.
- *
+ * Used by GUI. Needed by the Bundle Deploy and Revert wizards GUI to generate a deployment name for display.
+ * <pre>
+ * Required Permissions: Either:
+ * - Global.DEPLOY_BUNDLES and a view of the relevant bundle and a view of the relevant resource group (may involve multiple roles)
+ * - Resource.DEPLOY_BUNDLES_TO_GROUP and a view of the relevant bundle and a view of the relevant resource group (may involve multiple roles)
+ * </pre>
+ *
* @param subject
* @param bundleDestinationId required
* @param bundleVersionId required for progressive deployment, -1 for revert
@@ -151,18 +187,26 @@ public interface BundleManagerLocal extends BundleManagerRemote {
int prevDeploymentId);
/**
- * Not for general consumption. A special case method to build the pojo that can be sent to the agent to
+ * Internal use only. A special case method to build the pojo that can be sent to the agent to
* schedule the deployment request. Uses NOT_SUPPORTED transaction attribute to avoid having the cleaned pojo
* affect the persistence context.
+ * </p>
+ * This method performs NO AUTHZ!
+ * </p>
+ *
* @throws Exception
*/
public BundleScheduleRequest getScheduleRequest(Subject subject, int resourceDeploymentId,
boolean isCleanDeployment, boolean isRevert) throws Exception;
/**
- * This is a simple attempt at delete, typically used for removing a poorly defined deployment before it is
- * actually scheduled for deployment. The status must be PENDING. It will
- * fail if anything actually refers to it.
+ * Used by GUI. This is a simple attempt at delete, typically used for removing a poorly defined deployment before it is
+ * actually scheduled for deployment. The status must be PENDING. It will fail if anything actually refers to it.
+ * <pre>
+ * Required Permissions: Either:
+ * - Global.DEPLOY_BUNDLES and a view of the relevant bundle and a view of the relevant resource group (may involve multiple roles)
+ * - Resource.DEPLOY_BUNDLES_TO_GROUP and a view of the relevant bundle and a view of the relevant resource group (may involve multiple roles)
+ * </pre>
*
* @param subject
* @param bundleDeploymentId
@@ -171,8 +215,13 @@ public interface BundleManagerLocal extends BundleManagerRemote {
void deleteBundleDeployment(Subject subject, int bundleDeploymentId) throws Exception;
/**
- * This is a simple attempt at delete, typically used for removing a poorly defined destination. It will
+ * Used by GUI. This is a simple attempt at delete, typically used for removing a poorly defined destination. It will
* fail if any actual deployments are referring to the destination.
+ * <pre>
+ * Required Permissions: Either:
+ * - Global.DEPLOY_BUNDLES and a view of the relevant bundle and a view of the relevant resource group (may involve multiple roles)
+ * - Resource.DEPLOY_BUNDLES_TO_GROUP and a view of the relevant bundle and a view of the relevant resource group (may involve multiple roles)
+ * </pre>
*
* @param subject
* @param bundleDestinationId
@@ -181,7 +230,11 @@ public interface BundleManagerLocal extends BundleManagerRemote {
void deleteBundleDestination(Subject subject, int bundleDestinationId) throws Exception;
/**
- * Called internally to set deployment status. Typically to a completion status when deployment ends.
+ * Internal use only. Called internally to set deployment status. Typically to a completion status when deployment
+ * ends.
+ * </p>
+ * This method performs NO AUTHZ!
+ * </p>
*
* @param subject
* @param resourceDeploymentId id of the resource deployment appending the history record
@@ -192,9 +245,14 @@ public interface BundleManagerLocal extends BundleManagerRemote {
BundleDeploymentStatus status) throws Exception;
/**
- * This is for internal use only - when {@link #purgeBundleDestination(Subject, int)} is done, it
+ * Internal use only
+ * </p>
+ * When {@link #purgeBundleDestination(Subject, int)} is done, it
* calls this so the purge can be finalized. This is required because this method is called with
* a transactional context, as opposed to the main purge method.
+ * </p>
+ * This method performs NO AUTHZ!
+ * </p>
*
* @param subject
* @param bundleDeployment
@@ -204,29 +262,4 @@ public interface BundleManagerLocal extends BundleManagerRemote {
void _finalizePurge(Subject subject, BundleDeployment bundleDeployment,
Map<BundleResourceDeployment, String> failedToPurge) throws Exception;
- /**
- * Fetch bundles by criteria and then on the result objects
- * @param subject Caller
- * @param criteria criteria to fetch the bundles
- * @return List of bundles with destinations filtered.
- */
- PageList<Bundle> findBundlesByCriteriaWithDestinationFilter(Subject subject, BundleCriteria criteria);
-
- /**
- * Fetch bundle versions by criteria and then filter destination on the result objects to limit what the user can see
- * @param subject Caller
- * @param criteria criteria to fetch the bundles
- * @return List of bundles with destinations filtered.
- */
- PageList<BundleVersion> findBundleVersionsByCriteriaWithDestinationFilter(Subject subject,
- BundleVersionCriteria criteria);
-
- /**
- * Fetch bundle deployments by criteria and then filter on destinations on the result objects to limit what the user can see
- * @param subject Caller
- * @param criteria criteria to fetch the deployments
- * @return List of deployments with destinations filtered.
- */
- PageList<BundleDeployment> findBundleDeploymentsByCriteriaWithDestinationFilter(Subject subject,
- BundleDeploymentCriteria criteria);
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerRemote.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerRemote.java
index 5ff63d0..c1b9eef 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerRemote.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerRemote.java
@@ -72,12 +72,13 @@ public interface BundleManagerRemote {
/**
* Adds a BundleFile to the BundleVersion and implicitly creates the backing PackageVersion. If the PackageVersion
* already exists use {@link #addBundleFileViaPackageVersion(Subject, int, String, int)}
- * </p>
+ * <pre>
* Required Permissions: Either:
* - Global.CREATE_BUNDLES and Global.VIEW_BUNDLES
* - Global.CREATE_BUNDLES and BundleGroup.VIEW_BUNDLES_IN_GROUP for bundle group BG and the relevant bundle is assigned to BG
* - BundleGroup.CREATE_BUNDLES_IN_GROUP for bundle group BG and the relevant bundle is assigned to BG
- *
+ * </pre>
+ *
* @param subject user that must have proper permissions
* @param bundleVersionId id of the BundleVersion incorporating this BundleFile
* @param name name of the BundleFile (and the resulting Package)
@@ -94,12 +95,13 @@ public interface BundleManagerRemote {
* A convenience method taking a byte array as opposed to a stream for the file bits.
* WARNING: obviously, this requires the entire bundle file to have been loaded fully in memory.
* For very large files, this could cause OutOfMemoryErrors.
- * </p>
+ * <pre>
* Required Permissions: Either:
* - Global.CREATE_BUNDLES and Global.VIEW_BUNDLES
* - Global.CREATE_BUNDLES and BundleGroup.VIEW_BUNDLES_IN_GROUP for bundle group BG and the relevant bundle is assigned to BG
* - BundleGroup.CREATE_BUNDLES_IN_GROUP for bundle group BG and the relevant bundle is assigned to BG
- *
+ * </pre>
+ *
* @see {@link #addBundleFile(Subject, int, String, String, Architecture, InputStream)}
*/
BundleFile addBundleFileViaByteArray(Subject subject, int bundleVersionId, String name, String version,
@@ -107,12 +109,13 @@ public interface BundleManagerRemote {
/**
* A convenience method taking a URL String whose content will be streamed to the server and used for the file bits.
- * </p>
+ * <pre>
* Required Permissions: Either:
* - Global.CREATE_BUNDLES and Global.VIEW_BUNDLES
* - Global.CREATE_BUNDLES and BundleGroup.VIEW_BUNDLES_IN_GROUP for bundle group BG and the relevant bundle is assigned to BG
* - BundleGroup.CREATE_BUNDLES_IN_GROUP for bundle group BG and the relevant bundle is assigned to BG
- *
+ * </pre>
+ *
* @see #addBundleFile(Subject, int, String, String, Architecture, InputStream)
*/
BundleFile addBundleFileViaURL(Subject subject, int bundleVersionId, String name, String version,
@@ -121,12 +124,13 @@ public interface BundleManagerRemote {
/**
* A variant of {@link #addBundleFileViaURL(Subject, int, String, String, Architecture, String)} supporting the
* HTTP basic authentication.
- * </p>
+ * <pre>
* Required Permissions: Either:
* - Global.CREATE_BUNDLES and Global.VIEW_BUNDLES
* - Global.CREATE_BUNDLES and BundleGroup.VIEW_BUNDLES_IN_GROUP for bundle group BG and the relevant bundle is assigned to BG
* - BundleGroup.CREATE_BUNDLES_IN_GROUP for bundle group BG and the relevant bundle is assigned to BG
- *
+ * </pre>
+ *
* @see #addBundleFileViaURL(Subject, int, String, String, Architecture, String)
*/
BundleFile addBundleFileViaURL(Subject subject, int bundleVersionId, String name, String version,
@@ -134,12 +138,13 @@ public interface BundleManagerRemote {
/**
* A convenience method taking an existing PackageVersion as opposed to a stream for the file bits.
- * </p>
+ * <pre>
* Required Permissions: Either:
* - Global.CREATE_BUNDLES and Global.VIEW_BUNDLES
* - Global.CREATE_BUNDLES and BundleGroup.VIEW_BUNDLES_IN_GROUP for bundle group BG and the relevant bundle is assigned to BG
* - BundleGroup.CREATE_BUNDLES_IN_GROUP for bundle group BG and the relevant bundle is assigned to BG
- *
+ * </pre>
+ *
* @see {@link #addBundleFile(Subject, int, String, String, Architecture, InputStream)}
*/
BundleFile addBundleFileViaPackageVersion(Subject subject, int bundleVersionId, String name, int packageVersionId)
@@ -147,11 +152,12 @@ public interface BundleManagerRemote {
/**
* Assign the specified bundles to the specified bundle group.
- * </p>
+ * <pre>
* Requires VIEW permission for the relevant bundle and either:
* - Global.CREATE_BUNDLE
* - BundleGroup.CREATE_BUNDLES_IN_GROUP or BundleGroup.ASSIGN_BUNDLES_TO_GROUP for the relevant bundle group
- *
+ * </pre>
+ *
* @param subject
* @param bundleGroupId
* @param bundleIds
@@ -163,11 +169,12 @@ public interface BundleManagerRemote {
* call. This provides useful, uniform naming for display. An optional, custom description
* can be added. This call defines a deployment. The defined deployment can then be
* scheduled in a separate call.
- * </p>
+ * <pre>
* Required Permissions: Either:
* - Global.DEPLOY_BUNDLES and a view of the relevant bundle and a view of the relevant resource group (may involve multiple roles)
* - Resource.DEPLOY_BUNDLES_TO_GROUP and a view of the relevant bundle and a view of the relevant resource group (may involve multiple roles)
- *
+ * </pre>
+ *
* @param subject user that must have proper permissions
* @param bundleVersionId the BundleVersion being deployed by this deployment
* @param bundleDestinationId the BundleDestination for the deployment
@@ -182,11 +189,12 @@ public interface BundleManagerRemote {
/**
* Creates a bundle destination that describes a target for the bundle deployments.
- * </p>
+ * <pre>
* Required Permissions: Either:
* - Global.DEPLOY_BUNDLES and a view of the relevant bundle and a view of the relevant resource group (may involve multiple roles)
* - Resource.DEPLOY_BUNDLES_TO_GROUP and a view of the relevant bundle and a view of the relevant resource group (may involve multiple roles)
- *
+ * </pre>
+ *
* @param subject user must have MANAGE_INVENTORY permission
* @param bundleId the Bundle to be deployed to this Destination
* @param name a name for this destination. not null or empty
@@ -225,12 +233,13 @@ public interface BundleManagerRemote {
* </p>
* If this bundle version is the initial version of a new bundle that needs to be created, the subject must
* have Global.VIEW_BUNDLES because the new bundle will not be associated with any bundle group.
- * </p>
+ * <pre>
* Required Permissions: Either:
* - Global.CREATE_BUNDLES and Global.VIEW_BUNDLES
* - Global.CREATE_BUNDLES and BundleGroup.VIEW_BUNDLES_IN_GROUP for bundle group BG and the relevant bundle is assigned to BG
* - BundleGroup.CREATE_BUNDLES_IN_GROUP for bundle group BG and the relevant bundle is assigned to BG
- *
+ * </pre>
+ *
* @param subject user that must have proper permissions
* @param recipe the recipe that defines the bundle version to be created
* @return the persisted BundleVersion with alot of the internal relationships filled in to help the caller
@@ -244,19 +253,21 @@ public interface BundleManagerRemote {
* should be assigned to.
* If bundleGroupId is 0, then the new bundle will not be associated with any bundle group - this is only
* allowed if the caller has the permission Global.VIEW_BUNDLES.
- * </p>
+ * <pre>
* Required Permissions: Either:
* - Global.CREATE_BUNDLES and Global.VIEW_BUNDLES
* - Global.CREATE_BUNDLES and BundleGroup.VIEW_BUNDLES_IN_GROUP for bundle group BG
* - BundleGroup.CREATE_BUNDLES_IN_GROUP for bundle group BG
- *
+ * </pre>
+ *
* @param subject user that must have proper permissions
* @param bundleGroupId identifies the bundle group that the new bundle will be associated with; 0 if no group
* @param recipe the recipe that defines the bundle version to be created
* @return the persisted BundleVersion with alot of the internal relationships filled in to help the caller
* understand all that this method did.
*/
- BundleVersion createInitialBundleVersionViaRecipe(Subject subject, int bundleGroupId, String recipe) throws Exception;
+ BundleVersion createInitialBundleVersionViaRecipe(Subject subject, int bundleGroupId, String recipe)
+ throws Exception;
/**
* Creates a bundle version based on a Bundle Distribution file. Typically a zip file, the bundle distribution
@@ -267,12 +278,13 @@ public interface BundleManagerRemote {
* </p>
* If this bundle version is the initial version of a new bundle that needs to be created, the subject must
* have Global.VIEW_BUNDLES because the new bundle will not be associated with any bundle group.
- * </p>
+ * <pre>
* Required Permissions: Either:
* - Global.CREATE_BUNDLES and Global.VIEW_BUNDLES
* - Global.CREATE_BUNDLES and BundleGroup.VIEW_BUNDLES_IN_GROUP for bundle group BG and the relevant bundle is assigned to BG
* - BundleGroup.CREATE_BUNDLES_IN_GROUP for bundle group BG and the relevant bundle is assigned to BG
- *
+ * </pre>
+ *
* @param subject user that must have proper permissions
* @param distributionFile a local Bundle Distribution file. It must be read accessible by the RHQ server process.
* @return the persisted BundleVersion with alot of the internal relationships filled in to help the caller
@@ -286,12 +298,13 @@ public interface BundleManagerRemote {
* should be assigned to.
* If bundleGroupId is 0, then the new bundle will not be associated with any bundle group - this is only
* allowed if the caller has the permission Global.VIEW_BUNDLES.
- * </p>
+ * <pre>
* Required Permissions: Either:
* - Global.CREATE_BUNDLES and Global.VIEW_BUNDLES
* - Global.CREATE_BUNDLES and BundleGroup.VIEW_BUNDLES_IN_GROUP for bundle group BG
* - BundleGroup.CREATE_BUNDLES_IN_GROUP for bundle group BG
- *
+ * </pre>
+ *
* @param subject user that must have proper permissions
* @param bundleGroupId identifies the bundle group that the new bundle will be associated with; 0 if no group
* @param distributionFile a local Bundle Distribution file. It must be read accessible by the RHQ server process.
@@ -299,7 +312,8 @@ public interface BundleManagerRemote {
* understand all that this method did. Bundle files specifically are returned.
* @throws Exception
*/
- BundleVersion createInitialBundleVersionViaFile(Subject subject, int bundleGroupId, File distributionFile) throws Exception;
+ BundleVersion createInitialBundleVersionViaFile(Subject subject, int bundleGroupId, File distributionFile)
+ throws Exception;
/**
* Creates a bundle version based on the actual bytes of a Bundle Distribution file. This is essentially
@@ -310,12 +324,13 @@ public interface BundleManagerRemote {
* </p>
* If this bundle version is the initial version of a new bundle that needs to be created, the subject must
* have Global.VIEW_BUNDLES because the new bundle will not be associated with any bundle group.
- * </p>
+ * <pre>
* Required Permissions: Either:
* - Global.CREATE_BUNDLES and Global.VIEW_BUNDLES
* - Global.CREATE_BUNDLES and BundleGroup.VIEW_BUNDLES_IN_GROUP for bundle group BG and the relevant bundle is assigned to BG
* - BundleGroup.CREATE_BUNDLES_IN_GROUP for bundle group BG and the relevant bundle is assigned to BG
- *
+ * </pre>
+ *
* @param subject user that must have proper permissions
* @param fileBytes the file bits that make up the entire bundle distribution file
* @return the persisted BundleVersion with a lot of the internal relationships filled in to help the caller
@@ -329,12 +344,13 @@ public interface BundleManagerRemote {
* should be assigned to.
* If bundleGroupId is 0, then the new bundle will not be associated with any bundle group - this is only
* allowed if the caller has the permission Global.VIEW_BUNDLES.
- * </p>
+ * <pre>
* Required Permissions: Either:
* - Global.CREATE_BUNDLES and Global.VIEW_BUNDLES
* - Global.CREATE_BUNDLES and BundleGroup.VIEW_BUNDLES_IN_GROUP for bundle group BG
* - BundleGroup.CREATE_BUNDLES_IN_GROUP for bundle group BG
- *
+ * </pre>
+ *
* @param subject user that must have proper permissions
* @param bundleGroupId identifies the bundle group that the new bundle will be associated with; 0 if no group
* @param fileBytes the file bits that make up the entire bundle distribution file
@@ -342,7 +358,8 @@ public interface BundleManagerRemote {
* understand all that this method did. Bundle files specifically are returned.
* @throws Exception
*/
- BundleVersion createInitialBundleVersionViaByteArray(Subject subject, int bundleGroupId, byte[] fileBytes) throws Exception;
+ BundleVersion createInitialBundleVersionViaByteArray(Subject subject, int bundleGroupId, byte[] fileBytes)
+ throws Exception;
/**
* Creates a bundle version based on a Bundle Distribution file. Typically a zip file, the bundle distribution
@@ -355,12 +372,13 @@ public interface BundleManagerRemote {
* </p>
* If this bundle version is the initial version of a new bundle that needs to be created, the subject must
* have Global.VIEW_BUNDLES because the new bundle will not be associated with any bundle group.
- * </p>
+ * <pre>
* Required Permissions: Either:
* - Global.CREATE_BUNDLES and Global.VIEW_BUNDLES
* - Global.CREATE_BUNDLES and BundleGroup.VIEW_BUNDLES_IN_GROUP for bundle group BG and the relevant bundle is assigned to BG
* - BundleGroup.CREATE_BUNDLES_IN_GROUP for bundle group BG and the relevant bundle is assigned to BG
- *
+ * </pre>
+ *
* @param subject user that must have proper permissions
* @param distributionFileUrl a URL String to the Bundle Distribution file. It must be live, resolvable and read accessible
* by the RHQ server process.
@@ -376,12 +394,13 @@ public interface BundleManagerRemote {
* should be assigned to.
* If bundleGroupId is 0, then the new bundle will not be associated with any bundle group - this is only
* allowed if the caller has the permission Global.VIEW_BUNDLES.
- * </p>
+ * <pre>
* Required Permissions: Either:
* - Global.CREATE_BUNDLES and Global.VIEW_BUNDLES
* - Global.CREATE_BUNDLES and BundleGroup.VIEW_BUNDLES_IN_GROUP for bundle group BG
* - BundleGroup.CREATE_BUNDLES_IN_GROUP for bundle group BG
- *
+ * </pre>
+ *
* @param subject user that must have proper permissions
* @param bundleGroupId identifies the bundle group that the new bundle will be associated with; 0 if no group
* @param distributionFileUrl a URL String to the Bundle Distribution file. It must be live, resolvable and read accessible
@@ -390,7 +409,8 @@ public interface BundleManagerRemote {
* understand all that this method did. Bundle files specifically are returned.
* @throws Exception
*/
- BundleVersion createInitialBundleVersionViaURL(Subject subject, int bundleGroupId, String distributionFileUrl) throws Exception;
+ BundleVersion createInitialBundleVersionViaURL(Subject subject, int bundleGroupId, String distributionFileUrl)
+ throws Exception;
/**
* A version of the {@link #createBundleVersionViaURL(org.rhq.core.domain.auth.Subject, String)} that accepts a
@@ -398,12 +418,13 @@ public interface BundleManagerRemote {
* </p>
* If this bundle version is the initial version of a new bundle that needs to be created, the subject must
* have Global.VIEW_BUNDLES because the new bundle will not be associated with any bundle group.
- * </p>
+ * <pre>
* Required Permissions: Either:
* - Global.CREATE_BUNDLES and Global.VIEW_BUNDLES
* - Global.CREATE_BUNDLES and BundleGroup.VIEW_BUNDLES_IN_GROUP for bundle group BG and the relevant bundle is assigned to BG
* - BundleGroup.CREATE_BUNDLES_IN_GROUP for bundle group BG and the relevant bundle is assigned to BG
- *
+ * </pre>
+ *
* @see #createBundleVersionViaURL(org.rhq.core.domain.auth.Subject, String)
*/
BundleVersion createBundleVersionViaURL(Subject subject, String distributionFileUrl, String username,
@@ -415,27 +436,30 @@ public interface BundleManagerRemote {
* should be assigned to.
* If bundleGroupId is 0, then the new bundle will not be associated with any bundle group - this is only
* allowed if the caller has the permission Global.VIEW_BUNDLES.
- * </p>
+ * <pre>
* Required Permissions: Either:
* - Global.CREATE_BUNDLES and Global.VIEW_BUNDLES
* - Global.CREATE_BUNDLES and BundleGroup.VIEW_BUNDLES_IN_GROUP for bundle group BG
* - BundleGroup.CREATE_BUNDLES_IN_GROUP for bundle group BG
- *
+ * </pre>
+ *
* @see #createBundleVersionViaURL(org.rhq.core.domain.auth.Subject, String)
*/
- BundleVersion createInitialBundleVersionViaURL(Subject subject, int bundleGroupId, String distributionFileUrl, String username, String password) throws Exception;
+ BundleVersion createInitialBundleVersionViaURL(Subject subject, int bundleGroupId, String distributionFileUrl,
+ String username, String password) throws Exception;
/**
* Remove everything associated with the Bundles with the exception of files laid down by related deployments.
* Deployed files are left as is on the deployment platforms but the bundle mechanism will no longer track
* the deployment of all bundles that have been deleted.
* The bundles that are deleted will be removed from all bundle groups that it was a member of.
- * </p>
+ * <pre>
* Required Permissions: Either:
* - Global.DELETE_BUNDLES and Global.VIEW_BUNDLES
* - Global.DELETE_BUNDLES and BundleGroup.VIEW_BUNDLES_IN_GROUP for bundle group BG and the relevant bundle is assigned to BG
* - BundleGroup.DELETE_BUNDLES_FROM_GROUP for bundle group BG and the relevant bundle is assigned to BG
- *
+ * </pre>
+ *
* @param subject user that must have proper permissions
* @param bundleIds IDs of all bundles to be deleted
* @throws Exception if any part of the removal fails.
@@ -447,12 +471,13 @@ public interface BundleManagerRemote {
* Deployed files are left as is on the deployment platforms but the bundle mechanism will no longer track
* the deployment.
* The bundles that are deleted will be removed from all bundle groups that it was a member of.
- * </p>
+ * <pre>
* Required Permissions: Either:
* - Global.DELETE_BUNDLES and Global.VIEW_BUNDLES
* - Global.DELETE_BUNDLES and BundleGroup.VIEW_BUNDLES_IN_GROUP for bundle group BG and the relevant bundle is assigned to BG
* - BundleGroup.DELETE_BUNDLES_FROM_GROUP for bundle group BG and the relevant bundle is assigned to BG
- *
+ * </pre>
+ *
* @param subject user that must have proper permissions
* @param bundleId the id of the bundle to remove
* @throws Exception if any part of the removal fails.
@@ -476,12 +501,13 @@ public interface BundleManagerRemote {
* Deployed files are left as is on the deployment platforms but the bundle mechanism will no longer track
* the deployment.
* The deleted bundle version will no longer exist in any bundle group.
- * </p>
+ * <pre>
* Required Permissions: Either:
* - Global.DELETE_BUNDLES and Global.VIEW_BUNDLES
* - Global.DELETE_BUNDLES and BundleGroup.VIEW_BUNDLES_IN_GROUP for bundle group BG and the relevant bundle is assigned to BG
* - BundleGroup.DELETE_BUNDLES_FROM_GROUP for bundle group BG and the relevant bundle is assigned to BG
- *
+ * </pre>
+ *
* @param subject user that must have proper permissions
* @param bundleVersionId the id of the bundle version to remove
* @param deleteBundleIfEmpty if <code>true</code> and if this method deletes the last bundle version for its
@@ -490,14 +516,40 @@ public interface BundleManagerRemote {
*/
void deleteBundleVersion(Subject subject, int bundleVersionId, boolean deleteBundleIfEmpty) throws Exception;
+ /**
+ * Return the <code>Bundles</code> narrowed by the supplied Criteria. The results are implicitly
+ * narrowed to those bundles viewable by the <code>subject</code>.
+ */
PageList<Bundle> findBundlesByCriteria(Subject subject, BundleCriteria criteria);
+ /**
+ * Return the <code>BundleGroups</code> narrowed by the supplied Criteria. The results are implicitly
+ * narrowed to those bundle groups viewable by the <code>subject</code>.
+ */
PageList<BundleGroup> findBundleGroupsByCriteria(Subject subject, BundleGroupCriteria criteria);
+ /**
+ * Return the <code>BundleDeployments</code> narrowed by the supplied Criteria. The results are implicitly
+ * narrowed to those for bundles and destination groups viewable by the <code>subject</code>.
+ */
PageList<BundleDeployment> findBundleDeploymentsByCriteria(Subject subject, BundleDeploymentCriteria criteria);
+ /**
+ * Return the <code>BundleDestinations</code> narrowed by the supplied Criteria. The results are implicitly
+ * narrowed to those with destination resource groups viewable by the <code>subject</code>.
+ */
PageList<BundleDestination> findBundleDestinationsByCriteria(Subject subject, BundleDestinationCriteria criteria);
+ /**
+ * Note that this can involves permissions on bundles and resources. Results will always be narrowed to the bundles
+ * viewable by <code>subject</code>. If optionally requesting the relevant Resources
+ * via <code>BundleResourceDeploymentCriteria.fetchResources(true)</code> the results will be further narrowed to
+ * the viewable resources.
+ *
+ * @param subject
+ * @param criteria
+ * @return
+ */
PageList<BundleResourceDeployment> findBundleResourceDeploymentsByCriteria(Subject subject,
BundleResourceDeploymentCriteria criteria);
@@ -516,12 +568,13 @@ public interface BundleManagerRemote {
* Determine the files required for a BundleVersion and return all of the filenames or optionally, just those
* that lack BundleFiles for the BundleVersion. The recipe may be parsed as part of this call.
* This is needed as part of the bundle creation workflow, hence why creation permissions are needed.
- * </p>
+ * <pre>
* Required Permissions: Either:
* - Global.CREATE_BUNDLES and Global.VIEW_BUNDLES
* - Global.CREATE_BUNDLES and BundleGroup.VIEW_BUNDLES_IN_GROUP for bundle group BG and the relevant bundle is assigned to BG
* - BundleGroup.CREATE_BUNDLES_IN_GROUP for bundle group BG and the relevant bundle is assigned to BG
- *
+ * </pre>
+ *
* @param subject user that must have proper permissions
* @param bundleVersionId the BundleVersion being queried
* @param withoutBundleFileOnly if true omit any filenames that already have a corresponding BundleFile for
@@ -534,7 +587,7 @@ public interface BundleManagerRemote {
/**
* Purges the destination's live deployment content from the remote platforms.
- * </p>
+ * </pre>
* Required Permissions: Either:
* - Global.DEPLOY_BUNDLES and a view of the relevant bundle and a view of the relevant resource group (may involve multiple roles)
* - Resource.DEPLOY_BUNDLES_TO_GROUP and a view of the relevant bundle and a view of the relevant resource group (may involve multiple roles)
@@ -550,7 +603,7 @@ public interface BundleManagerRemote {
* complete. The returned BundleDeployment can be used to track the history of the individual deployments.
* <br/><br/>
* TODO: Add the scheduling capability, currently it's Immediate.
- * </p>
+ * </pre>
* Required Permissions: Either:
* - Global.DEPLOY_BUNDLES and a view of the relevant bundle and a view of the relevant resource group (may involve multiple roles)
* - Resource.DEPLOY_BUNDLES_TO_GROUP and a view of the relevant bundle and a view of the relevant resource group (may involve multiple roles)
@@ -574,7 +627,7 @@ public interface BundleManagerRemote {
* call. This provides useful, uniform naming for display. An optional, custom description can be added.
* <br/><br/>
* TODO: Add the scheduling capability, currently it's Immediate.
- * </p>
+ * </pre>
* Required Permissions: Either:
* - Global.DEPLOY_BUNDLES and a view of the relevant bundle and a view of the relevant resource group (may involve multiple roles)
* - Resource.DEPLOY_BUNDLES_TO_GROUP and a view of the relevant bundle and a view of the relevant resource group (may involve multiple roles)
@@ -592,7 +645,7 @@ public interface BundleManagerRemote {
/**
* Unassign the specified bundles from the specified bundle group.
- * </p>
+ * </pre>
* Requires VIEW permission for the relevant bundles and either:
* - Global.DELETE_BUNDLE
* - BundleGroup.DELETE_BUNDLES_FROM_GROUP or BundleGroup.UNASSIGN_BUNDLES_FROM_GROUP for the relevant bundle group
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleServerServiceImpl.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleServerServiceImpl.java
index a78d7e9..4e73171 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleServerServiceImpl.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleServerServiceImpl.java
@@ -56,7 +56,7 @@ public class BundleServerServiceImpl implements BundleServerService {
public void addDeploymentHistory(int bundleDeploymentId, BundleResourceDeploymentHistory history) {
try {
BundleManagerLocal bm = LookupUtil.getBundleManager();
- bm.addBundleResourceDeploymentHistory(LookupUtil.getSubjectManager().getOverlord(), bundleDeploymentId,
+ bm.addBundleResourceDeploymentHistoryInNewTrans(LookupUtil.getSubjectManager().getOverlord(), bundleDeploymentId,
history);
} catch (Exception e) {
log.error("Failed to add history to deployment id: " + bundleDeploymentId, e);
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java
index e65d9f3..0a1060d 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java
@@ -69,7 +69,8 @@ public final class CriteriaQueryGenerator {
public enum AuthorizationTokenType {
RESOURCE, // specifies the resource alias to join on for standard res-group-role-subject authorization checking
GROUP, // specifies the group alias to join on for standard group-role-subject authorization checking
- BUNDLE; // specifies the bundle alias to join on for standard bundle-bundleGroup-role-subject authorization checking
+ BUNDLE, // specifies the bundle alias to join on for standard bundle-bundleGroup-role-subject authorization checking
+ BUNDLE_GROUP; // specifies the bundle group alias to join on for standard bundleGroup-role-subject authorization checking
}
private Criteria criteria;
@@ -125,6 +126,8 @@ public final class CriteriaQueryGenerator {
setAuthorizationResourceFragment(type, defaultFragment, subjectId);
} else if (type == AuthorizationTokenType.BUNDLE) {
setAuthorizationBundleFragment(subjectId);
+ } else if (type == AuthorizationTokenType.BUNDLE_GROUP) {
+ setAuthorizationBundleGroupFragment(subjectId);
}
}
@@ -249,6 +252,39 @@ public final class CriteriaQueryGenerator {
customAuthzFragment = customAuthzFragment.replace("%aliasWithFragment%", aliasReplacement);
customAuthzFragment = customAuthzFragment.replace("%innerAlias%", innerAliasReplacement);
customAuthzFragment = customAuthzFragment.replace("%subjectId%", String.valueOf(subjectId));
+ this.authorizationCustomConditionFragment = customAuthzFragment;
+
+ // If the query results are narrowed by requiredPerms generate the fragment now. It's done
+ // here for two reasons. First, it seems to make sense to apply this only when an authFragment is
+ // being used. Second, because one day the query may be less brute force and may modify or
+ // leverage the joinFragment above. But, after extensive trying a more elegant
+ // query could not be constructed due to Hibernate limitations. So, for now, here it is...
+ List<Permission> requiredPerms = this.criteria.getRequiredPermissions();
+ if (!(null == requiredPerms || requiredPerms.isEmpty())) {
+ this.authorizationPermsFragment = "" //
+ + "( SELECT COUNT(DISTINCT p)" + NL //
+ + " FROM Subject innerSubject" + NL //
+ + " JOIN innerSubject.roles r" + NL //
+ + " JOIN r.permissions p" + NL //
+ + " WHERE innerSubject.id = " + this.authorizationSubjectId + NL //
+ + " AND p IN ( :requiredPerms ) ) = :requiredPermsSize" + NL;
+ }
+ }
+
+ public void setAuthorizationBundleGroupFragment(int subjectId) {
+ String fragment = "bundleGroup";
+ String customAuthzFragment = "" //
+ + "( %aliasWithFragment%.id IN ( SELECT %innerAlias%.id " + NL //
+ + " FROM %alias% innerAlias " + NL //
+ + " JOIN %innerAlias%.roles r JOIN r.subjects s " + NL //
+ + " WHERE s.id = %subjectId% ) ) " + NL;
+ String aliasReplacement = criteria.getAlias() + (fragment != null ? "." + fragment : "");
+ String innerAliasReplacement = "innerAlias" + (fragment != null ? "." + fragment : "");
+ customAuthzFragment = customAuthzFragment.replace("%alias%", criteria.getAlias());
+ customAuthzFragment = customAuthzFragment.replace("%aliasWithFragment%", aliasReplacement);
+ customAuthzFragment = customAuthzFragment.replace("%innerAlias%", innerAliasReplacement);
+ customAuthzFragment = customAuthzFragment.replace("%subjectId%", String.valueOf(subjectId));
+ this.authorizationCustomConditionFragment = customAuthzFragment;
// If the query results are narrowed by requiredPerms generate the fragment now. It's done
// here for two reasons. First, it seems to make sense to apply this only when an authFragment is
@@ -724,9 +760,9 @@ public final class CriteriaQueryGenerator {
private void addPersistentBag(String fieldName) {
Field f = findField(fieldName);
if (f == null) {
- LOG.warn(
- "Failed to add persistent bag collection [" + fieldName + "] on class [" + criteria.getPersistentClass().getName() +
- "]. There doesn't seem to be a field of that name on the class or any of its superclasses.");
+ LOG.warn("Failed to add persistent bag collection [" + fieldName + "] on class ["
+ + criteria.getPersistentClass().getName()
+ + "]. There doesn't seem to be a field of that name on the class or any of its superclasses.");
} else {
persistentBagFields.add(f);
}
@@ -735,9 +771,9 @@ public final class CriteriaQueryGenerator {
private void addJoinFetch(String fieldName) {
Field f = findField(fieldName);
if (f == null) {
- LOG.warn(
- "Failed to add join fetch field [" + fieldName + "] on class [" + criteria.getPersistentClass().getName() +
- "]. There doesn't seem to be a field of that name on the class or any of its superclasses.");
+ LOG.warn("Failed to add join fetch field [" + fieldName + "] on class ["
+ + criteria.getPersistentClass().getName()
+ + "]. There doesn't seem to be a field of that name on the class or any of its superclasses.");
} else {
joinFetchFields.add(f);
}