Merge "Fix SubscribeServlet Vulnerabilities"
[dmaap/datarouter.git] / datarouter-prov / src / main / java / org / onap / dmaap / datarouter / provisioning / GroupServlet.java
1 /*******************************************************************************
2  * ============LICENSE_START==================================================
3  * * org.onap.dmaap
4  * * ===========================================================================
5  * * Copyright © 2017 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  * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
21  * *
22  ******************************************************************************/
23
24
25 package org.onap.dmaap.datarouter.provisioning;
26
27 import java.io.IOException;
28 import java.io.InvalidObjectException;
29
30 import javax.servlet.http.HttpServletRequest;
31 import javax.servlet.http.HttpServletResponse;
32
33 import org.json.JSONObject;
34 import org.onap.dmaap.datarouter.provisioning.beans.EventLogRecord;
35 import org.onap.dmaap.datarouter.provisioning.beans.Group;
36
37 import static org.onap.dmaap.datarouter.provisioning.utils.HttpServletUtils.sendResponseError;
38
39 /**
40  * This servlet handles provisioning for the <groups> which is generated by the provisioning
41  * server to handle the creation and inspection of groups for FEEDS and SUBSCRIPTIONS.
42  *
43  * @author Vikram Singh
44  * @version $Id$
45  * @version $Id: Group.java,v 1.0 2016/07/19
46  */
47 @SuppressWarnings("serial")
48 public class GroupServlet extends ProxyServlet {
49     /**
50      * DELETE on the <GRUPS> -- not supported.
51      */
52     @Override
53     public void doDelete(HttpServletRequest req, HttpServletResponse resp) {
54         String message = "DELETE not allowed for the GROUPS.";
55         EventLogRecord elr = new EventLogRecord(req);
56         elr.setMessage(message);
57         elr.setResult(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
58         eventlogger.info(elr);
59         sendResponseError(resp, HttpServletResponse.SC_METHOD_NOT_ALLOWED, message, eventlogger);
60     }
61     /**
62      * GET on the the list of groups to a feed/sub.
63      * See the <i>Groups Collection Query</i> section in the <b>Provisioning API</b>
64      * document for details on how this method should be invoked.
65      */
66     @Override
67     public void doGet(HttpServletRequest req, HttpServletResponse resp) {
68         EventLogRecord elr = new EventLogRecord(req);
69         String message = isAuthorizedForProvisioning(req);
70         if (message != null) {
71             elr.setMessage(message);
72             elr.setResult(HttpServletResponse.SC_FORBIDDEN);
73             eventlogger.info(elr);
74             sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
75             return;
76         }
77         if (isProxyServer()) {
78             try {
79                 super.doGet(req, resp);
80             } catch (IOException ioe) {
81                 eventlogger.error("IOException" + ioe.getMessage());
82             }
83             return;
84         }
85         String bhdr = req.getHeader(BEHALF_HEADER);
86         if (bhdr == null) {
87             message = "Missing "+BEHALF_HEADER+" header.";
88             elr.setMessage(message);
89             elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
90             eventlogger.info(elr);
91             sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
92             return;
93         }
94
95         // Check with the Authorizer
96         /*AuthorizationResponse aresp = authz.decide(req);
97         if (! aresp.isAuthorized()) {
98             message = "Policy Engine disallows access.";
99             elr.setMessage(message);
100             elr.setResult(HttpServletResponse.SC_FORBIDDEN);
101             eventlogger.info(elr);
102             resp.sendError(HttpServletResponse.SC_FORBIDDEN, message);
103             return;
104         }*/
105
106
107         /*ContentHeader ch = getContentHeader(req);
108         String ver = ch.getAttribute("version");
109         if (!ch.getType().equals(GROUPLIST_CONTENT_TYPE) || !(ver.equals("1.0") || ver.equals("2.0"))) {
110             intlogger.debug("Content-type is: "+req.getHeader("Content-Type"));
111             message = "Incorrect content-type";
112             elr.setMessage(message);
113             elr.setResult(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
114             eventlogger.info(elr);
115             resp.sendError(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE, message);
116             return;
117         }*/
118
119
120         int groupid = getIdFromPath(req);
121         if (groupid < 0) {
122             message = "Missing or bad group number.";
123             elr.setMessage(message);
124             elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
125             eventlogger.info(elr);
126             sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
127             return;
128         }
129
130         Group gup = Group.getGroupById(groupid);
131         // send response
132         elr.setResult(HttpServletResponse.SC_OK);
133         eventlogger.info(elr);
134         resp.setStatus(HttpServletResponse.SC_OK);
135         resp.setContentType(GROUPFULL_CONTENT_TYPE);
136         try {
137             resp.getOutputStream().print(gup.asJSONObject().toString());
138         } catch (IOException ioe) {
139             eventlogger.error("IOException" + ioe.getMessage());
140         }
141
142         // Display a list of Groups
143         /*Collection<Group> list = Group.getGroupById(groupid);
144         String t = JSONUtilities.createJSONArray(list);
145
146         // send response
147         elr.setResult(HttpServletResponse.SC_OK);
148         eventlogger.info(elr);
149         resp.setStatus(HttpServletResponse.SC_OK);
150         resp.setContentType(GROUPLIST_CONTENT_TYPE);
151         resp.getOutputStream().print(t);*/
152     }
153     /**
154      * PUT on the &lt;GROUPS&gt; -- not supported.
155      */
156     @Override
157     public void doPut(HttpServletRequest req, HttpServletResponse resp) {
158         EventLogRecord elr = new EventLogRecord(req);
159         String message = isAuthorizedForProvisioning(req);
160         if (message != null) {
161             elr.setMessage(message);
162             elr.setResult(HttpServletResponse.SC_FORBIDDEN);
163             eventlogger.info(elr);
164             sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
165             return;
166         }
167         if (isProxyServer()) {
168             try {
169                 super.doPut(req, resp);
170             } catch (IOException ioe) {
171                 eventlogger.error("IOException" + ioe.getMessage());
172             }
173             return;
174         }
175         String bhdr = req.getHeader(BEHALF_HEADER);
176         if (bhdr == null) {
177             message = "Missing "+BEHALF_HEADER+" header.";
178             elr.setMessage(message);
179             elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
180             eventlogger.info(elr);
181             sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
182             return;
183         }
184         int groupid = getIdFromPath(req);
185         if (groupid < 0) {
186             message = "Missing or bad groupid.";
187             elr.setMessage(message);
188             elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
189             eventlogger.info(elr);
190             sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
191             return;
192         }
193         Group oldgup = Group.getGroupById(groupid);
194         if (oldgup == null) {
195             message = "Missing or bad group number.";
196             elr.setMessage(message);
197             elr.setResult(HttpServletResponse.SC_NOT_FOUND);
198             eventlogger.info(elr);
199             sendResponseError(resp, HttpServletResponse.SC_NOT_FOUND, message, eventlogger);
200             return;
201         }
202         // Check with the Authorizer
203         /*AuthorizationResponse aresp = authz.decide(req);
204         if (! aresp.isAuthorized()) {
205             message = "Policy Engine disallows access.";
206             elr.setMessage(message);
207             elr.setResult(HttpServletResponse.SC_FORBIDDEN);
208             eventlogger.info(elr);
209             resp.sendError(HttpServletResponse.SC_FORBIDDEN, message);
210             return;
211         }*/
212         // check content type is SUB_CONTENT_TYPE, version 1.0
213         ContentHeader ch = getContentHeader(req);
214         String ver = ch.getAttribute("version");
215         if (!ch.getType().equals(GROUP_BASECONTENT_TYPE) || !(ver.equals("1.0") || ver.equals("2.0"))) {
216             message = "Incorrect content-type";
217             elr.setMessage(message);
218             elr.setResult(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
219             eventlogger.info(elr);
220             sendResponseError(resp, HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE, message, eventlogger);
221             return;
222         }
223         JSONObject jo = getJSONfromInput(req);
224         if (jo == null) {
225             message = "Badly formed JSON";
226             elr.setMessage(message);
227             elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
228             eventlogger.info(elr);
229             sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
230             return;
231         }
232         if (intlogger.isDebugEnabled())
233             intlogger.debug(jo.toString());
234         Group gup;
235         try {
236             gup = new Group(jo);
237         } catch (InvalidObjectException e) {
238             message = e.getMessage();
239             elr.setMessage(message);
240             elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
241             eventlogger.info(elr);
242             sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
243             return;
244         }
245         gup.setGroupid(oldgup.getGroupid());
246         Group gb2 = Group.getGroupMatching(gup, oldgup.getGroupid());
247         if (gb2 != null) {
248             eventlogger.warn("PROV0011 Creating a duplicate Group: "+gup.getName());
249             elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
250             sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, "Duplicate Group:"+gup.getName(), eventlogger);
251             return;
252         }
253
254         // Update Groups table entries
255         if (doUpdate(gup)) {
256             // send response
257             elr.setResult(HttpServletResponse.SC_OK);
258             eventlogger.info(elr);
259             resp.setStatus(HttpServletResponse.SC_OK);
260             resp.setContentType(GROUPFULL_CONTENT_TYPE);
261             try {
262                 resp.getOutputStream().print(gup.asJSONObject().toString());
263             } catch (IOException ioe) {
264                 eventlogger.error("IOException" + ioe.getMessage());
265             }
266             provisioningDataChanged();
267         } else {
268             // Something went wrong with the UPDATE
269             elr.setResult(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
270             eventlogger.info(elr);
271             sendResponseError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, DB_PROBLEM_MSG, eventlogger);
272         }
273     }
274     /**
275      * POST on the &lt;groups&gt; -- create a new GROUPS to a feed.
276      * See the <i>Creating a GROUPS</i> section in the <b>Provisioning API</b>
277      * document for details on how this method should be invoked.
278      */
279     @Override
280     public void doPost(HttpServletRequest req, HttpServletResponse resp) {
281         EventLogRecord elr = new EventLogRecord(req);
282         String message = isAuthorizedForProvisioning(req);
283         if (message != null) {
284             elr.setMessage(message);
285             elr.setResult(HttpServletResponse.SC_FORBIDDEN);
286             eventlogger.info(elr);
287             sendResponseError(resp, HttpServletResponse.SC_FORBIDDEN, message, eventlogger);
288             return;
289         }
290         if (isProxyServer()) {
291             try {
292                 super.doPost(req, resp);
293             } catch (IOException ioe) {
294                 eventlogger.error("IOException" + ioe.getMessage());
295             }
296             return;
297         }
298         String bhdr = req.getHeader(BEHALF_HEADER);
299         if (bhdr == null) {
300             message = "Missing "+BEHALF_HEADER+" header.";
301             elr.setMessage(message);
302             elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
303             eventlogger.info(elr);
304             sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
305             return;
306         }
307         /*int feedid = getIdFromPath(req);
308         if (feedid < 0) {
309             message = "Missing or bad feed number.";
310             elr.setMessage(message);
311             elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
312             eventlogger.info(elr);
313             resp.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
314             return;
315         }
316         Feed feed = Feed.getFeedById(feedid);
317         if (feed == null || feed.isDeleted()) {
318             message = "Missing or bad feed number.";
319             elr.setMessage(message);
320             elr.setResult(HttpServletResponse.SC_NOT_FOUND);
321             eventlogger.info(elr);
322             resp.sendError(HttpServletResponse.SC_NOT_FOUND, message);
323             return;
324         }*/
325         // Check with the Authorizer
326         /*AuthorizationResponse aresp = authz.decide(req);
327         if (! aresp.isAuthorized()) {
328             message = "Policy Engine disallows access.";
329             elr.setMessage(message);
330             elr.setResult(HttpServletResponse.SC_FORBIDDEN);
331             eventlogger.info(elr);
332             resp.sendError(HttpServletResponse.SC_FORBIDDEN, message);
333             return;
334         }*/
335
336         // check content type is SUB_CONTENT_TYPE, version 1.0
337         ContentHeader ch = getContentHeader(req);
338         String ver = ch.getAttribute("version");
339         if (!ch.getType().equals(GROUP_BASECONTENT_TYPE) || !(ver.equals("1.0") || ver.equals("2.0"))) {
340             intlogger.debug("Content-type is: "+req.getHeader("Content-Type"));
341             message = "Incorrect content-type";
342             elr.setMessage(message);
343             elr.setResult(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
344             eventlogger.info(elr);
345             sendResponseError(resp, HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE, message, eventlogger);
346             return;
347         }
348         JSONObject jo = getJSONfromInput(req);
349         if (jo == null) {
350             message = "Badly formed JSON";
351             elr.setMessage(message);
352             elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
353             eventlogger.info(elr);
354             sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
355             return;
356         }
357         if (intlogger.isDebugEnabled())
358             intlogger.debug(jo.toString());
359
360         Group gup;
361         try {
362             gup = new Group(jo);
363         } catch (InvalidObjectException e) {
364             message = e.getMessage();
365             elr.setMessage(message);
366             elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
367             eventlogger.info(elr);
368             sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, message, eventlogger);
369             return;
370         }
371         //gup.setFeedid(feedid);
372         //sub.setSubscriber(bhdr);    // set from X-ATT-DR-ON-BEHALF-OF header
373
374         // Check if this group already exists; not an error (yet), just warn
375         Group gb2 = Group.getGroupMatching(gup);
376         if (gb2 != null) {
377             eventlogger.warn("PROV0011 Creating a duplicate Group: "+gup.getName());
378             elr.setResult(HttpServletResponse.SC_BAD_REQUEST);
379             sendResponseError(resp, HttpServletResponse.SC_BAD_REQUEST, "Duplicate Group:"+gup.getName(), eventlogger);
380             return;
381         }
382
383
384         // Create GROUPS table entries
385         if (doInsert(gup)) {
386             // send response
387             elr.setResult(HttpServletResponse.SC_CREATED);
388             eventlogger.info(elr);
389             resp.setStatus(HttpServletResponse.SC_CREATED);
390             resp.setContentType(GROUPFULL_CONTENT_TYPE);
391             try {
392                 resp.getOutputStream().print(gup.asJSONObject().toString());
393             } catch (IOException ioe) {
394                 eventlogger.error("IOException" + ioe.getMessage());
395             }
396             provisioningDataChanged();
397         } else {
398             // Something went wrong with the INSERT
399             elr.setResult(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
400             eventlogger.info(elr);
401             sendResponseError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, DB_PROBLEM_MSG, eventlogger);
402         }
403     }
404 }