Remove logging passwords in clear text
[ccsdk/sli/plugins.git] / properties-node / provider / src / main / java / org / onap / ccsdk / sli / plugins / prop / PropertiesNode.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * openECOMP : SDN-C
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights
6  *                      reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.ccsdk.sli.plugins.prop;
23
24 import java.io.File;
25 import java.io.FileInputStream;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.util.HashSet;
29 import java.util.Map;
30 import java.util.Properties;
31 import java.util.Set;
32 import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
33 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
34 import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38 public class PropertiesNode implements SvcLogicJavaPlugin {
39
40     private static final Logger log = LoggerFactory.getLogger(PropertiesNode.class);
41
42     public void readProperties(Map<String, String> paramMap, SvcLogicContext ctx) throws SvcLogicException {
43         Parameters param = getParameters(paramMap);
44         Properties prop = new Properties();
45         try {
46             File file = new File(param.fileName);
47             try (InputStream in = new FileInputStream(file)) {
48                 Map<String, String> mm = null;
49                 String pfx = param.contextPrefix != null ? param.contextPrefix + '.' : "";
50                 if (param.fileBasedParsing) {
51                     byte[] data = new byte[(int) file.length()];
52                     if ("json".equalsIgnoreCase(getFileExtension(param.fileName))) {
53                         in.read(data);
54                         String str = new String(data, "UTF-8");
55                         mm = JsonParser.convertToProperties(str);
56                     } else if ("xml".equalsIgnoreCase(getFileExtension(param.fileName))) {
57                         in.read(data);
58                         String str = new String(data, "UTF-8");
59                         mm = XmlParser.convertToProperties(str, param.listNameList);
60                     } else {
61                         prop.load(in);
62                         for (Object key : prop.keySet()) {
63                             String name = (String) key;
64                             String value = prop.getProperty(name);
65                             if (value != null && value.trim().length() > 0) {
66                                 ctx.setAttribute(pfx + name, value.trim());
67                                 log.info("+++ " + pfx + name + ": [" + maskPassword(pfx + name, value) + "]");
68                             }
69                         }
70                     }
71                     if (mm != null) {
72                         for (Map.Entry<String, String> entry : mm.entrySet()) {
73                             ctx.setAttribute(pfx + entry.getKey(), entry.getValue());
74                             log.info("+++ " + pfx + entry.getKey() + ": ["
75                                     + maskPassword(pfx + entry.getKey(), entry.getValue()) + "]");
76                         }
77                     }
78                 } else {
79                     prop.load(in);
80                     for (Object key : prop.keySet()) {
81                         String name = (String) key;
82                         String value = prop.getProperty(name);
83                         if (value != null && value.trim().length() > 0) {
84                             ctx.setAttribute(pfx + name, value.trim());
85                             log.info("+++ " + pfx + name + ": [" + maskPassword(pfx + name, value) + "]");
86                         }
87                     }
88                 }
89             }
90         } catch (IOException e) {
91             throw new SvcLogicException("Cannot read property file: " + param.fileName + ": " + e.getMessage(), e);
92         }
93     }
94
95     /*
96      * Getting extension has to do the following "" --> "" "name" --> "" "name.txt" --> "txt"
97      * ".htpasswd" --> "" "name.with.many.dots.myext" --> "myext"
98      */
99     private static String getFileExtension(String fileName) {
100         if (fileName.lastIndexOf(".") != -1 && fileName.lastIndexOf(".") != 0) {
101             return fileName.substring(fileName.lastIndexOf(".") + 1);
102         } else {
103             return "";
104         }
105     }
106
107     protected Parameters getParameters(Map<String, String> paramMap) throws SvcLogicException {
108         Parameters p = new Parameters();
109         p.fileName = parseParam(paramMap, "fileName", true, null);
110         p.contextPrefix = parseParam(paramMap, "contextPrefix", false, null);
111         p.listNameList = getListNameList(paramMap);
112         String fileBasedParsingStr = paramMap.get("fileBasedParsing");
113         p.fileBasedParsing = "true".equalsIgnoreCase(fileBasedParsingStr);
114         return p;
115     }
116
117     protected Set<String> getListNameList(Map<String, String> paramMap) {
118         Set<String> ll = new HashSet<>();
119         for (Map.Entry<String, String> entry : paramMap.entrySet()) {
120             if (entry.getKey().startsWith("listName")) {
121                 ll.add(entry.getValue());
122             }
123         }
124         return ll;
125     }
126
127     private String parseParam(Map<String, String> paramMap, String name, boolean required, String def)
128             throws SvcLogicException {
129         String s = paramMap.get(name);
130
131         if (s == null || s.trim().length() == 0) {
132             if (!required) {
133                 return def;
134             }
135             throw new SvcLogicException("Parameter " + name + " is required in PropertiesNode");
136         }
137
138         s = s.trim();
139         String value = "";
140         int i = 0;
141         int i1 = s.indexOf('%');
142         while (i1 >= 0) {
143             int i2 = s.indexOf('%', i1 + 1);
144             if (i2 < 0) {
145                 throw new SvcLogicException("Cannot parse parameter " + name + ": " + s + ": no matching %");
146             }
147
148             String varName = s.substring(i1 + 1, i2);
149             String varValue = System.getenv(varName);
150             if (varValue == null) {
151                 varValue = "";
152             }
153
154             value += s.substring(i, i1);
155             value += varValue;
156
157             i = i2 + 1;
158             i1 = s.indexOf('%', i);
159         }
160         value += s.substring(i);
161
162         log.info("Parameter " + name + ": " + maskPassword(name, value));
163         return value;
164     }
165
166     private static Object maskPassword(String name, Object value) {
167         String[] pwdNames = {"pwd", "passwd", "password", "Pwd", "Passwd", "Password"};
168         for (String pwdName : pwdNames) {
169             if (name.contains(pwdName)) {
170                 return "**********";
171             }
172         }
173         return value;
174     }
175 }