c1a27fa77c5a6ef5c94a018f3ef8ff43e74e0198
[aaf/authz.git] / cadi / core / src / main / java / org / onap / aaf / cadi / lur / LocalLur.java
1 /**
2  * ============LICENSE_START====================================================
3  * org.onap.aaf
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
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
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====================================================
19  *
20  */
21
22 package org.onap.aaf.cadi.lur;
23
24 import java.io.IOException;
25 import java.security.Principal;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Set;
29 import java.util.TreeSet;
30
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;
40
41
42 /**
43  * An in-memory Lur that can be configured locally with User info via properties, similar to Tomcat-users.xml mechanisms.
44  * 
45  * @author Jonathan
46  *
47  */
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*";
53         
54         // Use to quickly determine whether any given group is supported by this LUR
55         private final Set<String> supportingGroups;
56         private String supportedRealm; 
57         
58         /**
59          * Construct by building structure, see "build"
60          * 
61          * Reconstruct with "build"
62          * 
63          * @param userProperty
64          * @param groupProperty
65          * @param decryptor
66          * @throws IOException
67          */
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>();
72                 
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);
78                                 String u;
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());
83                                         }
84
85                                         u = userpass[0];
86                                         byte[] pass = access.decrypt(userpass[1], true).getBytes();
87                                         usr = new User<LocalPermission>(new ConfigPrincipal(u, pass));
88                                 } else {
89                                         u = us[0];
90                                         usr = new User<LocalPermission>(new ConfigPrincipal(u, (byte[])null));
91                                 }
92                                 addUser(usr);
93                                 access.log(Level.INIT, "Local User:",usr.principal);
94                                 
95                                 if(us.length>1) {
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));
100                                         }
101                                         usr.setMap(newMap);
102                                 }
103                         }
104                 }
105                 if(groupProperty!=null) {
106                         // For each Group name...
107                         for(String group : groupProperty.trim().split(SEMI)) {
108                                 String[] gs = group.split(COLON,2);
109                                 if(gs.length>1) {
110                                         supportingGroups.add(gs[0]);
111                                         LocalPermission p = new LocalPermission(gs[0]);
112                                         // Add all users (known by comma separators)    
113                                         
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());
119                                                 }
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);
126                                                 } else {
127                                                         addUser(usr=new User<LocalPermission>(new ConfigPrincipal(userpass[0],(byte[])null)));
128                                                 }
129                                                 usr.add(p);
130                                                 access.log(Level.INIT, "Local User:",usr.principal);
131                                         }
132                                 }
133                         }
134                 }
135         }
136         
137         public boolean validate(String user, CredVal.Type type, byte[] cred, Object state) {
138                 User<LocalPermission> usr = getUser(user,cred);
139                 switch(type) {
140                         case PASSWORD:
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());
144                                 }
145                                 break;
146                 }
147                 return false;
148         }
149
150         //      @Override
151         public boolean fish(Principal bait, Permission pond) {
152                 if(pond == null) {
153                         return false;
154                 }
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);
158                         }
159                 return false;
160         }
161
162         // We do not want to expose the actual Group, so make a copy.
163         public void fishAll(Principal bait, List<Permission> perms) {
164                 if(handles(bait)) {
165                         User<LocalPermission> user = getUser(bait);
166                         if(user!=null) {
167                                 user.copyPermsTo(perms);
168                         }
169                 }
170         }
171
172         /* (non-Javadoc)
173          * @see org.onap.aaf.cadi.Lur#handles(java.security.Principal)
174          */
175         @Override
176         public boolean handles(Principal principal) {
177                 return principal!=null && principal.getName().endsWith(supportedRealm);
178         }
179
180 //      public boolean supports(String userName) {
181 //              return userName!=null && userName.endsWith(supportedRealm);
182 //      }
183 //
184         public boolean handlesExclusively(Permission pond) {
185                 return supportingGroups.contains(pond.getKey());
186         }
187
188         /* (non-Javadoc)
189          * @see org.onap.aaf.cadi.Lur#createPerm(java.lang.String)
190          */
191         @Override
192         public Permission createPerm(String p) {
193                 return new LocalPermission(p);
194         }
195
196 }