diff options
4 files changed, 175 insertions, 53 deletions
diff --git a/src/main/java/org/onap/aai/auth/AAIMicroServiceAuthCore.java b/src/main/java/org/onap/aai/auth/AAIMicroServiceAuthCore.java index ddbc002..0eec7e1 100644 --- a/src/main/java/org/onap/aai/auth/AAIMicroServiceAuthCore.java +++ b/src/main/java/org/onap/aai/auth/AAIMicroServiceAuthCore.java @@ -2,8 +2,8 @@ * ============LICENSE_START======================================================= * org.onap.aai * ================================================================================ - * Copyright © 2017-2019 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017-2019 European Software Marketing Ltd. + * Copyright (c) 2017-2019 AT&T Intellectual Property. All rights reserved. + * Copyright (c) 2017-2019 European Software Marketing Ltd. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,12 +27,14 @@ import com.fasterxml.jackson.databind.ObjectMapper; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Map.Entry; +import java.util.Optional; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.TimeUnit; @@ -44,15 +46,15 @@ public class AAIMicroServiceAuthCore { private static LogHelper applicationLogger = LogHelper.INSTANCE; - private static final String CONFIG_HOME = System.getProperty("CONFIG_HOME"); - - public static final String FILESEP = - (System.getProperty("file.separator") == null) ? "/" : System.getProperty("file.separator"); - public static final String APPCONFIG_DIR = - (CONFIG_HOME == null) ? System.getProperty("APP_HOME") + FILESEP + "appconfig" : CONFIG_HOME; - - private static String appConfigAuthDir = APPCONFIG_DIR + FILESEP + "auth"; - private static String defaultAuthFileName = appConfigAuthDir + FILESEP + "auth_policy.json"; + /** + * The default policy file is expected to be located in either one of + * <ul> + * <li><code>$CONFIG_HOME/auth_policy.json</code></li> + * <li><code>$CONFIG_HOME/auth/auth_policy.json</code></li> + * <p> + * Note that if <code>CONFIG_HOME</code> is not set then assume it has a value of <code>$APP_HOME/appconfig</code> + */ + private static String defaultAuthFileName = "auth_policy.json"; private static boolean usersInitialized = false; private static HashMap<String, AAIAuthUser> users; @@ -83,8 +85,9 @@ public class AAIMicroServiceAuthCore { applicationLogger.error(ApplicationMsgs.PROCESS_REQUEST_ERROR, e); throw new AAIAuthException(e.getMessage()); } + if (policyAuthFileName == null) { - throw new AAIAuthException("Auth policy file could not be found" + CONFIG_HOME + APPCONFIG_DIR); + throw new AAIAuthException("Auth policy file could not be found"); } AAIMicroServiceAuthCore.reloadUsers(); @@ -116,21 +119,46 @@ public class AAIMicroServiceAuthCore { } public static String getConfigFile(String authPolicyFile) throws IOException { - File authFile = new File(authPolicyFile); - if (authFile.exists()) { - return authFile.getCanonicalPath(); - } - authFile = new File(appConfigAuthDir + FILESEP + authPolicyFile); - if (authFile.exists()) { - return authFile.getCanonicalPath(); - } - if (defaultAuthFileName != null) { - authFile = new File(defaultAuthFileName); - if (authFile.exists()) { - return defaultAuthFileName; + return locateConfigFile(authPolicyFile).orElse(locateConfigFile(defaultAuthFileName).orElse(null)); + } + + /** + * Locate the auth policy file by its name or path. + * <ul> + * <li>First try to use the absolute path to the file (if provided), or instead locate the path relative to the + * current (or user) dir.</li> + * <li>If this fails, try resolving the path relative to the configuration home location (either + * <code>$CONFIG_HOME</code> or <code>$APP_HOME/appconfig</code>).</li> + * <li>If this fails try resolving relative to the <code>auth</code> folder under configuration home.</li> + * + * @param authPolicyFile + * filename or path + * @return the Optional canonical path to the located policy file + * @throws IOException + * if the construction of the canonical pathname requires filesystem queries which cause I/O error(s) + */ + private static Optional<String> locateConfigFile(String authPolicyFile) throws IOException { + if (authPolicyFile != null) { + List<Path> paths = new ArrayList<>(); + paths.add(Paths.get(".")); + + String configHome = System.getProperty("CONFIG_HOME"); + if (configHome == null) { + configHome = System.getProperty("APP_HOME") + "/appconfig"; + } + + paths.add(Paths.get(configHome)); + paths.add(Paths.get(configHome).resolve("auth")); + + for (Path path : paths) { + File authFile = path.resolve(authPolicyFile).toFile(); + if (authFile.exists()) { + return Optional.of(authFile.getCanonicalPath()); + } } } - return null; + + return Optional.empty(); } public static synchronized void reloadUsers() throws AAIAuthException { @@ -190,28 +218,18 @@ public class AAIMicroServiceAuthCore { user = new AAIAuthUser(); } applicationLogger.debug("Assigning " + roleName + " to user " + name); - user.setUser(name); user.addRole(roleName, r); users.put(name, user); } } public static class AAIAuthUser { - private String username; private HashMap<String, AAIAuthRole> roles; public AAIAuthUser() { this.roles = new HashMap<>(); } - public String getUser() { - return this.username; - } - - public Map<String, AAIAuthRole> getRoles() { - return this.roles; - } - public void addRole(String roleName, AAIAuthRole r) { this.roles.put(roleName, r); } @@ -225,10 +243,6 @@ public class AAIMicroServiceAuthCore { } return false; } - - public void setUser(String myuser) { - this.username = myuser; - } } public static class AAIAuthRole { @@ -243,12 +257,6 @@ public class AAIMicroServiceAuthCore { this.allowedFunctions.add(func); } - public void delAllowedFunction(String delFunc) { - if (this.allowedFunctions.contains(delFunc)) { - this.allowedFunctions.remove(delFunc); - } - } - public boolean hasAllowedFunction(String afunc) { return this.allowedFunctions.contains(afunc); } diff --git a/src/main/java/org/onap/aai/babel/config/BabelAuthConfig.java b/src/main/java/org/onap/aai/babel/config/BabelAuthConfig.java index 21525a1..cae71de 100644 --- a/src/main/java/org/onap/aai/babel/config/BabelAuthConfig.java +++ b/src/main/java/org/onap/aai/babel/config/BabelAuthConfig.java @@ -2,8 +2,8 @@ * ============LICENSE_START======================================================= * org.onap.aai * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017-2018 European Software Marketing Ltd. + * Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. + * Copyright (c) 2017-2018 European Software Marketing Ltd. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ * limitations under the License. * ============LICENSE_END========================================================= */ + package org.onap.aai.babel.config; import org.springframework.beans.factory.annotation.Value; diff --git a/src/test/java/org/onap/aai/babel/MicroServiceAuthTest.java b/src/test/java/org/onap/aai/babel/MicroServiceAuthTest.java index b9a8ff9..ef9504b 100644 --- a/src/test/java/org/onap/aai/babel/MicroServiceAuthTest.java +++ b/src/test/java/org/onap/aai/babel/MicroServiceAuthTest.java @@ -27,9 +27,11 @@ import static org.junit.Assert.assertThat; import java.io.File; import java.io.FileWriter; import java.io.IOException; +import java.util.concurrent.TimeUnit; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import org.junit.Before; import org.junit.Test; import org.onap.aai.auth.AAIAuthException; import org.onap.aai.auth.AAIMicroServiceAuth; @@ -46,11 +48,26 @@ public class MicroServiceAuthTest { private static final String VALID_ADMIN_USER = "cn=common-name, ou=org-unit, o=org, l=location, st=state, c=us"; private static final String authPolicyFile = "auth_policy.json"; - static { + @Before + public void setup() { System.setProperty("CONFIG_HOME", "src/test/resources"); } /** + * Test authorization of a request when authentication is disabled. + * + * @throws AAIAuthException + * if the test creates invalid Auth Policy roles + */ + @Test + public void testAuthenticationDisabled() throws AAIAuthException { + BabelAuthConfig babelAuthConfig = new BabelAuthConfig(); + babelAuthConfig.setAuthenticationDisable(true); + AAIMicroServiceAuth auth = new AAIMicroServiceAuth(babelAuthConfig); + assertThat(auth.validateRequest(null, new MockHttpServletRequest(), null, "any/uri"), is(true)); + } + + /** * Temporarily invalidate the default policy file and then try to initialize the authorization class using the name * of a policy file that does not exist. * @@ -71,6 +88,26 @@ public class MicroServiceAuthTest { } /** + * Temporarily invalidate the default policy file and then try to initialize the authorization class using a null + * policy file name. + * + * @throws AAIAuthException + * if the Auth policy file cannot be loaded + */ + @Test(expected = AAIAuthException.class) + public void testNullPolicyFile() throws AAIAuthException { + String defaultFile = AAIMicroServiceAuthCore.getDefaultAuthFileName(); + try { + AAIMicroServiceAuthCore.setDefaultAuthFileName("invalid.default.file"); + BabelAuthConfig babelServiceAuthConfig = new BabelAuthConfig(); + babelServiceAuthConfig.setAuthPolicyFile(null); + new AAIMicroServiceAuth(babelServiceAuthConfig); + } finally { + AAIMicroServiceAuthCore.setDefaultAuthFileName(defaultFile); + } + } + + /** * Test loading of a temporary file created with the specified roles. * * @throws AAIAuthException @@ -89,6 +126,40 @@ public class MicroServiceAuthTest { } /** + * Test re-loading of users by changing the contents of a temporary file. + * + * @throws JSONException + * if this test creates an invalid JSON object + * @throws AAIAuthException + * if the test creates invalid Auth Policy roles + * @throws IOException + * for I/O failures + * @throws InterruptedException + * if interrupted while sleeping + */ + @Test + public void createLocalAuthFileOnChange() + throws JSONException, AAIAuthException, IOException, InterruptedException { + JSONObject roles = createRoleObject("role", createUserObject("user"), createFunctionObject("func")); + File file = createTempPolicyFile(roles); + + BabelAuthConfig babelAuthConfig = new BabelAuthConfig(); + babelAuthConfig.setAuthPolicyFile(file.getAbsolutePath()); + new AAIMicroServiceAuth(babelAuthConfig); + + // Make changes to the temp file + FileWriter fileWriter = new FileWriter(file); + fileWriter.write(""); + fileWriter.flush(); + fileWriter.close(); + + // Wait for the file to be reloaded + TimeUnit.SECONDS.sleep(3); + + AAIMicroServiceAuthCore.cleanup(); + } + + /** * Test that the default policy file is loaded when a non-existent file is passed to the authorisation class. * * @throws AAIAuthException @@ -104,6 +175,23 @@ public class MicroServiceAuthTest { } /** + * Test that the default policy file is loaded when a non-existent file is passed to the authorisation class and + * CONFIG_HOME is not set. + * + * @throws AAIAuthException + * if the Auth Policy cannot be loaded + */ + @Test + public void createAuthFromDefaultFileAppHome() throws AAIAuthException { + System.clearProperty("CONFIG_HOME"); + System.setProperty("APP_HOME", "src/test/resources"); + BabelAuthConfig babelServiceAuthConfig = new BabelAuthConfig(); + babelServiceAuthConfig.setAuthPolicyFile("non-existent-file"); + new AAIMicroServiceAuth(babelServiceAuthConfig); + // The default policy will have been loaded from APP_HOME/appconfig + } + + /** * Test loading of the policy file relative to CONFIG_HOME. * * @throws AAIAuthException @@ -146,16 +234,29 @@ public class MicroServiceAuthTest { * if the auth policy file cannot be loaded */ private AAIMicroServiceAuth createAuthService(JSONObject roles) throws AAIAuthException, IOException { + File file = createTempPolicyFile(roles); + BabelAuthConfig babelAuthConfig = new BabelAuthConfig(); + babelAuthConfig.setAuthPolicyFile(file.getAbsolutePath()); + return new AAIMicroServiceAuth(babelAuthConfig); + } + + /** + * Create a temporary JSON file using the supplied roles. + * + * @param roles + * the roles to use to populate the new file + * @return the new temporary file + * @throws IOException + * for I/O errors + */ + private File createTempPolicyFile(JSONObject roles) throws IOException { File file = File.createTempFile("auth-policy", "json"); file.deleteOnExit(); FileWriter fileWriter = new FileWriter(file); fileWriter.write(roles.toString()); fileWriter.flush(); fileWriter.close(); - - BabelAuthConfig babelAuthConfig = new BabelAuthConfig(); - babelAuthConfig.setAuthPolicyFile(file.getAbsolutePath()); - return new AAIMicroServiceAuth(babelAuthConfig); + return file; } /** diff --git a/src/test/resources/appconfig/auth/auth_policy.json b/src/test/resources/appconfig/auth/auth_policy.json new file mode 100644 index 0000000..dc966e0 --- /dev/null +++ b/src/test/resources/appconfig/auth/auth_policy.json @@ -0,0 +1,12 @@ +{"roles": [ + { + "name": "nofuncauth", + "functions": [{ + "name": "nofuncutil" + }], + "users": [{ + "user": "aai", + "pass": "OBF:1u2a1t2v1vgb1s3g1s3m1vgj1t3b1u30" + }] + } +]} |