aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/org/onap/music/authentication
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/onap/music/authentication')
-rw-r--r--src/main/java/org/onap/music/authentication/AuthUtil.java270
-rw-r--r--src/main/java/org/onap/music/authentication/AuthorizationError.java55
-rwxr-xr-xsrc/main/java/org/onap/music/authentication/CachingUtil.java452
-rw-r--r--src/main/java/org/onap/music/authentication/CadiAuthFilter.java90
-rw-r--r--src/main/java/org/onap/music/authentication/MusicAAFAuthentication.java181
-rw-r--r--src/main/java/org/onap/music/authentication/MusicAuthenticator.java62
-rw-r--r--src/main/java/org/onap/music/authentication/MusicAuthorizationFilter.java170
7 files changed, 520 insertions, 760 deletions
diff --git a/src/main/java/org/onap/music/authentication/AuthUtil.java b/src/main/java/org/onap/music/authentication/AuthUtil.java
new file mode 100644
index 00000000..999acc75
--- /dev/null
+++ b/src/main/java/org/onap/music/authentication/AuthUtil.java
@@ -0,0 +1,270 @@
+/*
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property
+ * ===================================================================
+ * 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.music.authentication;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.codec.DecoderException;
+import org.apache.commons.codec.binary.Hex;
+import org.onap.aaf.cadi.CadiWrap;
+import org.onap.aaf.cadi.Permission;
+import org.onap.aaf.cadi.aaf.AAFPermission;
+import org.onap.music.eelf.logging.EELFLoggerDelegate;
+
+public class AuthUtil {
+
+ private static final String decodeValueOfForwardSlash = "2f";
+ private static final String decodeValueOfHyphen = "2d";
+ private static final String decodeValueOfAsterisk = "2a";
+ private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(AuthUtil.class);
+
+ /**
+ * Get the list of permissions from the Request object.
+ *
+ *
+ * @param request servlet request object
+ * @return returns list of AAFPermission of the requested MechId for all the
+ * namespaces
+ */
+ public static List<AAFPermission> getAAFPermissions(ServletRequest request) {
+ CadiWrap wrapReq = (CadiWrap) request;
+
+ List<Permission> perms = wrapReq.getPermissions(wrapReq.getUserPrincipal());
+ List<AAFPermission> aafPermsList = new ArrayList<>();
+ for (Permission perm : perms) {
+ AAFPermission aafPerm = (AAFPermission) perm;
+ aafPermsList.add(aafPerm);
+ }
+ return aafPermsList;
+ }
+
+ /**
+ * Here is a sample of a permission object in AAI. The key attribute will have
+ * Type|Instance|Action.
+ * AAFPermission:
+ * NS: null
+ * Type: org.onap.music.cadi.keyspace ( Permission Type )
+ * Instance: tomtest ( Cassandra Keyspace )
+ * Action: *|GET|ALL ( Access Level [*|ALL] for full access and [GET] for Read only)
+ * Key: org.onap.music.cadi.keyspace|tomtest|*
+ *
+ * This method will filter all permissions whose key starts with the requested namespace.
+ * The nsamespace here is the music namespace which is defined in music.property file.
+ * i;e is the type contains in key is org.onap.music.cadi.keyspace and the namespace
+ * value is org.onap.music.cadi.keyspace, it will add to list
+ * otherwise reject.
+ *
+ * @param nameSpace
+ * @param allPermissionsList
+ * @return
+ */
+ private static List<AAFPermission> filterNameSpacesAAFPermissions(String nameSpace,
+ List<AAFPermission> allPermissionsList) {
+ List<AAFPermission> list = new ArrayList<>();
+ for (Iterator iterator = allPermissionsList.iterator(); iterator.hasNext();) {
+ AAFPermission aafPermission = (AAFPermission) iterator.next();
+ if(aafPermission.getType().indexOf(nameSpace) == 0) {
+ list.add(aafPermission);
+ }
+ }
+ return list;
+ }
+
+ /**
+ * Decode certian characters from url encoded to normal.
+ *
+ * @param str - String being decoded.
+ * @return returns the decoded string.
+ * @throws Exception throws excpetion
+ */
+ public static String decodeFunctionCode(String str) throws Exception {
+ String decodedString = str;
+ List<Pattern> 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(EELFLoggerDelegate.applicationLogger,
+ "AuthUtil Decode Failed! for instance: " + str);
+ throw new Exception("decode failed", e);
+ }
+ }
+
+ return decodedString;
+ }
+
+ /**
+ *
+ *
+ * @param request servlet request object
+ * @param nameSpace application namespace
+ * @return boolean value if the access is allowed
+ * @throws Exception throws exception
+ */
+ public static boolean isAccessAllowed(ServletRequest request, String nameSpace) throws Exception {
+
+ if (nameSpace.isEmpty()) {
+ throw new Exception("NameSpace not Declared!");
+ }
+
+ boolean isauthorized = false;
+ List<AAFPermission> aafPermsList = getAAFPermissions(request);
+ //logger.info(EELFLoggerDelegate.applicationLogger,
+ // "AAFPermission of the requested MechId for all the namespaces: " + aafPermsList);
+
+ String requestUri = null;
+ logger.debug(EELFLoggerDelegate.applicationLogger, "Requested nameSpace: " + nameSpace);
+ HttpServletRequest httpRequest = null;
+
+
+ List<AAFPermission> aafPermsFinalList = filterNameSpacesAAFPermissions(nameSpace, aafPermsList);
+
+ logger.debug(EELFLoggerDelegate.applicationLogger,
+ "AuthUtil list of AAFPermission for the specific namespace ::::::::::::::::::::::::::::::::::::::::::::"
+ + aafPermsFinalList);
+
+ if (null != request) {
+ httpRequest = (HttpServletRequest) request;
+ requestUri = httpRequest.getRequestURI().substring(httpRequest.getContextPath().length() + 1);
+ }
+
+ logger.debug(EELFLoggerDelegate.applicationLogger,
+ "AuthUtil requestUri ::::::::::::::::::::::::::::::::::::::::::::" + requestUri);
+
+ for (Iterator iterator = aafPermsFinalList.iterator(); iterator.hasNext();) {
+ AAFPermission aafPermission = (AAFPermission) iterator.next();
+ if(!isauthorized) {
+ isauthorized = isMatchPatternWithInstanceAndAction(aafPermission, requestUri, httpRequest.getMethod());
+ }
+ }
+
+ logger.debug(EELFLoggerDelegate.applicationLogger,
+ "isAccessAllowed for the request uri: " + requestUri + "is :" + isauthorized);
+ return isauthorized;
+ }
+
+ /**
+ *
+ * This method will check, if the requested URI matches any of the instance
+ * found with the AAF permission list.
+ * i;e if the request URI is; /v2/keyspaces/tomtest/tables/emp15 and in the
+ * AAF permission table, we have an instance
+ * defined as "tomtest" mapped the logged in user, it will allow else error.
+ *
+ * User trying to create or aquire a lock
+ * Here is the requested URI /v2/locks/create/tomtest.MyTable.Field1
+ * Here the keyspace name i;e tomtest will be test throught out the URL if it
+ * matches, it will allow the user to create a lock.
+ * "tomtest" here is the key, which is mapped as an instance in permission object.
+ * Instance can be delimited with ":" i;e ":music-cassandra-1908-dev:admin". In this case,
+ * each delimited
+ * token will be matched with that of request URI.
+ *
+ * Example Permission:
+ * org.onap.music.api.user.access|tomtest|* or ALL
+ * org.onap.music.api.user.access|tomtest|GET
+ * In case of the action field is ALL and *, user will be allowed else it will
+ * be matched with the requested http method type.
+ *
+ *
+ *
+ * @param aafPermission - AAfpermission obtained by cadi.
+ * @param requestUri - Rest URL client is calling.
+ * @param method - REST Method being used (GET,POST,PUT,DELETE)
+ * @return returns a boolean
+ * @throws Exception - throws an exception
+ */
+ private static boolean isMatchPatternWithInstanceAndAction(
+ AAFPermission aafPermission,
+ String requestUri,
+ String method) throws Exception {
+ if (null == aafPermission || null == requestUri || null == method) {
+ return false;
+ }
+
+ String permKey = aafPermission.getKey();
+
+ logger.info(EELFLoggerDelegate.applicationLogger, "isMatchPattern permKey: "
+ + permKey + ", requestUri " + requestUri + " ," + method);
+
+ String[] keyArray = permKey.split("\\|");
+ String[] subPath = null;
+ //String type = null;
+ //type = keyArray[0];
+ String instance = null;
+ instance = keyArray[1];
+ String action = null;
+ action = keyArray[2];
+
+ //if the instance & action both are * , then allow
+ if ("*".equalsIgnoreCase(instance) && "*".equalsIgnoreCase(action)) {
+ return true;
+ }
+ //Decode string like %2f, %2d and %2a
+ if (!"*".equals(instance)) {
+ instance = decodeFunctionCode(instance);
+ }
+ if (!"*".equals(action)) {
+ action = decodeFunctionCode(action);
+ }
+ //Instance: :music-cassandra-1908-dev:admin
+ List<String> instanceList = Arrays.asList(instance.split(":"));
+
+ String[] path = requestUri.split("/");
+
+ for (int i = 0; i < path.length; i++) {
+ // Sometimes the value will begin with "$", so we need to remove it
+ if (path[i].startsWith("$")) {
+ path[i] = path[i].replace("$","");
+ }
+ // Each path element can again delemited by ".";i;e
+ // tomtest.tables.emp. We have scenarios like lock aquire URL
+ subPath = path[i].split("\\.");
+ for (int j = 0; j < subPath.length; j++) {
+ if (instanceList.contains(subPath[j])) {
+ if ("*".equals(action) || "ALL".equalsIgnoreCase(action)) {
+ return true;
+ } else if (method.equalsIgnoreCase(action)) {
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ continue;
+ }
+ }
+ }
+ return false;
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/onap/music/authentication/AuthorizationError.java b/src/main/java/org/onap/music/authentication/AuthorizationError.java
new file mode 100644
index 00000000..7015b550
--- /dev/null
+++ b/src/main/java/org/onap/music/authentication/AuthorizationError.java
@@ -0,0 +1,55 @@
+/*
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property
+ * ===================================================================
+ * 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.music.authentication;
+
+
+/**
+ * Authorization error class used while setting error code and description back to client.
+ *
+ *
+ * @author sp931a
+ *
+ */
+public class AuthorizationError {
+
+ private int responseCode;
+
+ private String responseMessage;
+
+ public int getResponseCode() {
+ return responseCode;
+ }
+
+ public void setResponseCode(int responseCode) {
+ this.responseCode = responseCode;
+ }
+
+ public String getResponseMessage() {
+ return responseMessage;
+ }
+
+ public void setResponseMessage(String responseMessage) {
+ this.responseMessage = responseMessage;
+ }
+
+} \ No newline at end of file
diff --git a/src/main/java/org/onap/music/authentication/CachingUtil.java b/src/main/java/org/onap/music/authentication/CachingUtil.java
deleted file mode 100755
index dba23195..00000000
--- a/src/main/java/org/onap/music/authentication/CachingUtil.java
+++ /dev/null
@@ -1,452 +0,0 @@
-/*
- * ============LICENSE_START==========================================
- * org.onap.music
- * ===================================================================
- * Copyright (c) 2017 AT&T Intellectual Property
- * ===================================================================
- * Modifications Copyright (c) 2018 IBM
- * Modifications Copyright (c) 2019 Samsung
- * ===================================================================
- * 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.music.authentication;
-
-import java.util.Calendar;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import javax.ws.rs.core.MediaType;
-
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.jcs.JCS;
-import org.apache.commons.jcs.access.CacheAccess;
-import org.apache.commons.jcs.engine.CompositeCacheAttributes;
-import org.apache.commons.jcs.engine.ElementAttributes;
-import org.apache.commons.jcs.engine.behavior.ICompositeCacheAttributes;
-import org.apache.commons.jcs.engine.behavior.IElementAttributes;
-import org.mindrot.jbcrypt.BCrypt;
-import org.onap.music.authentication.MusicAuthenticator.Operation;
-import org.onap.music.datastore.PreparedQueryObject;
-import org.onap.music.eelf.logging.EELFLoggerDelegate;
-import org.onap.music.eelf.logging.format.AppMessages;
-import org.onap.music.eelf.logging.format.ErrorSeverity;
-import org.onap.music.eelf.logging.format.ErrorTypes;
-import org.onap.music.exceptions.MusicServiceException;
-import org.onap.music.main.MusicCore;
-import org.onap.music.main.MusicUtil;
-import com.datastax.driver.core.DataType;
-import com.datastax.driver.core.ResultSet;
-import com.datastax.driver.core.Row;
-import com.datastax.driver.core.exceptions.InvalidQueryException;
-import com.sun.jersey.api.client.Client;
-import com.sun.jersey.api.client.ClientResponse;
-import com.sun.jersey.api.client.WebResource;
-
-/**
- * All Caching related logic is handled by this class and a schedule cron runs to update cache.
- *
- * @author Vikram
- *
- */
-public class CachingUtil implements Runnable {
-
- private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(CachingUtil.class);
-
- /** keyspace & ns */
- private static CacheAccess<String, String> musicCache = JCS.getInstance("musicCache");
- /** cache to hold isaaf application */
- private static CacheAccess<String, String> appNameCache = JCS.getInstance("appNameCache");
- /** hold user creds for namespace */
- private static CacheAccess<String, Map<String, String>> musicValidateCache = JCS.getInstance("musicValidateCache");
- private static Map<String, Number> userAttempts = new HashMap<>();
- private static Map<String, Calendar> lastFailedTime = new HashMap<>();
- private static CacheAccess<String, String> adminUserCache = JCS.getInstance("adminUserCache");
-
- public static CacheAccess<String, String> getAdminUserCache() {
- return adminUserCache;
- }
-
- public static void updateAdminUserCache(String authorization,String userId) {
- adminUserCache.put(authorization,userId);
- }
-
- private static final String USERNAME="username";
- private static final String PASSWORD="password";
-
-
- public void initializeAafCache() throws MusicServiceException {
- logger.info(EELFLoggerDelegate.applicationLogger,"Resetting and initializing AAF Cache...");
-
- String query = "SELECT uuid, application_name, keyspace_name, username, password FROM admin.keyspace_master WHERE is_api = ? allow filtering";
- PreparedQueryObject pQuery = new PreparedQueryObject();
- pQuery.appendQueryString(query);
- try {
- pQuery.addValue(MusicUtil.convertToActualDataType(DataType.cboolean(), false));
- } catch (Exception e1) {
- logger.error(EELFLoggerDelegate.errorLogger, e1.getMessage(),AppMessages.CACHEERROR,
- ErrorSeverity.CRITICAL, ErrorTypes.GENERALSERVICEERROR, e1);
- }
- ResultSet rs = MusicCore.get(pQuery);
- Iterator<Row> it = rs.iterator();
- Map<String, String> map = null;
- while (it.hasNext()) {
- Row row = it.next();
- String nameSpace = row.getString("keyspace_name");
- String userId = row.getString(USERNAME);
- String password = row.getString(PASSWORD);
- String keySpace = row.getString("application_name");
- try {
- userAttempts.put(nameSpace, 0);
- boolean responseObj = triggerAAF(nameSpace, userId, password);
- if (responseObj) {
- map = new HashMap<>();
- map.put(userId, password);
- musicValidateCache.put(nameSpace, map);
- musicCache.put(keySpace, nameSpace);
- logger.debug("Cronjob: Cache Updated with AAF response for namespace "
- + nameSpace);
- }
- } catch (Exception e) {
- logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.UNKNOWNERROR, ErrorSeverity
- .INFO, ErrorTypes.GENERALSERVICEERROR, e);
- logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),"Something at AAF was changed for ns: " + nameSpace+" So not updating Cache for the namespace. ");
- }
- }
-
- }
-
- @Override
- public void run() {
- logger.info(EELFLoggerDelegate.applicationLogger,"Scheduled task invoked. Refreshing Cache...");
- try {
- initializeAafCache();
- } catch (MusicServiceException e) {
- logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(),AppMessages.UNKNOWNERROR, ErrorSeverity.INFO,
- ErrorTypes.GENERALSERVICEERROR, e);
- }
- }
-
- public static boolean authenticateAAFUser(String nameSpace, String userId, String password,
- String keySpace) throws Exception {
-
- if (musicValidateCache.get(nameSpace) != null && musicCache.get(keySpace)!=null) {
- if (keySpace != null && !musicCache.get(keySpace).equals(nameSpace)) {
- logger.info(EELFLoggerDelegate.applicationLogger,"Create new application for the same namespace.");
- } else if (musicValidateCache.get(nameSpace).get(userId).equals(password)) {
- logger.info(EELFLoggerDelegate.applicationLogger,"Authenticated with cache value..");
- // reset invalid attempts to 0
- userAttempts.put(nameSpace, 0);
- return true;
- } else {
- // call AAF update cache with new password
- if (userAttempts.get(nameSpace) == null)
- userAttempts.put(nameSpace, 0);
- if ((Integer) userAttempts.get(nameSpace) >= 3) {
- logger.info(EELFLoggerDelegate.applicationLogger,"Reached max attempts. Checking if time out..");
- logger.info(EELFLoggerDelegate.applicationLogger,"Failed time: "+lastFailedTime.get(nameSpace).getTime());
- Calendar calendar = Calendar.getInstance();
- long delayTime = (calendar.getTimeInMillis()-lastFailedTime.get(nameSpace).getTimeInMillis());
- logger.info(EELFLoggerDelegate.applicationLogger,"Delayed time: "+delayTime);
- if( delayTime > 120000) {
- logger.info(EELFLoggerDelegate.applicationLogger,"Resetting failed attempt.");
- userAttempts.put(nameSpace, 0);
- } else {
- logger.info(EELFLoggerDelegate.applicationLogger,"No more attempts allowed. Please wait for atleast 2 min.");
- throw new Exception("No more attempts allowed. Please wait for atleast 2 min.");
- }
- }
- logger.error(EELFLoggerDelegate.errorLogger,"",AppMessages.CACHEAUTHENTICATION,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
- logger.info(EELFLoggerDelegate.applicationLogger,"Check AAF again...");
- }
- }
-
- boolean responseObj = false;
- try {
- responseObj = triggerAAF(nameSpace, userId, password);
- }catch (Exception ex) {
- logger.info("Exception while trigger aaf", ex);
- logger.info("Exception: " + ex.getMessage());
- throw new Exception("Exception raised while triggering AAF authentication" +ex.getMessage());
- }
- if (responseObj) {
- logger.info(EELFLoggerDelegate.applicationLogger,"Valid user. Cache is updated for "+nameSpace);
- Map<String, String> map = new HashMap<>();
- map.put(userId, password);
- musicValidateCache.put(nameSpace, map);
- musicCache.put(keySpace, nameSpace);
- return true;
- }
- logger.info(EELFLoggerDelegate.applicationLogger,"Invalid user. Cache not updated");
- return false;
- }
-
- private static boolean triggerAAF(String nameSpace, String userId, String password)
- throws Exception {
- logger.info(EELFLoggerDelegate.applicationLogger,"Inside AAF authorization");
- if (MusicUtil.getAafEndpointUrl() == null) {
- logger.error(EELFLoggerDelegate.errorLogger,"AAF endpoint is not set. Please specify in the properties file.",AppMessages.UNKNOWNERROR,ErrorSeverity.WARN, ErrorTypes.GENERALSERVICEERROR);
- throw new Exception("AAF endpoint is not set. Please specify in the properties file.");
- }
- Client client = Client.create();
- WebResource webResource = client.resource(MusicUtil.getAafEndpointUrl().concat(nameSpace));
- String plainCreds = userId + ":" + password;
- byte[] plainCredsBytes = plainCreds.getBytes();
- byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
- String base64Creds = new String(base64CredsBytes);
-
- ClientResponse response = webResource.accept(MediaType.APPLICATION_JSON)
- .header("Authorization", "Basic " + base64Creds)
- .header("content-type", "application/json").get(ClientResponse.class);
- logger.info(EELFLoggerDelegate.applicationLogger, "aaf response: "+response.toString());
- if (response.getStatus() != 200) {
- if (userAttempts.get(nameSpace) == null)
- userAttempts.put(nameSpace, 0);
- if ((Integer) userAttempts.get(nameSpace) >= 2) {
- lastFailedTime.put(nameSpace, Calendar.getInstance());
- userAttempts.put(nameSpace, ((Integer) userAttempts.get(nameSpace) + 1));
- throw new Exception(
- "Reached max invalid attempts. Please contact admin and retry with valid credentials.");
- }
- userAttempts.put(nameSpace, ((Integer) userAttempts.get(nameSpace) + 1));
- throw new Exception(
- "Unable to authenticate. Please check the AAF credentials against namespace.");
- // TODO Allow for 2-3 times and forbid any attempt to trigger AAF with invalid values
- // for specific time.
- }
- /*response.getHeaders().put(HttpHeaders.CONTENT_TYPE,
- Arrays.asList(MediaType.APPLICATION_JSON));
- // AAFResponse output = response.getEntity(AAFResponse.class);
- response.bufferEntity();
- String x = response.getEntity(String.class);
- AAFResponse responseObj = new ObjectMapper().readValue(x, AAFResponse.class);*/
-
- return true;
- }
-
- public static void updateMusicCache(String keyspace, String nameSpace) {
- logger.info(EELFLoggerDelegate.applicationLogger,"Updating musicCache for keyspace " + keyspace + " with nameSpace " + nameSpace);
- musicCache.put(keyspace, nameSpace);
- }
-
- public static void updateCadiCache(String user, String keyspace) {
- musicCache.put(user, keyspace);
- }
-
- public static String getKSFromCadiCache(String user) {
- return musicCache.get(user);
- }
-
- public static void updateMusicValidateCache(String nameSpace, String userId, String password) {
- logger.info(EELFLoggerDelegate.applicationLogger,"Updating musicCache for nameSpacce " + nameSpace + " with userId " + userId);
- Map<String, String> map = new HashMap<>();
- map.put(userId, password);
- musicValidateCache.put(nameSpace, map);
- }
-
- public static void updateisAAFCache(String namespace, String isAAF) {
- appNameCache.put(namespace, isAAF);
- }
-
- public static String isAAFApplication(String namespace) throws MusicServiceException {
- String isAAF = appNameCache.get(namespace);
- if (isAAF == null) {
- PreparedQueryObject pQuery = new PreparedQueryObject();
- pQuery.appendQueryString(
- "SELECT is_aaf from admin.keyspace_master where application_name = '"
- + namespace + "' allow filtering");
- Row rs = null;
- try {
- rs = MusicCore.get(pQuery).one();
- } catch(InvalidQueryException e) {
- logger.error(EELFLoggerDelegate.errorLogger,"Exception admin keyspace not configured."+ e.getMessage
- (), e);
- throw new MusicServiceException("Please make sure admin.keyspace_master table is configured.");
- }
- try {
- isAAF = String.valueOf(rs.getBool("is_aaf"));
- if(isAAF != null)
- appNameCache.put(namespace, isAAF);
- } catch (Exception e) {
- logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(), AppMessages.QUERYERROR,ErrorSeverity
- .ERROR, ErrorTypes.QUERYERROR, e);
- }
- }
- return isAAF;
- }
-
- public static String getUuidFromMusicCache(String keyspace) throws MusicServiceException {
- String uuid = null;
- if (uuid == null) {
- PreparedQueryObject pQuery = new PreparedQueryObject();
- pQuery.appendQueryString(
- "SELECT uuid from admin.keyspace_master where keyspace_name = '"
- + keyspace + "' allow filtering");
- Row rs = MusicCore.get(pQuery).one();
- try {
- uuid = rs.getUUID("uuid").toString();
- } catch (Exception e) {
- logger.error(EELFLoggerDelegate.errorLogger,"Exception occurred during uuid retrieval from DB."+e
- .getMessage(), e);
- }
- }
- return uuid;
- }
-
- public static String getAppName(String keyspace) throws MusicServiceException {
- String appName = null;
- PreparedQueryObject pQuery = new PreparedQueryObject();
- pQuery.appendQueryString(
- "SELECT application_name from admin.keyspace_master where keyspace_name = '"
- + keyspace + "' allow filtering");
- Row rs = MusicCore.get(pQuery).one();
- try {
- appName = rs.getString("application_name");
- } catch (Exception e) {
- logger.error(EELFLoggerDelegate.errorLogger, e.getMessage(), AppMessages.QUERYERROR, ErrorSeverity
- .ERROR, ErrorTypes.QUERYERROR, e);
- }
- return appName;
- }
-
- @Deprecated
- public static Map<String, Object> validateRequest(String nameSpace, String userId,
- String password, String keyspace, String aid, String operation) {
- Map<String, Object> resultMap = new HashMap<>();
- if (!"createKeySpace".equals(operation)) {
- if (nameSpace == null) {
- resultMap.put("Exception", "Application namespace is mandatory.");
- }
- }
- return resultMap;
- }
-
- public static Map<String, Object> validateRequest(String nameSpace, String userId,
- String password, String keyspace, String aid, Operation operation) {
- Map<String, Object> resultMap = new HashMap<>();
- if (Operation.CREATE_KEYSPACE!=operation) {
- if (nameSpace == null) {
- resultMap.put("Exception", "Application namespace is mandatory.");
- }
- }
- return resultMap;
- }
-
- public static Map<String, Object> verifyOnboarding(String ns, String userId, String password) {
- Map<String, Object> resultMap = new HashMap<>();
- if (ns == null || userId == null || password == null) {
- logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
- logger.error(EELFLoggerDelegate.errorLogger,"One or more required headers is missing. userId: "+userId+" :: password: "+password);
- resultMap.put("Exception",
- "One or more required headers appName(ns), userId, password is missing. Please check.");
- return resultMap;
- }
- PreparedQueryObject queryObject = new PreparedQueryObject();
- queryObject.appendQueryString(
- "select * from admin.keyspace_master where application_name = ? allow filtering");
- try {
- queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), ns));
- } catch(Exception e) {
- resultMap.put("Exception",
- "Unable to process input data. Invalid input data type. Please check ns, userId and password values. "+e.getMessage());
- return resultMap;
- }
- Row rs = null;
- try {
- rs = MusicCore.get(queryObject).one();
- } catch (MusicServiceException e) {
- String errorMsg = "Unable to process operation. Error is "+e.getMessage();
- logger.error(EELFLoggerDelegate.errorLogger, errorMsg, e);
- resultMap.put("Exception", errorMsg);
- return resultMap;
- } catch (InvalidQueryException e) {
- logger.error(EELFLoggerDelegate.errorLogger,"Exception admin keyspace not configured."+e.getMessage(), e);
- resultMap.put("Exception", "Please make sure admin.keyspace_master table is configured.");
- return resultMap;
- }
- if (rs == null) {
- logger.error(EELFLoggerDelegate.errorLogger,"Application is not onboarded. Please contact admin.");
- resultMap.put("Exception", "Application is not onboarded. Please contact admin.");
- } else {
- if(!(rs.getString(USERNAME).equals(userId)) || !(BCrypt.checkpw(password, rs.getString(PASSWORD)))) {
- logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.AUTHENTICATIONERROR, ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
- logger.error(EELFLoggerDelegate.errorLogger,"Namespace, UserId and password doesn't match. namespace: "+ns+" and userId: "+userId);
- resultMap.put("Exception", "Namespace, UserId and password doesn't match. namespace: "+ns+" and userId: "+userId);
- return resultMap;
- }
- }
- return resultMap;
- }
-
- public static Map<String, Object> authenticateAIDUser(String nameSpace, String userId, String password,
- String keyspace) {
- Map<String, Object> resultMap = new HashMap<>();
- String pwd = null;
- if((musicCache.get(keyspace) != null) && (musicValidateCache.get(nameSpace) != null)
- && (musicValidateCache.get(nameSpace).containsKey(userId))) {
- if(!musicCache.get(keyspace).equals(nameSpace)) {
- resultMap.put("Exception", "Namespace and keyspace doesn't match");
- return resultMap;
- }
- if(!BCrypt.checkpw(password,musicValidateCache.get(nameSpace).get(userId))) {
- resultMap.put("Exception", "Namespace, userId and password doesn't match");
- return resultMap;
- }
- return resultMap;
- }
- PreparedQueryObject queryObject = new PreparedQueryObject();
- queryObject.appendQueryString(
- "select * from admin.keyspace_master where keyspace_name = ? allow filtering");
- try {
- queryObject.addValue(MusicUtil.convertToActualDataType(DataType.text(), keyspace));
- } catch (Exception e) {
- logger.error(EELFLoggerDelegate.errorLogger,"Adding value to query object failed: " + e.getMessage(), e);
- }
- Row rs = null;
- try {
- rs = MusicCore.get(queryObject).one();
- } catch (MusicServiceException e) {
- String errMsg = "Unable to process operation. Error is "+e.getMessage();
- logger.error(EELFLoggerDelegate.errorLogger, errMsg, e);
- resultMap.put("Exception", errMsg);
- return resultMap;
- }
- if(rs == null) {
- resultMap.put("Exception", "Please make sure keyspace:"+keyspace+" exists.");
- return resultMap;
- }
- else {
- String user = rs.getString(USERNAME);
- pwd = rs.getString(PASSWORD);
- String ns = rs.getString("application_name");
- if(!ns.equals(nameSpace)) {
- resultMap.put("Exception", "Namespace and keyspace doesn't match");
- return resultMap;
- }
- if(!user.equals(userId)) {
- resultMap.put("Exception", "Invalid userId :"+userId);
- return resultMap;
- }
- if(!BCrypt.checkpw(password, pwd)) {
- resultMap.put("Exception", "Invalid password");
- return resultMap;
- }
- }
- CachingUtil.updateMusicCache(keyspace, nameSpace);
- CachingUtil.updateMusicValidateCache(nameSpace, userId, pwd);
- return resultMap;
- }
-}
diff --git a/src/main/java/org/onap/music/authentication/CadiAuthFilter.java b/src/main/java/org/onap/music/authentication/CadiAuthFilter.java
index 56371c7d..765face7 100644
--- a/src/main/java/org/onap/music/authentication/CadiAuthFilter.java
+++ b/src/main/java/org/onap/music/authentication/CadiAuthFilter.java
@@ -21,25 +21,22 @@
*/
package org.onap.music.authentication;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+
+import java.io.IOException;
+
+import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
-import javax.servlet.http.HttpServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.annotation.WebFilter;
-import com.att.eelf.configuration.EELFLogger;
-import org.onap.aaf.cadi.CadiWrap;
-import org.onap.aaf.cadi.Permission;
import org.onap.aaf.cadi.PropAccess;
-import org.onap.aaf.cadi.aaf.AAFPermission;
import org.onap.aaf.cadi.filter.CadiFilter;
import org.onap.music.eelf.logging.EELFLoggerDelegate;
-import org.onap.music.main.MusicCore;
+@WebFilter(urlPatterns = { "/*" })
public class CadiAuthFilter extends CadiFilter {
private static final EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(CadiAuthFilter.class);
@@ -47,64 +44,27 @@ public class CadiAuthFilter extends CadiFilter {
public CadiAuthFilter(PropAccess access) throws ServletException {
super(true, access);
}
-
- public void init(FilterConfig filterConfig) throws ServletException {
- super.init(filterConfig);
- }
-
- private boolean matchPattern(String requestedPath, String includeUrl) {
- includeUrl = includeUrl.substring(1);
- String[] path = requestedPath.split("/");
- if (path.length > 1) {
- String[] roleFunctionArray = includeUrl.split("/");
- boolean match = true;
- for (int i = 0; i < roleFunctionArray.length; i++) {
- if (match) {
- if (!"*".equals(roleFunctionArray[i])) {
- Pattern p = Pattern.compile(Pattern.quote(path[i]), Pattern.CASE_INSENSITIVE);
- Matcher m = p.matcher(roleFunctionArray[i]);
- match = m.matches();
- } else if (roleFunctionArray[i].equals("*")) {
- match = true;
- }
-
- }
- }
- if (match)
- return match;
- } else {
- if (requestedPath.matches(includeUrl))
- return true;
- else if ("*".equals(includeUrl))
- return true;
- }
- return false;
+ public CadiAuthFilter() throws ServletException {
+ super();
}
-
- public static List<AAFPermission> getAAFPermissions(HttpServletRequest request) {
- CadiWrap wrapReq = (CadiWrap) request;
- List<Permission> perms = wrapReq.getPermissions(wrapReq.getUserPrincipal());
- List<AAFPermission> aafPermsList = new ArrayList<>();
- for (Permission perm : perms) {
- AAFPermission aafPerm = (AAFPermission) perm;
- aafPermsList.add(aafPerm);
- logger.info(aafPerm.toString());
- logger.info(aafPerm.getType());
- }
- return aafPermsList;
- }
-
- public static List<AAFPermission> getAAFPermissions(ServletRequest request) {
- CadiWrap wrapReq = (CadiWrap) request;
- List<Permission> perms = wrapReq.getPermissions(wrapReq.getUserPrincipal());
- List<AAFPermission> aafPermsList = new ArrayList<>();
- for (Permission perm : perms) {
- AAFPermission aafPerm = (AAFPermission) perm;
- aafPermsList.add(aafPerm);
- }
- return aafPermsList;
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {
+ super.init(filterConfig);
}
+ @Override
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
+ throws IOException, ServletException {
+ logger.info(EELFLoggerDelegate.applicationLogger, "Request is entering cadifilter");
+
+ long startTime = System.currentTimeMillis();
+ request.setAttribute("startTime", startTime);
+
+ super.doFilter(request, response, chain);
+
+ //Commented by saumya (sp931a) on 04/11/19 for auth filter
+ //chain.doFilter(request, response);
+ }
} \ No newline at end of file
diff --git a/src/main/java/org/onap/music/authentication/MusicAAFAuthentication.java b/src/main/java/org/onap/music/authentication/MusicAAFAuthentication.java
deleted file mode 100644
index a84bdd9b..00000000
--- a/src/main/java/org/onap/music/authentication/MusicAAFAuthentication.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * ============LICENSE_START==========================================
- * org.onap.music
- * ===================================================================
- * Copyright (c) 2017 AT&T Intellectual Property
- * ===================================================================
- * Modifications Copyright (c) 2019 Samsung
- * ===================================================================
- * 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.music.authentication;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.ws.rs.core.MediaType;
-
-import org.apache.commons.jcs.access.CacheAccess;
-import org.onap.music.datastore.PreparedQueryObject;
-import org.onap.music.eelf.logging.EELFLoggerDelegate;
-import org.onap.music.eelf.logging.format.AppMessages;
-import org.onap.music.eelf.logging.format.ErrorSeverity;
-import org.onap.music.eelf.logging.format.ErrorTypes;
-import org.onap.music.exceptions.MusicServiceException;
-import org.onap.music.authentication.MusicAuthenticator.Operation;
-import org.onap.music.main.MusicCore;
-import org.onap.music.main.MusicUtil;
-
-import com.datastax.driver.core.DataType;
-import com.datastax.driver.core.Row;
-import com.sun.jersey.api.client.Client;
-import com.sun.jersey.api.client.ClientResponse;
-import com.sun.jersey.api.client.WebResource;
-
-public class MusicAAFAuthentication implements MusicAuthenticator {
-
- private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicAAFAuthentication.class);
-
- @Override
- public boolean authenticateAdmin(String authorization) {
- logger.info(EELFLoggerDelegate.applicationLogger, "MusicCore.authenticateAdmin: ");
- String userId = MusicUtil.extractBasicAuthentication(authorization).get(MusicUtil.USERID);
- CacheAccess<String, String> adminCache = CachingUtil.getAdminUserCache();
- if (authorization == null) {
- logger.error(EELFLoggerDelegate.errorLogger, "Authorization cannot be empty...");
- return false;
- }
- if (adminCache.get(authorization) != null && adminCache.get(authorization).equals(userId)) {
- logger.info(EELFLoggerDelegate.applicationLogger, "MusicCore.authenticateAdmin: Validated against admincache.. ");
- return true;
- }
- else {
- Client client = Client.create();
- String aafUrl = MusicUtil.getAafAdminUrl();
- if (aafUrl==null) {
- logger.error(EELFLoggerDelegate.errorLogger, "Admin url is not set, please set in properties");
- return false;
- }
-
- WebResource webResource = client.resource(
- MusicUtil.getAafAdminUrl().concat(userId).concat("/").concat(MusicUtil.getAdminAafRole()));
-
- ClientResponse response = webResource.accept(MediaType.APPLICATION_JSON)
- .header("Authorization", authorization).get(ClientResponse.class);
- if (response.getStatus() == 200) {
- CachingUtil.updateAdminUserCache(authorization, userId);
- return true;
- }
- }
- return false;
- }
-
- @Override
- public boolean authenticateUser(String namespace, String authorization, String keyspace,
- String aid, Operation operation) {
- logger.info(EELFLoggerDelegate.applicationLogger,"Inside User Authentication.......");
- Map<String,String> userCredentials = MusicUtil.extractBasicAuthentication(authorization);
- String userId = userCredentials.get(MusicUtil.USERID);
- String password = userCredentials.get(MusicUtil.PASSWORD);
-
- Map<String, Object> resultMap = new HashMap<>();
- String uuid = null;
- if(! MusicUtil.getIsCadi()) {
- resultMap = CachingUtil.validateRequest(namespace, userId, password, keyspace, aid,
- operation);
- if (!resultMap.isEmpty())
- return false;
- String isAAFApp = null;
- try {
- isAAFApp= CachingUtil.isAAFApplication(namespace);
- } catch(MusicServiceException e) {
- logger.error(e.getErrorMessage(), e);
- resultMap.put("Exception", e.getMessage());
- return false;
- }
- if(isAAFApp == null) {
- resultMap.put("Exception", "Namespace: "+namespace+" doesn't exist. Please make sure ns(appName)"
- + " is correct and Application is onboarded.");
- return false;
- }
- boolean isAAF = Boolean.parseBoolean(isAAFApp);
- if (userId == null || password == null) {
- logger.error(EELFLoggerDelegate.errorLogger,"", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
- logger.error(EELFLoggerDelegate.errorLogger,"UserId/Password or more required headers is missing.");
- resultMap.put("Exception",
- "UserId and Password are mandatory for the operation " + operation);
- return false;
- }
- if(!isAAF && !(operation==Operation.CREATE_KEYSPACE)) {
- resultMap = CachingUtil.authenticateAIDUser(namespace, userId, password, keyspace);
- if (!resultMap.isEmpty())
- return false;
-
- }
- if (isAAF && namespace != null && userId != null && password != null) {
- boolean isValid = true;
- try {
- isValid = CachingUtil.authenticateAAFUser(namespace, userId, password, keyspace);
- } catch (Exception e) {
- logger.error(EELFLoggerDelegate.errorLogger,"Error while aaf authentication for user:" + userId);
- logger.error(EELFLoggerDelegate.errorLogger,"Error: "+ e.getMessage(), e);
- logger.error(EELFLoggerDelegate.errorLogger,e.getMessage(), AppMessages.AUTHENTICATIONERROR ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
- logger.error(EELFLoggerDelegate.errorLogger,"Got exception while AAF authentication for namespace " + namespace);
- resultMap.put("Exception", e.getMessage());
- }
- if (!isValid) {
- logger.error(EELFLoggerDelegate.errorLogger,"User not authenticated...", AppMessages.MISSINGINFO ,ErrorSeverity.WARN, ErrorTypes.AUTHENTICATIONERROR);
- resultMap.put("Exception", "User not authenticated...");
- }
- if (!resultMap.isEmpty())
- return false;
-
- }
- } else {
-
- String cachedKS = CachingUtil.getKSFromCadiCache(userId);
- if(cachedKS != null && !cachedKS.equals(keyspace)) {
- resultMap.put("Exception", "User not authenticated to access this keyspace...");
- return false;
- }
- }
-
- if (operation==Operation.CREATE_KEYSPACE) {
- try {
- logger.info(EELFLoggerDelegate.applicationLogger,"AID is not provided. Creating new UUID for keyspace.");
- PreparedQueryObject pQuery = new PreparedQueryObject();
- pQuery.appendQueryString(
- "select uuid from admin.keyspace_master where application_name=? and username=? and keyspace_name=? allow filtering");
- pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), namespace));
- pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(), userId));
- pQuery.addValue(MusicUtil.convertToActualDataType(DataType.text(),
- MusicUtil.DEFAULTKEYSPACENAME));
- Row rs = MusicCore.get(pQuery).one();
- uuid = rs.getUUID("uuid").toString();
- resultMap.put("uuid", "existing");
- } catch (Exception e) {
- logger.error(EELFLoggerDelegate.applicationLogger,"No UUID found in DB. So creating new UUID.", e);
- uuid = MusicUtil.generateUUID();
- resultMap.put("uuid", "new");
- }
- resultMap.put("aid", uuid);
- CachingUtil.updateCadiCache(userId, keyspace);
- }
- return true;
- }
-
-}
diff --git a/src/main/java/org/onap/music/authentication/MusicAuthenticator.java b/src/main/java/org/onap/music/authentication/MusicAuthenticator.java
deleted file mode 100644
index 78f76ab1..00000000
--- a/src/main/java/org/onap/music/authentication/MusicAuthenticator.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * ============LICENSE_START==========================================
- * org.onap.music
- * ===================================================================
- * Copyright (c) 2019 AT&T Intellectual Property
- * ===================================================================
- * 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.music.authentication;
-
-public interface MusicAuthenticator {
- public enum Operation{
- CREATE_KEYSPACE,
- DROP_KEYSPACE,
- CREATE_TABLE,
- CREATE_INDEX,
- INSERT_INTO_TABLE,
- UPDATE_TABLE,
- DELETE_FROM_TABLE,
- DROP_TABLE,
- SELECT_CRITICAL,
- SELECT,
- CREATE_LOCKREF,
- ACQUIRE_LOCK,
- CURRENT_LOCK,
- DELETE_LOCK
- }
-
- /**
- * Authenticate a user account
- * @param namespace - user's namespace
- * @param authorization - basicAuth representation of username/password
- * @param keyspace - keyspace user is trying to access
- * @param aid - aid that identifies the user
- * @param operation - operation that user is trying to do
- * @return true if user has access
- */
- public boolean authenticateUser(String namespace, String authorization,
- String keyspace, String aid, Operation operation);
-
- /**
- * Authenticate an administrative account
- * @param authorization - basicAuth representation of username/password
- * @return true if user has admin privileges
- */
- public boolean authenticateAdmin(String authorization);
-
-}
diff --git a/src/main/java/org/onap/music/authentication/MusicAuthorizationFilter.java b/src/main/java/org/onap/music/authentication/MusicAuthorizationFilter.java
new file mode 100644
index 00000000..b1db1083
--- /dev/null
+++ b/src/main/java/org/onap/music/authentication/MusicAuthorizationFilter.java
@@ -0,0 +1,170 @@
+/*
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property
+ * ===================================================================
+ * Modifications Copyright (c) 2019 Samsung
+ * ===================================================================
+ * 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.music.authentication;
+
+import java.io.IOException;
+import java.util.Base64;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.onap.music.eelf.logging.EELFLoggerDelegate;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.PropertySource;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+/**
+ * This filter class does authorization from AAF
+ *
+ * @author sp931a
+ *
+ */
+@PropertySource(value = {"file:/opt/app/music/etc/music.properties"})
+public class MusicAuthorizationFilter implements Filter {
+
+ @Value("${music.aaf.ns}")
+ private String musicNS;
+
+ private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MusicAuthorizationFilter.class);
+
+ public MusicAuthorizationFilter() throws ServletException {
+ super();
+ }
+
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {
+
+ }
+
+ @Override
+ public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
+ throws IOException, ServletException {
+
+ logger.debug(EELFLoggerDelegate.applicationLogger,
+ "In MusicAuthorizationFilter doFilter start() ::::::::::::::::::::::::");
+
+ HttpServletResponse httpResponse = null;
+
+ boolean isAuthAllowed = false;
+
+ if (null != servletRequest && null != servletResponse) {
+ httpResponse = (HttpServletResponse) servletResponse;
+
+ logger.debug(EELFLoggerDelegate.applicationLogger,
+ "Music NS defined in music property file --------------------------" + musicNS);
+
+ long startTime = 0;
+ if( null != servletRequest.getAttribute("startTime")) {
+ startTime = ((Long)servletRequest.getAttribute("startTime")).longValue();
+ } else {
+ startTime = System.currentTimeMillis(); // this will set only incase the request attribute not found
+ }
+
+ try {
+ isAuthAllowed = AuthUtil.isAccessAllowed(servletRequest, musicNS);
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.applicationLogger,
+ "Error while checking authorization :::" + e.getMessage());
+ }
+
+ long endTime = System.currentTimeMillis();
+
+ //startTime set in <code>CadiAuthFilter</code> doFilter
+ logger.debug(EELFLoggerDelegate.applicationLogger,
+ "Time took for authentication & authorization : "
+ + (endTime - startTime) + " milliseconds");
+
+ if (!isAuthAllowed) {
+ logger.debug(EELFLoggerDelegate.applicationLogger,
+ "Unauthorized Access");
+ AuthorizationError authError = new AuthorizationError();
+ authError.setResponseCode(HttpServletResponse.SC_UNAUTHORIZED);
+ authError.setResponseMessage("Unauthorized Access - Please make sure you are "
+ + "onboarded and have proper access to MUSIC. ");
+
+ byte[] responseToSend = restResponseBytes(authError);
+ httpResponse.setHeader("Content-Type", "application/json");
+
+ httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+ servletResponse.getOutputStream().write(responseToSend);
+ return;
+ } else {
+ filterChain.doFilter(servletRequest, servletResponse);
+ }
+ }
+ logger.debug(EELFLoggerDelegate.applicationLogger,
+ "In MusicAuthorizationFilter doFilter exit() ::::::::::::::::::::::::");
+ }
+
+ private byte[] restResponseBytes(AuthorizationError eErrorResponse) throws IOException {
+ String serialized = new ObjectMapper().writeValueAsString(eErrorResponse);
+ return serialized.getBytes();
+ }
+
+ private Map<String, String> getHeadersInfo(HttpServletRequest request) {
+
+ Map<String, String> map = new HashMap<String, String>();
+
+ Enumeration headerNames = request.getHeaderNames();
+ while (headerNames.hasMoreElements()) {
+ String key = (String) headerNames.nextElement();
+ String value = request.getHeader(key);
+ map.put(key, value);
+ }
+
+ return map;
+ }
+
+ private static String getUserNamefromRequest(HttpServletRequest httpRequest) {
+ String authHeader = httpRequest.getHeader("Authorization");
+ String username = null;
+ if (authHeader != null) {
+ String[] split = authHeader.split("\\s+");
+ if (split.length > 0) {
+ String basic = split[0];
+
+ if ("Basic".equalsIgnoreCase(basic)) {
+ byte[] decodedBytes = Base64.getDecoder().decode(split[1]);
+ String decodedString = new String(decodedBytes);
+ int p = decodedString.indexOf(":");
+ if (p != -1) {
+ username = decodedString.substring(0, p);
+ }
+ }
+ }
+ }
+ return username;
+ }
+}