2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (c) 2017-2019 AT&T Intellectual Property. All rights reserved.
6 * Copyright (c) 2017-2019 European Software Marketing Ltd.
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
22 package org.onap.aai.babel;
24 import static org.hamcrest.CoreMatchers.is;
25 import static org.hamcrest.MatcherAssert.assertThat;
26 import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
27 import static org.junit.jupiter.api.Assertions.assertThrows;
28 import static org.junit.jupiter.api.Assertions.assertTrue;
31 import java.io.FileWriter;
32 import java.io.IOException;
33 import java.util.concurrent.TimeUnit;
34 import org.json.JSONArray;
35 import org.json.JSONException;
36 import org.json.JSONObject;
37 import org.junit.jupiter.api.Assertions;
38 import org.junit.jupiter.api.BeforeEach;
39 import org.junit.jupiter.api.Test;
40 import org.onap.aai.auth.AAIAuthException;
41 import org.onap.aai.auth.AAIMicroServiceAuth;
42 import org.onap.aai.auth.AAIMicroServiceAuthCore;
43 import org.onap.aai.babel.config.BabelAuthConfig;
44 import org.springframework.mock.web.MockHttpServletRequest;
47 * Tests {@link AAIMicroServiceAuth}.
50 public class TestMicroServiceAuth {
52 private static final String VALID_ADMIN_USER = "cn=common-name, ou=org-unit, o=org, l=location, st=state, c=us";
53 private static final String TEST_POLICY_FILE = "auth_policy.json";
57 System.setProperty("CONFIG_HOME", "src/test/resources");
61 * Test authorization of a request when authentication is disabled.
63 * @throws AAIAuthException
64 * if the test creates invalid Auth Policy roles
67 public void testAuthenticationDisabled() throws AAIAuthException {
68 BabelAuthConfig babelAuthConfig = new BabelAuthConfig();
69 babelAuthConfig.setAuthenticationDisable(true);
70 AAIMicroServiceAuth auth = new AAIMicroServiceAuth(babelAuthConfig);
71 assertThat(auth.validateRequest(null, new MockHttpServletRequest(), null, "any/uri"), is(true));
75 * Temporarily invalidate the default policy file and then try to initialize the authorization class using the name
76 * of a policy file that does not exist.
78 * @throws AAIAuthException
79 * if the Auth policy file cannot be loaded
82 public void missingPolicyFile() throws AAIAuthException {
83 assertThrows(AAIAuthException.class, () -> {
84 String defaultFile = AAIMicroServiceAuthCore.getDefaultAuthFileName();
86 AAIMicroServiceAuthCore.setDefaultAuthFileName("invalid.default.file");
87 BabelAuthConfig babelServiceAuthConfig = new BabelAuthConfig();
88 babelServiceAuthConfig.setAuthPolicyFile("invalid.file.name");
89 new AAIMicroServiceAuth(babelServiceAuthConfig);
91 AAIMicroServiceAuthCore.setDefaultAuthFileName(defaultFile);
97 * Temporarily invalidate the default policy file and then try to initialize the authorization class using a null
100 * @throws AAIAuthException
101 * if the Auth policy file cannot be loaded
104 public void testNullPolicyFile() throws AAIAuthException {
105 assertThrows(AAIAuthException.class, () -> {
106 String defaultFile = AAIMicroServiceAuthCore.getDefaultAuthFileName();
108 AAIMicroServiceAuthCore.setDefaultAuthFileName("invalid.default.file");
109 BabelAuthConfig babelServiceAuthConfig = new BabelAuthConfig();
110 babelServiceAuthConfig.setAuthPolicyFile(null);
111 new AAIMicroServiceAuth(babelServiceAuthConfig);
113 AAIMicroServiceAuthCore.setDefaultAuthFileName(defaultFile);
119 * Test reloading of the auth policy file after this file has been deleted.
121 * @throws AAIAuthException
122 * if the test creates invalid Auth Policy roles
123 * @throws JSONException
124 * if this test creates an invalid JSON object
125 * @throws IOException
126 * for I/O failures, e.g. when creating the temporary auth policy file
129 public void testReloadDeletedFile() throws AAIAuthException, JSONException, IOException {
130 File file = createTestPolicyFile();
131 AAIMicroServiceAuthCore.init(file.getAbsolutePath());
132 assertThat(file.delete(), is(true));
134 AAIMicroServiceAuthCore.reloadUsers();
135 Assertions.fail("Expected an AAIAuthException to be thrown");
136 } catch (AAIAuthException e) {
142 * Test reloading of the auth policy file after this file has been made invalid.
144 * @throws AAIAuthException
145 * if the test creates invalid Auth Policy roles
146 * @throws JSONException
147 * if this test creates an invalid JSON object
148 * @throws IOException
149 * for I/O failures, e.g. when creating the temporary auth policy file
152 public void testReloadInvalidFile() throws AAIAuthException, JSONException, IOException {
153 assertThrows(AAIAuthException.class, () -> {
154 File file = createTestPolicyFile();
155 AAIMicroServiceAuthCore.init(file.getAbsolutePath());
156 writeToFile(file, "not valid JSON content");
157 AAIMicroServiceAuthCore.reloadUsers();
162 * Test loading of a temporary file created with the specified roles.
164 * @throws AAIAuthException
165 * if the test creates invalid Auth Policy roles
166 * @throws IOException
168 * @throws JSONException
169 * if this test creates an invalid JSON object
172 public void createLocalAuthFile() throws JSONException, AAIAuthException, IOException {
174 assertThat(AAIMicroServiceAuthCore.authorize("nosuchuser", "method:func"), is(false));
175 assertThat(AAIMicroServiceAuthCore.authorize("user", "method:func"), is(true));
179 * Test re-loading of users by changing the contents of a temporary file.
181 * @throws JSONException
182 * if this test creates an invalid JSON object
183 * @throws AAIAuthException
184 * if the test creates invalid Auth Policy roles
185 * @throws IOException
187 * @throws InterruptedException
188 * if interrupted while sleeping
191 public void createLocalAuthFileOnChange()
192 throws JSONException, AAIAuthException, IOException, InterruptedException {
193 assertDoesNotThrow(() -> {
194 File file = createTestPolicyFile();
196 BabelAuthConfig babelAuthConfig = new BabelAuthConfig();
197 babelAuthConfig.setAuthPolicyFile(file.getAbsolutePath());
198 new AAIMicroServiceAuth(babelAuthConfig);
200 // Make changes to the temp file
201 writeToFile(file, "");
203 // Wait for the file to be reloaded
204 TimeUnit.SECONDS.sleep(3);
206 AAIMicroServiceAuthCore.cleanup();
211 * Test that the default policy file is loaded when a non-existent file is passed to the authorization class.
213 * @throws AAIAuthException
214 * if the Auth Policy cannot be loaded
217 public void createAuthFromDefaultFile() throws AAIAuthException {
218 BabelAuthConfig babelServiceAuthConfig = new BabelAuthConfig();
219 babelServiceAuthConfig.setAuthPolicyFile("non-existent-file");
220 AAIMicroServiceAuth auth = new AAIMicroServiceAuth(babelServiceAuthConfig);
221 // The default policy will have been loaded
222 assertAdminUserAuthorisation(auth, VALID_ADMIN_USER);
226 * Test that the default policy file is loaded when a non-existent file is passed to the authorisation class and
227 * CONFIG_HOME is not set.
229 * @throws AAIAuthException
230 * if the Auth Policy cannot be loaded
233 public void createAuthFromDefaultFileAppHome() throws AAIAuthException {
234 assertDoesNotThrow(() -> {
235 System.clearProperty("CONFIG_HOME");
236 System.setProperty("APP_HOME", "src/test/resources");
237 BabelAuthConfig babelServiceAuthConfig = new BabelAuthConfig();
238 babelServiceAuthConfig.setAuthPolicyFile("non-existent-file");
239 new AAIMicroServiceAuth(babelServiceAuthConfig);
240 // The default policy will have been loaded from APP_HOME/appconfig
242 // The default policy will have been loaded from APP_HOME/appconfig
246 * Test loading of the policy file relative to CONFIG_HOME.
248 * @throws AAIAuthException
249 * if the Auth Policy cannot be loaded
252 public void createAuth() throws AAIAuthException {
253 AAIMicroServiceAuth auth = createStandardAuth();
254 assertAdminUserAuthorisation(auth, VALID_ADMIN_USER);
258 public void testAuthUser() throws AAIAuthException {
259 createStandardAuth();
260 assertThat(AAIMicroServiceAuthCore.authorize(VALID_ADMIN_USER, "GET:actions"), is(true));
261 assertThat(AAIMicroServiceAuthCore.authorize(VALID_ADMIN_USER, "WRONG:action"), is(false));
265 public void testValidateRequest() throws AAIAuthException {
266 AAIMicroServiceAuth auth = createStandardAuth();
267 assertThat(auth.validateRequest(null, new MockHttpServletRequest(), null, "app/v1/babel"), is(false));
270 private AAIMicroServiceAuth createStandardAuth() throws AAIAuthException {
271 BabelAuthConfig babelServiceAuthConfig = new BabelAuthConfig();
272 babelServiceAuthConfig.setAuthPolicyFile(TEST_POLICY_FILE);
273 return new AAIMicroServiceAuth(babelServiceAuthConfig);
278 * Create a temporary JSON file using some valid test roles.
280 * @return the new temporary file
281 * @throws IOException
284 private File createTestPolicyFile() throws JSONException, IOException {
285 return createTempPolicyFile(createRoleObject("role", createUserObject("user"), createFunctionObject("func")));
289 * Create a test Auth policy JSON file and pass this to the Auth Service.
292 * the Auth policy JSON content
293 * @return a new Auth Service configured with the supplied roles
294 * @throws IOException
296 * @throws AAIAuthException
297 * if the auth policy file cannot be loaded
298 * @throws JSONException
299 * if this test creates an invalid JSON object
301 private AAIMicroServiceAuth createAuthService() throws AAIAuthException, IOException, JSONException {
302 File file = createTestPolicyFile();
303 BabelAuthConfig babelAuthConfig = new BabelAuthConfig();
304 babelAuthConfig.setAuthPolicyFile(file.getAbsolutePath());
305 return new AAIMicroServiceAuth(babelAuthConfig);
309 * Create a temporary JSON file using the supplied roles.
312 * the roles to use to populate the new file
313 * @return the new temporary file
314 * @throws IOException
317 private File createTempPolicyFile(JSONObject roles) throws IOException {
318 File file = File.createTempFile("auth-policy", "json");
320 writeToFile(file, roles.toString());
325 * Write String content to a file, flush and close.
328 * the file to write to
330 * the String content to write to the file
331 * @throws IOException
332 * if the file cannot be opened for writing, or an I/O error occurs
334 private void writeToFile(File file, String text) throws IOException {
335 FileWriter fileWriter = new FileWriter(file);
336 fileWriter.write(text);
342 * Assert authorization results for an admin user based on the test policy file.
345 * the Auth Service to test
348 * @throws AAIAuthException
349 * if the Auth Service is not initialized
351 private void assertAdminUserAuthorisation(AAIMicroServiceAuth auth, String adminUser) throws AAIAuthException {
352 assertThat(AAIMicroServiceAuthCore.authorize(adminUser, "GET:actions"), is(true));
353 assertThat(AAIMicroServiceAuthCore.authorize(adminUser, "POST:actions"), is(true));
354 assertThat(AAIMicroServiceAuthCore.authorize(adminUser, "PUT:actions"), is(true));
355 assertThat(AAIMicroServiceAuthCore.authorize(adminUser, "DELETE:actions"), is(true));
358 private JSONArray createFunctionObject(String functionName) throws JSONException {
359 JSONArray functionsArray = new JSONArray();
360 JSONObject func = new JSONObject();
361 func.put("name", functionName);
362 func.put("methods", createMethodObject("method"));
363 functionsArray.put(func);
364 return functionsArray;
367 private JSONArray createMethodObject(String methodName) throws JSONException {
368 JSONArray methodsArray = new JSONArray();
369 JSONObject method = new JSONObject();
370 method.put("name", methodName);
371 methodsArray.put(method);
375 private JSONArray createUserObject(String username) throws JSONException {
376 JSONArray usersArray = new JSONArray();
377 JSONObject user = new JSONObject();
378 user.put("username", username);
379 usersArray.put(user);
383 private JSONObject createRoleObject(String roleName, JSONArray usersArray, JSONArray functionsArray)
384 throws JSONException {
385 JSONObject role = new JSONObject();
386 role.put("name", roleName);
387 role.put("functions", functionsArray);
388 role.put("users", usersArray);
390 JSONArray rolesArray = new JSONArray();
391 rolesArray.put(role);
393 JSONObject roles = new JSONObject();
394 roles.put("roles", rolesArray);