[AAF-21] Initial code import
[aaf/cadi.git] / core / src / main / java / com / att / cadi / filter / PathFilter.java
1 /*******************************************************************************\r
2  * ============LICENSE_START====================================================\r
3  * * org.onap.aai\r
4  * * ===========================================================================\r
5  * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.\r
6  * * Copyright © 2017 Amdocs\r
7  * * ===========================================================================\r
8  * * Licensed under the Apache License, Version 2.0 (the "License");\r
9  * * you may not use this file except in compliance with the License.\r
10  * * You may obtain a copy of the License at\r
11  * * \r
12  *  *      http://www.apache.org/licenses/LICENSE-2.0\r
13  * * \r
14  *  * Unless required by applicable law or agreed to in writing, software\r
15  * * distributed under the License is distributed on an "AS IS" BASIS,\r
16  * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
17  * * See the License for the specific language governing permissions and\r
18  * * limitations under the License.\r
19  * * ============LICENSE_END====================================================\r
20  * *\r
21  * * ECOMP is a trademark and service mark of AT&T Intellectual Property.\r
22  * *\r
23  ******************************************************************************/\r
24 package com.att.cadi.filter;\r
25 \r
26 import java.io.IOException;\r
27 \r
28 import javax.servlet.Filter;\r
29 import javax.servlet.FilterChain;\r
30 import javax.servlet.FilterConfig;\r
31 import javax.servlet.ServletContext;\r
32 import javax.servlet.ServletException;\r
33 import javax.servlet.ServletRequest;\r
34 import javax.servlet.ServletResponse;\r
35 import javax.servlet.http.HttpServletRequest;\r
36 import javax.servlet.http.HttpServletResponse;\r
37 \r
38 import com.att.cadi.Access;\r
39 import com.att.cadi.Access.Level;\r
40 import com.att.cadi.config.Config;\r
41 \r
42 /**\r
43  * PathFilter\r
44  * \r
45  * This class implements Servlet Filter, and uses AAF to validate access to a Path.\r
46  * \r
47  * This class can be used in a standard J2EE Servlet manner.\r
48  *  \r
49  *\r
50  */\r
51 public class PathFilter implements Filter {\r
52         private ServletContext context;\r
53         private String aaf_type;\r
54         private String not_authorized_msg;\r
55         private final Log log;\r
56 \r
57         /**\r
58          * Construct a viable Filter for installing in Container WEB.XML, etc.\r
59          * \r
60          */\r
61         public PathFilter() {\r
62                 log = new Log() {\r
63                         public void info(String ... msg) {\r
64                                 context.log(build("INFO:",msg));\r
65                         }\r
66                         public void audit(String ... msg) {\r
67                                 context.log(build("AUDIT:",msg));\r
68                         }\r
69                         private String build(String type, String []msg) {\r
70                                 StringBuilder sb = new StringBuilder(type);\r
71                                 for(String s : msg) {\r
72                                         sb.append(' ');\r
73                                         sb.append(s);\r
74                                 }\r
75                                 return sb.toString();\r
76                         }\r
77                 \r
78                 };\r
79         }\r
80         \r
81         /**\r
82          * Filter that can be constructed within Java\r
83          * @param access\r
84          */\r
85         public PathFilter(final Access access) {\r
86                 log = new Log() {\r
87                         public void info(String ... msg) {\r
88                                 access.log(Level.INFO, (Object[])msg);\r
89                         }\r
90                         public void audit(String ... msg) {\r
91                                 access.log(Level.AUDIT, (Object[])msg);\r
92                         }\r
93                 };\r
94         }\r
95         \r
96         /**\r
97          * Init\r
98          * \r
99          * Standard Filter "init" call with FilterConfig to obtain properties.  POJOs can construct a\r
100          * FilterConfig with the mechanism of their choice, and standard J2EE Servlet engines utilize this\r
101          * mechanism already.\r
102          */\r
103         public void init(FilterConfig filterConfig) throws ServletException {\r
104                 // need the Context for Logging, instantiating ClassLoader, etc\r
105                 context = filterConfig.getServletContext();\r
106                 StringBuilder sb = new StringBuilder();\r
107                 StringBuilder err = new StringBuilder(); \r
108                 Object attr = context.getAttribute(Config.PATHFILTER_NS);\r
109                 if(attr==null) {\r
110                         err.append("PathFilter - pathfilter_ns is not set");\r
111                 } else {\r
112                         sb.append(attr.toString()); \r
113                 }\r
114 \r
115                 attr = context.getAttribute(Config.PATHFILTER_STACK);\r
116                 if(attr==null) {\r
117                         log.info("PathFilter - No pathfilter_stack set, ignoring");\r
118                 } else {\r
119                         sb.append('.');\r
120                         sb.append(attr.toString());\r
121                 }\r
122 \r
123                 attr = context.getAttribute(Config.PATHFILTER_URLPATTERN);\r
124                 if(attr==null) {\r
125                         log.info("PathFilter - No pathfilter_urlpattern set, defaulting to 'urlpattern'");\r
126                         sb.append(".urlpattern");\r
127                 } else {\r
128                         sb.append('.');\r
129                         sb.append(attr.toString());\r
130                 }\r
131 \r
132                 log.info("PathFilter - AAF Permission Type is",sb.toString());\r
133                 \r
134                 sb.append('|');\r
135                 \r
136                 aaf_type = sb.toString();\r
137 \r
138                 attr = context.getAttribute(Config.PATHFILTER_NOT_AUTHORIZED_MSG);\r
139                 if(attr==null) {\r
140                         not_authorized_msg = "Forbidden - Not Authorized to access this Path";\r
141                 } else {\r
142                         not_authorized_msg = attr.toString();\r
143                 }\r
144 \r
145                 if(err.length()>0) {\r
146                         throw new ServletException(err.toString());\r
147                 }\r
148         }\r
149 \r
150         private interface Log {\r
151                 public void info(String ... msg);\r
152                 public void audit(String ... msg);\r
153         }\r
154 \r
155         /**\r
156          * doFilter\r
157          * \r
158          * This is the standard J2EE invocation.  Analyze the request, modify response as necessary, and\r
159          * only call the next item in the filterChain if request is suitably Authenticated.\r
160          */\r
161         //TODO Always validate changes against Tomcat AbsCadiValve and Jaspi CadiSAM functions\r
162         public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {\r
163                 HttpServletRequest hreq = (HttpServletRequest)request;\r
164                 HttpServletResponse hresp = (HttpServletResponse)response;\r
165                 String perm = aaf_type+hreq.getPathInfo()+'|'+hreq.getMethod();\r
166                 if(hreq.isUserInRole(perm)) {\r
167                         chain.doFilter(request, response);\r
168                 } else {\r
169                         log.audit("PathFilter has denied",hreq.getUserPrincipal().getName(),"access to",perm);\r
170                         hresp.sendError(403,not_authorized_msg);\r
171                 }\r
172         }\r
173 \r
174         /**\r
175          * Containers call "destroy" when time to cleanup \r
176          */\r
177         public void destroy() {\r
178                 log.info("PathFilter destroyed.");\r
179         }\r
180 \r
181 \r
182 \r
183 }\r
184 \r