5caeb50e6aa41fb24bc392f25ed2652c47ab3beb
[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 import java.nio.charset.StandardCharsets;\r
22 import java.util.Base64;\r
23 \r
24 import org.commscope.tr069adapter.acs.common.dto.DeviceData;\r
25 import org.commscope.tr069adapter.acs.cpe.rpc.Inform;\r
26 import org.commscope.tr069adapter.acs.cpe.utils.FactorySrvcDependencyConfig;\r
27 import org.slf4j.Logger;\r
28 import org.slf4j.LoggerFactory;\r
29 import org.springframework.beans.factory.annotation.Autowired;\r
30 import org.springframework.http.ResponseEntity;\r
31 import org.springframework.stereotype.Component;\r
32 import org.springframework.web.client.RestTemplate;\r
33 \r
34 @Component\r
35 public class DeviceValidator {\r
36 \r
37   private static final Logger logger = LoggerFactory.getLogger(DeviceValidator.class);\r
38 \r
39   @Autowired\r
40   FactorySrvcDependencyConfig factorySrvcDependencyConfig;\r
41 \r
42   @Autowired\r
43   RestTemplate restTemplate;\r
44 \r
45   public void setFactorySrvcDependencyConfig(\r
46       FactorySrvcDependencyConfig factorySrvcDependencyConfig) {\r
47     this.factorySrvcDependencyConfig = factorySrvcDependencyConfig;\r
48   }\r
49 \r
50   /**\r
51    * @param inform\r
52    * @param authorization\r
53    * @return\r
54    */\r
55   public Boolean isDeviceAuthorized(Inform inform, String authorization) {\r
56     if (authorization == null) {\r
57       logger.debug("HTTP Challenge failed as Authorization header does not exist");\r
58       return false;\r
59     }\r
60 \r
61     Boolean isAuthorized = true;\r
62     if (authorization.toLowerCase().startsWith("basic")) {\r
63       isAuthorized = performBasicAuthentication(inform, authorization);\r
64     } else if (authorization.toLowerCase().startsWith("digest")) {\r
65       isAuthorized = performDigestAuthentication(inform, authorization);\r
66     }\r
67 \r
68     return isAuthorized;\r
69   }\r
70 \r
71   /**\r
72    * @param deviceId\r
73    * @param oui\r
74    * @param pc\r
75    * @return\r
76    */\r
77   public Boolean validateDevice(String deviceId, String oui, String pc) {\r
78     if (oui == null || pc == null) {\r
79       logger.error(\r
80           "OUI or Product Class cannot be null, Device has not sent the OUI or Product class in the Inform!");\r
81       return false;\r
82     }\r
83 \r
84     Boolean isValid = true;\r
85     try {\r
86       if (factorySrvcDependencyConfig.getDeviceValidationURL() == null) {\r
87         logger.debug(\r
88             "Device Validation URL is not configured, hence not performing device validation against factory data");\r
89         return isValid;\r
90       }\r
91 \r
92       DeviceData deviceData = new DeviceData();\r
93       deviceData.setSerialNumber(deviceId);\r
94       deviceData.setOui(oui);\r
95       deviceData.setProductClass(pc);\r
96       ResponseEntity<Boolean> restResponse = restTemplate.postForEntity(\r
97           factorySrvcDependencyConfig.getDeviceValidationURL(), deviceData, Boolean.class);\r
98       isValid = restResponse.getBody();\r
99       logger.debug("Is Device valid : {}", isValid);\r
100     } catch (Exception e) {\r
101       logger.error("An error occurred while validating the device with Factory data, Reason: {}",\r
102           e.getMessage());\r
103       isValid = false;\r
104     }\r
105 \r
106     return isValid;\r
107   }\r
108 \r
109   /**\r
110    * @param inform\r
111    * @param authorization\r
112    * @return\r
113    */\r
114   private Boolean performBasicAuthentication(Inform inform, String authorization) {\r
115     Boolean isAuthorized = false;\r
116     // Authorization: Basic base64credentials\r
117     String base64Credentials = authorization.substring("Basic".length()).trim();\r
118     logger.debug("Authorizing by basic authentication");\r
119     DeviceData deviceData = buildAuthorizationRequest(inform.getSn(), base64Credentials);\r
120 \r
121     logger.debug("Doing authentication from rest service: {}",\r
122         factorySrvcDependencyConfig.getBasicAuthorizationURL());\r
123     try {\r
124       if (factorySrvcDependencyConfig.getBasicAuthorizationURL() == null) {\r
125         logger.debug(\r
126             "Device Basic Authentication URL is not configured, hence not performing device authentication against factory data");\r
127         isAuthorized = true;\r
128       } else {\r
129         ResponseEntity<Boolean> restResponse = restTemplate.postForEntity(\r
130             factorySrvcDependencyConfig.getBasicAuthorizationURL(), deviceData, Boolean.class);\r
131         isAuthorized = restResponse.getBody();\r
132         if (isAuthorized.booleanValue()) {\r
133           logger.debug("Updating the username and password");\r
134           byte[] credDecoded = Base64.getDecoder().decode(base64Credentials);\r
135           String credentials = new String(credDecoded, StandardCharsets.UTF_8);\r
136           // credentials = username:password\r
137           final String[] values = credentials.split(":", 2);\r
138           inform.getParams().put(inform.getRoot() + ".ManagementServer.ConnectionRequestUsername",\r
139               values[0]);\r
140           inform.getParams().put(inform.getRoot() + ".ManagementServer.ConnectionRequestPassword",\r
141               values[1]);\r
142         }\r
143       }\r
144     } catch (Exception e) {\r
145       logger.error("Unable to authenticate the HTTP request, Reason: {}", e.getMessage());\r
146     }\r
147 \r
148     return isAuthorized;\r
149   }\r
150 \r
151   /**\r
152    * @param inform\r
153    * @param authorization\r
154    * @return\r
155    */\r
156   private Boolean performDigestAuthentication(Inform inform, String authorization) {\r
157     Boolean isAuthorized = false;\r
158     // Authorization: Basic base64credentials\r
159     String authenticationString = authorization.substring("Digest".length()).trim();\r
160     logger.debug("Authorizing by digest authentication");\r
161     DeviceData deviceData = buildAuthorizationRequest(inform.getSn(), authenticationString);\r
162 \r
163     logger.debug("Doing authentication from rest service: {}",\r
164         factorySrvcDependencyConfig.getDigestAuthorizationURL());\r
165     try {\r
166       if (factorySrvcDependencyConfig.getDigestAuthorizationURL() == null) {\r
167         logger.debug(\r
168             "Device Digest Authentication URL is not configured, hence not performing device authentication against factory data");\r
169         isAuthorized = true;\r
170       } else {\r
171         ResponseEntity<Boolean> restResponse = restTemplate.postForEntity(\r
172             factorySrvcDependencyConfig.getDigestAuthorizationURL(), deviceData, Boolean.class);\r
173         isAuthorized = restResponse.getBody();\r
174       }\r
175     } catch (Exception e) {\r
176       logger.error("Unable to authenticate the HTTP request, Reason: {}", e.getMessage());\r
177     }\r
178 \r
179     return isAuthorized;\r
180   }\r
181 \r
182   /**\r
183    * @param serialNumber\r
184    * @param base64Credentials\r
185    * @return\r
186    */\r
187   private DeviceData buildAuthorizationRequest(String serialNumber, String base64Credentials) {\r
188     DeviceData deviceData = new DeviceData();\r
189     deviceData.setSerialNumber(serialNumber);\r
190     deviceData.setAutenticationString(base64Credentials);\r
191     return deviceData;\r
192   }\r
193 }\r