09a81c381e5fbba88ba40fdd00fb82ac000a8e7b
[ccsdk/features.git] /
1 /*
2  * ============LICENSE_START=======================================================
3  * ONAP : ccsdk features
4  * ================================================================================
5  * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property.
6  * All rights 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.features.sdnr.wt.dataprovider.http;
23
24 import java.io.IOException;
25 import java.nio.charset.StandardCharsets;
26 import java.util.Base64;
27 import java.util.regex.Matcher;
28 import java.util.regex.Pattern;
29 import javax.servlet.ServletException;
30 import javax.servlet.http.HttpServlet;
31 import javax.servlet.http.HttpServletRequest;
32 import javax.servlet.http.HttpServletResponse;
33 import org.json.JSONObject;
34 import org.onap.ccsdk.features.sdnr.wt.common.http.BaseHTTPClient;
35 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.HtUserdataManager;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 public class UserdataHttpServlet extends HttpServlet {
40
41     private static final long serialVersionUID = 1L;
42     private static final Logger LOG = LoggerFactory.getLogger(UserdataHttpServlet.class);
43     private static final String REGEX = "^\\/userdata[\\/]?([a-zA-Z0-9]+)?$";
44     private static final Pattern PATTERN = Pattern.compile(REGEX);
45     private static final String JWT_PAYLOAD_USERNAME_PROPERTYKEY = "sub";
46     private HtUserdataManager dbUserManager;
47
48     @Override
49     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
50         final String uri = req.getRequestURI();
51         final Matcher matcher = PATTERN.matcher(uri);
52         if (matcher.find()) {
53             LOG.info("GET found match");
54             this.handleGetRequest(req, resp, matcher.groupCount() > 0 ? matcher.group(1) : null);
55         } else {
56             LOG.info("no valid request");
57             super.doGet(req, resp);
58         }
59     }
60
61     @Override
62     protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
63         final String uri = req.getRequestURI();
64         final Matcher matcher = PATTERN.matcher(uri);
65         if (matcher.find()) {
66             LOG.info("PUT found match");
67             final String payload = getPayload(req);
68             this.handlePutRequest(req, resp, payload, matcher.groupCount() > 0 ? matcher.group(1) : null);
69         } else {
70             LOG.info("no valid request");
71             super.doPut(req, resp);
72         }
73     }
74
75     private String getPayload(HttpServletRequest req) throws IOException {
76         return DataTreeHttpServlet.readPayload(req);
77     }
78
79     @Override
80     protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
81         final String uri = req.getRequestURI();
82         final Matcher matcher = PATTERN.matcher(uri);
83         if (matcher.find()) {
84             LOG.info("DELETE found match");
85             this.handleDeleteRequest(req, resp, matcher.groupCount() > 0 ? matcher.group(1) : null);
86         } else {
87             LOG.info("no valid request");
88             super.doPut(req, resp);
89         }
90     }
91
92     private void handleGetRequest(HttpServletRequest req, HttpServletResponse resp, String key) {
93         final String username = this.getUsername(req);
94         if(username==null) {
95             resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
96             return;
97         }
98         sendJsonResponse(resp,
99                 key == null ? this.dbUserManager.getUserdata(username) : this.dbUserManager.getUserdata(username, key));
100     }
101
102
103     private void handlePutRequest(HttpServletRequest req, HttpServletResponse resp, String data, String key) {
104         final String username = this.getUsername(req);
105         if(username==null) {
106             resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
107             return;
108         }
109         boolean success = key == null ? this.dbUserManager.setUserdata(username, data)
110                 : this.dbUserManager.setUserdata(username, key, data);
111         resp.setStatus(success ? HttpServletResponse.SC_OK : HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
112     }
113
114     private void handleDeleteRequest(HttpServletRequest req, HttpServletResponse resp, String key) {
115         final String username = this.getUsername(req);
116         if(username==null) {
117             resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
118             return;
119         }
120         boolean success = key == null ? this.dbUserManager.removeUserdata(username)
121                 : this.dbUserManager.removeUserdata(username, key);
122         resp.setStatus(success ? HttpServletResponse.SC_OK : HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
123     }
124
125     private String getUsername(HttpServletRequest req) {
126         final String authHeader = req.getHeader("Authorization");
127         if(authHeader==null) {
128             return null;
129         }
130         String username = null;
131         if(authHeader.startsWith("Basic")) {
132             username = BaseHTTPClient.decodeBasicAuthHeaderUsername(authHeader);
133         }
134         else if(authHeader.startsWith("Bearer")) {
135             username = decodeJWTPayloadUsername(authHeader, JWT_PAYLOAD_USERNAME_PROPERTYKEY);
136         }
137         return username;
138     }
139
140     public static String decodeJWTPayloadUsername(String authHeader, String key) {
141         String username = null;
142         if(authHeader.startsWith("Bearer")) {
143             authHeader = authHeader.substring(7);
144         }
145         String[] tmp = authHeader.split("\\.");
146         if(tmp.length==3) {
147             final String decoded = new String(Base64.getDecoder().decode(tmp[1]));
148             JSONObject o  = new JSONObject(decoded);
149             if(o.has(key)) {
150                 username = o.getString(key);
151                 if(username!=null && username.contains("@")) {
152                     username = username.split("@")[0];
153                 }
154             }
155         }
156         return username;
157     }
158
159     private static void sendJsonResponse(HttpServletResponse resp, String userdata) {
160         resp.setContentType("application/json");
161         resp.setStatus(HttpServletResponse.SC_OK);
162         try {
163
164             resp.getOutputStream().write(userdata.getBytes(StandardCharsets.UTF_8));
165         } catch (IOException e) {
166             LOG.warn("problem sending response: ", e);
167         }
168
169     }
170
171     public void setDatabaseClient(HtUserdataManager dbUserManager) {
172         this.dbUserManager = dbUserManager;
173     }
174
175 }