/* * ============LICENSE_START========================================== * ONAP Portal SDK * =================================================================== * Copyright © 2018 AT&T Intellectual Property. All rights reserved. * =================================================================== * * Unless otherwise specified, all software contained herein is licensed * under the Apache License, Version 2.0 (the "License"); * you may not use this software 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. * * Unless otherwise specified, all documentation contained herein is licensed * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); * you may not use this documentation except in compliance with the License. * You may obtain a copy of the License at * * https://creativecommons.org/licenses/by/4.0/ * * Unless required by applicable law or agreed to in writing, documentation * 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.portalsdk.core.onboarding.util; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; import javax.servlet.http.HttpServletRequest; import org.apache.commons.codec.DecoderException; import org.apache.commons.codec.binary.Hex; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.onap.aaf.cadi.CadiWrap; import org.onap.aaf.cadi.Permission; import org.onap.aaf.cadi.aaf.AAFPermission; import org.onap.portalsdk.core.onboarding.crossapi.IPortalRestCentralService; import org.onap.portalsdk.core.onboarding.exception.PortalAPIException; public class AuthUtil { private static final String decodeValueOfForwardSlash = "2f"; private static final String decodeValueOfHyphen = "2d"; private static final String decodeValueOfAsterisk = "2a"; private static final Log logger = LogFactory.getLog(AuthUtil.class); /* * This method compares the portalApiPath against the urlPattern; splits the * portalApiPath by "/" and compares each part with that of the urlPattern. * * Example: "xyz/1/abc" matches with the pattern "xyz/* /abc" but not with * "xyz/*" * */ public static Boolean matchPattern(String portalApiPath, String urlPattern) { String[] path = portalApiPath.split("/"); if (path.length > 1) { String[] roleFunctionArray = urlPattern.split("/"); boolean match = true; if (roleFunctionArray.length == path.length) { for (int i = 0; i < roleFunctionArray.length; i++) { if (match) { if (!roleFunctionArray[i].equals("*")) { Pattern p = Pattern.compile(Pattern.quote(path[i]), Pattern.CASE_INSENSITIVE); Matcher m = p.matcher(roleFunctionArray[i]); match = m.matches(); } } } if (match) return match; } } else { if (urlPattern.equals("*")) return true; else if (portalApiPath.matches(urlPattern)) return true; } return false; } /** * * @param request * @return returns list of AAFPermission of the requested MechId for all the * namespaces */ public static List getAAFPermissions(HttpServletRequest request) { CadiWrap wrapReq = (CadiWrap) request; List perms = wrapReq.getPermissions(wrapReq.getUserPrincipal()); List aafPermsList = new ArrayList<>(); for (Permission perm : perms) { AAFPermission aafPerm = (AAFPermission) perm; aafPermsList.add(aafPerm); } return aafPermsList; } /** * * @param request * @return returns list of AAFPermission for the specific namespace */ public static List getNameSpacesAAFPermissions(String nameSpace, List allPermissionsList) { String type = nameSpace + ".url"; allPermissionsList.removeIf(perm -> (!perm.getType().equals(type))); return allPermissionsList; } /** * * @param permsList * @return returns the list of instaces of namespace * @throws PortalAPIException */ public static List getAllInstances(List permsList) throws PortalAPIException { List instanceList = permsList.stream().map(AAFPermission::getInstance).collect(Collectors.toList()); List finalInstanceList = new ArrayList<>(); for (String instance : instanceList) { String str = ""; if (instance.equals("*")) str = instance; else str = decodeFunctionCode(instance); finalInstanceList.add(str); } if (logger.isDebugEnabled()) logger.debug("List of AllInstances: " + finalInstanceList); return finalInstanceList; } public static String decodeFunctionCode(String str) throws PortalAPIException { String decodedString = str; List decodingList = new ArrayList<>(); decodingList.add(Pattern.compile(decodeValueOfForwardSlash)); decodingList.add(Pattern.compile(decodeValueOfHyphen)); decodingList.add(Pattern.compile(decodeValueOfAsterisk)); for (Pattern xssInputPattern : decodingList) { try { decodedString = decodedString.replaceAll("%" + xssInputPattern, new String(Hex.decodeHex(xssInputPattern.toString().toCharArray()))); } catch (DecoderException e) { logger.error("Decode Failed! for instance: " + str); throw new PortalAPIException("decode failed", e); } } return decodedString; } /** * * @param request * @param nameSpace * application namespace * @return boolean value if the access is allowed * @throws PortalAPIException */ public static boolean isAccessAllowed(HttpServletRequest request, String nameSpace, Map appCredentials) throws PortalAPIException { boolean isauthorized = false; try { CadiWrap wrapReq = (CadiWrap) request; List aafPermsList = getAAFPermissions(request); logger.debug("Application nameSpace: " + nameSpace); if (nameSpace.isEmpty()) { throw new PortalAPIException("NameSpace not Declared!"); } List aafPermsFinalList = getNameSpacesAAFPermissions(nameSpace, aafPermsList); List finalInstanceList = getAllInstances(aafPermsFinalList); finalInstanceList.add("api/v3/timeoutSession"); String requestUri = request.getRequestURI().substring(request.getContextPath().length() + 1); for (String str : finalInstanceList) { if (!isauthorized) isauthorized = matchPattern(requestUri, str); } logger.debug("isAccessAllowed for the request uri: " + requestUri + "is" + isauthorized); if (isauthorized) { logger.debug("Request is Authorized"); } } catch (ClassCastException e) { logger.warn("Given request is not CADI request: ", e); if (appCredentials.isEmpty()) { logger.debug("app credentails are empty"); return false; } String appUserName = ""; String appPassword = ""; String appName = ""; for (Map.Entry entry : appCredentials.entrySet()) { if (entry.getKey().equalsIgnoreCase(IPortalRestCentralService.CREDENTIALS_USER)) { appUserName = entry.getValue(); } else if (entry.getKey().equalsIgnoreCase(IPortalRestCentralService.CREDENTIALS_PASS)) { appPassword = entry.getValue(); } else { appName = entry.getValue(); } } try { String appUser = request.getHeader(IPortalRestCentralService.CREDENTIALS_USER); String password = request.getHeader(IPortalRestCentralService.CREDENTIALS_PASS); if (password.equals(appPassword) && appUserName.equals(appUser)) { isauthorized = true; } logger.debug("isAccessAllowed for the request " + isauthorized); } catch (Exception e1) { String response = "AuthUtil.isAccessAllowed failed"; logger.error(response, e1); throw new PortalAPIException(response, e1); } } return isauthorized; } }