2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright © 2017-2019 AT&T Intellectual Property. All rights reserved.
6 * Copyright © 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.auth;
24 import com.fasterxml.jackson.core.JsonProcessingException;
25 import com.fasterxml.jackson.databind.JsonNode;
26 import com.fasterxml.jackson.databind.ObjectMapper;
28 import java.io.FileNotFoundException;
29 import java.io.IOException;
30 import java.util.ArrayList;
31 import java.util.Date;
32 import java.util.HashMap;
33 import java.util.List;
35 import java.util.Map.Entry;
36 import java.util.Timer;
37 import java.util.TimerTask;
38 import java.util.concurrent.TimeUnit;
39 import org.onap.aai.babel.logging.ApplicationMsgs;
40 import org.onap.aai.babel.logging.LogHelper;
42 /** Authentication and authorization by user and role. */
43 public class AAIMicroServiceAuthCore {
45 private static LogHelper applicationLogger = LogHelper.INSTANCE;
47 private static final String CONFIG_HOME = System.getProperty("CONFIG_HOME");
49 public static final String FILESEP =
50 (System.getProperty("file.separator") == null) ? "/" : System.getProperty("file.separator");
51 public static final String APPCONFIG_DIR =
52 (CONFIG_HOME == null) ? System.getProperty("APP_HOME") + FILESEP + "appconfig" : CONFIG_HOME;
54 private static String appConfigAuthDir = APPCONFIG_DIR + FILESEP + "auth";
55 private static String defaultAuthFileName = appConfigAuthDir + FILESEP + "auth_policy.json";
57 private static boolean usersInitialized = false;
58 private static HashMap<String, AAIAuthUser> users;
59 private static boolean timerSet = false;
60 private static Timer timer = null;
61 private static String policyAuthFileName;
63 public enum HTTP_METHODS {
64 GET, PUT, DELETE, HEAD, POST
68 private AAIMicroServiceAuthCore() {}
70 public static String getDefaultAuthFileName() {
71 return defaultAuthFileName;
74 public static void setDefaultAuthFileName(String defaultAuthFileName) {
75 AAIMicroServiceAuthCore.defaultAuthFileName = defaultAuthFileName;
78 public static synchronized void init(String authPolicyFile) throws AAIAuthException {
80 policyAuthFileName = AAIMicroServiceAuthCore.getConfigFile(authPolicyFile);
81 } catch (IOException e) {
82 applicationLogger.debug("Exception while retrieving policy file.");
83 applicationLogger.error(ApplicationMsgs.PROCESS_REQUEST_ERROR, e);
84 throw new AAIAuthException(e.getMessage());
86 if (policyAuthFileName == null) {
87 throw new AAIAuthException("Auth policy file could not be found" + CONFIG_HOME + APPCONFIG_DIR);
89 AAIMicroServiceAuthCore.reloadUsers();
91 TimerTask task = new FileWatcher(new File(policyAuthFileName)) {
93 protected void onChange(File file) {
94 // here we implement the onChange
95 applicationLogger.debug("File " + file.getName() + " has been changed!");
97 AAIMicroServiceAuthCore.reloadUsers();
98 } catch (AAIAuthException e) {
99 applicationLogger.error(ApplicationMsgs.PROCESS_REQUEST_ERROR, e);
101 applicationLogger.debug("File " + file.getName() + " has been reloaded!");
108 long period = TimeUnit.SECONDS.toMillis(1);
109 timer.schedule(task, new Date(), period);
110 applicationLogger.debug("Config Watcher Interval = " + period);
114 public static void cleanup() {
118 public static String getConfigFile(String authPolicyFile) throws IOException {
119 File authFile = new File(authPolicyFile);
120 if (authFile.exists()) {
121 return authFile.getCanonicalPath();
123 authFile = new File(appConfigAuthDir + FILESEP + authPolicyFile);
124 if (authFile.exists()) {
125 return authFile.getCanonicalPath();
127 if (defaultAuthFileName != null) {
128 authFile = new File(defaultAuthFileName);
129 if (authFile.exists()) {
130 return defaultAuthFileName;
136 public static synchronized void reloadUsers() throws AAIAuthException {
137 users = new HashMap<>();
139 ObjectMapper mapper = new ObjectMapper();
141 applicationLogger.debug("Reading from " + policyAuthFileName);
142 JsonNode rootNode = mapper.readTree(new File(policyAuthFileName));
143 for (JsonNode roleNode : rootNode.path("roles")) {
144 String roleName = roleNode.path("name").asText();
145 AAIAuthRole r = new AAIAuthRole();
146 installFunctionOnRole(roleNode.path("functions"), roleName, r);
147 assignRoleToUsers(roleNode.path("users"), roleName, r);
149 } catch (FileNotFoundException e) {
150 throw new AAIAuthException("Auth policy file could not be found", e);
151 } catch (JsonProcessingException e) {
152 throw new AAIAuthException("Error processing Auth policy file ", e);
153 } catch (IOException e) {
154 throw new AAIAuthException("Error reading Auth policy file", e);
157 usersInitialized = true;
160 private static void installFunctionOnRole(JsonNode functionsNode, String roleName, AAIAuthRole r) {
161 for (JsonNode functionNode : functionsNode) {
162 String function = functionNode.path("name").asText();
163 JsonNode methodsNode = functionNode.path("methods");
164 boolean hasMethods = false;
165 for (JsonNode method_node : methodsNode) {
166 String methodName = method_node.path("name").asText();
168 String func = methodName + ":" + function;
169 applicationLogger.debug("Installing function " + func + " on role " + roleName);
170 r.addAllowedFunction(func);
174 for (HTTP_METHODS meth : HTTP_METHODS.values()) {
175 String func = meth.toString() + ":" + function;
176 applicationLogger.debug("Installing (all methods) " + func + " on role " + roleName);
177 r.addAllowedFunction(func);
183 private static void assignRoleToUsers(JsonNode usersNode, String roleName, AAIAuthRole r) {
184 for (JsonNode userNode : usersNode) {
185 String name = userNode.path("username").asText().toLowerCase();
187 if (users.containsKey(name)) {
188 user = users.get(name);
190 user = new AAIAuthUser();
192 applicationLogger.debug("Assigning " + roleName + " to user " + name);
194 user.addRole(roleName, r);
195 users.put(name, user);
199 public static class AAIAuthUser {
200 private String username;
201 private HashMap<String, AAIAuthRole> roles;
203 public AAIAuthUser() {
204 this.roles = new HashMap<>();
207 public String getUser() {
208 return this.username;
211 public Map<String, AAIAuthRole> getRoles() {
215 public void addRole(String roleName, AAIAuthRole r) {
216 this.roles.put(roleName, r);
219 public boolean checkAllowed(String checkFunc) {
220 for (Entry<String, AAIAuthRole> role_entry : roles.entrySet()) {
221 AAIAuthRole role = role_entry.getValue();
222 if (role.hasAllowedFunction(checkFunc)) {
229 public void setUser(String myuser) {
230 this.username = myuser;
234 public static class AAIAuthRole {
236 private List<String> allowedFunctions;
238 public AAIAuthRole() {
239 this.allowedFunctions = new ArrayList<>();
242 public void addAllowedFunction(String func) {
243 this.allowedFunctions.add(func);
246 public void delAllowedFunction(String delFunc) {
247 if (this.allowedFunctions.contains(delFunc)) {
248 this.allowedFunctions.remove(delFunc);
252 public boolean hasAllowedFunction(String afunc) {
253 return this.allowedFunctions.contains(afunc);
257 public static boolean authorize(String username, String authFunction) throws AAIAuthException {
258 if (!usersInitialized || users == null) {
259 throw new AAIAuthException("Auth module not initialized");
261 if (users.containsKey(username)) {
262 if (users.get(username).checkAllowed(authFunction)) {
263 logAuthenticationResult(username, authFunction, "AUTH ACCEPTED");
266 logAuthenticationResult(username, authFunction, "AUTH FAILED");
270 logAuthenticationResult(username, authFunction, "User not found");
275 private static void logAuthenticationResult(String username, String authFunction, String result) {
276 applicationLogger.debug(result + ": " + username + " on function " + authFunction);