KNOX-1338 - Add Config Property for Knox Admin Groups for AclsAuthz Provider Use
authorLarry McCay <lmccay@HW14155.home>
Sat, 2 Jun 2018 20:48:17 +0000 (16:48 -0400)
committerLarry McCay <lmccay@HW14155.home>
Sat, 2 Jun 2018 20:48:17 +0000 (16:48 -0400)
gateway-provider-security-authz-acls/src/main/java/org/apache/knox/gateway/deploy/impl/AclsAuthzDeploymentContributor.java
gateway-provider-security-authz-acls/src/main/java/org/apache/knox/gateway/filter/AclsAuthorizationFilter.java
gateway-provider-security-authz-acls/src/test/java/org/apache/knox/gateway/filter/AclsAuthzFilterTest.java [new file with mode: 0644]
gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java
gateway-spi/src/main/java/org/apache/knox/gateway/config/GatewayConfig.java
gateway-test-release-utils/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java

index e15ddfe..6d5c262 100644 (file)
@@ -60,6 +60,14 @@ public class AclsAuthzDeploymentContributor extends ProviderDeploymentContributo
     }
     // add resource role to params so that we can determine the acls to enforce at runtime
     params.add( resource.createFilterParam().name( "resource.role" ).value(resource.role() ) );
+    
+    // the following are used within the AclsAuthz provider to replace
+    // placeholders within the acls KNOX_ADMIN_GROUPS and KNOX_ADMIN_USERS
+    String adminGroups = context.getGatewayConfig().getKnoxAdminGroups();
+    params.add(resource.createFilterParam().name("knox.admin.groups").value(adminGroups));
+
+    String adminUsers = context.getGatewayConfig().getKnoxAdminUsers();
+    params.add(resource.createFilterParam().name("knox.admin.users").value(adminUsers));
 
     // blindly add all the provider params as filter init params
     // this will include any {resource.role}-ACLS parameters to be enforced - such as NAMENODE-ACLS
