modules/core/domain/src/main/java/org/rhq/core/domain/auth/Subject.java | 12
modules/core/domain/src/main/java/org/rhq/core/domain/criteria/RoleCriteria.java | 22 -
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/list/BundlesListView.java | 103 ++++----
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/AuthorizedTableAction.java | 4
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/BundleAuthorizedTableAction.java | 125 ++++++++++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/RoleAuthorizedTableAction.java | 85 ++++++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/AuthorizationGWTService.java | 13 +
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AuthorizationGWTServiceImpl.java | 37 ++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/AuthorizationManagerBean.java | 15 +
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/AuthorizationManagerLocal.java | 13 +
10 files changed, 360 insertions(+), 69 deletions(-)
New commits:
commit 2807c04d36735ed07af9000ac646340775ab94b0
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Tue Aug 20 11:49:30 2013 -0400
get button enablement working for bundles list view using the various permission schemes
- add some new authz mgr bean support for bundle perms
- fix the newly added permissions filter in RoleCriteria
- add BundleAuthorizedTableAction and RoleAuthorizedTableAction
-
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/auth/Subject.java b/modules/core/domain/src/main/java/org/rhq/core/domain/auth/Subject.java
index c70d651..12fb916 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/auth/Subject.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/auth/Subject.java
@@ -211,6 +211,17 @@ import org.rhq.core.domain.resource.group.ResourceGroup;
+ "FROM Subject s, IN (s.roles) r, IN (r.permissions) p, IN (r.resourceGroups) g, IN (g.implicitResources) res "
+ "WHERE s = :subject AND p = :permission AND res.inventoryStatus = 'COMMITTED'"),
+ /*
+ * No easy way to test whether ALL bundles are in some bundle group in some role in some subject where
+ * subject.id = <id> & role.permission = <perm>
+ *
+ * Instead, we must use this potentially VERY costly query (costly because the result list could be huge in large
+ * environments). However, we can return bundle.id only, to save a lot of traffic across the line and speed it up.
+ */
+ @NamedQuery(name = Subject.QUERY_GET_BUNDLES_BY_PERMISSION, query = "SELECT distinct bundle.id "
+ + "FROM Subject s, IN (s.roles) r, IN (r.permissions) p, IN (r.bundleGroups) g, IN (g.bundles) bundle "
+ + "WHERE s = :subject AND p = :permission"),
+
@NamedQuery(name = Subject.QUERY_FIND_AVAILABLE_SUBJECTS_FOR_ROLE_WITH_EXCLUDES, query = "" //
+ "SELECT DISTINCT s " + " FROM Subject AS s LEFT JOIN s.roles AS r " //
+ " WHERE s.id NOT IN " //
@@ -263,6 +274,7 @@ public class Subject implements Serializable {
public static final String QUERY_CAN_VIEW_BUNDLE = "Subject.canViewBundle";
public static final String QUERY_CAN_VIEW_BUNDLE_GROUP = "Subject.canViewBundleGroup";
+ public static final String QUERY_GET_BUNDLES_BY_PERMISSION = "Subject.getBundlesByPermission";
public static final String QUERY_GET_RESOURCES_BY_PERMISSION = "Subject.getResourcesByPermission";
public static final String QUERY_FIND_AVAILABLE_SUBJECTS_FOR_ROLE_WITH_EXCLUDES = "Subject.findAvailableSubjectsForRoleWithExcludes";
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/RoleCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/RoleCriteria.java
index b44f62d..e68df50 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/RoleCriteria.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/RoleCriteria.java
@@ -57,21 +57,21 @@ public class RoleCriteria extends Criteria {
public RoleCriteria() {
filterOverrides.put("subjectId", "" //
- + "id IN ( SELECT innerRole.id " //
- + " FROM Role innerRole " //
- + " JOIN innerRole.subjects innerSubject " //
- + " WHERE innerSubject.id = ? )");
+ + "id IN ( SELECT innerRole1.id " //
+ + " FROM Role innerRole1 " //
+ + " JOIN innerRole1.subjects innerSubject1 " //
+ + " WHERE innerSubject1.id = ? )");
filterOverrides.put("ldapSubjectId", "" //
- + "id IN ( SELECT innerRole.id " //
- + " FROM Role innerRole " //
- + " JOIN innerRole.ldapSubjects innerSubject " //
- + " WHERE innerSubject.id = ? )");
+ + "id IN ( SELECT innerRole2.id " //
+ + " FROM Role innerRole2 " //
+ + " JOIN innerRole2.ldapSubjects innerSubject2 " //
+ + " WHERE innerSubject2.id = ? )");
filterOverrides.put("permissions", "" //
- + "id IN ( SELECT innerRole.id " //
- + " FROM Role innerRole " //
- + " JOIN irole.permissions perm " //
+ + "id IN ( SELECT innerRole3.id " //
+ + " FROM Role innerRole3 " //
+ + " JOIN innerRole3.permissions perm " //
+ " WHERE perm IN ( ? ) )");
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/list/BundlesListView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/list/BundlesListView.java
index 756e4f7..ad66e49 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/list/BundlesListView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/list/BundlesListView.java
@@ -19,10 +19,13 @@
package org.rhq.enterprise.gui.coregui.client.bundle.list;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
import java.util.Set;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.smartgwt.client.data.Criteria;
+import com.smartgwt.client.data.Record;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.ListGridFieldType;
import com.smartgwt.client.widgets.events.DoubleClickEvent;
@@ -42,7 +45,9 @@ import org.rhq.enterprise.gui.coregui.client.IconEnum;
import org.rhq.enterprise.gui.coregui.client.LinkManager;
import org.rhq.enterprise.gui.coregui.client.bundle.create.BundleCreateWizard;
import org.rhq.enterprise.gui.coregui.client.bundle.deploy.BundleDeployWizard;
-import org.rhq.enterprise.gui.coregui.client.components.table.AbstractTableAction;
+import org.rhq.enterprise.gui.coregui.client.components.table.BundleAuthorizedTableAction;
+import org.rhq.enterprise.gui.coregui.client.components.table.RecordExtractor;
+import org.rhq.enterprise.gui.coregui.client.components.table.RoleAuthorizedTableAction;
import org.rhq.enterprise.gui.coregui.client.components.table.Table;
import org.rhq.enterprise.gui.coregui.client.components.table.TableActionEnablement;
import org.rhq.enterprise.gui.coregui.client.gwt.BundleGWTServiceAsync;
@@ -61,7 +66,7 @@ import org.rhq.enterprise.gui.coregui.client.util.message.Message.Severity;
*/
public class BundlesListView extends Table<BundlesWithLatestVersionDataSource> {
- private final Set<Permission> permissions;
+ private final Set<Permission> globalPermissions;
/**
* Creates a new list view.
@@ -74,7 +79,7 @@ public class BundlesListView extends Table<BundlesWithLatestVersionDataSource> {
public BundlesListView(Criteria criteria, Set<Permission> perms) {
super(MSG.common_title_bundles(), criteria, IconEnum.BUNDLE.getIcon24x24Path());
- this.permissions = perms;
+ this.globalPermissions = perms;
setDataSource(new BundlesWithLatestVersionDataSource());
}
@@ -129,63 +134,72 @@ public class BundlesListView extends Table<BundlesWithLatestVersionDataSource> {
});
// only show the buttons if we were given a set of permissions - passing in null is a way to say you only want the list, no actions
- if (this.permissions != null) {
+ if (this.globalPermissions != null) {
+ boolean hasGlobalDelete = globalPermissions.contains(Permission.DELETE_BUNDLES);
- // TODO NEW BUNDLE ENABLEMENT
- // boolean hasAuth = permissions.contains(Permission._BUNDLE);
- boolean hasAuth = true;
+ addTableAction(MSG.common_button_new(), null, new RoleAuthorizedTableAction(BundlesListView.this,
+ Permission.CREATE_BUNDLES, Permission.CREATE_BUNDLES_IN_GROUP) {
- addTableAction(MSG.common_button_new(), null, new AbstractTableAction(
- (hasAuth) ? TableActionEnablement.ALWAYS : TableActionEnablement.NEVER) {
public void executeAction(ListGridRecord[] selection, Object actionValue) {
- new BundleCreateWizard(permissions).startWizard();
+ new BundleCreateWizard(globalPermissions).startWizard();
// we can refresh the table buttons immediately since the wizard is a dialog, the
// user can't access enabled buttons anyway.
BundlesListView.this.refreshTableInfo();
}
});
- addTableAction(MSG.common_button_delete(), MSG.view_bundle_list_deleteConfirm(), new AbstractTableAction(
- (hasAuth) ? TableActionEnablement.ANY : TableActionEnablement.NEVER) {
- public void executeAction(ListGridRecord[] selections, Object actionValue) {
- if (selections == null || selections.length == 0) {
- return;
- }
-
- BundlesWithLatestVersionDataSource ds = (BundlesWithLatestVersionDataSource) getDataSource();
- final ArrayList<String> doomedNames = new ArrayList<String>(selections.length);
- int[] doomedIds = new int[selections.length];
- int i = 0;
- for (ListGridRecord selection : selections) {
- BundleWithLatestVersionComposite object = ds.copyValues(selection);
- doomedNames.add(object.getBundleName());
- doomedIds[i++] = object.getBundleId();
- }
+ addTableAction(MSG.common_button_delete(), MSG.view_bundle_list_deleteConfirm(),
+ new BundleAuthorizedTableAction(BundlesListView.this, TableActionEnablement.ANY,
+ (hasGlobalDelete ? null : Permission.DELETE_BUNDLES_FROM_GROUP), new RecordExtractor<Integer>() {
+ public Collection<Integer> extract(Record[] records) {
+ List<Integer> result = new ArrayList<Integer>(records.length);
+ for (Record record : records) {
+ result.add(record.getAttributeAsInt("id"));
+ }
+ return result;
+ }
+ }) {
- BundleGWTServiceAsync bundleManager = GWTServiceLookup.getBundleService();
- bundleManager.deleteBundles(doomedIds, new AsyncCallback<Void>() {
- public void onFailure(Throwable caught) {
- String names = doomedNames.toString();
- String error = ErrorHandler.getAllMessages(caught);
- Message m = new Message(MSG.view_bundle_list_deletesFailure(), names + "<br/>\n" + error,
- Severity.Error);
- CoreGUI.getMessageCenter().notify(m);
+ public void executeAction(ListGridRecord[] selections, Object actionValue) {
+ if (selections == null || selections.length == 0) {
+ return;
}
- public void onSuccess(Void result) {
- Message m = new Message(MSG.view_bundle_list_deletesSuccessful(), doomedNames.toString(),
- Severity.Info);
- CoreGUI.getMessageCenter().notify(m);
- CoreGUI.refresh();
+ BundlesWithLatestVersionDataSource ds = (BundlesWithLatestVersionDataSource) getDataSource();
+ final ArrayList<String> doomedNames = new ArrayList<String>(selections.length);
+ int[] doomedIds = new int[selections.length];
+ int i = 0;
+ for (ListGridRecord selection : selections) {
+ BundleWithLatestVersionComposite object = ds.copyValues(selection);
+ doomedNames.add(object.getBundleName());
+ doomedIds[i++] = object.getBundleId();
}
- });
- }
- });
+
+ BundleGWTServiceAsync bundleManager = GWTServiceLookup.getBundleService();
+ bundleManager.deleteBundles(doomedIds, new AsyncCallback<Void>() {
+ public void onFailure(Throwable caught) {
+ String names = doomedNames.toString();
+ String error = ErrorHandler.getAllMessages(caught);
+ Message m = new Message(MSG.view_bundle_list_deletesFailure(), names + "<br/>\n"
+ + error, Severity.Error);
+ CoreGUI.getMessageCenter().notify(m);
+ }
+
+ public void onSuccess(Void result) {
+ Message m = new Message(MSG.view_bundle_list_deletesSuccessful(), doomedNames
+ .toString(), Severity.Info);
+ CoreGUI.getMessageCenter().notify(m);
+ CoreGUI.refresh();
+ }
+ });
+ }
+ });
// can change this back to SINGLE selection when we feel like it. currently allowing the wizard to
// select the bundle.
- addTableAction(MSG.view_bundle_deploy(), null, new AbstractTableAction(
- (hasAuth) ? TableActionEnablement.ALWAYS : TableActionEnablement.NEVER) {
+ addTableAction(MSG.view_bundle_deploy(), null, new RoleAuthorizedTableAction(BundlesListView.this,
+ Permission.DEPLOY_BUNDLES, Permission.DEPLOY_BUNDLES_TO_GROUP) {
+
public void executeAction(ListGridRecord[] selection, Object actionValue) {
if (selection.length == 0) {
new BundleDeployWizard().startWizard();
@@ -222,6 +236,5 @@ public class BundlesListView extends Table<BundlesWithLatestVersionDataSource> {
}
});
}
-
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/AuthorizedTableAction.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/AuthorizedTableAction.java
index 7b51bc7..d21fc70 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/AuthorizedTableAction.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/AuthorizedTableAction.java
@@ -56,8 +56,8 @@ public abstract class AuthorizedTableAction extends AbstractTableAction {
case GLOBAL:
globalPermissions.add(p);
break;
- case RESOURCE:
- throw new IllegalArgumentException("Does not support Resource permissions");
+ default:
+ throw new IllegalArgumentException("Does not support non-global permissions");
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/BundleAuthorizedTableAction.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/BundleAuthorizedTableAction.java
new file mode 100644
index 0000000..2da610a
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/BundleAuthorizedTableAction.java
@@ -0,0 +1,125 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2013 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.enterprise.gui.coregui.client.components.table;
+
+import java.util.Collection;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+
+import org.rhq.core.domain.authz.Permission;
+import org.rhq.core.domain.authz.Permission.Target;
+import org.rhq.enterprise.gui.coregui.client.CoreGUI;
+import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
+
+/**
+ * This class allows for TableAction (ie. Button) enablement based on row selection and bundle perm authorization
+ * on the selected rows. If possible it is recommended that the table be built using composites that include the
+ * bundle permission information already, as performance will be better. This approach will require an async
+ * authz call to the server on each refresh of the TableActions (i.e. each time selection changes in the Table).
+ *
+ * For Global Perm authorization see {@link AuthorizedTableAction}.
+ *
+ * @author Jay Shaughnessy
+ */
+public abstract class BundleAuthorizedTableAction extends AbstractTableAction {
+
+ private Table<?> table;
+ private Permission requiredPermission;
+ private RecordExtractor<Integer> extractor;
+ private Collection<Integer> authorizedBundleIds;
+
+ private Boolean isAuthorized;
+
+ /**
+ * @param table
+ * @param enablement
+ * @param requiredPermission if null no check is performed and authorization always passes
+ * @param extractor
+ */
+ protected BundleAuthorizedTableAction(Table<?> table, Permission requiredPermission,
+ RecordExtractor<Integer> extractor) {
+ this(table, TableActionEnablement.ALWAYS, requiredPermission, extractor);
+ }
+
+ /**
+ * @param table
+ * @param enablement
+ * @param requiredPermission if null no check is performed and authorization always passes
+ * @param extractor
+ */
+ protected BundleAuthorizedTableAction(Table<?> table, TableActionEnablement enablement,
+ Permission requiredPermission, RecordExtractor<Integer> extractor) {
+ super(enablement);
+
+ this.table = table;
+ this.requiredPermission = requiredPermission;
+ this.extractor = extractor;
+
+ if (null != this.requiredPermission && Target.BUNDLE != this.requiredPermission.getTarget()) {
+ throw new IllegalArgumentException("Does not support Global permission");
+ }
+ }
+
+ @Override
+ public boolean isEnabled(ListGridRecord[] selection) {
+ // first make sure row selection enablement passes
+ if (!super.isEnabled(selection)) {
+ return false;
+ }
+
+ // if there is no required permission then no check is performed
+ if (null == requiredPermission) {
+ return true;
+ }
+
+ final Collection<Integer> selectedBundleIds = extractor.extract(selection);
+ boolean isNewSelection = !selectedBundleIds.equals(this.authorizedBundleIds);
+
+ if (isNewSelection) {
+ isAuthorized = false;
+ authorizedBundleIds = selectedBundleIds;
+ } else {
+ return isAuthorized;
+ }
+
+ // kick off the async auth check. return false initially and update when the async call returns
+
+ GWTServiceLookup.getAuthorizationService().hasBundlePermission(requiredPermission, selectedBundleIds,
+ new AsyncCallback<Boolean>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError("", caught);
+ }
+
+ public void onSuccess(Boolean result) {
+ boolean isStale = !selectedBundleIds.equals(authorizedBundleIds);
+ if (isStale) {
+ return;
+ }
+
+ isAuthorized = result;
+ table.refreshTableInfo();
+ }
+
+ });
+
+ return isAuthorized;
+ }
+}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/RoleAuthorizedTableAction.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/RoleAuthorizedTableAction.java
new file mode 100644
index 0000000..497631c
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/RoleAuthorizedTableAction.java
@@ -0,0 +1,85 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2013 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.rhq.enterprise.gui.coregui.client.components.table;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.authz.Permission;
+import org.rhq.core.domain.authz.Role;
+import org.rhq.core.domain.criteria.RoleCriteria;
+import org.rhq.core.domain.util.PageList;
+import org.rhq.enterprise.gui.coregui.client.CoreGUI;
+import org.rhq.enterprise.gui.coregui.client.UserSessionManager;
+import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
+
+/**
+ * This is used only to determine enablement of certain bundle buttons (new, deploy). It activates the button if the user
+ * has any role with the specified permissions. It requires only one async call and then uses the cached value.
+ *
+ * For strict Global Perm authorization see {@link AuthorizedTableAction}.
+ *
+ * @author Jay Shaughnessy
+ */
+public abstract class RoleAuthorizedTableAction extends AbstractTableAction {
+
+ private Table<?> table;
+ List<Permission> permissions;
+ private Boolean isAuthorized;
+
+ protected RoleAuthorizedTableAction(Table<?> table, Permission... permissions) {
+ this.table = table;
+ this.permissions = Arrays.asList(permissions);
+ }
+
+ @Override
+ public boolean isEnabled(ListGridRecord[] selection) {
+ // first make sure row selection enablement passes
+ if (!super.isEnabled(selection)) {
+ return false;
+ }
+
+ if (null != isAuthorized) {
+ return isAuthorized.booleanValue();
+ }
+
+ // kick off the async auth check. return false initially and update when the async call returns
+ RoleCriteria criteria = new RoleCriteria();
+ Subject subject = UserSessionManager.getSessionSubject();
+ criteria.addFilterSubjectId(subject.getId());
+ criteria.addFilterPermissions(permissions);
+ GWTServiceLookup.getRoleService().findRolesByCriteria(criteria, new AsyncCallback<PageList<Role>>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError("", caught);
+ }
+
+ public void onSuccess(PageList<Role> result) {
+ isAuthorized = !result.isEmpty();
+ table.refreshTableInfo();
+ }
+ });
+
+ return false;
+ }
+}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/AuthorizationGWTService.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/AuthorizationGWTService.java
index fdcd01d..2af16c3 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/AuthorizationGWTService.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/AuthorizationGWTService.java
@@ -86,4 +86,17 @@ public interface AuthorizationGWTService extends RemoteService {
*/
boolean hasResourcePermission(Permission permission, Collection<Integer> resourceIds) throws RuntimeException;
+ /**
+ * Returns true if the current user possesses either: 1) the specified bundle permission for *all* of the
+ * specified bundles, or 2) is a system superuser which, by definition, gives full access to all bundles
+ * NOTE: The size of the collection must be less than or equal to 1000 (due to an Oracle limitation).
+ *
+ * @param subject the current subject or caller
+ * @param permission a resource permission (i.e. permission.getTarget() == Permission.Target.RESOURCE)
+ * @param bundleIds the ids of some Bundles to check permissions against (size of collection must be <= 1000)
+ *
+ * @return true if the current user possesses the specified resource permission for the specified resource
+ */
+ boolean hasBundlePermission(Permission permission, Collection<Integer> bundleIds);
+
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AuthorizationGWTServiceImpl.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AuthorizationGWTServiceImpl.java
index 4be6eb9..9dc365f 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AuthorizationGWTServiceImpl.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AuthorizationGWTServiceImpl.java
@@ -39,8 +39,9 @@ public class AuthorizationGWTServiceImpl extends AbstractGWTServiceImpl implemen
public Set<Permission> getExplicitResourcePermissions(int resourceId) throws RuntimeException {
try {
- return SerialUtility.prepare(new HashSet<Permission>(authorizationManager.getExplicitResourcePermissions(
- getSessionSubject(), resourceId)), "AuthorizationManager.getExplicitResourcePermissions");
+ return SerialUtility.prepare(
+ new HashSet<Permission>(authorizationManager.getExplicitResourcePermissions(getSessionSubject(),
+ resourceId)), "AuthorizationManager.getExplicitResourcePermissions");
} catch (Throwable t) {
throw getExceptionToThrowToClient(t);
}
@@ -48,8 +49,9 @@ public class AuthorizationGWTServiceImpl extends AbstractGWTServiceImpl implemen
public Set<Permission> getImplicitResourcePermissions(int resourceId) throws RuntimeException {
try {
- return SerialUtility.prepare(new HashSet<Permission>(authorizationManager.getImplicitResourcePermissions(
- getSessionSubject(), resourceId)), "AuthorizationManager.getImplicitResourcePermissions");
+ return SerialUtility.prepare(
+ new HashSet<Permission>(authorizationManager.getImplicitResourcePermissions(getSessionSubject(),
+ resourceId)), "AuthorizationManager.getImplicitResourcePermissions");
} catch (Throwable t) {
throw getExceptionToThrowToClient(t);
}
@@ -57,8 +59,10 @@ public class AuthorizationGWTServiceImpl extends AbstractGWTServiceImpl implemen
public Set<Permission> getExplicitGroupPermissions(int groupId) throws RuntimeException {
try {
- return SerialUtility.prepare(new HashSet<Permission>(authorizationManager.getExplicitGroupPermissions(
- getSessionSubject(), groupId)), "AuthorizationManager.getExplicitGroupPermissions");
+ return SerialUtility
+ .prepare(
+ new HashSet<Permission>(authorizationManager.getExplicitGroupPermissions(getSessionSubject(),
+ groupId)), "AuthorizationManager.getExplicitGroupPermissions");
} catch (Throwable t) {
throw getExceptionToThrowToClient(t);
}
@@ -66,8 +70,10 @@ public class AuthorizationGWTServiceImpl extends AbstractGWTServiceImpl implemen
public Set<Permission> getImplicitGroupPermissions(int groupId) throws RuntimeException {
try {
- return SerialUtility.prepare(new HashSet<Permission>(authorizationManager.getImplicitGroupPermissions(
- getSessionSubject(), groupId)), "AuthorizationManager.getImplicitGroupPermissions");
+ return SerialUtility
+ .prepare(
+ new HashSet<Permission>(authorizationManager.getImplicitGroupPermissions(getSessionSubject(),
+ groupId)), "AuthorizationManager.getImplicitGroupPermissions");
} catch (Throwable t) {
throw getExceptionToThrowToClient(t);
}
@@ -75,15 +81,16 @@ public class AuthorizationGWTServiceImpl extends AbstractGWTServiceImpl implemen
public Set<Permission> getExplicitGlobalPermissions() throws RuntimeException {
try {
- return SerialUtility.prepare(new HashSet<Permission>(authorizationManager
- .getExplicitGlobalPermissions(getSessionSubject())),
+ return SerialUtility.prepare(
+ new HashSet<Permission>(authorizationManager.getExplicitGlobalPermissions(getSessionSubject())),
"AuthorizationManager.getExplicitGlobalPermissions");
} catch (Throwable t) {
throw getExceptionToThrowToClient(t);
}
}
- public boolean hasResourcePermission(Permission permission, Collection<Integer> resourceIds) throws RuntimeException {
+ public boolean hasResourcePermission(Permission permission, Collection<Integer> resourceIds)
+ throws RuntimeException {
try {
boolean result = authorizationManager.hasResourcePermission(getSessionSubject(), permission, resourceIds);
return result;
@@ -92,4 +99,12 @@ public class AuthorizationGWTServiceImpl extends AbstractGWTServiceImpl implemen
}
}
+ public boolean hasBundlePermission(Permission permission, Collection<Integer> bundleIds) throws RuntimeException {
+ try {
+ boolean result = authorizationManager.hasBundlePermission(getSessionSubject(), permission, bundleIds);
+ return result;
+ } catch (Throwable t) {
+ throw getExceptionToThrowToClient(t);
+ }
+ }
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/AuthorizationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/AuthorizationManagerBean.java
index d5746d3..8464133 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/AuthorizationManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/AuthorizationManagerBean.java
@@ -203,6 +203,21 @@ public class AuthorizationManagerBean implements AuthorizationManagerLocal {
return (count != 0);
}
+ @Override
+ @SuppressWarnings("unchecked")
+ public boolean hasBundlePermission(Subject subject, Permission permission, Collection<Integer> bundleIds) {
+ if (isSystemSuperuser(subject)) {
+ return true;
+ }
+
+ Query query = entityManager.createNamedQuery(Subject.QUERY_GET_BUNDLES_BY_PERMISSION);
+ query.setParameter("subject", subject);
+ query.setParameter("permission", permission);
+
+ List<Integer> results = query.getResultList();
+ return results.containsAll(bundleIds);
+ }
+
@SuppressWarnings("unchecked")
@Override
public boolean hasBundleGroupPermission(Subject subject, Permission permission, int bundleGroupId) {
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/AuthorizationManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/AuthorizationManagerLocal.java
index 62d3c0c..18003fb 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/AuthorizationManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/AuthorizationManagerLocal.java
@@ -168,6 +168,19 @@ public interface AuthorizationManagerLocal {
boolean hasBundlePermission(Subject subject, Permission permission, int bundleId);
/**
+ * Returns true if the current user possesses either: 1) the specified bundle permission for *all* of the
+ * specified bundles, or 2) is a system superuser which, by definition, gives full access to all bundles
+ * NOTE: The size of the collection must be less than or equal to 1000 (due to an Oracle limitation).
+ *
+ * @param subject the current subject or caller
+ * @param permission a resource permission (i.e. permission.getTarget() == Permission.Target.RESOURCE)
+ * @param bundleIds the ids of some Bundles to check permissions against (size of collection must be <= 1000)
+ *
+ * @return true if the current user possesses the specified resource permission for the specified resource
+ */
+ boolean hasBundlePermission(Subject subject, Permission permission, Collection<Integer> bundleIds);
+
+ /**
* Returns true if the current user possesses the specified bundle permission for the specified bundle group.
*
* @param subject the current subject or caller