Initial Contribution

Signed-off-by: Vinay Vishal <vinay.vishal@oracle.com>
diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-custom/pom.xml b/appserver/tests/appserv-tests/devtests/security/soteria/app-custom/pom.xml
new file mode 100644
index 0000000..2103a8d
--- /dev/null
+++ b/appserver/tests/appserv-tests/devtests/security/soteria/app-custom/pom.xml
@@ -0,0 +1,47 @@
+<!--
+
+    Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved.
+
+    This program and the accompanying materials are made available under the
+    terms of the Eclipse Public License v. 2.0, which is available at
+    http://www.eclipse.org/legal/epl-2.0.
+
+    This Source Code may also be made available under the following Secondary
+    Licenses when the conditions for such availability set forth in the
+    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+    version 2 with the GNU Classpath Exception, which is available at
+    https://www.gnu.org/software/classpath/license.html.
+
+    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.glassfish.soteria.test</groupId>
+    <artifactId>soteria</artifactId>
+    <version>5.0.1-SNAPSHOT</version>
+  </parent>
+
+	<artifactId>app-custom</artifactId>
+	<packaging>war</packaging>
+	
+	<build>
+        <finalName>app-custom</finalName>
+	</build>
+    
+    <properties>
+        <failOnMissingWebXml>false</failOnMissingWebXml>
+    </properties>
+  <dependencies>
+    <dependency>
+      <groupId>org.glassfish.soteria.test</groupId>
+      <artifactId>common</artifactId>
+      <version>5.0.1-SNAPSHOT</version>
+      <scope>test</scope>
+      </dependency>
+  </dependencies>
+
+</project>
diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-custom/src/main/java/org/glassfish/soteria/test/ProtectedServlet.java b/appserver/tests/appserv-tests/devtests/security/soteria/app-custom/src/main/java/org/glassfish/soteria/test/ProtectedServlet.java
new file mode 100644
index 0000000..f7bfe5d
--- /dev/null
+++ b/appserver/tests/appserv-tests/devtests/security/soteria/app-custom/src/main/java/org/glassfish/soteria/test/ProtectedServlet.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.soteria.test;
+
+import java.io.IOException;
+
+import javax.inject.Inject;
+import javax.security.enterprise.SecurityContext;
+import javax.servlet.ServletException;
+import javax.servlet.annotation.HttpConstraint;
+import javax.servlet.annotation.ServletSecurity;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Test Servlet that prints out the name of the authenticated caller and whether
+ * this caller is in any of the roles {foo, bar, kaz}
+ * 
+ *
+ */
+@WebServlet("/protectedServlet")
+@ServletSecurity(@HttpConstraint(rolesAllowed = "foo"))
+public class ProtectedServlet extends HttpServlet {
+
+    private static final long serialVersionUID = 1L;
+    
+    @Inject
+    private SecurityContext securityContext;
+
+    @Override
+    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+
+        response.getWriter().write("This is a servlet \n");
+
+        String webName = null;
+        if (request.getUserPrincipal() != null) {
+            webName = request.getUserPrincipal().getName();
+        }
+
+        response.getWriter().write("web username: " + webName + "\n");
+
+        response.getWriter().write("web user has role \"foo\": " + request.isUserInRole("foo") + "\n");
+        response.getWriter().write("web user has role \"bar\": " + request.isUserInRole("bar") + "\n");
+        response.getWriter().write("web user has role \"kaz\": " + request.isUserInRole("kaz") + "\n");
+        
+        String contextName = null;
+        if (securityContext.getCallerPrincipal() != null) {
+            contextName = securityContext.getCallerPrincipal().getName();
+        }
+        
+        response.getWriter().write("context username: " + contextName + "\n");
+        
+        response.getWriter().write("context user has role \"foo\": " + securityContext.isCallerInRole("foo") + "\n");
+        response.getWriter().write("context user has role \"bar\": " + securityContext.isCallerInRole("bar") + "\n");
+        response.getWriter().write("context user has role \"kaz\": " + securityContext.isCallerInRole("kaz") + "\n");
+        
+        response.getWriter().write("has access " + securityContext.hasAccessToWebResource("/servlets"));
+        
+        
+    }
+
+}
diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-custom/src/main/java/org/glassfish/soteria/test/Servlet.java b/appserver/tests/appserv-tests/devtests/security/soteria/app-custom/src/main/java/org/glassfish/soteria/test/Servlet.java
new file mode 100644
index 0000000..375f477
--- /dev/null
+++ b/appserver/tests/appserv-tests/devtests/security/soteria/app-custom/src/main/java/org/glassfish/soteria/test/Servlet.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.soteria.test;
+
+import java.io.IOException;
+
+import javax.annotation.security.DeclareRoles;
+import javax.inject.Inject;
+import javax.security.enterprise.SecurityContext;
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.glassfish.soteria.SecurityContextImpl;
+
+/**
+ * Test Servlet that prints out the name of the authenticated caller and whether
+ * this caller is in any of the roles {foo, bar, kaz}
+ * 
+ *
+ */
+@DeclareRoles({ "foo", "bar", "kaz" })
+@WebServlet("/servlet")
+public class Servlet extends HttpServlet {
+
+    private static final long serialVersionUID = 1L;
+    
+    @Inject
+    private SecurityContext securityContext;
+
+    @Override
+    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+
+        response.getWriter().write("This is a servlet \n");
+
+        String webName = null;
+        if (request.getUserPrincipal() != null) {
+            webName = request.getUserPrincipal().getName();
+        }
+
+        response.getWriter().write("web username: " + webName + "\n");
+
+        response.getWriter().write("web user has role \"foo\": " + request.isUserInRole("foo") + "\n");
+        response.getWriter().write("web user has role \"bar\": " + request.isUserInRole("bar") + "\n");
+        response.getWriter().write("web user has role \"kaz\": " + request.isUserInRole("kaz") + "\n");
+        
+        String contextName = null;
+        if (securityContext.getCallerPrincipal() != null) {
+            contextName = securityContext.getCallerPrincipal().getName();
+        }
+        
+        response.getWriter().write("context username: " + contextName + "\n");
+        
+        response.getWriter().write("context user has role \"foo\": " + securityContext.isCallerInRole("foo") + "\n");
+        response.getWriter().write("context user has role \"bar\": " + securityContext.isCallerInRole("bar") + "\n");
+        response.getWriter().write("context user has role \"kaz\": " + securityContext.isCallerInRole("kaz") + "\n");
+        
+        response.getWriter().write("has access " + securityContext.hasAccessToWebResource("/protectedServlet") + "\n");
+        
+        response.getWriter().write("All declared roles of user " + ((SecurityContextImpl)securityContext).getAllDeclaredCallerRoles() + "\n");
+    }
+
+}
diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-custom/src/main/java/org/glassfish/soteria/test/TestAuthenticationMechanism.java b/appserver/tests/appserv-tests/devtests/security/soteria/app-custom/src/main/java/org/glassfish/soteria/test/TestAuthenticationMechanism.java
new file mode 100644
index 0000000..cae948f
--- /dev/null
+++ b/appserver/tests/appserv-tests/devtests/security/soteria/app-custom/src/main/java/org/glassfish/soteria/test/TestAuthenticationMechanism.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.soteria.test;
+
+import static javax.security.enterprise.identitystore.CredentialValidationResult.Status.VALID;
+
+import javax.enterprise.context.RequestScoped;
+import javax.inject.Inject;
+import javax.security.enterprise.AuthenticationStatus;
+import javax.security.enterprise.AuthenticationException;
+import javax.security.auth.message.AuthException;
+import javax.security.enterprise.authentication.mechanism.http.HttpAuthenticationMechanism;
+import javax.security.enterprise.authentication.mechanism.http.HttpMessageContext;
+import javax.security.enterprise.identitystore.CredentialValidationResult;
+import javax.security.enterprise.identitystore.IdentityStoreHandler;
+import javax.security.enterprise.credential.UsernamePasswordCredential;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+@RequestScoped
+public class TestAuthenticationMechanism implements HttpAuthenticationMechanism {
+    
+    @Inject
+    private IdentityStoreHandler identityStoreHandler;
+
+    @Override
+    public AuthenticationStatus validateRequest(HttpServletRequest request, HttpServletResponse response, HttpMessageContext httpMessageContext) throws AuthenticationException {
+
+    	// Get the (caller) name and password from the request
+        // NOTE: This is for the smallest possible example only. In practice
+        // putting the password in a request query parameter is highly
+        // insecure
+        String name = request.getParameter("name");
+        String password = request.getParameter("password");
+    	
+        if (name != null && password != null) {
+
+            // Delegate the {credentials in -> identity data out} function to
+            // the Identity Store
+            CredentialValidationResult result = identityStoreHandler.validate(
+                new UsernamePasswordCredential(name, password));
+
+            if (result.getStatus() == VALID) {
+                // Communicate the details of the authenticated user to the
+                // container. In many cases the underlying handler will just store the details 
+                // and the container will actually handle the login after we return from 
+                // this method.
+                return httpMessageContext.notifyContainerAboutLogin(
+                    result.getCallerPrincipal(), result.getCallerGroups());
+            } else {
+                return httpMessageContext.responseUnauthorized();
+            }
+        } 
+
+        return httpMessageContext.doNothing();
+    }
+    
+}
diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-custom/src/main/java/org/glassfish/soteria/test/TestIdentityStore.java b/appserver/tests/appserv-tests/devtests/security/soteria/app-custom/src/main/java/org/glassfish/soteria/test/TestIdentityStore.java
new file mode 100644
index 0000000..0200b04
--- /dev/null
+++ b/appserver/tests/appserv-tests/devtests/security/soteria/app-custom/src/main/java/org/glassfish/soteria/test/TestIdentityStore.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.soteria.test;
+
+import static java.util.Arrays.asList;
+import static javax.security.enterprise.identitystore.CredentialValidationResult.INVALID_RESULT;
+
+import java.util.HashSet;
+
+import javax.enterprise.context.RequestScoped;
+import javax.security.enterprise.identitystore.CredentialValidationResult;
+import javax.security.enterprise.identitystore.IdentityStore;
+import javax.security.enterprise.credential.UsernamePasswordCredential;
+
+@RequestScoped
+public class TestIdentityStore implements IdentityStore {
+
+    public CredentialValidationResult validate(UsernamePasswordCredential usernamePasswordCredential) {
+
+        if (usernamePasswordCredential.compareTo("reza", "secret1")) {
+            return new CredentialValidationResult("reza", new HashSet<>(asList("foo", "bar")));
+        }
+
+        return INVALID_RESULT;
+    }
+
+}
diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-custom/src/main/webapp/WEB-INF/beans.xml b/appserver/tests/appserv-tests/devtests/security/soteria/app-custom/src/main/webapp/WEB-INF/beans.xml
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/appserver/tests/appserv-tests/devtests/security/soteria/app-custom/src/main/webapp/WEB-INF/beans.xml
diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-custom/src/main/webapp/WEB-INF/web.xml b/appserver/tests/appserv-tests/devtests/security/soteria/app-custom/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..09fffb4
--- /dev/null
+++ b/appserver/tests/appserv-tests/devtests/security/soteria/app-custom/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved.
+
+    This program and the accompanying materials are made available under the
+    terms of the Eclipse Public License v. 2.0, which is available at
+    http://www.eclipse.org/legal/epl-2.0.
+
+    This Source Code may also be made available under the following Secondary
+    Licenses when the conditions for such availability set forth in the
+    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+    version 2 with the GNU Classpath Exception, which is available at
+    https://www.gnu.org/software/classpath/license.html.
+
+    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<web-app
+	xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
+	version="3.1"
+>
+
+	<!-- Security constraints and roles. -->
+
+	<security-constraint>
+		<web-resource-collection>
+			<web-resource-name>User pages</web-resource-name>
+			<url-pattern>/protectedServlet</url-pattern>
+		</web-resource-collection>
+		<auth-constraint>
+			<role-name>foo</role-name>
+		</auth-constraint>
+	</security-constraint>
+
+
+	<security-role>
+		<role-name>foo</role-name>
+	</security-role>
+
+</web-app>
diff --git a/appserver/tests/appserv-tests/devtests/security/soteria/app-custom/src/test/java/org/glassfish/soteria/test/AppCustomIT.java b/appserver/tests/appserv-tests/devtests/security/soteria/app-custom/src/test/java/org/glassfish/soteria/test/AppCustomIT.java
new file mode 100644
index 0000000..f48f1b8
--- /dev/null
+++ b/appserver/tests/appserv-tests/devtests/security/soteria/app-custom/src/test/java/org/glassfish/soteria/test/AppCustomIT.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.soteria.test;
+
+import static org.glassfish.soteria.test.Assert.*;
+import static org.glassfish.soteria.test.ShrinkWrap.mavenWar;
+
+import org.glassfish.soteria.test.ArquillianBase;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.Archive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.junit.Rule;
+import org.junit.AfterClass;
+import org.junit.rules.TestWatcher;
+
+import com.gargoylesoftware.htmlunit.DefaultCredentialsProvider;
+import com.gargoylesoftware.htmlunit.WebResponse;
+import com.sun.ejte.ccl.reporter.SimpleReporterAdapter;
+
+@RunWith(Arquillian.class)
+public class AppCustomIT extends ArquillianBase {
+    private static SimpleReporterAdapter stat =
+            new SimpleReporterAdapter("appserv-tests");
+    @Rule
+    public TestWatcher reportWatcher=new ReportWatcher(stat, "Security::soteria::AppCustom");
+
+    @AfterClass
+    public static void printSummary(){
+      stat.printSummary();
+    }
+   
+    @Deployment(testable = false)
+    public static Archive<?> createDeployment() {
+        return mavenWar();
+    }
+
+    @Test
+    public void testAuthenticated() {
+        assertDefaultAuthenticated(
+                responseFromServer("/servlet?name=reza&password=secret1"));
+    }
+    
+    @Test
+    public void testNotAuthenticated() {
+        assertDefaultNotAuthenticatedUnprotected(
+                responseFromServer("/servlet"));
+    }
+    
+    @Test
+    public void testNotAuthenticatedWrongName() {
+        assertDefaultNotAuthenticated(
+                responseFromServer("/servlet?name=romo&password=secret1"));
+    }
+    
+    @Test
+    public void testNotAuthenticatedWrongPassword() {
+        assertDefaultNotAuthenticated(
+                responseFromServer("/servlet?name=reza&password=wrongpassword"));
+    }
+
+}