diff options
author | 2018-10-24 23:42:28 +0200 | |
---|---|---|
committer | 2019-03-13 16:02:01 -0400 | |
commit | 66309b15a0c1c458e2feb22db3bd3d4c13bd1a64 (patch) | |
tree | bd70ea29725249a01b06536153d4012eb86d4ba3 /aai-traversal/src/main/java/org/onap | |
parent | 41dbe0955bbae67c54bbc5ed651384e5d951799b (diff) |
Fix of reading payload in request and response
Reading the request response payload leads to an exception, adding a buffer class which enables multiple reads. Also adding logging of AAF.
Check if response not sent
Check if someone else didn't already flush the response
Changing interpretation of role
Letting users with advanced roles run non-gremlin queries. Adding logging.
Change-Id: If5c9c94b63c3203d2193b43eed5fcd5993f0c4fa
Issue-ID: AAI-1762
Signed-off-by: Kajur, Harish (vk250x) <vk250x@att.com>
Diffstat (limited to 'aai-traversal/src/main/java/org/onap')
4 files changed, 91 insertions, 16 deletions
diff --git a/aai-traversal/src/main/java/org/onap/aai/config/aaf/AafAuthorizationFilter.java b/aai-traversal/src/main/java/org/onap/aai/config/aaf/AafAuthorizationFilter.java index a64d3e5..9382946 100644 --- a/aai-traversal/src/main/java/org/onap/aai/config/aaf/AafAuthorizationFilter.java +++ b/aai-traversal/src/main/java/org/onap/aai/config/aaf/AafAuthorizationFilter.java @@ -19,6 +19,9 @@ */ package org.onap.aai.config.aaf; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.apache.commons.io.IOUtils; import org.onap.aai.Profiles; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.web.filter.OrderedRequestContextFilter; @@ -31,9 +34,7 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; -import java.util.stream.Collectors; - -import static org.onap.aai.config.aaf.ResponseFormatter.errorResponse; +import java.nio.charset.StandardCharsets; /** * AAF authorization filter @@ -44,8 +45,11 @@ import static org.onap.aai.config.aaf.ResponseFormatter.errorResponse; @PropertySource("file:${server.local.startpath}/aaf/permissions.properties") public class AafAuthorizationFilter extends OrderedRequestContextFilter { + private static final EELFLogger logger = EELFManager.getInstance().getLogger(AafAuthorizationFilter.class.getName()); + private static final String ADVANCED = "advanced"; private static final String BASIC = "basic"; + private static final String ECHO_ENDPOINT = "^.*/util/echo$"; @Value("${permission.type}") String type; @@ -58,19 +62,33 @@ public class AafAuthorizationFilter extends OrderedRequestContextFilter { } @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException { + protected void doFilterInternal(HttpServletRequest req, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException { - if(request.getRequestURI().matches("^.*/util/echo$")){ + PayloadBufferingRequestWrapper request = new PayloadBufferingRequestWrapper(req); + + if(request.getRequestURI().matches(ECHO_ENDPOINT)){ filterChain.doFilter(request, response); } - boolean containsWordGremlin = request.getReader().lines().collect(Collectors.joining(System.lineSeparator())).contains("\"gremlin\""); - //if the request contains the word "gremlin" it's an advanced query - String queryType = containsWordGremlin ? ADVANCED : BASIC; - String permission = String.format("%s|%s|%s", type, instance, queryType); + String payload = IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8.name()); + boolean containsWordGremlin = payload.contains("\"gremlin\""); + + //if the request contains the word "gremlin" it's an "advanced" query needing an "advanced" role + String permissionBasic = String.format("%s|%s|%s", type, instance, ADVANCED); + String permissionAdvanced = String.format("%s|%s|%s", type, instance, BASIC); + + boolean isAuthorized; + + if(containsWordGremlin){ + isAuthorized = request.isUserInRole(permissionAdvanced); + }else{ + isAuthorized = request.isUserInRole(permissionAdvanced) || request.isUserInRole(permissionBasic); + } - if(!request.isUserInRole(permission)){ - errorResponse(request, response); + if(!isAuthorized){ + String name = request.getUserPrincipal() != null ? request.getUserPrincipal().getName() : "unknown"; + logger.info("User " + name + " does not have a role for " + (containsWordGremlin ? "gremlin" : "non-gremlin") + " query" ); + response.setStatus(403); }else{ filterChain.doFilter(request,response); } diff --git a/aai-traversal/src/main/java/org/onap/aai/config/aaf/AafFilter.java b/aai-traversal/src/main/java/org/onap/aai/config/aaf/AafFilter.java index 6295c8e..51e0c17 100644 --- a/aai-traversal/src/main/java/org/onap/aai/config/aaf/AafFilter.java +++ b/aai-traversal/src/main/java/org/onap/aai/config/aaf/AafFilter.java @@ -19,6 +19,8 @@ */ package org.onap.aai.config.aaf; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; import org.onap.aaf.cadi.PropAccess; import org.onap.aaf.cadi.filter.CadiFilter; import org.onap.aai.Profiles; @@ -44,6 +46,8 @@ import static org.onap.aai.config.aaf.ResponseFormatter.errorResponse; @Profile(Profiles.AAF_AUTHENTICATION) public class AafFilter extends OrderedRequestContextFilter { + private static final EELFLogger log = EELFManager.getInstance().getLogger(AafFilter.class.getName()); + private final CadiFilter cadiFilter; public AafFilter() throws IOException, ServletException { @@ -57,7 +61,8 @@ public class AafFilter extends OrderedRequestContextFilter { protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException { if(!request.getRequestURI().matches("^.*/util/echo$")) { cadiFilter.doFilter(request, response, filterChain); - if (response.getStatus() >= 400 && response.getStatus() < 500) { + if (response.getStatus() == 401 || response.getStatus() == 403) { + log.info("User does not have permissions to run the query" ); errorResponse(request, response); } } diff --git a/aai-traversal/src/main/java/org/onap/aai/config/aaf/PayloadBufferingRequestWrapper.java b/aai-traversal/src/main/java/org/onap/aai/config/aaf/PayloadBufferingRequestWrapper.java new file mode 100644 index 0000000..ea0260c --- /dev/null +++ b/aai-traversal/src/main/java/org/onap/aai/config/aaf/PayloadBufferingRequestWrapper.java @@ -0,0 +1,49 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. 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. + * 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.aai.config.aaf; + +import org.apache.commons.io.IOUtils; +import org.onap.aaf.cadi.BufferedServletInputStream; + +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import java.io.*; + +/** + * This class buffers the payload of the servlet request. The reason is that we access the payload multiple times, + * which is not supported by the request per se. + */ + +class PayloadBufferingRequestWrapper extends HttpServletRequestWrapper { + + private byte[] buffer; + + PayloadBufferingRequestWrapper(HttpServletRequest req) throws IOException { + super(req); + this.buffer = IOUtils.toByteArray(req.getInputStream()); + } + + @Override + public ServletInputStream getInputStream() { + ByteArrayInputStream bais = new ByteArrayInputStream(this.buffer); + return new BufferedServletInputStream(bais); + } +} diff --git a/aai-traversal/src/main/java/org/onap/aai/config/aaf/ResponseFormatter.java b/aai-traversal/src/main/java/org/onap/aai/config/aaf/ResponseFormatter.java index 9e09827..0fc64bc 100644 --- a/aai-traversal/src/main/java/org/onap/aai/config/aaf/ResponseFormatter.java +++ b/aai-traversal/src/main/java/org/onap/aai/config/aaf/ResponseFormatter.java @@ -34,12 +34,15 @@ class ResponseFormatter { private static final String ACCEPT_HEADER = "accept"; static void errorResponse(HttpServletRequest request, HttpServletResponse response) throws IOException { + if (response.isCommitted()){ + return; + } + String accept = request.getHeader(ACCEPT_HEADER) == null ? MediaType.APPLICATION_XML : request.getHeader(ACCEPT_HEADER); AAIException aaie = new AAIException("AAI_3300"); response.setStatus(aaie.getErrorObject().getHTTPResponseCode().getStatusCode()); - response.getWriter().write(ErrorLogHelper.getRESTAPIErrorResponse(Collections.singletonList(MediaType.valueOf(accept)), aaie, new ArrayList<>())); - response.getWriter().flush(); - response.getWriter().close(); + response.resetBuffer(); + response.getOutputStream().print(ErrorLogHelper.getRESTAPIErrorResponse(Collections.singletonList(MediaType.valueOf(accept)), aaie, new ArrayList<>())); + response.flushBuffer(); } - } |