Author: rareddy
Date: 2009-07-06 17:17:43 -0400 (Mon, 06 Jul 2009)
New Revision: 1095
Added:
trunk/build/kit-embedded/deploy/admin-roles.properties
trunk/embedded/src/main/java/com/metamatrix/platform/security/authorization/service/AdminAuthorizationPolicyProvider.java
Modified:
trunk/build/kit-embedded/deploy.properties
trunk/common-internal/src/main/java/com/metamatrix/platform/security/api/AuthorizationPolicyFactory.java
trunk/embedded/src/main/java/com/metamatrix/jdbc/EmbeddedGuiceModule.java
trunk/embedded/src/main/java/com/metamatrix/platform/security/authorization/service/AuthorizationServiceImpl.java
trunk/embedded/src/main/resources/com/metamatrix/dqp/embedded/i18n.properties
trunk/embedded/src/test/java/com/metamatrix/platform/security/api/TestAuthorizationPolicyFactory.java
trunk/engine/src/main/java/com/metamatrix/dqp/service/AuthorizationService.java
Log:
TEIID-665: Adding the configuration option to define the admin roles for the user groups.
Added: trunk/build/kit-embedded/deploy/admin-roles.properties
===================================================================
--- trunk/build/kit-embedded/deploy/admin-roles.properties (rev
0)
+++ trunk/build/kit-embedded/deploy/admin-roles.properties 2009-07-06 21:17:43 UTC (rev
1095)
@@ -0,0 +1,18 @@
+# This file defines admin role grants for each user "group" in the system.
+# based on the this permission the user will be able to call the admin
+# function calls into the system. The following format needs to be used
+# define the permissions
+
+# role1 = groupA, groupB
+# role2 = groupB, groupC
+
+# for group names check your membership provider configuration.
+
+# This role grants full permissions to any configuration, runtime-management and
monitoring of the system
+Admin.SystemAdmin=
+
+# This role grants runtime-management and monitoring of the system
+Admin.ProductAdmin=
+
+# This role grants only monitoring of the system.
+Admin.ReadOnlyAdmin=
Property changes on: trunk/build/kit-embedded/deploy/admin-roles.properties
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: trunk/build/kit-embedded/deploy.properties
===================================================================
--- trunk/build/kit-embedded/deploy.properties 2009-07-02 21:38:17 UTC (rev 1094)
+++ trunk/build/kit-embedded/deploy.properties 2009-07-06 21:17:43 UTC (rev 1095)
@@ -119,6 +119,7 @@
# Enable entitlements (data, admin)
entitlements.enabled=false
+entitlements.adminRolesFile=./deploy/admin-roles.properties
#
Modified:
trunk/common-internal/src/main/java/com/metamatrix/platform/security/api/AuthorizationPolicyFactory.java
===================================================================
---
trunk/common-internal/src/main/java/com/metamatrix/platform/security/api/AuthorizationPolicyFactory.java 2009-07-02
21:38:17 UTC (rev 1094)
+++
trunk/common-internal/src/main/java/com/metamatrix/platform/security/api/AuthorizationPolicyFactory.java 2009-07-06
21:17:43 UTC (rev 1095)
@@ -29,7 +29,9 @@
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
+import java.util.Properties;
import java.util.Set;
+import java.util.StringTokenizer;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
@@ -47,6 +49,7 @@
import com.metamatrix.common.log.LogManager;
import com.metamatrix.common.util.LogConstants;
+import com.metamatrix.platform.security.util.RolePermissionFactory;
/**
* The class build the Policies from the xml file or converts the policies to xml file
for importing and exporting of the policy
@@ -93,20 +96,15 @@
docBuilder.setErrorHandler(new ErrorHandler() {
public void warning(SAXParseException arg0) throws SAXException {
- LogManager.logWarning(LogConstants.CTX_AUTHORIZATION,
- arg0,
-
SecurityPlugin.Util.getString("AuthorizationPolicyFactory.parsing_warning",
//$NON-NLS-1$
- arg0.getMessage()));
+
LogManager.logWarning(LogConstants.CTX_AUTHORIZATION,arg0,SecurityPlugin.Util.getString("AuthorizationPolicyFactory.parsing_warning",
arg0.getMessage())); //$NON-NLS-1$
}
public void error(SAXParseException arg0) throws SAXException {
- throw new
SAXException(SecurityPlugin.Util.getString("AuthorizationPolicyFactory.parsing_error",
//$NON-NLS-1$
- arg0.getMessage()),
arg0);
+ throw new
SAXException(SecurityPlugin.Util.getString("AuthorizationPolicyFactory.parsing_error",
arg0.getMessage()), arg0); //$NON-NLS-1$
}
public void fatalError(SAXParseException arg0) throws SAXException {
- throw new
SAXException(SecurityPlugin.Util.getString("AuthorizationPolicyFactory.parsing_error",
//$NON-NLS-1$
- arg0.getMessage()),
arg0);
+ throw new
SAXException(SecurityPlugin.Util.getString("AuthorizationPolicyFactory.parsing_error",
arg0.getMessage()), arg0); //$NON-NLS-1$
}
});
@@ -242,4 +240,33 @@
return baos.toString().toCharArray();
}
+
+ /**
+ * The properties will have format of
+ * role1 = group1, group2
+ * role2 = group3
+ *
+ * @param roles
+ * @return
+ */
+ public static Collection<AuthorizationPolicy> buildAdminPolicies(Properties
roleMap) {
+ List<AuthorizationPolicy> result = new ArrayList<AuthorizationPolicy>();
+ Set keys = roleMap.keySet();
+
+ for(Object key:keys) {
+ String role = (String)key;
+ AuthorizationPolicyID policyID = new AuthorizationPolicyID(role, role);
+ AuthorizationPolicy policy = new AuthorizationPolicy(policyID);
+
+ // allowed groups
+ StringTokenizer st = new StringTokenizer(roleMap.getProperty(role),
","); //$NON-NLS-1$
+ while (st.hasMoreTokens()) {
+ String group = st.nextToken();
+ MetaMatrixPrincipalName member = new MetaMatrixPrincipalName(group,
MetaMatrixPrincipal.TYPE_GROUP);
+ policy.addPrincipal(member);
+ }
+ result.add(policy);
+ }
+ return result;
+ }
}
Modified: trunk/embedded/src/main/java/com/metamatrix/jdbc/EmbeddedGuiceModule.java
===================================================================
--- trunk/embedded/src/main/java/com/metamatrix/jdbc/EmbeddedGuiceModule.java 2009-07-02
21:38:17 UTC (rev 1094)
+++ trunk/embedded/src/main/java/com/metamatrix/jdbc/EmbeddedGuiceModule.java 2009-07-06
21:17:43 UTC (rev 1095)
@@ -25,6 +25,7 @@
import java.net.InetAddress;
import java.net.URL;
import java.net.UnknownHostException;
+import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
@@ -36,6 +37,7 @@
import com.google.inject.AbstractModule;
import com.google.inject.Injector;
import com.google.inject.Scopes;
+import com.google.inject.TypeLiteral;
import com.google.inject.name.Names;
import com.metamatrix.cache.CacheFactory;
import com.metamatrix.cache.jboss.JBossCacheFactory;
@@ -54,9 +56,9 @@
import com.metamatrix.dqp.embedded.services.EmbeddedMetadataService;
import com.metamatrix.dqp.embedded.services.EmbeddedTransactionService;
import com.metamatrix.dqp.embedded.services.EmbeddedVDBService;
-import com.metamatrix.dqp.service.AuthorizationService;
import com.metamatrix.dqp.service.DQPServiceNames;
-import com.metamatrix.platform.security.api.service.MembershipServiceInterface;
+import com.metamatrix.platform.security.api.AuthorizationPolicy;
+import
com.metamatrix.platform.security.authorization.service.AdminAuthorizationPolicyProvider;
import com.metamatrix.platform.security.authorization.service.AuthorizationServiceImpl;
import com.metamatrix.platform.security.membership.service.MembershipServiceImpl;
import com.metamatrix.platform.security.session.service.SessionServiceImpl;
@@ -93,6 +95,7 @@
bind(DQPContextCache.class).in(Scopes.SINGLETON);
bind(DQPCore.class).in(Scopes.SINGLETON);
+ bind(new
TypeLiteral<Collection<AuthorizationPolicy>>(){}).annotatedWith(Names.named("AdminRoles")).toProvider(AdminAuthorizationPolicyProvider.class).in(Scopes.SINGLETON);
//$NON-NLS-1$
configureServices();
Added:
trunk/embedded/src/main/java/com/metamatrix/platform/security/authorization/service/AdminAuthorizationPolicyProvider.java
===================================================================
---
trunk/embedded/src/main/java/com/metamatrix/platform/security/authorization/service/AdminAuthorizationPolicyProvider.java
(rev 0)
+++
trunk/embedded/src/main/java/com/metamatrix/platform/security/authorization/service/AdminAuthorizationPolicyProvider.java 2009-07-06
21:17:43 UTC (rev 1095)
@@ -0,0 +1,71 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+package com.metamatrix.platform.security.authorization.service;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Properties;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+import com.google.inject.name.Named;
+import com.metamatrix.common.log.LogManager;
+import com.metamatrix.common.protocol.URLHelper;
+import com.metamatrix.common.util.LogConstants;
+import com.metamatrix.common.util.PropertiesUtils;
+import com.metamatrix.dqp.embedded.DQPEmbeddedPlugin;
+import com.metamatrix.dqp.service.AuthorizationService;
+import com.metamatrix.platform.security.api.AuthorizationPolicy;
+import com.metamatrix.platform.security.api.AuthorizationPolicyFactory;
+
+@Singleton
+public class AdminAuthorizationPolicyProvider implements
Provider<Collection<AuthorizationPolicy>> {
+
+ @Inject @Named("DQPProperties")
+ Properties props;
+
+ @Inject @Named("BootstrapURL")
+ private URL dqpURL;
+
+ @Override
+ public Collection<AuthorizationPolicy> get() {
+ String fileName = this.props.getProperty(AuthorizationService.ADMIN_ROLES_FILE);
+
+ if (fileName != null) {
+ try {
+ URL url = URLHelper.buildURL(this.dqpURL, fileName);
+ Properties roles = PropertiesUtils.loadFromURL(url);
+ return AuthorizationPolicyFactory.buildAdminPolicies(roles);
+ }catch(IOException e) {
+ LogManager.logError(LogConstants.CTX_AUTHORIZATION, e,
DQPEmbeddedPlugin.Util.getString("failed_to_load_admin_roles")); //$NON-NLS-1$
+ }
+ }
+ else {
+ LogManager.logDetail(LogConstants.CTX_AUTHORIZATION,
DQPEmbeddedPlugin.Util.getString("admin_roles_not_defined")); //$NON-NLS-1$
+ }
+ return Collections.EMPTY_LIST;
+ }
+
+}
Property changes on:
trunk/embedded/src/main/java/com/metamatrix/platform/security/authorization/service/AdminAuthorizationPolicyProvider.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified:
trunk/embedded/src/main/java/com/metamatrix/platform/security/authorization/service/AuthorizationServiceImpl.java
===================================================================
---
trunk/embedded/src/main/java/com/metamatrix/platform/security/authorization/service/AuthorizationServiceImpl.java 2009-07-02
21:38:17 UTC (rev 1094)
+++
trunk/embedded/src/main/java/com/metamatrix/platform/security/authorization/service/AuthorizationServiceImpl.java 2009-07-06
21:17:43 UTC (rev 1095)
@@ -40,6 +40,7 @@
import org.xml.sax.SAXException;
import com.google.inject.Inject;
+import com.google.inject.name.Named;
import com.metamatrix.admin.api.exception.security.InvalidSessionException;
import com.metamatrix.admin.api.exception.security.MetaMatrixSecurityException;
import com.metamatrix.api.exception.MetaMatrixComponentException;
@@ -100,11 +101,12 @@
protected MembershipServiceInterface membershipService;
protected VDBService vdbService;
protected LRUCache<VDBKey, Collection<AuthorizationPolicy>> policyCache =
new LRUCache<VDBKey, Collection<AuthorizationPolicy>>();
- private Collection<AuthorizationPolicy> adminPolicies;
- // Permission factory is reusable and threadsafe
+ // Permission factory is reusable and thread safe
private static final BasicAuthorizationPermissionFactory PERMISSION_FACTORY = new
BasicAuthorizationPermissionFactory();
+ Collection<AuthorizationPolicy> adminPolicies;
+
/*
* @see
com.metamatrix.common.application.ApplicationService#initialize(java.util.Properties)
*/
@@ -263,8 +265,7 @@
}
}
- private boolean matchesPrincipal(Set<MetaMatrixPrincipalName> principals,
- AuthorizationPolicy policy) {
+ private boolean matchesPrincipal(Set<MetaMatrixPrincipalName> principals,
AuthorizationPolicy policy) {
for (MetaMatrixPrincipalName principal : principals) {
if (policy.getPrincipals().contains(principal)) {
return true;
@@ -279,7 +280,7 @@
return true;
}
- Collection policies;
+ Collection<AuthorizationPolicy> policies;
try {
policies = getPoliciesForPrincipal(new MetaMatrixPrincipalName(session.getUsername(),
MetaMatrixPrincipal.TYPE_USER), realm);
} catch (InvalidPrincipalException e) {
@@ -298,14 +299,11 @@
}
}
- for (Iterator i = policies.iterator(); i.hasNext();) {
- AuthorizationPolicy policy = (AuthorizationPolicy) i.next();
- if (applicablePolicies.contains(policy.getAuthorizationPolicyID()
- .getDisplayName())) {
+ for (AuthorizationPolicy policy:policies) {
+ if (applicablePolicies.contains(policy.getAuthorizationPolicyID().getDisplayName()))
{
return true;
}
}
-
return false;
}
@@ -350,18 +348,14 @@
return result;
}
- if (realm.getSubRealmName() != null) {
- Collection<AuthorizationPolicy> policies = getPoliciesInRealm(realm);
- for (AuthorizationPolicy policy : policies) {
- if (matchesPrincipal(principals, policy)) {
- result.add(policy);
- continue;
- }
- }
- } else {
- //TODO: looking for admin roles
+ Collection<AuthorizationPolicy> policies = getPoliciesInRealm(realm);
+
+ for (AuthorizationPolicy policy : policies) {
+ if (matchesPrincipal(principals, policy)) {
+ result.add(policy);
+ continue;
+ }
}
-
return result;
}
@@ -370,35 +364,51 @@
Collection<AuthorizationPolicy> policies = null;
+ VDBKey key = null;
+
if (realm.getSubRealmName() != null) {
- VDBKey key = new VDBKey(realm.getSuperRealmName(), realm.getSubRealmName());
- synchronized (this.policyCache) {
- policies = this.policyCache.get(key);
- if (policies == null) {
- try {
- VDBArchive vdb = vdbService.getVDB(realm.getSuperRealmName(),
realm.getSubRealmName());
- if (vdb.getDataRoles() == null) {
- policies = Collections.emptyList();
- }
- else {
- policies = AuthorizationPolicyFactory.buildPolicies(vdb.getName(),
vdb.getVersion(), vdb.getDataRoles());
- }
- } catch (SAXException e) {
- throw new AuthorizationMgmtException(e);
- } catch (IOException e) {
- throw new AuthorizationMgmtException(e);
- } catch (ParserConfigurationException e) {
- throw new AuthorizationMgmtException(e);
- } catch (MetaMatrixComponentException e) {
- throw new AuthorizationMgmtException(e);
- }
- this.policyCache.put(key, policies);
+ // get data roles for the user
+ key = new VDBKey(realm.getSuperRealmName(), realm.getSubRealmName());
+ synchronized (this.policyCache) {
+ policies = this.policyCache.get(key);
+ if (policies == null ) {
+ policies = getDataPolicies(realm);
}
- }
- }
-
+ this.policyCache.put(key, policies);
+ }
+ }
+ else {
+ // get admin roles
+ policies = getAdminPolicies();
+ }
return policies;
}
+
+ private Collection<AuthorizationPolicy> getDataPolicies(AuthorizationRealm realm)
throws AuthorizationMgmtException {
+ Collection<AuthorizationPolicy> policies = null;
+ try {
+ VDBArchive vdb = vdbService.getVDB(realm.getSuperRealmName(),
realm.getSubRealmName());
+ if (vdb.getDataRoles() == null) {
+ policies = Collections.emptyList();
+ }
+ else {
+ policies = AuthorizationPolicyFactory.buildPolicies(vdb.getName(),
vdb.getVersion(), vdb.getDataRoles());
+ }
+ } catch (SAXException e) {
+ throw new AuthorizationMgmtException(e);
+ } catch (IOException e) {
+ throw new AuthorizationMgmtException(e);
+ } catch (ParserConfigurationException e) {
+ throw new AuthorizationMgmtException(e);
+ } catch (MetaMatrixComponentException e) {
+ throw new AuthorizationMgmtException(e);
+ }
+ return policies;
+ }
+
+ private Collection<AuthorizationPolicy> getAdminPolicies() {
+ return adminPolicies;
+ }
public void updatePoliciesInRealm(AuthorizationRealm realm,
Collection<AuthorizationPolicy> policies) throws AuthorizationMgmtException {
@@ -422,7 +432,8 @@
}
}
else {
- // update admin roles.
+ // there is no admin API way to update the Admin Roles.
+ this.adminPolicies = policies;
}
}
@@ -547,10 +558,10 @@
this.membershipService = membershipService;
}
-// @Inject
-// public void setAdminPolicies(Collection<AuthorizationPolicy> adminPolicies)
{
-// this.adminPolicies = adminPolicies;
-// }
+ @Inject
+ public void setAdminPolicies(@Named("AdminRoles")
Collection<AuthorizationPolicy> adminPolicies) {
+ this.adminPolicies = adminPolicies;
+ }
public void setUseEntitlements(boolean useEntitlements) {
this.useEntitlements = useEntitlements;
Modified: trunk/embedded/src/main/resources/com/metamatrix/dqp/embedded/i18n.properties
===================================================================
---
trunk/embedded/src/main/resources/com/metamatrix/dqp/embedded/i18n.properties 2009-07-02
21:38:17 UTC (rev 1094)
+++
trunk/embedded/src/main/resources/com/metamatrix/dqp/embedded/i18n.properties 2009-07-06
21:17:43 UTC (rev 1095)
@@ -207,4 +207,7 @@
ServerSecurityAdminImpl.vdbName_can_not_be_null=Supplied VDB name is null
ServerSecurityAdminImpl.vdbVersion_can_not_be_null=Supplied VDB version is null
ServerSecurityAdminImpl.no_vdb_exists=No VDB with name {0}.{1} deployed in the system.
-ServerSecurityAdminImpl.not_implemented=This feature not available.
\ No newline at end of file
+ServerSecurityAdminImpl.not_implemented=This feature not available.
+
+failed_to_load_admin_roles=Failed to load Admin role permissions
+admin_roles_not_defined=Admin Role permissions are not defined. Refer to
admin-roles.properties file
\ No newline at end of file
Modified:
trunk/embedded/src/test/java/com/metamatrix/platform/security/api/TestAuthorizationPolicyFactory.java
===================================================================
---
trunk/embedded/src/test/java/com/metamatrix/platform/security/api/TestAuthorizationPolicyFactory.java 2009-07-02
21:38:17 UTC (rev 1094)
+++
trunk/embedded/src/test/java/com/metamatrix/platform/security/api/TestAuthorizationPolicyFactory.java 2009-07-06
21:17:43 UTC (rev 1095)
@@ -33,6 +33,8 @@
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
+import java.util.Properties;
+import java.util.Set;
import junit.framework.TestCase;
@@ -89,10 +91,10 @@
//add doc to test against
char[] result = AuthorizationPolicyFactory.exportPolicies(policies);
- String expected = FileUtil.read(new
FileReader(UnitTestUtil.getTestDataPath()+File.separator+"permissions.xml"));
- String actual = new String(result).replaceAll("\r\n", "\n");
+ String expected = FileUtil.read(new
FileReader(UnitTestUtil.getTestDataPath()+File.separator+"permissions.xml"));
//$NON-NLS-1$
+ String actual = new String(result).replaceAll("\r\n", "\n");
//$NON-NLS-1$ //$NON-NLS-2$
- assertEquals(expected, actual); //$NON-NLS-1$
+ assertEquals(expected, actual);
}
public void testImport() throws Exception {
@@ -119,9 +121,9 @@
}
char[] result = AuthorizationPolicyFactory.exportPolicies(roles);
- String expected = FileUtil.read(new FileReader(UnitTestUtil.getTestDataPath() +
"/permissions2.xml"));
- String actual = new String(result).replaceAll("\r\n", "\n");
- assertEquals(expected, actual); //$NON-NLS-1$
+ String expected = FileUtil.read(new FileReader(UnitTestUtil.getTestDataPath() +
"/permissions2.xml")); //$NON-NLS-1$
+ String actual = new String(result).replaceAll("\r\n", "\n");
//$NON-NLS-1$ //$NON-NLS-2$
+ assertEquals(expected, actual);
}
public void testParsingFails() throws Exception {
@@ -135,4 +137,27 @@
}
+ public void testAdminRoles() {
+ Properties p = new Properties();
+ p.setProperty("Admin.SystemAdmin", "GroupA, GroupB");
//$NON-NLS-1$ //$NON-NLS-2$
+ p.setProperty("Admin.ProductAdmin", "GroupB"); //$NON-NLS-1$
//$NON-NLS-2$
+ p.setProperty("Admin.ReadOnlyAdmin", "");//$NON-NLS-1$
//$NON-NLS-2$
+
+ Collection<AuthorizationPolicy> policies =
AuthorizationPolicyFactory.buildAdminPolicies(p);
+
+ assertEquals(3, policies.size());
+
+ for (AuthorizationPolicy policy: policies) {
+ if
(policy.getAuthorizationPolicyID().getName().equalsIgnoreCase("Admin.SystemAdmin"))
{ //$NON-NLS-1$
+ Set<MetaMatrixPrincipalName> principals = policy.getPrincipals();
+ assertEquals(2, principals.size());
+ }
+ else if
(policy.getAuthorizationPolicyID().getName().equalsIgnoreCase("Admin.ProductAdmin"))
{ //$NON-NLS-1$
+ Set<MetaMatrixPrincipalName> principals = policy.getPrincipals();
+ assertEquals(1, principals.size());
+ assertEquals(new MetaMatrixPrincipalName("GroupB",
MetaMatrixPrincipal.TYPE_GROUP), principals.iterator().next()); //$NON-NLS-1$
+ }
+ }
+ }
+
}
\ No newline at end of file
Modified: trunk/engine/src/main/java/com/metamatrix/dqp/service/AuthorizationService.java
===================================================================
---
trunk/engine/src/main/java/com/metamatrix/dqp/service/AuthorizationService.java 2009-07-02
21:38:17 UTC (rev 1094)
+++
trunk/engine/src/main/java/com/metamatrix/dqp/service/AuthorizationService.java 2009-07-06
21:17:43 UTC (rev 1095)
@@ -58,6 +58,7 @@
public static final String DEFAULT_WSDL_USERNAME =
CoreConstants.DEFAULT_ANON_USERNAME;
public static final String ENTITELEMENTS_ENABLED = "entitlements.enabled";
//$NON-NLS-1$
+ public static final String ADMIN_ROLES_FILE =
"entitlements.adminRolesFile"; //$NON-NLS-1$
/**
* Determine which of a set of resources a connection does not have permission to