index f26c753..bdb602c 100644 (file)
@@ -41,6 +41,9 @@ import org.apache.knox.gateway.security.PrimaryPrincipal;
 import java.io.IOException;
 import java.security.AccessController;
 import java.security.Principal;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 
 public class AclsAuthorizationFilter implements Filter {
   private static AclsAuthorizationMessages log = MessagesFactory.get( AclsAuthorizationMessages.class );
@@ -50,10 +53,22 @@ public class AclsAuthorizationFilter implements Filter {
   private String resourceRole = null;
   private String aclProcessingMode = null;
   private AclParser parser = new AclParser();
+  private ArrayList<String> adminGroups = new ArrayList<String>();;
+  private ArrayList<String> adminUsers = new ArrayList<String>();;
 
   
   @Override
   public void init(FilterConfig filterConfig) throws ServletException {
+    String adminGroups = filterConfig.getInitParameter("knox.admin.groups");
+    if (adminGroups != null) {
+      parseAdminGroupConfig(adminGroups);
+    }
+    
+    String adminUsers = filterConfig.getInitParameter("knox.admin.users");
+    if (adminUsers != null) {
+      parseAdminUserConfig(adminUsers);
+    }
+
     resourceRole = getInitParameter(filterConfig, "resource.role");
     log.initializingForResourceRole(resourceRole);
     aclProcessingMode = getInitParameter(filterConfig, resourceRole + ".acl.mode");
@@ -72,6 +87,14 @@ public class AclsAuthorizationFilter implements Filter {
     return filterConfig.getInitParameter(paramName.toLowerCase());
   }
 
+  private void parseAdminGroupConfig(String groups) {
+    Collections.addAll(adminGroups, groups.split(","));
+  }
+
+  private void parseAdminUserConfig(String users) {
+    Collections.addAll(adminUsers, users.split(","));
+  }
+
   public void destroy() {
   }
 
@@ -90,7 +113,7 @@ public class AclsAuthorizationFilter implements Filter {
     }
   }
 
-  private boolean enforceAclAuthorizationPolicy(ServletRequest request,
+  protected boolean enforceAclAuthorizationPolicy(ServletRequest request,
       ServletResponse response, FilterChain chain) {
     HttpServletRequest req = (HttpServletRequest) request;
     
@@ -162,7 +185,7 @@ public class AclsAuthorizationFilter implements Filter {
     return allowed;
   }
 
-  private boolean checkUserAcls(Principal user) {
+  boolean checkUserAcls(Principal user) {
     boolean allowed = false;
     if (user == null) {
       return false;
@@ -174,11 +197,15 @@ public class AclsAuthorizationFilter implements Filter {
       if (parser.users.contains(user.getName())) {
         allowed = true;
       }
+      else if (parser.users.contains("KNOX_ADMIN_USERS") &&
+          adminUsers.contains(user.getName())) {
+        allowed = true;
+      }
     }
     return allowed;
   }
 
-  private boolean checkGroupAcls(Object[] userGroups) {
+  boolean checkGroupAcls(Object[] userGroups) {
     boolean allowed = false;
     if (userGroups == null) {
       return false;
@@ -187,16 +214,25 @@ public class AclsAuthorizationFilter implements Filter {
       allowed = true;
     }
     else {
-      for (int i = 0; i < userGroups.length; i++) {
-        if (parser.groups.contains(((Principal)userGroups[i]).getName())) {
-          allowed = true;
-          break;
-        }
+      allowed = hasAllowedPrincipal(parser.groups, userGroups);
+      if (!allowed && parser.groups.contains("KNOX_ADMIN_GROUPS")) {
+        allowed = hasAllowedPrincipal(adminGroups, userGroups);
       }
     }
     return allowed;
   }
 
+  private boolean hasAllowedPrincipal(List<String> allowed, Object[] userGroups) {
+    boolean rc = false;
+    for (int i = 0; i < userGroups.length; i++) {
+      if (allowed.contains(((Principal)userGroups[i]).getName())) {
+        rc = true;
+        break;
+      }
+    }
+    return rc;
+  }
+
   private void sendForbidden(HttpServletResponse res) {
     sendErrorCode(res, 403);
   }
diff --git a/gateway-provider-security-authz-acls/src/test/java/org/apache/knox/gateway/filter/AclsAuthzFilterTest.java b/gateway-provider-security-authz-acls/src/test/java/org/apache/knox/gateway/filter/AclsAuthzFilterTest.java
new file mode 100644 (file)
index 0000000..6e29d31
--- /dev/null
@@ -0,0 +1,457 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.filter;
+
+import static org.junit.Assert.assertEquals;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import javax.security.auth.Subject;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.knox.gateway.security.GroupPrincipal;
+import org.apache.knox.gateway.security.PrimaryPrincipal;
+import org.easymock.EasyMock;
+import org.junit.Before;
+import org.junit.Test;
+
+public class AclsAuthzFilterTest {
+  private boolean accessGranted = false;
+  private Filter filter = null;
+  
+  @Before
+  public void setup() {
+    filter = new AclsAuthorizationFilter() {
+      public void doFilter(ServletRequest request, ServletResponse response,
+          FilterChain chain) throws IOException, ServletException {
+        boolean accessGranted = enforceAclAuthorizationPolicy(request, response, chain);
+        String sourceUrl = (String)request.getAttribute( AbstractGatewayFilter.SOURCE_REQUEST_CONTEXT_URL_ATTRIBUTE_NAME );
+        if (accessGranted) {
+          chain.doFilter(request, response);
+        }
+      }
+      
+      protected boolean enforceAclAuthorizationPolicy(ServletRequest request,
+          ServletResponse response, FilterChain chain) {
+        accessGranted = super.enforceAclAuthorizationPolicy(request, response, chain);
+        return accessGranted;
+      }
+    };
+  }
+  
+  @Test
+  public void testKnoxAdminGroupsValid() throws ServletException, IOException,
+      URISyntaxException {
+
+    FilterConfig config = EasyMock.createNiceMock( FilterConfig.class );
+    EasyMock.expect(config.getInitParameter("knox.admin.users")).andReturn(null);
+    EasyMock.expect(config.getInitParameter("knox.admin.groups")).andReturn("admin");
+    EasyMock.expect(config.getInitParameter("resource.role")).andReturn("KNOX");
+    EasyMock.expect(config.getInitParameter("knox.acl.mode")).andReturn("OR");
+    EasyMock.expect(config.getInitParameter("knox.acl")).andReturn("*;KNOX_ADMIN_GROUPS;*");
+    EasyMock.replay( config );
+
+    final HttpServletRequest request = EasyMock.createNiceMock( HttpServletRequest.class );
+    EasyMock.replay( request );
+
+    final HttpServletResponse response = EasyMock.createNiceMock( HttpServletResponse.class );
+    EasyMock.replay( response );
+
+    final FilterChain chain = new FilterChain() {
+      @Override
+      public void doFilter(ServletRequest request, ServletResponse response)
+          throws IOException, ServletException {
+      }
+    };
+    
+    filter.init(config);
+    
+    Subject subject = new Subject();
+    subject.getPrincipals().add(new PrimaryPrincipal("larry"));
+    subject.getPrincipals().add(new GroupPrincipal("users"));
+    subject.getPrincipals().add(new GroupPrincipal("admin"));
+    try {
+      Subject.doAs(
+        subject,
+        new PrivilegedExceptionAction<Object>() {
+          public Object run() throws Exception {
+            filter.doFilter(request, response, chain);
+            return null;
+          }
+        });
+    }
+    catch (PrivilegedActionException e) {
+      Throwable t = e.getCause();
+      if (t instanceof IOException) {
+        throw (IOException) t;
+      }
+      else if (t instanceof ServletException) {
+        throw (ServletException) t;
+      }
+      else {
+        throw new ServletException(t);
+      }
+    }
+    assertEquals(true, accessGranted);
+  }
+
+  @Test
+  public void testKnoxAdminGroupsInvalid() throws ServletException, IOException,
+      URISyntaxException {
+
+    FilterConfig config = EasyMock.createNiceMock( FilterConfig.class );
+    EasyMock.expect(config.getInitParameter("knox.admin.users")).andReturn(null);
+    EasyMock.expect(config.getInitParameter("knox.admin.groups")).andReturn("admin");
+    EasyMock.expect(config.getInitParameter("resource.role")).andReturn("KNOX");
+    EasyMock.expect(config.getInitParameter("knox.acl.mode")).andReturn("OR");
+    EasyMock.expect(config.getInitParameter("knox.acl")).andReturn("*;KNOX_ADMIN_GROUPS;*");
+    EasyMock.replay( config );
+
+    final HttpServletRequest request = EasyMock.createNiceMock( HttpServletRequest.class );
+    EasyMock.replay( request );
+
+    final HttpServletResponse response = EasyMock.createNiceMock( HttpServletResponse.class );
+    EasyMock.replay( response );
+
+    final FilterChain chain = new FilterChain() {
+      @Override
+      public void doFilter(ServletRequest request, ServletResponse response)
+          throws IOException, ServletException {
+      }
+    };
+    
+    filter.init(config);
+    
+    Subject subject = new Subject();
+    subject.getPrincipals().add(new PrimaryPrincipal("larry"));
+    subject.getPrincipals().add(new GroupPrincipal("users"));
+    subject.getPrincipals().add(new GroupPrincipal("nonadmin"));
+    try {
+      Subject.doAs(
+        subject,
+        new PrivilegedExceptionAction<Object>() {
+          public Object run() throws Exception {
+            filter.doFilter(request, response, chain);
+            return null;
+          }
+        });
+    }
+    catch (PrivilegedActionException e) {
+      Throwable t = e.getCause();
+      if (t instanceof IOException) {
+        throw (IOException) t;
+      }
+      else if (t instanceof ServletException) {
+        throw (ServletException) t;
+      }
+      else {
+        throw new ServletException(t);
+      }
+    }
+    assertEquals(false, accessGranted);
+  }
+  
+  @Test
+  public void testKnoxAdminUsersValid() throws ServletException, IOException,
+      URISyntaxException {
+
+    FilterConfig config = EasyMock.createNiceMock( FilterConfig.class );
+    EasyMock.expect(config.getInitParameter("knox.admin.users")).andReturn("adminuser");
+    EasyMock.expect(config.getInitParameter("knox.admin.groups")).andReturn(null);
+    EasyMock.expect(config.getInitParameter("resource.role")).andReturn("KNOX");
+    EasyMock.expect(config.getInitParameter("knox.acl.mode")).andReturn("OR");
+    EasyMock.expect(config.getInitParameter("knox.acl")).andReturn("KNOX_ADMIN_USERS;*;*");
+    EasyMock.replay( config );
+
+    final HttpServletRequest request = EasyMock.createNiceMock( HttpServletRequest.class );
+    EasyMock.replay( request );
+
+    final HttpServletResponse response = EasyMock.createNiceMock( HttpServletResponse.class );
+    EasyMock.replay( response );
+
+    final FilterChain chain = new FilterChain() {
+      @Override
+      public void doFilter(ServletRequest request, ServletResponse response)
+          throws IOException, ServletException {
+      }
+    };
+    
+    filter.init(config);
+    
+    Subject subject = new Subject();
+    subject.getPrincipals().add(new PrimaryPrincipal("adminuser"));
+    subject.getPrincipals().add(new GroupPrincipal("users"));
+    subject.getPrincipals().add(new GroupPrincipal("admin"));
+    try {
+      Subject.doAs(
+        subject,
+        new PrivilegedExceptionAction<Object>() {
+          public Object run() throws Exception {
+            filter.doFilter(request, response, chain);
+            return null;
+          }
+        });
+    }
+    catch (PrivilegedActionException e) {
+      Throwable t = e.getCause();
+      if (t instanceof IOException) {
+        throw (IOException) t;
+      }
+      else if (t instanceof ServletException) {
+        throw (ServletException) t;
+      }
+      else {
+        throw new ServletException(t);
+      }
+    }
+    assertEquals(true, accessGranted);
+  }
+
+  @Test
+  public void testKnoxAdminUsersInvalid() throws ServletException, IOException,
+      URISyntaxException {
+
+    FilterConfig config = EasyMock.createNiceMock( FilterConfig.class );
+    EasyMock.expect(config.getInitParameter("knox.admin.users")).andReturn("adminuser");
+    EasyMock.expect(config.getInitParameter("knox.admin.groups")).andReturn(null);
+    EasyMock.expect(config.getInitParameter("resource.role")).andReturn("KNOX");
+    EasyMock.expect(config.getInitParameter("knox.acl.mode")).andReturn("OR");
+    EasyMock.expect(config.getInitParameter("knox.acl")).andReturn("KNOX_ADMIN_USERS;*;*");
+    EasyMock.replay( config );
+
+    final HttpServletRequest request = EasyMock.createNiceMock( HttpServletRequest.class );
+    EasyMock.replay( request );
+
+    final HttpServletResponse response = EasyMock.createNiceMock( HttpServletResponse.class );
+    EasyMock.replay( response );
+
+    final FilterChain chain = new FilterChain() {
+      @Override
+      public void doFilter(ServletRequest request, ServletResponse response)
+          throws IOException, ServletException {
+      }
+    };
+    
+    filter.init(config);
+    
+    Subject subject = new Subject();
+    subject.getPrincipals().add(new PrimaryPrincipal("larry"));
+    subject.getPrincipals().add(new GroupPrincipal("users"));
+    subject.getPrincipals().add(new GroupPrincipal("admin"));
+    try {
+      Subject.doAs(
+        subject,
+        new PrivilegedExceptionAction<Object>() {
+          public Object run() throws Exception {
+            filter.doFilter(request, response, chain);
+            return null;
+          }
+        });
+    }
+    catch (PrivilegedActionException e) {
+      Throwable t = e.getCause();
+      if (t instanceof IOException) {
+        throw (IOException) t;
+      }
+      else if (t instanceof ServletException) {
+        throw (ServletException) t;
+      }
+      else {
+        throw new ServletException(t);
+      }
+    }
+    assertEquals(false, accessGranted);
+  }
+  
+  @Test
+  public void testKnoxAdminUsersInvalidButACLUsersValid() throws ServletException, IOException,
+      URISyntaxException {
+
+    FilterConfig config = EasyMock.createNiceMock( FilterConfig.class );
+    EasyMock.expect(config.getInitParameter("knox.admin.users")).andReturn("adminuser");
+    EasyMock.expect(config.getInitParameter("knox.admin.groups")).andReturn(null);
+    EasyMock.expect(config.getInitParameter("resource.role")).andReturn("KNOX");
+    EasyMock.expect(config.getInitParameter("knox.acl.mode")).andReturn("OR");
+    EasyMock.expect(config.getInitParameter("knox.acl")).andReturn("KNOX_ADMIN_USERS,larry;*;*");
+    EasyMock.replay( config );
+
+    final HttpServletRequest request = EasyMock.createNiceMock( HttpServletRequest.class );
+    EasyMock.replay( request );
+
+    final HttpServletResponse response = EasyMock.createNiceMock( HttpServletResponse.class );
+    EasyMock.replay( response );
+
+    final FilterChain chain = new FilterChain() {
+      @Override
+      public void doFilter(ServletRequest request, ServletResponse response)
+          throws IOException, ServletException {
+      }
+    };
+    
+    filter.init(config);
+    
+    Subject subject = new Subject();
+    subject.getPrincipals().add(new PrimaryPrincipal("larry"));
+    subject.getPrincipals().add(new GroupPrincipal("users"));
+    subject.getPrincipals().add(new GroupPrincipal("admin"));
+    try {
+      Subject.doAs(
+        subject,
+        new PrivilegedExceptionAction<Object>() {
+          public Object run() throws Exception {
+            filter.doFilter(request, response, chain);
+            return null;
+          }
+        });
+    }
+    catch (PrivilegedActionException e) {
+      Throwable t = e.getCause();
+      if (t instanceof IOException) {
+        throw (IOException) t;
+      }
+      else if (t instanceof ServletException) {
+        throw (ServletException) t;
+      }
+      else {
+        throw new ServletException(t);
+      }
+    }
+    assertEquals(true, accessGranted);
+  }
+
+  @Test
+  public void testKnoxAdminUsersInvalidButACLGroupValid() throws ServletException, IOException,
+      URISyntaxException {
+
+    FilterConfig config = EasyMock.createNiceMock( FilterConfig.class );
+    EasyMock.expect(config.getInitParameter("knox.admin.users")).andReturn("adminuser");
+    EasyMock.expect(config.getInitParameter("knox.admin.groups")).andReturn(null);
+    EasyMock.expect(config.getInitParameter("resource.role")).andReturn("KNOX");
+    EasyMock.expect(config.getInitParameter("knox.acl.mode")).andReturn("OR");
+    EasyMock.expect(config.getInitParameter("knox.acl")).andReturn("KNOX_ADMIN_USERS;admin;*");
+    EasyMock.replay( config );
+
+    final HttpServletRequest request = EasyMock.createNiceMock( HttpServletRequest.class );
+    EasyMock.replay( request );
+
+    final HttpServletResponse response = EasyMock.createNiceMock( HttpServletResponse.class );
+    EasyMock.replay( response );
+
+    final FilterChain chain = new FilterChain() {
+      @Override
+      public void doFilter(ServletRequest request, ServletResponse response)
+          throws IOException, ServletException {
+      }
+    };
+    
+    filter.init(config);
+    
+    Subject subject = new Subject();
+    subject.getPrincipals().add(new PrimaryPrincipal("larry"));
+    subject.getPrincipals().add(new GroupPrincipal("users"));
+    subject.getPrincipals().add(new GroupPrincipal("admin"));
+    try {
+      Subject.doAs(
+        subject,
+        new PrivilegedExceptionAction<Object>() {
+          public Object run() throws Exception {
+            filter.doFilter(request, response, chain);
+            return null;
+          }
+        });
+    }
+    catch (PrivilegedActionException e) {
+      Throwable t = e.getCause();
+      if (t instanceof IOException) {
+        throw (IOException) t;
+      }
+      else if (t instanceof ServletException) {
+        throw (ServletException) t;
+      }
+      else {
+        throw new ServletException(t);
+      }
+    }
+    assertEquals(true, accessGranted);
+  }
+
+  @Test
+  public void testKnoxAdminUsersInvalidButKnoxAdminGroupValid() throws ServletException, IOException,
+      URISyntaxException {
+
+    FilterConfig config = EasyMock.createNiceMock( FilterConfig.class );
+    EasyMock.expect(config.getInitParameter("knox.admin.users")).andReturn("adminuser");
+    EasyMock.expect(config.getInitParameter("knox.admin.groups")).andReturn("admingroup");
+    EasyMock.expect(config.getInitParameter("resource.role")).andReturn("KNOX");
+    EasyMock.expect(config.getInitParameter("knox.acl.mode")).andReturn("OR");
+    EasyMock.expect(config.getInitParameter("knox.acl")).andReturn("KNOX_ADMIN_USERS;KNOX_ADMIN_GROUPS,admin;*");
+    EasyMock.replay( config );
+
+    final HttpServletRequest request = EasyMock.createNiceMock( HttpServletRequest.class );
+    EasyMock.replay( request );
+
+    final HttpServletResponse response = EasyMock.createNiceMock( HttpServletResponse.class );
+    EasyMock.replay( response );
+
+    final FilterChain chain = new FilterChain() {
+      @Override
+      public void doFilter(ServletRequest request, ServletResponse response)
+          throws IOException, ServletException {
+      }
+    };
+    
+    filter.init(config);
+    
+    Subject subject = new Subject();
+    subject.getPrincipals().add(new PrimaryPrincipal("larry"));
+    subject.getPrincipals().add(new GroupPrincipal("users"));
+    subject.getPrincipals().add(new GroupPrincipal("admingroup"));
+    try {
+      Subject.doAs(
+        subject,
+        new PrivilegedExceptionAction<Object>() {
+          public Object run() throws Exception {
+            filter.doFilter(request, response, chain);
+            return null;
+          }
+        });
+    }
+    catch (PrivilegedActionException e) {
+      Throwable t = e.getCause();
+      if (t instanceof IOException) {
+        throw (IOException) t;
+      }
+      else if (t instanceof ServletException) {
+        throw (ServletException) t;
+      }
+      else {
+        throw new ServletException(t);
+      }
+    }
+    assertEquals(true, accessGranted);
+  }
+}
index 9ad0432..a6325b6 100644 (file)
@@ -243,6 +243,9 @@ public class GatewayConfigImpl extends Configuration implements GatewayConfig {
   static final String DEFAULT_DISCOVERY_ADDRESS = GATEWAY_CONFIG_FILE_PREFIX + ".discovery.default.address";
   static final String DEFAULT_DISCOVERY_CLUSTER = GATEWAY_CONFIG_FILE_PREFIX + ".discovery.default.cluster";
 
+  static final String KNOX_ADMIN_GROUPS = GATEWAY_CONFIG_FILE_PREFIX + ".knox.admin.groups";
+  static final String KNOX_ADMIN_USERS = GATEWAY_CONFIG_FILE_PREFIX + ".knox.admin.users";
+
   private static List<String> DEFAULT_GLOBAL_RULES_SERVICES;
 
 
@@ -1042,4 +1045,16 @@ public class GatewayConfigImpl extends Configuration implements GatewayConfig {
     return topologyNames;
   }
 
+  @Override
+  public String getKnoxAdminGroups() {
+    final String result = get(KNOX_ADMIN_GROUPS, null);
+    return result;
+  }
+
+  @Override
+  public String getKnoxAdminUsers() {
+    final String result = get(KNOX_ADMIN_USERS, null);
+    return result;
+  }
+
 }
index ab6a473..3423220 100644 (file)
@@ -389,4 +389,15 @@ public interface GatewayConfig {
    */
   List<String> getReadOnlyOverrideTopologyNames();
 
+  /**
+   * Get the comma separated list of group names that represent Knox Admin users
+   * @return
+   */
+  String getKnoxAdminGroups();
+
+  /**
+   * Get the comma separated list of user names that represent Knox Admin users
+   * @return
+   */
+  String getKnoxAdminUsers();
 }
index cb2de7f..cca0081 100644 (file)
@@ -693,4 +693,14 @@ public class GatewayTestConfig extends Configuration implements GatewayConfig {
     return readOnly;
   }
 
+  @Override
+  public String getKnoxAdminGroups() {
+    return null;
+  }
+
+  @Override
+  public String getKnoxAdminUsers() {
+    return null;
+  }
+
 }