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