2 * ============LICENSE_START====================================================
4 * ===========================================================================
5 * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
6 * ===========================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END====================================================
22 package org.onap.aaf.cadi.lur;
24 import java.io.IOException;
25 import java.security.Principal;
26 import java.util.List;
29 import java.util.TreeSet;
31 import org.onap.aaf.cadi.AbsUserCache;
32 import org.onap.aaf.cadi.Access;
33 import org.onap.aaf.cadi.CredVal;
34 import org.onap.aaf.cadi.Hash;
35 import org.onap.aaf.cadi.Lur;
36 import org.onap.aaf.cadi.Permission;
37 import org.onap.aaf.cadi.User;
38 import org.onap.aaf.cadi.Access.Level;
39 import org.onap.aaf.cadi.config.Config;
42 * An in-memory Lur that can be configured locally with User info via properties, similar to Tomcat-users.xml mechanisms.
47 public final class LocalLur extends AbsUserCache<LocalPermission> implements Lur, CredVal {
48 public static final String SEMI = "\\s*;\\s*";
49 public static final String COLON = "\\s*:\\s*";
50 public static final String COMMA = "\\s*,\\s*";
51 public static final String PERCENT = "\\s*%\\s*";
53 // Use to quickly determine whether any given group is supported by this LUR
54 private final Set<String> supportingGroups;
55 private String supportedRealm;
58 * Construct by building structure, see "build"
60 * Reconstruct with "build"
62 * @param userProperties
63 * @param groupProperties
67 public LocalLur(Access access, String userProperties, String groupProperties) throws IOException {
68 super(access, 0, 0, Integer.MAX_VALUE); // data doesn't expire
69 supportedRealm = access.getProperty(Config.BASIC_REALM, "localized");
70 supportingGroups = new TreeSet<>();
72 if (userProperties != null) {
73 parseUserProperties(userProperties);
76 if (groupProperties != null) {
77 parseGroupProperties(groupProperties);
81 public boolean validate(String user, CredVal.Type type, byte[] cred, Object state) {
85 User<LocalPermission> usr = getUser(user, cred);
89 // covers null as well as bad pass
90 if ((type == Type.PASSWORD) && (usr.principal instanceof ConfigPrincipal)) {;
91 return Hash.isEqual(cred, ((ConfigPrincipal)usr.principal).getCred());
97 public boolean fish(Principal bait, Permission ... pond) {
101 for(Permission p : pond) {
102 if (handles(bait) && p instanceof LocalPermission) { // local Users only have LocalPermissions
103 User<LocalPermission> user = getUser(bait);
105 return user.contains((LocalPermission)p);
112 // We do not want to expose the actual Group, so make a copy.
113 public void fishAll(Principal bait, List<Permission> perms) {
115 User<LocalPermission> user = getUser(bait);
117 user.copyPermsTo(perms);
123 * @see org.onap.aaf.cadi.Lur#handles(java.security.Principal)
126 public boolean handles(Principal principal) {
127 if (principal == null) {
130 return principal.getName().endsWith(supportedRealm);
134 public boolean handlesExclusively(Permission ... pond) {
136 for (Permission p : pond) {
137 if(rv=supportingGroups.contains(p.getKey())) {
145 * @see org.onap.aaf.cadi.Lur#createPerm(java.lang.String)
148 public Permission createPerm(String p) {
149 return new LocalPermission(p);
152 private void parseUserProperties(String userProperties) throws IOException {
153 // For each User name...
154 for (String userProperty : userProperties.trim().split(SEMI)) {
155 String[] userInfo = userProperty.split(COLON, 2);
156 String[] userPass = userInfo[0].split(PERCENT, 2);
157 String userName = userPass[0];
159 byte[] password = null;
160 if (userPass.length > 1) {
161 password = access.decrypt(userPass[1], true).getBytes();
162 if (userName.indexOf('@') < 0) {
163 userName += '@' + access.getProperty(Config.AAF_DEFAULT_REALM, Config.getDefaultRealm());
166 User<LocalPermission> usr;
167 usr = new User<>(new ConfigPrincipal(userName, password));
169 access.log(Level.INIT, "Local User:", usr.principal);
171 if (userInfo.length > 1) {
172 Map<String, Permission> newMap = usr.newMap();
173 for (String group : userInfo[1].split(COMMA)) {
174 supportingGroups.add(group);
175 usr.add(newMap, new LocalPermission(group));
183 private void parseGroupProperties(String groupProperties) throws IOException {
184 // For each Group name...
185 for (String group : groupProperties.trim().split(SEMI)) {
186 String[] groups = group.split(COLON, 2);
187 if (groups.length <= 1) {
190 supportingGroups.add(groups[0]);
191 LocalPermission p = new LocalPermission(groups[0]);
193 // Add all users (known by comma separators)
194 for (String groupMember : groups[1].split(COMMA)) {
195 // look for password, if so, put in passMap
196 String[] userPass = groupMember.split(PERCENT, 2);
197 String userName = userPass[0];
198 if (userName.indexOf('@') < 0) {
199 userName += '@' + access.getProperty(Config.AAF_DEFAULT_REALM, Config.getDefaultRealm());
202 User<LocalPermission> usr = null;
203 byte[] password = null;
204 if (userPass.length > 1) {
205 password = access.decrypt(userPass[1], true).getBytes();
207 usr = getUser(userName, password);
209 usr = new User<>(new ConfigPrincipal(userName, password));
213 usr.principal = new ConfigPrincipal(userName, password);
216 access.log(Level.INIT, "Local User:", usr.principal);