sonar code issues addressed
[oam/tr069-adapter.git] / acs / cpe / src / main / java / org / commscope / tr069adapter / acs / cpe / handler / DeviceValidator.java
1 /*\r
2  * ============LICENSE_START========================================================================\r
3  * ONAP : tr-069-adapter\r
4  * =================================================================================================\r
5  * Copyright (C) 2020 CommScope Inc Intellectual Property.\r
6  * =================================================================================================\r
7  * This tr-069-adapter software file is distributed by CommScope Inc under the Apache License,\r
8  * Version 2.0 (the "License"); you may not use this file except in compliance with the License. You\r
9  * may obtain a copy of the License at\r
10  *\r
11  * http://www.apache.org/licenses/LICENSE-2.0\r
12  *\r
13  * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\r
14  * either express or implied. See the License for the specific language governing permissions and\r
15  * limitations under the License.\r
16  * ===============LICENSE_END=======================================================================\r
17  */\r
18 \r
19 package org.commscope.tr069adapter.acs.cpe.handler;\r
20 \r
21 \r
22 import java.nio.charset.StandardCharsets;\r
23 import java.util.Base64;\r
24 \r
25 import org.commscope.tr069adapter.acs.common.dto.DeviceData;\r
26 import org.commscope.tr069adapter.acs.cpe.rpc.Inform;\r
27 import org.commscope.tr069adapter.acs.cpe.utils.FactorySrvcDependencyConfig;\r
28 import org.slf4j.Logger;\r
29 import org.slf4j.LoggerFactory;\r
30 import org.springframework.beans.factory.annotation.Autowired;\r
31 import org.springframework.beans.factory.annotation.Value;\r
32 import org.springframework.http.ResponseEntity;\r
33 import org.springframework.stereotype.Component;\r
34 import org.springframework.web.client.RestTemplate;\r
35 \r
36 @Component\r
37 public class DeviceValidator {\r
38 \r
39   private static final Logger logger = LoggerFactory.getLogger(DeviceValidator.class);\r
40 \r
41   @Autowired\r
42   FactorySrvcDependencyConfig factorySrvcDependencyConfig;\r
43 \r
44   @Autowired\r
45   RestTemplate restTemplate;\r
46 \r
47   @Value("${config.isDeviceAuthorizationEnabled:true}")\r
48   private boolean isDeviceAuthorizationEnabled;\r
49 \r
50   public void setFactorySrvcDependencyConfig(\r
51       FactorySrvcDependencyConfig factorySrvcDependencyConfig) {\r
52     this.factorySrvcDependencyConfig = factorySrvcDependencyConfig;\r
53   }\r
54 \r
55   /**\r
56    * @param inform\r
57    * @param authorization\r
58    * @return\r
59    */\r
60   public Boolean isDeviceAuthorized(Inform inform, String authorization) {\r
61     if(!isDeviceAuthorizationEnabled){\r
62       logger.debug("Device authentication is not needed here. Hence always authorizing.");\r
63       return true;\r
64     }\r
65     if (authorization == null) {\r
66       logger.debug("HTTP Challenge failed as Authorization header does not exist");\r
67       return false;\r
68     }\r
69 \r
70     Boolean isAuthorized = true;\r
71     if (authorization.toLowerCase().startsWith("basic")) {\r
72       isAuthorized = performBasicAuthentication(inform, authorization);\r
73     } else if (authorization.toLowerCase().startsWith("digest")) {\r
74       isAuthorized = performDigestAuthentication(inform, authorization);\r
75     }\r
76 \r
77     return isAuthorized;\r
78   }\r
79 \r
80   /**\r
81    * @param deviceId\r
82    * @param oui\r
83    * @param pc\r
84    * @return\r
85    */\r
86   public Boolean validateDevice(String deviceId, String oui, String pc) {\r
87     if (oui == null || pc == null) {\r
88       logger.error(\r
89           "OUI or Product Class cannot be null, Device has not sent the OUI or Product class in the Inform!");\r
90       return false;\r
91     }\r
92 \r
93     Boolean isValid = true;\r
94     try {\r
95       if (factorySrvcDependencyConfig.getDeviceValidationURL() == null) {\r
96         logger.debug(\r
97             "Device Validation URL is not configured, hence not performing device validation against factory data");\r
98         return isValid;\r
99       }\r
100 \r
101       DeviceData deviceData = new DeviceData();\r
102       deviceData.setSerialNumber(deviceId);\r
103       deviceData.setOui(oui);\r
104       deviceData.setProductClass(pc);\r
105       ResponseEntity<Boolean> restResponse = restTemplate.postForEntity(\r
106           factorySrvcDependencyConfig.getDeviceValidationURL(), deviceData, Boolean.class);\r
107       isValid = restResponse.getBody();\r
108       logger.debug("Is Device valid : {}", isValid);\r
109     } catch (Exception e) {\r
110       logger.error("An error occurred while validating the device with Factory data, Reason: {}",\r
111           e.getMessage());\r
112       isValid = false;\r
113     }\r
114 \r
115     return isValid;\r
116   }\r
117 \r
118   /**\r
119    * @param inform\r
120    * @param authorization\r
121    * @return\r
122    */\r
123   private Boolean performBasicAuthentication(Inform inform, String authorization) {\r
124     Boolean isAuthorized = false;\r
125     // Authorization: Basic base64credentials\r
126     String base64Credentials = authorization.substring("Basic".length()).trim();\r
127     logger.debug("Authorizing by basic authentication");\r
128     DeviceData deviceData = buildAuthorizationRequest(inform.getSn(), base64Credentials);\r
129 \r
130     logger.debug("Doing authentication from rest service: {}",\r
131         factorySrvcDependencyConfig.getBasicAuthorizationURL());\r
132     try {\r
133       if (factorySrvcDependencyConfig.getBasicAuthorizationURL() == null) {\r
134         logger.debug(\r
135             "Device Basic Authentication URL is not configured, hence not performing device authentication against factory data");\r
136         isAuthorized = true;\r
137       } else {\r
138         ResponseEntity<Boolean> restResponse = restTemplate.postForEntity(\r
139             factorySrvcDependencyConfig.getBasicAuthorizationURL(), deviceData, Boolean.class);\r
140         isAuthorized = restResponse.getBody();\r
141         if (isAuthorized.booleanValue()) {\r
142           logger.debug("Updating the username and password");\r
143           byte[] credDecoded = Base64.getDecoder().decode(base64Credentials);\r
144           String credentials = new String(credDecoded, StandardCharsets.UTF_8);\r
145           // credentials = username:password\r
146           final String[] values = credentials.split(":", 2);\r
147           inform.getParams().put(inform.getRoot() + ".ManagementServer.ConnectionRequestUsername",\r
148               values[0]);\r
149           inform.getParams().put(inform.getRoot() + ".ManagementServer.ConnectionRequestPassword",\r
150               values[1]);\r
151         }\r
152       }\r
153     } catch (Exception e) {\r
154       logger.error("Unable to authenticate the HTTP request, Reason: {}", e.getMessage());\r
155     }\r
156 \r
157     return isAuthorized;\r
158   }\r
159 \r
160   /**\r
161    * @param inform\r
162    * @param authorization\r
163    * @return\r
164    */\r
165   private Boolean performDigestAuthentication(Inform inform, String authorization) {\r
166     Boolean isAuthorized = false;\r
167     // Authorization: Basic base64credentials\r
168     String authenticationString = authorization.substring("Digest".length()).trim();\r
169     logger.debug("Authorizing by digest authentication");\r
170     DeviceData deviceData = buildAuthorizationRequest(inform.getSn(), authenticationString);\r
171 \r
172     logger.debug("Doing authentication from rest service: {}",\r
173         factorySrvcDependencyConfig.getDigestAuthorizationURL());\r
174     try {\r
175       if (factorySrvcDependencyConfig.getDigestAuthorizationURL() == null) {\r
176         logger.debug(\r
177             "Device Digest Authentication URL is not configured, hence not performing device authentication against factory data");\r
178         isAuthorized = true;\r
179       } else {\r
180         ResponseEntity<Boolean> restResponse = restTemplate.postForEntity(\r
181             factorySrvcDependencyConfig.getDigestAuthorizationURL(), deviceData, Boolean.class);\r
182         isAuthorized = restResponse.getBody();\r
183       }\r
184     } catch (Exception e) {\r
185       logger.error("Unable to authenticate the HTTP request, Reason: {}", e.getMessage());\r
186     }\r
187 \r
188     return isAuthorized;\r
189   }\r
190 \r
191   /**\r
192    * @param serialNumber\r
193    * @param base64Credentials\r
194    * @return\r
195    */\r
196   private DeviceData buildAuthorizationRequest(String serialNumber, String base64Credentials) {\r
197     DeviceData deviceData = new DeviceData();\r
198     deviceData.setSerialNumber(serialNumber);\r
199     deviceData.setAutenticationString(base64Credentials);\r
200     return deviceData;\r
201   }\r
202 }\r