diff options
author | Krzysztof Gajewski <krzysztof.gajewski@nokia.com> | 2021-02-15 14:07:44 +0100 |
---|---|---|
committer | Krzysztof Gajewski <krzysztof.gajewski@nokia.com> | 2021-02-23 21:22:22 +0100 |
commit | 6055339221e6e81d76c33c2b95ecc8798d378996 (patch) | |
tree | 3e8233070b69d6bb84cf352e8e99990bcb0de049 /datafile-app-server/src/main/java/org/onap/dcaegen2/collectors/datafile/service | |
parent | 103342b5bc72ec32e3c2f074ac251f43840ce443 (diff) |
Add JWT support in HTTP/HTTPS based locations1.5.4
Issue-ID: DCAEGEN2-2536
Signed-off-by: Krzysztof Gajewski <krzysztof.gajewski@nokia.com>
Change-Id: I47a928159853333014b0fd413a085b7c50eeb7a0
Diffstat (limited to 'datafile-app-server/src/main/java/org/onap/dcaegen2/collectors/datafile/service')
-rw-r--r-- | datafile-app-server/src/main/java/org/onap/dcaegen2/collectors/datafile/service/HttpUtils.java | 191 |
1 files changed, 188 insertions, 3 deletions
diff --git a/datafile-app-server/src/main/java/org/onap/dcaegen2/collectors/datafile/service/HttpUtils.java b/datafile-app-server/src/main/java/org/onap/dcaegen2/collectors/datafile/service/HttpUtils.java index e2c1e2ff..69bfcf47 100644 --- a/datafile-app-server/src/main/java/org/onap/dcaegen2/collectors/datafile/service/HttpUtils.java +++ b/datafile-app-server/src/main/java/org/onap/dcaegen2/collectors/datafile/service/HttpUtils.java @@ -1,7 +1,7 @@ /*- * ============LICENSE_START====================================================================== * Copyright (C) 2018-2019 Nordix Foundation. All rights reserved. - * Modifications Copyright (C) 2020 Nokia. All rights reserved + * Modifications Copyright (C) 2020-2021 Nokia. All rights reserved * =============================================================================================== * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,23 +19,208 @@ package org.onap.dcaegen2.collectors.datafile.service; +import org.apache.hc.core5.http.NameValuePair; import org.apache.http.HttpStatus; +import org.jetbrains.annotations.NotNull; +import org.onap.dcaegen2.collectors.datafile.commons.FileServerData; +import java.util.ArrayList; import java.util.Base64; +import java.util.List; +import java.util.Optional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public final class HttpUtils implements HttpStatus { + private static final Logger logger = LoggerFactory.getLogger(HttpUtils.class); public static final int HTTP_DEFAULT_PORT = 80; public static final int HTTPS_DEFAULT_PORT = 443; + public static final String JWT_TOKEN_NAME = "access_token"; + public static final String AUTH_JWT_WARN = "Both JWT token and Basic auth data present. Omitting basic auth info."; + public static final String AUTH_JWT_ERROR = "More than one JWT token present in the queryParameters. Omitting JWT token."; private HttpUtils() { } - public static boolean isSuccessfulResponseCode(Integer statusCode) { + @NotNull + public static String nonRetryableResponse(int responseCode) { + return "Unexpected response code - " + responseCode; + } + + @NotNull + public static String retryableResponse(int responseCode) { + return "Unexpected response code - " + responseCode + ". No retry attempts will be done."; + } + + public static boolean isSuccessfulResponseCodeWithDataRouter(Integer statusCode) { return statusCode >= 200 && statusCode < 300; } - public static String basicAuth(String username, String password) { + public static boolean isBasicAuthDataFilled(final FileServerData fileServerData) { + return !fileServerData.userId().isEmpty() && !fileServerData.password().isEmpty(); + } + + public static String basicAuthContent(String username, String password) { return "Basic " + Base64.getEncoder().encodeToString((username + ":" + password).getBytes()); } + + public static String jwtAuthContent(String token) { + return "Bearer " + token; + } + + /** + * Prepare uri to retrieve file from xNF using HTTP connection. If JWT token was included + * in the queryParameters, it is removed. Other entries are rewritten. + * + * @param fileServerData fileServerData including - server address, port, queryParameters and uriRawFragment + * @param remoteFile file which has to be downloaded + * @return uri String representing the xNF HTTP location + */ + @NotNull public static String prepareHttpUri(FileServerData fileServerData, String remoteFile){ + return prepareUri("http", fileServerData, remoteFile, HTTP_DEFAULT_PORT); + } + + /** + * Prepare uri to retrieve file from xNF using HTTPS connection. If JWT token was included + * in the queryParameters, it is removed. Other entries are rewritten. + * + * @param fileServerData fileServerData including - server address, port, queryParameters and uriRawFragment + * @param remoteFile file which has to be downloaded + * @return uri String representing the xNF HTTPS location + */ + @NotNull public static String prepareHttpsUri(FileServerData fileServerData, String remoteFile){ + return prepareUri("https", fileServerData, remoteFile, HTTPS_DEFAULT_PORT); + } + + /** + * Prepare uri to retrieve file from xNF. If JWT token was included + * in the queryParameters, it is removed. Other entries are rewritten. + * + * @param scheme scheme which is used during the connection + * @param fileServerData fileServerData including - server address, port, query and fragment + * @param remoteFile file which has to be downloaded + * @param defaultPort default port which exchange empty entry for given connection type + * @return uri String representing the xNF location + */ + @NotNull public static String prepareUri(String scheme, FileServerData fileServerData, String remoteFile, int defaultPort) { + int port = fileServerData.port().orElse(defaultPort); + String query = rewriteQueryWithoutToken(fileServerData.queryParameters().orElse(new ArrayList<>())); + String fragment = fileServerData.uriRawFragment().orElse(""); + if (!query.isEmpty()) { + query = "?" + query; + } + if (!fragment.isEmpty()) { + fragment = "#" + fragment; + } + return scheme + "://" + fileServerData.serverAddress() + ":" + port + remoteFile + query + fragment; + } + + /** + * Returns JWT token string (if single exist) from the queryParameters. + * + * @param fileServerData file server data which contain queryParameters where JWT token may exist + * @return JWT token value if single token entry exist or empty string elsewhere. + * If JWT token key has no value, empty string will be returned. + */ + public static String getJWTToken(FileServerData fileServerData) { + Optional<List<NameValuePair>> query = fileServerData.queryParameters(); + if (!query.isPresent()) { + return ""; + } + List<NameValuePair> queryParameters = query.get(); + if (queryParameters.isEmpty()) { + return ""; + } + boolean jwtTokenKeyPresent = HttpUtils.isQueryWithSingleJWT(queryParameters); + if (!jwtTokenKeyPresent) { + return ""; + } + String token = HttpUtils.getJWTToken(query.get()); + if (HttpUtils.isBasicAuthDataFilled(fileServerData)) { + logger.warn(HttpUtils.AUTH_JWT_WARN); + } + return token; + } + + /** + * Checks if the queryParameters contains single JWT token entry. Valid queryParameters + * contains only one token entry. + * + * @param query queryParameters + * @return true if queryParameters contains single token + */ + public static boolean isQueryWithSingleJWT(List<NameValuePair> query) { + if (query == null) { + return false; + } + int i = getJWTTokenCount(query); + if (i == 0) { + return false; + } + if (i > 1) { + logger.error(AUTH_JWT_ERROR); + return false; + } + return true; + } + + /** + * Returns the number of JWT token entries. Valid queryParameters contains only one token entry. + * + * @param queryElements elements of the queryParameters + * @return true if queryParameters contains single JWT token entry + */ + public static int getJWTTokenCount(List<NameValuePair> queryElements) { + int i = 0; + for (NameValuePair element : queryElements) { + if (element.getName().equals(JWT_TOKEN_NAME)) { + i++; + } + } + return i; + } + + private static String getJWTToken(List<NameValuePair> query) { + for (NameValuePair element : query) { + if (!element.getName().equals(JWT_TOKEN_NAME)) { + continue; + } + if (element.getValue() != null) { + return element.getValue(); + } + return ""; + } + return ""; + } + + /** + * Rewrites HTTP queryParameters without JWT token + * + * @param query list of NameValuePair of elements sent in the queryParameters + * @return String representation of queryParameters elements which were provided in the input + * Empty string is possible when queryParameters is empty or contains only access_token key. + */ + public static String rewriteQueryWithoutToken(List<NameValuePair> query) { + if (query.isEmpty()) { + return ""; + } + StringBuilder sb = new StringBuilder(); + for (NameValuePair nvp : query) { + if (nvp.getName().equals(JWT_TOKEN_NAME)) { + continue; + } + sb.append(nvp.getName()); + if (nvp.getValue() != null) { + sb.append("="); + sb.append(nvp.getValue()); + } + sb.append("&"); + } + if ((sb.length() > 0) && (sb.charAt(sb.length() - 1 ) == '&')) { + sb.deleteCharAt(sb.length() - 1 ); + } + return sb.toString(); + } } |