Add Servlet Samples 63/65263/1
authorInstrumental <jonathan.gathman@att.com>
Fri, 7 Sep 2018 16:41:35 +0000 (11:41 -0500)
committerInstrumental <jonathan.gathman@att.com>
Fri, 7 Sep 2018 16:41:44 +0000 (11:41 -0500)
Issue-ID: AAF-472
Change-Id: I69aae6509d65340942c4dee718b5dfe7726aab04
Signed-off-by: Instrumental <jonathan.gathman@att.com>
13 files changed:
cadi/pom.xml
cadi/servlet-sample/.gitignore [new file with mode: 0644]
cadi/servlet-sample/WEB-INF/.gitignore [new file with mode: 0644]
cadi/servlet-sample/WEB-INF/web.xml [new file with mode: 0644]
cadi/servlet-sample/build.sh [new file with mode: 0644]
cadi/servlet-sample/index.html [new file with mode: 0644]
cadi/servlet-sample/pom.xml [new file with mode: 0644]
cadi/servlet-sample/src/test/java/org/onap/aaf/sample/cadi/MyServlet.java [new file with mode: 0644]
cadi/servlet-sample/src/test/java/org/onap/aaf/sample/cadi/jetty/Config.java [new file with mode: 0644]
cadi/servlet-sample/src/test/java/org/onap/aaf/sample/cadi/jetty/JettyServletServer.java [new file with mode: 0644]
cadi/servlet-sample/src/test/java/org/onap/aaf/sample/cadi/jetty/JettyStandalone.java [new file with mode: 0644]
cadi/servlet-sample/src/test/java/org/onap/aaf/sample/cadi/jetty/MiniJASPIWrap.java [new file with mode: 0644]
cadi/servlet-sample/src/test/java/org/onap/aaf/sample/cadi/tomcate/TomcatEmbedded.java [new file with mode: 0644]

index 86c4b1f..191dcac 100644 (file)
                <module>client</module>
                <module>aaf</module>
                <module>oauth-enduser</module>
+               <module>servlet-sample</module>
        </modules>
 
 
