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 if (handles(bait) && pond instanceof LocalPermission) { // local Users only have LocalPermissions
102 User<LocalPermission> user = getUser(bait);
104 return user.contains((LocalPermission)pond);
110 // We do not want to expose the actual Group, so make a copy.
111 public void fishAll(Principal bait, List<Permission> perms) {
113 User<LocalPermission> user = getUser(bait);
115 user.copyPermsTo(perms);
121 * @see org.onap.aaf.cadi.Lur#handles(java.security.Principal)
124 public boolean handles(Principal principal) {
125 if (principal == null) {
128 return principal.getName().endsWith(supportedRealm);
131 public boolean handlesExclusively(Permission pond) {
132 return supportingGroups.contains(pond.getKey());
136 * @see org.onap.aaf.cadi.Lur#createPerm(java.lang.String)
139 public Permission createPerm(String p) {
140 return new LocalPermission(p);
143 private void parseUserProperties(String userProperties) throws IOException {
144 // For each User name...
145 for (String userProperty : userProperties.trim().split(SEMI)) {
146 String[] userInfo = userProperty.split(COLON, 2);
147 String[] userPass = userInfo[0].split(PERCENT, 2);
148 String userName = userPass[0];
150 byte[] password = null;
151 if (userPass.length > 1) {
152 password = access.decrypt(userPass[1], true).getBytes();
153 if (userName.indexOf('@') < 0) {
154 userName += '@' + access.getProperty(Config.AAF_DEFAULT_REALM, Config.getDefaultRealm());
157 User<LocalPermission> usr;
158 usr = new User<>(new ConfigPrincipal(userName, password));
160 access.log(Level.INIT, "Local User:", usr.principal);
162 if (userInfo.length > 1) {
163 Map<String, Permission> newMap = usr.newMap();
164 for (String group : userInfo[1].split(COMMA)) {
165 supportingGroups.add(group);
166 usr.add(newMap, new LocalPermission(group));
174 private void parseGroupProperties(String groupProperties) throws IOException {
175 // For each Group name...
176 for (String group : groupProperties.trim().split(SEMI)) {
177 String[] groups = group.split(COLON, 2);
178 if (groups.length <= 1) {
181 supportingGroups.add(groups[0]);
182 LocalPermission p = new LocalPermission(groups[0]);
184 // Add all users (known by comma separators)
185 for (String groupMember : groups[1].split(COMMA)) {
186 // look for password, if so, put in passMap
187 String[] userPass = groupMember.split(PERCENT, 2);
188 String userName = userPass[0];
189 if (userName.indexOf('@') < 0) {
190 userName += '@' + access.getProperty(Config.AAF_DEFAULT_REALM, Config.getDefaultRealm());
193 User<LocalPermission> usr = null;
194 byte[] password = null;
195 if (userPass.length > 1) {
196 password = access.decrypt(userPass[1], true).getBytes();
198 usr = getUser(userName, password);
200 usr = new User<>(new ConfigPrincipal(userName, password));
204 usr.principal = new ConfigPrincipal(userName, password);
207 access.log(Level.INIT, "Local User:", usr.principal);