diff options
author | Michael Arrastia <MArrasti@amdocs.com> | 2018-06-08 10:40:54 +0100 |
---|---|---|
committer | Michael Arrastia <MArrasti@amdocs.com> | 2018-06-08 10:40:54 +0100 |
commit | fcf9451685f6de438a66b84189eba3a9b0db73a1 (patch) | |
tree | 92ca1992f6a4f1023cb3eeb7713e4b1731510307 /champ-service/src/main/java/org/onap | |
parent | 7eb81d52479e247050bee5968b2702030bf2c8c4 (diff) |
Add validation of request headers
Enforces presence of X-FromAppId and X-TransactionId headers
in REST requests.
Change-Id: I539e863049e4d5a985d9e952ee7dcbf3fd97f7b3
Issue-ID: AAI-1194
Signed-off-by: Michael Arrastia <MArrasti@amdocs.com>
Diffstat (limited to 'champ-service/src/main/java/org/onap')
-rw-r--r-- | champ-service/src/main/java/org/onap/champ/ChampRESTAPI.java | 42 | ||||
-rw-r--r-- | champ-service/src/main/java/org/onap/champ/util/HttpHeadersValidator.java | 48 |
2 files changed, 80 insertions, 10 deletions
diff --git a/champ-service/src/main/java/org/onap/champ/ChampRESTAPI.java b/champ-service/src/main/java/org/onap/champ/ChampRESTAPI.java index 726944b..b312af3 100644 --- a/champ-service/src/main/java/org/onap/champ/ChampRESTAPI.java +++ b/champ-service/src/main/java/org/onap/champ/ChampRESTAPI.java @@ -69,6 +69,7 @@ import org.onap.champ.service.logging.ChampMsgs; import org.onap.champ.service.logging.LoggingUtil; import org.onap.champ.util.ChampProperties; import org.onap.champ.util.ChampServiceConstants; +import org.onap.champ.util.HttpHeadersValidator; import org.onap.champ.util.etag.EtagGenerator; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -81,6 +82,7 @@ public class ChampRESTAPI { private ChampDataService champDataService; private EtagGenerator etagGenerator; + private HttpHeadersValidator httpHeadersValidator; private String TRANSACTION_METHOD = "method"; private Timer timer; @@ -108,6 +110,7 @@ public class ChampRESTAPI { mapper.registerModule(module); etagGenerator = new EtagGenerator(); + httpHeadersValidator = new HttpHeadersValidator(); } @GET @@ -130,6 +133,7 @@ public class ChampRESTAPI { ChampObject retrieved; try { + httpHeadersValidator.validateRequestHeaders(headers); ChampTransaction transaction = champDataService.getTransaction(tId); if (tId != null && transaction == null) { @@ -168,6 +172,7 @@ public class ChampRESTAPI { logger.info(ChampMsgs.INCOMING_REQUEST, tId, objectId); Response response = null; try { + httpHeadersValidator.validateRequestHeaders(headers); ChampTransaction transaction = champDataService.getTransaction(tId); if (tId != null && transaction == null) { @@ -201,6 +206,7 @@ public class ChampRESTAPI { logger.info(ChampMsgs.INCOMING_REQUEST, tId, champObj); Response response = null; try { + httpHeadersValidator.validateRequestHeaders(headers); ChampTransaction transaction = champDataService.getTransaction(tId); if (tId != null && transaction == null) { throw new ChampServiceException("transactionId not found", Status.BAD_REQUEST); @@ -240,6 +246,7 @@ public class ChampRESTAPI { Response response = null; try { + httpHeadersValidator.validateRequestHeaders(headers); ChampTransaction transaction = champDataService.getTransaction(tId); if (tId != null && transaction == null) { throw new ChampServiceException("transactionId not found", Status.BAD_REQUEST); @@ -277,6 +284,7 @@ public class ChampRESTAPI { Response response = null; ChampTransaction transaction = null; try { + httpHeadersValidator.validateRequestHeaders(headers); retrieved = champDataService.getRelationshipsByObject(oId, Optional.ofNullable(transaction)); EntityTag eTag = new EntityTag(etagGenerator.computeHashForChampRelationships(retrieved)); response = Response.status(Status.OK).entity(mapper.writeValueAsString(retrieved)).tag(eTag).build(); @@ -320,12 +328,12 @@ public class ChampRESTAPI { Response response = null; try { + httpHeadersValidator.validateRequestHeaders(headers); champObjects = champDataService.queryObjects(filter, properties); EntityTag eTag = new EntityTag(etagGenerator.computeHashForChampObjects(champObjects)); response = Response.status(Status.OK).type(MediaType.APPLICATION_JSON).tag(eTag).entity(mapper.writeValueAsString(champObjects)) .build(); } catch (JsonProcessingException e) { - e.printStackTrace(); response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); } catch (ChampServiceException e1) { response = Response.status(e1.getHttpStatus()).entity(e1.getMessage()).build(); @@ -350,6 +358,7 @@ public class ChampRESTAPI { ChampRelationship retrieved; Response response = null; try { + httpHeadersValidator.validateRequestHeaders(headers); ChampTransaction transaction = champDataService.getTransaction(tId); if (tId != null && transaction == null) { @@ -388,6 +397,7 @@ public class ChampRESTAPI { logger.info(ChampMsgs.INCOMING_REQUEST, tId, relationship); Response response = null; try { + httpHeadersValidator.validateRequestHeaders(headers); ChampTransaction transaction = champDataService.getTransaction(tId); if (tId != null && transaction == null) { throw new ChampServiceException("transactionId not found", Status.BAD_REQUEST); @@ -427,6 +437,7 @@ public class ChampRESTAPI { Response response = null; try { + httpHeadersValidator.validateRequestHeaders(headers); ChampTransaction transaction = champDataService.getTransaction(tId); if (tId != null && transaction == null) { throw new ChampServiceException("transactionId not found", Status.BAD_REQUEST); @@ -462,6 +473,7 @@ public class ChampRESTAPI { Response response = null; try { + httpHeadersValidator.validateRequestHeaders(headers); ChampTransaction transaction = champDataService.getTransaction(tId); if (tId != null && transaction == null) { throw new ChampServiceException("transactionId not found", Status.BAD_REQUEST); @@ -499,12 +511,12 @@ public class ChampRESTAPI { } Response response = null; try { + httpHeadersValidator.validateRequestHeaders(headers); champRelationshipList = champDataService.queryRelationships(filter); EntityTag eTag = new EntityTag(etagGenerator.computeHashForChampRelationships(champRelationshipList)); response = Response.status(Status.OK).type(MediaType.APPLICATION_JSON).tag(eTag).entity(mapper.writeValueAsString(champRelationshipList)) .build(); } catch (JsonProcessingException e) { - e.printStackTrace(); response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); } catch (ChampServiceException e1) { response = Response.status(e1.getHttpStatus()).entity(e1.getMessage()).build(); @@ -525,14 +537,19 @@ public class ChampRESTAPI { @Context HttpServletRequest req) { LoggingUtil.initMdcContext(req, headers); long startTimeInMs = System.currentTimeMillis(); - Status s; - String transaction = champDataService.openTransaction(); - - s = Status.OK; - Response response = Response.status(s).entity(transaction).build(); - logger.info(ChampMsgs.PROCESS_EVENT, "Opened Transaction with ID: " + transaction, s.toString()); - LoggingUtil.logRestRequest(logger, auditLogger, req, response); - metricsLogger.info(ChampMsgs.PROCESSED_REQUEST, "POST", Long.toString(System.currentTimeMillis() - startTimeInMs)); + Response response = null; + try { + httpHeadersValidator.validateRequestHeaders(headers); + String transaction = champDataService.openTransaction(); + Status s = Status.OK; + response = Response.status(s).entity(transaction).build(); + logger.info(ChampMsgs.PROCESS_EVENT, "Opened Transaction with ID: " + transaction, s.toString()); + } catch (ChampServiceException e) { + response = Response.status(e.getHttpStatus()).entity(e.getMessage()).build(); + } finally { + LoggingUtil.logRestRequest(logger, auditLogger, req, response); + metricsLogger.info(ChampMsgs.PROCESSED_REQUEST, "POST", Long.toString(System.currentTimeMillis() - startTimeInMs)); + } return response; } @@ -551,9 +568,12 @@ public class ChampRESTAPI { } try { + httpHeadersValidator.validateRequestHeaders(headers); response = Response.status(Status.OK).entity(mapper.writeValueAsString(tId + " is OPEN")).build(); } catch (JsonProcessingException e) { response = Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); + } catch (ChampServiceException e) { + response = Response.status(e.getHttpStatus()).entity(e.getMessage()).build(); } catch (Exception e) { response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build(); LoggingUtil.logInternalError(logger, e); @@ -576,6 +596,7 @@ public class ChampRESTAPI { Response response = null; try { + httpHeadersValidator.validateRequestHeaders(headers); JSONObject jsonObj = new JSONObject(t); String method = jsonObj.getString(this.TRANSACTION_METHOD); @@ -606,6 +627,7 @@ public class ChampRESTAPI { } return response; } + private boolean reservedKeyMatcher(Pattern p, String key) { Matcher m = p.matcher ( key ); if (m.matches()) { diff --git a/champ-service/src/main/java/org/onap/champ/util/HttpHeadersValidator.java b/champ-service/src/main/java/org/onap/champ/util/HttpHeadersValidator.java new file mode 100644 index 0000000..df85997 --- /dev/null +++ b/champ-service/src/main/java/org/onap/champ/util/HttpHeadersValidator.java @@ -0,0 +1,48 @@ +/** + * ============LICENSE_START========================================== + * org.onap.aai + * =================================================================== + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017-2018 Amdocs + * =================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + */ +package org.onap.champ.util; + +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.Response.Status; +import org.onap.champ.exception.ChampServiceException; + +public class HttpHeadersValidator { + + public void validateRequestHeaders(HttpHeaders headers) throws ChampServiceException { + String sourceOfTruth = null; + if (headers.getRequestHeaders().containsKey("X-FromAppId")) { + sourceOfTruth = headers.getRequestHeaders().getFirst("X-FromAppId"); + } + + if (sourceOfTruth == null || sourceOfTruth.trim() == "") { + throw new ChampServiceException("Invalid request, Missing X-FromAppId header", Status.BAD_REQUEST); + } + + String transId = null; + if (headers.getRequestHeaders().containsKey("X-TransactionId")) { + transId = headers.getRequestHeaders().getFirst("X-TransactionId"); + } + + if (transId == null || transId.trim() == "") { + throw new ChampServiceException("Invalid request, Missing X-TransactionId header", Status.BAD_REQUEST); + } + } +} |