diff --git a/cadi/servlet-sample/.gitignore b/cadi/servlet-sample/.gitignore
new file mode 100644 (file)
index 0000000..2c21dc6
--- /dev/null
@@ -0,0 +1,8 @@
+/target/
+/.settings/
+/META-INF/
+/.classpath
+/.project
+/logs/
+/run/
+/caditest.war
diff --git a/cadi/servlet-sample/WEB-INF/.gitignore b/cadi/servlet-sample/WEB-INF/.gitignore
new file mode 100644 (file)
index 0000000..8e4ce94
--- /dev/null
@@ -0,0 +1 @@
+classes/
diff --git a/cadi/servlet-sample/WEB-INF/web.xml b/cadi/servlet-sample/WEB-INF/web.xml
new file mode 100644 (file)
index 0000000..0b869fe
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<web-app xmlns="http://java.sun.com/xml/ns/javaee"
+   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+   version="2.5">
+     <servlet>
+         <servlet-name>MyServlet</servlet-name>
+         <servlet-class>org.onap.aaf.sample.cadi.MyServlet</servlet-class>
+     </servlet>
+     <servlet-mapping>
+         <servlet-name>MyServlet</servlet-name>
+         <url-pattern>/testme</url-pattern>
+     </servlet-mapping>
+     
+     <filter>
+       <filter-name>CADI</filter-name>
+       <filter-class>org.onap.aaf.cadi.filter.CadiFilter</filter-class>
+       <init-param>
+               <param-name>cadi_prop_files</param-name>
+               <param-value>/opt/app/osaafE/client/etc/org.osaaf.aaf.client.props</param-value>
+       </init-param>
+     </filter>
+       <filter-mapping>
+               <filter-name>CADI</filter-name>
+               <url-pattern>/*</url-pattern>
+       </filter-mapping>    
+</web-app>
+
diff --git a/cadi/servlet-sample/build.sh b/cadi/servlet-sample/build.sh
new file mode 100644 (file)
index 0000000..6880dbf
--- /dev/null
@@ -0,0 +1,4 @@
+#!/bin/bash
+rm -Rf WEB-INF/classes/*
+cp -Rf target/test-classes/* WEB-INF/classes
+jar -cvf caditest.war META-INF WEB-INF index.html
diff --git a/cadi/servlet-sample/index.html b/cadi/servlet-sample/index.html
new file mode 100644 (file)
index 0000000..926497a
--- /dev/null
@@ -0,0 +1,10 @@
+<html>
+  <header>
+       <title>CADI Test Page</title>
+  </header>
+  <body>
+       <h1>Welcome to the CADI Test Page</h1>
+       <p>This page is surrounded by a Tomcat Valve implementing CSP via TAF (CSSA) Framework</p>
+       Click <a href="testme">here</a> to test the protected Servlet
+  </body>
+</html>
\ No newline at end of file
diff --git a/cadi/servlet-sample/pom.xml b/cadi/servlet-sample/pom.xml
new file mode 100644 (file)
index 0000000..5711d44
--- /dev/null
@@ -0,0 +1,93 @@
+<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">
+       <parent>
+               <groupId>org.onap.aaf.authz</groupId>
+               <artifactId>cadiparent</artifactId>
+               <relativePath>..</relativePath>
+               <version>2.1.2-SNAPSHOT</version>
+       </parent>
+       <modelVersion>4.0.0</modelVersion>
+       <name>CADI Servlet Sample (Test Only)</name>
+       <artifactId>aaf-cadi-servlet-sample</artifactId>
+       <packaging>jar</packaging>
+       <properties>
+               <!--  Jetty Version set by oParent -->
+               <tomcat.version>8.5.23</tomcat.version>
+         </properties>
+
+       <dependencies>
+               <!-- needs to be first to avoid jar signer implications for servlet api  -->
+               <dependency>
+                       <groupId>org.eclipse.jetty</groupId>
+                       <artifactId>jetty-webapp</artifactId>
+                       <version>${project.jettyVersion}</version>
+               </dependency>
+
+               <dependency>
+               <groupId>org.apache.tomcat.embed</groupId>
+               <artifactId>tomcat-embed-jasper</artifactId>
+               <version>${tomcat.version}</version>
+           </dependency>
+            <dependency>
+               <groupId>org.apache.tomcat.embed</groupId>
+               <artifactId>tomcat-embed-core</artifactId>
+               <version>${tomcat.version}</version>
+           </dependency>
+           <dependency>
+               <groupId>org.apache.tomcat.embed</groupId>
+               <artifactId>tomcat-embed-jasper</artifactId>
+               <version>${tomcat.version}</version>
+           </dependency>
+           <dependency>
+               <groupId>org.apache.tomcat</groupId>
+               <artifactId>tomcat-jasper</artifactId>
+               <version>${tomcat.version}</version>
+           </dependency>
+           <dependency>
+               <groupId>org.apache.tomcat</groupId>
+               <artifactId>tomcat-jasper-el</artifactId>
+               <version>${tomcat.version}</version>
+           </dependency>
+           <dependency>
+               <groupId>org.apache.tomcat</groupId>
+               <artifactId>tomcat-jsp-api</artifactId>
+               <version>${tomcat.version}</version>
+           </dependency>
+
+               <dependency>
+                       <groupId>org.onap.aaf.authz</groupId>
+                       <artifactId>aaf-cadi-aaf</artifactId>
+                       <version>${project.version}</version>
+               </dependency>
+
+       </dependencies>
+       <build>
+               <pluginManagement>
+                       <plugins>
+                               <plugin>
+                                       <inherited>true</inherited>
+                                       <groupId>org.apache.maven.plugins</groupId>
+                                       <artifactId>maven-compiler-plugin</artifactId>
+                                       <version>3.1</version>
+                                       <configuration>
+                                               <source>1.7</source>
+                                               <target>1.7</target>
+                                       </configuration>
+                               </plugin>
+                               <plugin>
+                                       <groupId>org.apache.maven.plugins</groupId>
+                                       <version>2.4</version>
+                                       <artifactId>maven-jar-plugin</artifactId>
+                                       <configuration>
+                                               <outputDirectory>target</outputDirectory>
+                                               <archive>
+                                                       <manifestEntries>
+                                                               <Sealed>true</Sealed>
+                                                       </manifestEntries>
+                                               </archive>
+                                       </configuration>
+                               </plugin>
+                       </plugins>
+               </pluginManagement>
+       </build>
+</project>
diff --git a/cadi/servlet-sample/src/test/java/org/onap/aaf/sample/cadi/MyServlet.java b/cadi/servlet-sample/src/test/java/org/onap/aaf/sample/cadi/MyServlet.java
new file mode 100644 (file)
index 0000000..466c02d
--- /dev/null
@@ -0,0 +1,126 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.sample.cadi;
+
+import java.io.IOException;
+import java.security.Principal;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+
+import org.onap.aaf.cadi.aaf.v2_0.AAFCon;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.principal.TaggedPrincipal;
+
+// Uncomment if you utilized the "MiniJASPIWrap" in the Servlet setup in "main()", and want to protect your service via Permission or mapped role
+//     @RolesAllowed({"com.att.aaf.myPerm|myInstance|myAction"})
+       public class MyServlet implements Servlet {
+               private ServletConfig servletConfig;
+       
+               public void init(ServletConfig config) throws ServletException {
+                       servletConfig = config;
+               }
+       
+               public ServletConfig getServletConfig() {
+                       return servletConfig;
+               }
+       
+               public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
+                       HttpServletRequest request;
+                       try {
+                               request = (HttpServletRequest)req;
+                       } catch (ClassCastException e) {
+                               throw new ServletException("Only serving HTTP today",e);
+                       }
+                       
+                       res.getOutputStream().println("<html><header><title>CSP Servlet Test</title></header><body><h1>You're good to go!</h1><pre>" +
+                                       request.getUserPrincipal());
+                       
+                       String perm = request.getParameter("PERM");
+                       if(perm!=null) {
+                               if(request.isUserInRole(perm)) {
+                                       if(perm.indexOf('|')<0) { 
+                                               res.getOutputStream().println("\nCongrats!, You are in Role " + perm);
+                                       } else { 
+                                               res.getOutputStream().println("\nCongrats!, You have Permission " + perm);
+                                       }
+                               } else {
+                                       if(perm.indexOf('|')<0) { 
+                                               res.getOutputStream().println("\nSorry, you are NOT in Role " + perm);
+                                       } else {
+                                               res.getOutputStream().println("\nSorry, you do NOT have Permission " + perm);
+                                       }
+                               }
+                       }
+                       
+                       // You can get the working AAFCon from Trans
+                       AAFCon<?> aafcon = AAFCon.obtain(req);
+                       if(aafcon!=null) {
+                               try {
+                                       res.getOutputStream().println("----- Perms JSON from direct call -----");
+                                       final Principal up = request.getUserPrincipal();
+                                       TaggedPrincipal tp;
+                                       if(up instanceof TaggedPrincipal) {
+                                               tp = (TaggedPrincipal)up;
+                                       } else {
+                                               tp = new TaggedPrincipal() {
+                                                       @Override
+                                                       public String getName() {
+                                                               return up.getName();
+                                                       }
+
+                                                       @Override
+                                                       public String tag() {
+                                                               return "Unknown";
+                                                       }
+                                               };
+                                       }
+                                       // This call will be "as the user calling", but only if permission is set to trust.
+//                                     Future<String> future = aafcon.clientAs("2.0",tp).read("/authz/perms/user/"+request.getUserPrincipal().getName(),"application/Perms+json");
+                                       Future<String> future = aafcon.client("2.0").read("/authz/perms/user/"+request.getUserPrincipal().getName(),"application/Perms+json");
+                                       if(future.get(4000 /* timeout */)) {
+                                               res.getOutputStream().print(future.value);
+                                       } else {
+                                               System.err.println(future.code() + ", " + future.body());
+                                               res.getOutputStream().print(future.code() + ", " + future.body());
+                                       }
+                               } catch (Exception e) {
+                                       e.printStackTrace();
+                               }
+                       } else {
+                               res.getOutputStream().println("No AAFCon instantiated");
+                       }
+                       res.getOutputStream().print("</pre></body></html>");
+                       
+               }
+       
+               public String getServletInfo() {
+                       return "MyServlet";
+               }
+       
+               public void destroy() {
+               }
+       }
\ No newline at end of file
diff --git a/cadi/servlet-sample/src/test/java/org/onap/aaf/sample/cadi/jetty/Config.java b/cadi/servlet-sample/src/test/java/org/onap/aaf/sample/cadi/jetty/Config.java
new file mode 100644 (file)
index 0000000..17f9b19
--- /dev/null
@@ -0,0 +1,45 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.sample.cadi.jetty;
+
+import java.util.EnumSet;
+
+import javax.servlet.DispatcherType;
+
+import org.eclipse.jetty.webapp.WebAppContext;
+import org.onap.aaf.cadi.filter.CadiFilter;
+
+
+
+public class Config {
+       /**
+        * Method to make jetty configurations (others?) with more complex function possible
+        * 
+        * @param sc
+        */
+       public static final void addToContext(WebAppContext sc, String propFile) {
+               sc.addFilter(CadiFilter.class,"/*",EnumSet.of(DispatcherType.REQUEST));
+               sc.setInitParameter(org.onap.aaf.cadi.config.Config.CADI_PROP_FILES, propFile);
+       }
+       
+
+}
diff --git a/cadi/servlet-sample/src/test/java/org/onap/aaf/sample/cadi/jetty/JettyServletServer.java b/cadi/servlet-sample/src/test/java/org/onap/aaf/sample/cadi/jetty/JettyServletServer.java
new file mode 100644 (file)
index 0000000..2d1fc09
--- /dev/null
@@ -0,0 +1,112 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.sample.cadi.jetty;
+
+import java.net.Inet4Address;
+import java.util.concurrent.ArrayBlockingQueue;
+
+import javax.servlet.Servlet;
+
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.handler.ContextHandler;
+import org.eclipse.jetty.servlet.FilterHolder;
+import org.eclipse.jetty.servlet.FilterMapping;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.eclipse.jetty.util.thread.QueuedThreadPool;
+import org.onap.aaf.cadi.Access.Level;
+import org.onap.aaf.cadi.PropAccess;
+import org.onap.aaf.cadi.config.Config;
+import org.onap.aaf.cadi.config.SecurityInfo;
+import org.onap.aaf.cadi.filter.CadiFilter;
+
+public abstract class JettyServletServer implements Servlet {
+       
+       public static Server run(PropAccess access, String context, Class<? extends Servlet> servletCls, int port, String ...args) throws Exception {
+               // Defaults:
+               int blockingQueueSize = 10;
+        int corePoolSize = 10;
+        int maxPoolSize = 10;
+        int keepAliveTime  = 3000;
+               String hostname = access.getProperty(Config.HOSTNAME, null);
+               if(hostname==null) {
+                       hostname = Inet4Address.getLocalHost().getHostName();
+               }
+        
+        // Add your own Properties to override defaults
+
+        ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(blockingQueueSize);
+        QueuedThreadPool pool = new QueuedThreadPool(maxPoolSize,corePoolSize,keepAliveTime,queue);
+               Server server = new Server(pool);                       
+
+               String protocol;
+               if(access.getProperty(Config.CADI_KEYSTORE_PASSWORD,null)==null) {
+                       ServerConnector conn = new ServerConnector(server);
+                       conn.setHost(hostname);
+                       conn.setPort(port);
+                       server.addConnector(conn);
+                       protocol = "http";
+               } else {
+                       // Setup Security
+                       SecurityInfo securityInfo = new SecurityInfo(access);
+                       SslContextFactory scf = new SslContextFactory();
+                       scf.setSslContext(securityInfo.getSSLContext());
+                       scf.setWantClientAuth(true);
+                       ServerConnector sslConnector = new ServerConnector(server,scf); 
+               sslConnector.setHost(hostname);
+               sslConnector.setPort(port);
+               server.addConnector(sslConnector);
+                       protocol = "https";
+               }
+        
+        // Setup Sample Servlet
+        CadiFilter cf = new CadiFilter(true,access);
+               FilterHolder cfh = new FilterHolder(cf);
+               
+               ServletHandler shand = new ServletHandler();
+               shand.addFilterWithMapping(cfh, "/*", FilterMapping.ALL);
+               // To use normal Servlets, just add the class here... Actually, bug in Jetty... need to add with ServletHolder
+               ServletHolder sh = new ServletHolder();
+               sh.setServlet(servletCls.newInstance());
+               shand.addServletWithMapping(sh,"/*");
+               
+               // To use JASPI Authorization Style to protect the servlet, wrap the Servlet
+               // with the "MiniJSAPIWrap class, as shown here.  Then add "@RolesAllowed" on your 
+               // servlet (see sample).  Use Pipe delimited Permissions, not AAF Roles in the line
+               // shand.addServletWithMapping(new MiniJASPIWrap(MyServlet.class),"/*");
+               // call initialize after start
+               ContextHandler ch = new ServletContextHandler();
+               ch.setContextPath(context);
+               ch.setHandler(shand);
+               server.setHandler(ch);
+               // Startup the Server
+        server.setStopAtShutdown(true);
+        server.start();
+   
+        access.log(Level.INFO,"TestServlet is running at " + protocol + "://"+hostname+':'+port+context);
+        return server;
+       }
+
+}
diff --git a/cadi/servlet-sample/src/test/java/org/onap/aaf/sample/cadi/jetty/JettyStandalone.java b/cadi/servlet-sample/src/test/java/org/onap/aaf/sample/cadi/jetty/JettyStandalone.java
new file mode 100644 (file)
index 0000000..049e45e
--- /dev/null
@@ -0,0 +1,46 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.sample.cadi.jetty;
+
+import org.eclipse.jetty.server.Server;
+import org.onap.aaf.cadi.Access.Level;
+import org.onap.aaf.sample.cadi.MyServlet;
+import org.onap.aaf.cadi.PropAccess;
+
+
+
+
+public class JettyStandalone {
+       public static void main(String[] args) {
+               PropAccess access = new PropAccess(args);
+               try {
+                       Server server = JettyServletServer.run(access, "/caditest", MyServlet.class, 3456);
+               server.join();
+               } catch (Exception e) {
+                       access.log(Level.ERROR, e);
+               } finally {
+                       access.log(Level.INFO,"Stopping Service");
+               }
+               
+       }       
+
+}
diff --git a/cadi/servlet-sample/src/test/java/org/onap/aaf/sample/cadi/jetty/MiniJASPIWrap.java b/cadi/servlet-sample/src/test/java/org/onap/aaf/sample/cadi/jetty/MiniJASPIWrap.java
new file mode 100644 (file)
index 0000000..904f3cd
--- /dev/null
@@ -0,0 +1,101 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.sample.cadi.jetty;
+
+import java.io.IOException;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.UnavailableException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.onap.aaf.cadi.filter.RolesAllowed;
+
+
+
+/**
+ * MiniJASPIWrap
+ * 
+ * Support the ability to check JASPI Annotation Style Authorizations.
+ * 
+ * This can be a clean way to enforce API Authorization without mistakes in code.
+ * 
+ * @author JonathanGathman
+ *
+ */
+public class MiniJASPIWrap extends ServletHolder {
+       private RolesAllowed rolesAllowed;
+       //private String roles;
+       public MiniJASPIWrap(Class<? extends Servlet> servlet) {
+               super(servlet);
+               this.rolesAllowed = servlet.getAnnotation(RolesAllowed.class);
+               StringBuilder sb = new StringBuilder();
+               boolean first = true;
+               if(rolesAllowed!=null) {
+                       for(String str : rolesAllowed.value()) {
+                               if(first)first=false;
+                               else sb.append(',');
+                               sb.append(str);
+                       }
+               }
+               //roles = sb.toString();
+       }
+
+       /**
+        * handle
+        * 
+        * When utilized, this class authorizes the transaction by first calling the standard J2EE API call
+        * "isUserInRole" with the role(s) found in the class Annotations (JASPI Style) 
+        */
+       @Override
+       public void handle(Request baseRequest, ServletRequest request, ServletResponse response) throws ServletException,      UnavailableException, IOException {
+               if(rolesAllowed==null) {
+                       super.handle(baseRequest, request, response);
+               } else { // Validate
+                       try {
+                               
+                               HttpServletRequest hreq = (HttpServletRequest)request;
+                               boolean proceed = false;
+                               for(String role : rolesAllowed.value()) {
+                                       if(hreq.isUserInRole(role)) {
+                                               proceed = true;
+                                               break;
+                                       }
+                               }
+                               if(proceed) {
+                                       super.handle(baseRequest, request, response);
+                               } else {
+                                       //baseRequest.getServletContext().log(hreq.getUserPrincipal().getName()+" Refused " + roles);
+                                       ((HttpServletResponse)response).sendError(403); // forbidden
+                               }
+                       } catch(ClassCastException e) {
+                               throw new ServletException("JASPIWrap only supports HTTPServletRequest/HttpServletResponse");
+                       }
+               }               
+       }
+
+}
diff --git a/cadi/servlet-sample/src/test/java/org/onap/aaf/sample/cadi/tomcate/TomcatEmbedded.java b/cadi/servlet-sample/src/test/java/org/onap/aaf/sample/cadi/tomcate/TomcatEmbedded.java
new file mode 100644 (file)
index 0000000..415283a
--- /dev/null
@@ -0,0 +1,108 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed 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.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.sample.cadi.tomcate;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+
+import org.apache.catalina.Service;
+import org.apache.catalina.connector.Connector;
+import org.apache.catalina.startup.Tomcat;
+import org.apache.log4j.chainsaw.Main;
+import org.onap.aaf.cadi.Access;
+import org.onap.aaf.cadi.Access.Level;
+import org.onap.aaf.cadi.PropAccess;
+
+/** 
+ * @author JonathanGathman
+ *
+ */
+public class TomcatEmbedded {
+
+       public static void main(String[] args) throws Exception {
+        System.setProperty("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE", "true");
+        Tomcat tomcat = new Tomcat();
+        
+        Service service = tomcat.getService();
+        service.addConnector(getSslConnector(new PropAccess(args), 8081));
+        
+        tomcat.addWebapp("/caditest", getRootFolder().getAbsolutePath());
+        
+        tomcat.start();
+        tomcat.getServer().await();
+
+       }
+       
+    private static Connector getSslConnector(PropAccess access, int port) throws IOException {
+        Connector connector = new Connector();
+        connector.setPort(port);
+        connector.setSecure(true);
+        connector.setScheme("https");
+        setAttr(connector,access,"keyAlias","cadi_alias");
+        setAttr(connector,access,"keystoreFile","cadi_keystore");
+        connector.setAttribute("keystoreType", "PKCS12");
+        setAttr(connector,access,"keystorePass","cadi_keystore_password");
+        setAttr(connector,access,"truststoreFile","cadi_truststore");
+        connector.setAttribute("truststoreType", "JKS");
+        setAttr(connector,access,"truststorePass","cadi_truststore_password");
+        connector.setAttribute("clientAuth", "want");
+        connector.setAttribute("protocol", "HTTP/1.1");
+        connector.setAttribute("sslProtocol", "TLS");
+        connector.setAttribute("maxThreads", "200");
+        connector.setAttribute("protocol", "org.apache.coyote.http11.Http11AprProtocol");
+        connector.setAttribute("SSLEnabled", true);
+        return connector;
+     }
+    
+    private static void setAttr(Connector connector, Access access, String ctag, String atag) throws IOException {
+       String value = access.getProperty(atag, null);
+       if(value==null) {
+               access.log(Level.ERROR, atag, "is null");
+       } else {
+               if(value.startsWith("enc:")) {
+                       access.log(Level.INIT,atag,"=enc:************");
+                       value = access.decrypt(value, false);
+               } else {
+                       access.log(Level.INIT,atag,"=",value);
+               }
+               connector.setAttribute(ctag, value);
+       }
+    }
+
+       private static File getRootFolder() {
+           try {
+               File root;
+               String runningJarPath = Main.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath().replaceAll("\\\\", "/");
+               int lastIndexOf = runningJarPath.lastIndexOf("/target/");
+               if (lastIndexOf < 0) {
+                   root = new File("");
+               } else {
+                   root = new File(runningJarPath.substring(0, lastIndexOf));
+               }
+               System.out.println("application resolved root folder: " + root.getAbsolutePath());
+               return root;
+           } catch (URISyntaxException ex) {
+               throw new RuntimeException(ex);
+           }
+       }
+}