Fix Fortify Header Manipulation Issue
[policy/engine.git] / ONAP-PAP-REST / src / main / java / org / onap / policy / pap / xacml / rest / handler / DeleteHandler.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP-PAP-REST
4  * ================================================================================
5  * Copyright (C) 2017-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 package org.onap.policy.pap.xacml.rest.handler;
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.sql.Connection;
25 import java.sql.DriverManager;
26 import java.sql.ResultSet;
27 import java.sql.SQLException;
28 import java.sql.Statement;
29 import java.util.List;
30
31 import javax.persistence.EntityManager;
32 import javax.persistence.Query;
33 import javax.servlet.http.HttpServletRequest;
34 import javax.servlet.http.HttpServletResponse;
35
36 import org.onap.policy.common.logging.ONAPLoggingContext;
37 import org.onap.policy.common.logging.eelf.MessageCodes;
38 import org.onap.policy.common.logging.eelf.PolicyLogger;
39 import org.onap.policy.common.logging.flexlogger.FlexLogger;
40 import org.onap.policy.common.logging.flexlogger.Logger;
41 import org.onap.policy.pap.xacml.rest.XACMLPapServlet;
42 import org.onap.policy.pap.xacml.rest.components.PolicyDBDaoTransaction;
43 import org.onap.policy.pap.xacml.rest.elk.client.PolicyElasticSearchController;
44 import org.onap.policy.pap.xacml.rest.model.RemoveGroupPolicy;
45 import org.onap.policy.pap.xacml.rest.util.JPAUtils;
46 import org.onap.policy.rest.XACMLRestProperties;
47 import org.onap.policy.rest.adapter.PolicyRestAdapter;
48 import org.onap.policy.rest.jpa.PolicyEntity;
49 import org.onap.policy.rest.jpa.PolicyVersion;
50 import org.onap.policy.utils.PolicyUtils;
51 import org.onap.policy.xacml.api.XACMLErrorConstants;
52 import org.onap.policy.xacml.api.pap.OnapPDPGroup;
53 import org.onap.policy.xacml.std.pap.StdPAPPolicy;
54 import org.onap.policy.xacml.std.pap.StdPDPGroup;
55
56 import com.att.research.xacml.api.pap.PAPException;
57 import com.att.research.xacml.api.pap.PDPPolicy;
58 import com.att.research.xacml.util.XACMLProperties;
59
60 public class DeleteHandler {
61
62         private OnapPDPGroup newgroup;
63         private static Logger logger = FlexLogger.getLogger(DeleteHandler.class);
64         public static final String POLICY_IN_PDP = "PolicyInPDP";
65         public static final String ERROR = "error";
66         public static final String UNKNOWN = "unknown";
67         private static final String REGEX = "[0-9a-zA-Z._]*";
68
69         public void doAPIDeleteFromPAP(HttpServletRequest request, HttpServletResponse response) throws IOException, SQLException  {
70                 // get the request content into a String
71                 String json = null;
72                 java.util.Scanner scanner = new java.util.Scanner(request.getInputStream());
73                 scanner.useDelimiter("\\A");
74                 json =  scanner.hasNext() ? scanner.next() : "";
75                 scanner.close();
76                 PolicyLogger.info("JSON request from API to Delete Policy from the PAP: " + json);
77                 // convert Object sent as JSON into local object
78                 StdPAPPolicy policy = PolicyUtils.jsonStringToObject(json, StdPAPPolicy.class);
79                 String policyName = policy.getPolicyName();
80                 Boolean policyVersionDeleted = false;
81                 String removeXMLExtension;
82                 int currentVersion;
83                 String removeVersionExtension;
84                 String splitPolicyName = null;
85                 String[] split = null;
86                 String status = ERROR;
87                 PolicyEntity policyEntity = null;
88                 JPAUtils jpaUtils = null;
89
90                 String papDbDriver = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_DRIVER);
91                 String papDbUrl = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_URL);
92                 String papDbUser = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_USER);
93                 String papDbPassword = XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_DB_PASSWORD);
94                 Connection con = null;
95                 
96                 try {
97                         jpaUtils = JPAUtils.getJPAUtilsInstance(XACMLPapServlet.getEmf());
98                 } catch (Exception e) {
99                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", " Could not create JPAUtils instance on the PAP");
100                         response.addHeader(ERROR, "jpautils");
101                         response.addHeader("operation", "delete");
102                         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
103                         return;
104                 }
105                 if (jpaUtils.dbLockdownIgnoreErrors()) {
106                         PolicyLogger.warn("Policies are locked down");
107                         response.addHeader("operation", "delete");
108                         response.addHeader("lockdown", "true");
109                         response.setStatus(HttpServletResponse.SC_ACCEPTED);
110                         return;
111                 }
112                 EntityManager em = XACMLPapServlet.getEmf().createEntityManager();
113                 Query policyEntityQuery = null;
114                 try{
115                         if(policyName.endsWith(".xml")){
116                                 removeXMLExtension = policyName.replace(".xml", "");
117                                 currentVersion = Integer.parseInt(removeXMLExtension.substring(removeXMLExtension.lastIndexOf('.')+1));
118                                 removeVersionExtension = removeXMLExtension.substring(0, removeXMLExtension.lastIndexOf('.'));
119                                 boolean queryCheck = true;
120                                 if(policy.getDeleteCondition().equalsIgnoreCase("All Versions")){
121                                         if(policyName.contains("Config_")){
122                                                 splitPolicyName = removeVersionExtension.replace(".Config_", ":Config_");
123                                         }else if(policyName.contains("Action_")){
124                                                 splitPolicyName = removeVersionExtension.replace(".Action_", ":Action_");
125                                         }else if(policyName.contains("Decision_")){
126                                                 splitPolicyName = removeVersionExtension.replace(".Decision_", ":Decision_");
127                                         }
128                                         if(splitPolicyName != null){
129                                                 split = splitPolicyName.split(":");
130                                         }else{
131                                                 PolicyLogger.error(MessageCodes.ERROR_UNKNOWN + "Failed to delete the policy. Please, provide the valid policyname.");
132                                                 response.addHeader(ERROR, UNKNOWN);
133                                                 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
134                                                 return;
135                                         }
136                                         policyEntityQuery = em.createQuery("SELECT p FROM PolicyEntity p WHERE p.policyName LIKE :pName and p.scope=:pScope");
137                                 }else if(policy.getDeleteCondition().equalsIgnoreCase("Current Version")) {
138                                         if(policyName.contains("Config_")){
139                                                 splitPolicyName = policyName.replace(".Config_", ":Config_");
140                                         }else if(policyName.contains("Action_")){
141                                                 splitPolicyName = policyName.replace(".Action_", ":Action_");
142                                         }else if(policyName.contains("Decision_")){
143                                                 splitPolicyName = policyName.replace(".Decision_", ":Decision_");
144                                         }
145                                         split = splitPolicyName.split(":");
146                                         queryCheck = false;
147                                         policyEntityQuery = em.createQuery("SELECT p FROM PolicyEntity p WHERE p.policyName=:pName and p.scope=:pScope");
148                                 }
149                                 
150                                 if(queryCheck){
151                                         policyEntityQuery.setParameter("pName", "%"+split[1]+"%");
152                                 }else{
153                                         policyEntityQuery.setParameter("pName", split[1]);
154                                 }
155                                 
156                                 policyEntityQuery.setParameter("pScope", split[0]);
157                                 List<?> peResult = policyEntityQuery.getResultList();
158                                 if(!peResult.isEmpty()){
159                                         Query getPolicyVersion = em.createQuery("Select p from PolicyVersion p where p.policyName=:pname");
160                                         getPolicyVersion.setParameter("pname", removeVersionExtension.replace(".", File.separator));
161                                         List<?> pvResult = getPolicyVersion.getResultList();
162                                         PolicyVersion pVersion = (PolicyVersion) pvResult.get(0);
163                                         int newVersion = 0; 
164                                         em.getTransaction().begin();
165                                         Class.forName(papDbDriver);
166                                         con = DriverManager.getConnection(papDbUrl,papDbUser,papDbPassword);
167                                         
168                                         if(policy.getDeleteCondition().equalsIgnoreCase("All Versions")){
169                                                 boolean groupCheck = checkPolicyGroupEntity(con, peResult);
170                                                 if(!groupCheck){
171                                                         for(Object peData : peResult){
172                                                                 policyEntity = (PolicyEntity) peData;
173                                                                 status = deletePolicyEntityData(em, policyEntity);
174                                                         }
175                                                 }else{
176                                                         status = POLICY_IN_PDP;
177                                                 }
178                                                 if(status.equals(ERROR)){
179                                                         PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + "Exception Occured while deleting the Entity from Database.");
180                                                         response.addHeader(ERROR, UNKNOWN);
181                                                         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
182                                                         return;
183                                                 }else if(status.equals(POLICY_IN_PDP)){
184                                                         PolicyLogger.error(MessageCodes.GENERAL_WARNING + "Policy can't be deleted, it is active in PDP Groups.");
185                                                         response.addHeader(ERROR, POLICY_IN_PDP);
186                                                         response.setStatus(HttpServletResponse.SC_CONFLICT);
187                                                         return;
188                                                 }else{
189                                                         try{
190                                                                 policyVersionDeleted = true;
191                                                                 em.remove(pVersion);
192                                                         }catch(Exception e){
193                                                                 logger.error(e.getMessage(),e);
194                                                                 policyVersionDeleted = false;
195                                                         }
196                                                 }
197                                         }else if(policy.getDeleteCondition().equalsIgnoreCase("Current Version")){
198                                                 boolean groupCheck = checkPolicyGroupEntity(con, peResult);
199                                                 if(!groupCheck){
200                                                         policyEntity = (PolicyEntity) peResult.get(0);
201                                                         status = deletePolicyEntityData(em, policyEntity);
202                                                 }else{
203                                                         status = POLICY_IN_PDP;
204                                                 }
205                                                 
206                                                 if(ERROR.equals(status)){
207                                                         PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + "Exception Occured while deleting the Entity from Database.");
208                                                         response.addHeader(ERROR, UNKNOWN);
209                                                         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
210                                                         return;
211                                                 }else if(POLICY_IN_PDP.equals(status)){
212                                                         PolicyLogger.error(MessageCodes.GENERAL_WARNING + "Policy can't be deleted, it is active in PDP Groups.");
213                                                         response.addHeader(ERROR, POLICY_IN_PDP);
214                                                         response.setStatus(HttpServletResponse.SC_CONFLICT);
215                                                         return;
216                                                 }else{
217                                                         if(currentVersion > 1){
218                                                                 if(!peResult.isEmpty()){
219                                                                         for(Object object : peResult){
220                                                                                 policyEntity = (PolicyEntity) object;
221                                                                                 String policyEntityName = policyEntity.getPolicyName().replace(".xml", "");
222                                                                                 int policyEntityVersion = Integer.parseInt(policyEntityName.substring(policyEntityName.lastIndexOf('.')+1));
223                                                                                 if(policyEntityVersion > newVersion){
224                                                                                         newVersion = policyEntityVersion-1;
225                                                                                 }
226                                                                         }
227                                                                 }
228                                                                 pVersion.setActiveVersion(newVersion);
229                                                                 pVersion.setHigherVersion(newVersion);
230                                                                 try{
231                                                                         policyVersionDeleted = true;
232                                                                         em.persist(pVersion);
233                                                                 }catch(Exception e){
234                                                                         logger.error(e.getMessage(),e);
235                                                                         policyVersionDeleted = false;
236                                                                 }
237                                                         }else{
238                                                                 try{
239                                                                         policyVersionDeleted = true;
240                                                                         em.remove(pVersion);
241                                                                 }catch(Exception e){
242                                                                         logger.error(e.getMessage(),e);
243                                                                         policyVersionDeleted = false;
244                                                                 }
245                                                         }
246                                                 }
247                                         }
248                                 }else{
249                                         PolicyLogger.error(MessageCodes.ERROR_UNKNOWN + "Failed to delete the policy for an unknown reason.  Check the file system and other logs for further information.");
250                                         response.addHeader(ERROR, UNKNOWN);
251                                         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
252                                         return;
253                                 }
254                         }
255                         em.getTransaction().commit();
256                 }catch(Exception e){
257                         em.getTransaction().rollback();
258                         PolicyLogger.error(MessageCodes.EXCEPTION_ERROR, e, "XACMLPapServlet", " ERROR");
259                         response.addHeader(ERROR, "deleteDB");
260                         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
261                         return;
262                 } finally {
263                         em.close();
264                         if(con != null){
265                                 con.close();
266                         }
267                 }
268
269                 if (policyVersionDeleted) {
270                         response.setStatus(HttpServletResponse.SC_OK);
271                         response.addHeader("successMapKey", "success");
272                         response.addHeader("operation", "delete");
273                         return;                         
274                 } else {
275                         PolicyLogger.error(MessageCodes.ERROR_UNKNOWN + "Failed to delete the policy for an unknown reason.  Check the file system and other logs for further information.");
276                         response.addHeader(ERROR, UNKNOWN);
277                         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
278                         return;
279                 }
280         }
281         
282         public static String deletePolicyEntityData(EntityManager em, PolicyEntity policyEntity){
283                 PolicyElasticSearchController controller = new PolicyElasticSearchController();
284                 PolicyRestAdapter policyData = new PolicyRestAdapter();
285                 String policyName = policyEntity.getPolicyName();
286                 try{
287                         if(policyName.contains("Config_")){
288                                 em.remove(policyEntity.getConfigurationData());
289                         }else if(policyName.contains("Action_")){
290                                 em.remove(policyEntity.getActionBodyEntity());
291                         }
292                         String searchPolicyName = policyEntity.getScope() + "." + policyEntity.getPolicyName();
293                         policyData.setNewFileName(searchPolicyName);
294                         controller.deleteElk(policyData);
295                         em.remove(policyEntity);
296                 }catch(Exception e){
297                         logger.error(e.getMessage(),e);
298                         return ERROR;
299                 }
300                 return "success";
301         }
302         
303         public static boolean checkPolicyGroupEntity(Connection con, List<?> peResult) throws SQLException{
304                 for(Object peData : peResult){
305                         PolicyEntity policyEntity = (PolicyEntity) peData;
306                         try(Statement st = con.createStatement();
307                                         ResultSet rs = st.executeQuery("Select * from PolicyGroupEntity where policyid = '"+policyEntity.getPolicyId()+"'")){
308                                 boolean gEntityList = rs.next();
309                                 if(gEntityList){
310                                         return true;
311                                 }
312                         }
313                 }
314                 return false;
315         }
316
317         public void doAPIDeleteFromPDP(HttpServletRequest request, HttpServletResponse response, ONAPLoggingContext loggingContext) throws IOException {
318                 
319                 String policyName = request.getParameter("policyName");
320                 String groupId = request.getParameter("groupId");
321                 String responseString = null;
322                 
323                 if(groupId != null && !groupId.matches(REGEX) ){
324                         response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
325                         response.addHeader("error",ERROR);
326                         response.addHeader("message", "Group Id is not valid");
327                         return;
328                 }
329                                 
330                 PolicyLogger.info("JSON request from API to Delete Policy from the PDP: " + policyName);
331
332                 // for PUT operations the group may or may not need to exist before the operation can be done
333                 OnapPDPGroup group = null;
334                 try {
335                         group = XACMLPapServlet.getPAPEngine().getGroup(groupId);
336                 } catch (PAPException e) {
337                         PolicyLogger.error("Exception occured While PUT operation is performing for PDP Group"+e);
338                 }
339                 if (group == null) {
340                         String message = "Unknown groupId '" + groupId + "'.";
341                         PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " " + message);
342                         loggingContext.transactionEnded();
343                         PolicyLogger.audit("Transaction Failed - See Error.log");
344                         response.addHeader(ERROR, "UnknownGroup");
345                         response.addHeader("message", message);
346                         response.setStatus(HttpServletResponse.SC_NOT_FOUND);
347                         return;
348                 } else {
349                         loggingContext.setServiceName("API:PAP.deletPolicyFromPDPGroup");
350                         if (policyName.contains("xml")) {
351                                 PolicyLogger.debug("The full file name including the extension was provided for policyName.. continue.");
352                         } else {
353                                 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid policyName... "
354                                                 + "policyName must be the full name of the file to be deleted including version and extension";
355                                 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Invalid policyName... "
356                                                 + "policyName must be the full name of the file to be deleted including version and extension");
357                                 response.addHeader(ERROR, message);
358                         response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
359                                 return;
360                         }
361                         RemoveGroupPolicy removePolicy = new RemoveGroupPolicy((StdPDPGroup) group);
362                         PDPPolicy policy =  group.getPolicy(policyName);
363                         if (policy != null) {
364                                 
365                                 if ((policy.getId().contains("Config_MS_")) || (policy.getId().contains("BRMS_Param"))) {
366                                         if (preSafetyCheck(policy)) {
367                                                 PolicyLogger.debug("Precheck Successful.");
368                                         }
369                                 }
370                                 PolicyLogger.info("Preparing to remove policy from group: " + group.getId());
371                                 removePolicy.prepareToRemove(policy);
372                                 OnapPDPGroup updatedGroup = removePolicy.getUpdatedObject();
373                                 responseString = deletePolicyFromPDPGroup(updatedGroup, loggingContext);
374                         } else {
375                                 String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Policy does not exist on the PDP.";
376                                 PolicyLogger.error(message);
377                                 PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Policy does not exist on the PDP.");
378                                 response.addHeader(ERROR, message);
379                                 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
380                                 return;
381                         }                       
382                 }
383                 if (responseString.equals("success")) {
384                         loggingContext.transactionEnded();
385                         PolicyLogger.info("Policy successfully deleted!");
386                         PolicyLogger.audit("Policy successfully deleted!");
387                         response.setStatus(HttpServletResponse.SC_OK);
388                         response.addHeader("successMapKey", "success");
389                         response.addHeader("operation", "delete");
390                         return;         
391                 } else if (responseString.equals("No Group")) {
392                         String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Group update had bad input.";
393                         PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Group update had bad input.");
394                         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
395                         response.addHeader(ERROR, "groupUpdate");
396                         response.addHeader("message", message);
397                         return; 
398                 } else if (responseString.equals("DB Error")) {
399                         PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + " Error while updating group in the database");
400                         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
401                         response.addHeader(ERROR, "deleteDB");
402                         return;
403                 } else {
404                         PolicyLogger.error(MessageCodes.ERROR_UNKNOWN + " Failed to delete the policy for an unknown reason.  Check the file system and other logs for further information.");
405                         response.addHeader(ERROR, UNKNOWN);
406                         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
407                         return;
408                 }
409         }
410
411         private String deletePolicyFromPDPGroup (OnapPDPGroup group, ONAPLoggingContext loggingContext){
412                 PolicyDBDaoTransaction acPutTransaction = XACMLPapServlet.getDbDaoTransaction();
413                 String response = null;
414                 loggingContext.setServiceName("API:PAP.DeleteHandler");
415                 OnapPDPGroup existingGroup = null;
416                 try {
417                         existingGroup = XACMLPapServlet.getPAPEngine().getGroup(group.getId());
418                 } catch (PAPException e1) {
419                         PolicyLogger.error("Exception occured While Deleting Policy From PDP Group"+e1);
420                 }
421                 if (!(group instanceof StdPDPGroup) || existingGroup == null || !(group.getId().equals(existingGroup.getId()))) {
422                         String existingID = null;
423                         if(existingGroup != null){
424                                 existingID = existingGroup.getId();
425                         }
426                         PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + " Group update had bad input. id=" + existingID + " objectFromJSON="+group);
427                         loggingContext.transactionEnded();
428                         PolicyLogger.audit("Transaction Failed - See Error.log");
429                         response = "No Group";
430                         return response;
431                 }
432                 // The Path on the PAP side is not carried on the RESTful interface with the AC
433                 // (because it is local to the PAP)
434                 // so we need to fill that in before submitting the group for update
435                 ((StdPDPGroup)group).setDirectory(((StdPDPGroup)existingGroup).getDirectory());
436                 try{
437                         acPutTransaction.updateGroup(group, "XACMLPapServlet.doDelete");
438                 } catch(Exception e){
439                         PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "XACMLPapServlet", " Error while updating group in the database: "
440                                         +"group="+existingGroup.getId());
441                         response = "DB Error";
442                         return response;
443                 }
444                 try {
445                         XACMLPapServlet.getPAPEngine().updateGroup(group);
446                 } catch (PAPException e) {
447                         PolicyLogger.error("Exception occured While Updating PDP Groups"+e);
448                         response = "error in updateGroup method";
449                 }
450                 PolicyLogger.debug("Group '" + group.getId() + "' updated");
451                 acPutTransaction.commitTransaction();
452                 // Group changed, which might include changing the policies
453                 try {
454                         newgroup = existingGroup;
455                 }  catch (Exception e) {
456                         PolicyLogger.error("Exception occured in Group Change Method"+e);
457                         response = "error in groupChanged method";
458                 }
459                 if (response==null){
460                         response = "success";
461                         loggingContext.transactionEnded();
462                         PolicyLogger.audit("Policy successfully deleted!");
463                 }
464                 loggingContext.transactionEnded();
465                 PolicyLogger.audit("Transaction Ended");
466                 return response;
467         }
468         
469         public OnapPDPGroup getDeletedGroup(){
470                 return newgroup;
471         }
472         
473         public boolean preSafetyCheck(PDPPolicy policy) {
474                 return true;
475         }
476         
477         public static DeleteHandler getInstance() {
478                 try {
479                         Class<?> deleteHandler = Class.forName(XACMLProperties.getProperty("deletePolicy.impl.className", DeleteHandler.class.getName()));
480                         return (DeleteHandler) deleteHandler.newInstance(); 
481                 } catch (Exception e) {
482                         logger.error(e.getMessage(),e);
483                 }
484                 return null;
485         }
486
487 }