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;
43 * An in-memory Lur that can be configured locally with User info via properties, similar to Tomcat-users.xml mechanisms.
48 public final class LocalLur extends AbsUserCache<LocalPermission> implements Lur, CredVal {
49 public static final String SEMI = "\\s*;\\s*";
50 public static final String COLON = "\\s*:\\s*";
51 public static final String COMMA = "\\s*,\\s*";
52 public static final String PERCENT = "\\s*%\\s*";
54 // Use to quickly determine whether any given group is supported by this LUR
55 private final Set<String> supportingGroups;
56 private String supportedRealm;
59 * Construct by building structure, see "build"
61 * Reconstruct with "build"
64 * @param groupProperty
68 public LocalLur(Access access, String userProperty, String groupProperty) throws IOException {
69 super(access, 0, 0, Integer.MAX_VALUE); // data doesn't expire
70 supportedRealm = access.getProperty(Config.BASIC_REALM, "localized");
71 supportingGroups = new TreeSet<String>();
73 if(userProperty!=null) {
74 // For each User name...
75 for(String user : userProperty.trim().split(SEMI)) {
76 String[] us = user.split(COLON,2);
77 String[] userpass = us[0].split(PERCENT,2);
79 User<LocalPermission> usr;
80 if(userpass.length>1) {
81 if(userpass.length>0 && userpass[0].indexOf('@')<0) {
82 userpass[0]=userpass[0] + '@' + access.getProperty(Config.AAF_DEFAULT_REALM,Config.getDefaultRealm());
86 byte[] pass = access.decrypt(userpass[1], true).getBytes();
87 usr = new User<LocalPermission>(new ConfigPrincipal(u, pass));
90 usr = new User<LocalPermission>(new ConfigPrincipal(u, (byte[])null));
93 access.log(Level.INIT, "Local User:",usr.principal);
96 Map<String, Permission> newMap = usr.newMap();
97 for(String group : us[1].split(COMMA)) {
98 supportingGroups.add(group);
99 usr.add(newMap,new LocalPermission(group));
105 if(groupProperty!=null) {
106 // For each Group name...
107 for(String group : groupProperty.trim().split(SEMI)) {
108 String[] gs = group.split(COLON,2);
110 supportingGroups.add(gs[0]);
111 LocalPermission p = new LocalPermission(gs[0]);
112 // Add all users (known by comma separators)
114 for(String grpMem : gs[1].split(COMMA)) {
115 // look for password, if so, put in passMap
116 String[] userpass = grpMem.split(PERCENT,2);
117 if(userpass.length>0 && userpass[0].indexOf('@')<0) {
118 userpass[0]=userpass[0] + '@' + access.getProperty(Config.AAF_DEFAULT_REALM,Config.getDefaultRealm());
120 User<LocalPermission> usr = null;
121 if(userpass.length>1) {
122 byte[] pass = access.decrypt(userpass[1], true).getBytes();
123 usr = getUser(userpass[0],pass);
124 if(usr==null)addUser(usr=new User<LocalPermission>(new ConfigPrincipal(userpass[0],pass)));
125 else usr.principal=new ConfigPrincipal(userpass[0],pass);
127 addUser(usr=new User<LocalPermission>(new ConfigPrincipal(userpass[0],(byte[])null)));
130 access.log(Level.INIT, "Local User:",usr.principal);
137 public boolean validate(String user, CredVal.Type type, byte[] cred, Object state) {
138 User<LocalPermission> usr = getUser(user,cred);
141 // covers null as well as bad pass
142 if(usr!=null && cred!=null && usr.principal instanceof ConfigPrincipal) {
143 return Hash.isEqual(cred,((ConfigPrincipal)usr.principal).getCred());
151 public boolean fish(Principal bait, Permission pond) {
155 if(handles(bait) && pond instanceof LocalPermission) { // local Users only have LocalPermissions
156 User<LocalPermission> user = getUser(bait);
157 return user==null?false:user.contains((LocalPermission)pond);
162 // We do not want to expose the actual Group, so make a copy.
163 public void fishAll(Principal bait, List<Permission> perms) {
165 User<LocalPermission> user = getUser(bait);
167 user.copyPermsTo(perms);
173 * @see org.onap.aaf.cadi.Lur#handles(java.security.Principal)
176 public boolean handles(Principal principal) {
177 return principal!=null && principal.getName().endsWith(supportedRealm);
180 // public boolean supports(String userName) {
181 // return userName!=null && userName.endsWith(supportedRealm);
184 public boolean handlesExclusively(Permission pond) {
185 return supportingGroups.contains(pond.getKey());
189 * @see org.onap.aaf.cadi.Lur#createPerm(java.lang.String)
192 public Permission createPerm(String p) {
193 return new LocalPermission(p);