KNOX-3219 - New function in Virtual Group mapper to test request parameters (#1112)

diff --git a/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/VirtualGroupMapper.java b/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/VirtualGroupMapper.java
index 783835f..a3bc85e 100644
--- a/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/VirtualGroupMapper.java
+++ b/gateway-provider-identity-assertion-common/src/main/java/org/apache/knox/gateway/identityasserter/common/filter/VirtualGroupMapper.java
@@ -88,6 +88,8 @@
         if (req instanceof HttpServletRequest) {
             interpreter.addFunction("request-attribute", Arity.UNARY, params ->
                     ensureNotNull(req.getAttribute((String)params.get(0))));
+            interpreter.addFunction("request-parameter", Arity.UNARY, params ->
+                    ensureNotNull(req.getParameter((String)params.get(0))));
             interpreter.addFunction("request-header", Arity.UNARY, params ->
                     ensureNotNull(((HttpServletRequest) req).getHeader((String)params.get(0))));
             interpreter.addFunction("session", Arity.UNARY, params ->
diff --git a/gateway-provider-identity-assertion-common/src/test/java/org/apache/knox/gateway/identityasserter/common/filter/VirtualGroupMapperTest.java b/gateway-provider-identity-assertion-common/src/test/java/org/apache/knox/gateway/identityasserter/common/filter/VirtualGroupMapperTest.java
index 71bc83d..8227aeb 100644
--- a/gateway-provider-identity-assertion-common/src/test/java/org/apache/knox/gateway/identityasserter/common/filter/VirtualGroupMapperTest.java
+++ b/gateway-provider-identity-assertion-common/src/test/java/org/apache/knox/gateway/identityasserter/common/filter/VirtualGroupMapperTest.java
@@ -19,6 +19,7 @@
 
 import static java.util.Arrays.asList;
 import static java.util.Collections.emptyList;
+import static java.util.Collections.emptySet;
 import static java.util.Collections.singletonList;
 import static org.junit.Assert.assertEquals;
 
@@ -27,12 +28,17 @@
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Locale;
 import java.util.Set;
 
 import org.apache.knox.gateway.plang.AbstractSyntaxTree;
 import org.apache.knox.gateway.plang.Parser;
+import org.easymock.EasyMock;
 import org.junit.Test;
 
+import javax.servlet.ServletRequest;
+import javax.servlet.http.HttpServletRequest;
+
 @SuppressWarnings("PMD.NonStaticInitializer")
 public class VirtualGroupMapperTest {
     private Parser parser = new Parser();
@@ -117,8 +123,37 @@
         assertEquals(0, virtualGroups("user4", emptyList()).size());
     }
 
+    @Test
+    public void testRequestParameterContainsParam() {
+        testRequestParameter(true);
+    }
+
+    @Test
+    public void testRequestParameterNotContainsParam() {
+        testRequestParameter(false);
+    }
+
+    private void testRequestParameter(boolean containsParam) {
+        final String groupName = "non_rejected_request";
+        final String requestParamName = "impala.doas.user";
+        mapper = new VirtualGroupMapper(new HashMap<String, AbstractSyntaxTree>(){{
+            put(groupName, parser.parse(String.format(Locale.US, "(= (strlen (request-parameter '%s')) 0)", requestParamName)));
+        }});
+        final HttpServletRequest request = EasyMock.createNiceMock(HttpServletRequest.class);
+        if (containsParam) {
+            EasyMock.expect(request.getParameter(requestParamName)).andReturn("impala").anyTimes();
+        }
+        EasyMock.replay(request);
+        final Set<String> expectedGroups = containsParam ? emptySet() : setOf(groupName);
+        assertEquals(expectedGroups, virtualGroups("user1", emptyList(), request));
+    }
+
     private Set<String> virtualGroups(String user1, List<String> ldapGroups) {
-        return mapper.mapGroups(user1, new HashSet<>(ldapGroups), null);
+        return virtualGroups(user1, ldapGroups, null);
+    }
+
+    private Set<String> virtualGroups(String user1, List<String> ldapGroups, ServletRequest request) {
+        return mapper.mapGroups(user1, new HashSet<>(ldapGroups), request);
     }
 
     private static Set<String> setOf(String... strings) {
diff --git a/knox-site/docs/config_id_assertion.md b/knox-site/docs/config_id_assertion.md
index fa2381b..169b7ea 100644
--- a/knox-site/docs/config_id_assertion.md
+++ b/knox-site/docs/config_id_assertion.md
@@ -423,6 +423,17 @@
 Example
 
     (request-attribute 'sourceRequestUrl')
+
+###### request-parameter ######
+Returns the value of the specified request parameter as a String. If the given key doesn't exist empty string is returned.
+
+Number of arguments: 1
+
+    (request-parameter aString)
+
+Example
+
+    (request-parameter 'sample.request.param')
     
 ###### session ######