f8fa02e528c87237d69a39ea66acfd3f3da9fe50
[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  * An in-memory Lur that can be configured locally with User info via properties, similar to Tomcat-users.xml mechanisms.
43  *
44  * @author Jonathan
45  *
46  */
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*";
52
53     // Use to quickly determine whether any given group is supported by this LUR
54     private final Set<String> supportingGroups;
55     private String supportedRealm;
56
57     /**
58      * Construct by building structure, see "build"
59      *
60      * Reconstruct with "build"
61      *
62      * @param userProperties
63      * @param groupProperties
64      * @param decryptor
65      * @throws IOException
66      */
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<>();
71
72         if (userProperties != null) {
73             parseUserProperties(userProperties);
74         }
75
76         if (groupProperties != null) {
77             parseGroupProperties(groupProperties);
78         }
79     }
80
81     public boolean validate(String user, CredVal.Type type, byte[] cred, Object state) {
82         if (cred == null) {
83             return false;
84         }
85         User<LocalPermission> usr = getUser(user, cred);
86         if (usr == null) {
87             return false;
88         }
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());
92         }
93         return false;
94     }
95
96     //    @Override
97     public boolean fish(Principal bait, Permission ... pond) {
98         if (pond == null) {
99             return false;
100         }
101         for (Permission p : pond) {
102             if (handles(bait) && p instanceof LocalPermission) { // local Users only have LocalPermissions
103                 User<LocalPermission> user = getUser(bait);
104                 if (user != null) {
105                     return user.contains((LocalPermission)p);
106                 }
107             }
108         }
109         return false;
110     }
111
112     // We do not want to expose the actual Group, so make a copy.
113     public void fishAll(Principal bait, List<Permission> perms) {
114         if (handles(bait)) {
115             User<LocalPermission> user = getUser(bait);
116             if (user != null) {
117                 user.copyPermsTo(perms);
118             }
119         }
120     }
121
122     /* (non-Javadoc)
123      * @see org.onap.aaf.cadi.Lur#handles(java.security.Principal)
124      */
125     @Override
126     public boolean handles(Principal principal) {
127         if (principal == null) {
128             return false;
129         }
130         return principal.getName().endsWith(supportedRealm);
131     }
132
133     @Override
134     public boolean handlesExclusively(Permission ... pond) {
135         boolean rv = false;
136         for (Permission p : pond) {
137             if (rv=supportingGroups.contains(p.getKey())) {
138                 break;
139             }
140         }
141         return rv;
142     }
143
144     /* (non-Javadoc)
145      * @see org.onap.aaf.cadi.Lur#createPerm(java.lang.String)
146      */
147     @Override
148     public Permission createPerm(String p) {
149         return new LocalPermission(p);
150     }
151     
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];
158
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());
164                 }
165             }
166             User<LocalPermission> usr;
167             usr = new User<>(new ConfigPrincipal(userName, password));
168             addUser(usr);
169             access.log(Level.INIT, "Local User:", usr.principal);
170
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));
176                 }
177                 usr.setMap(newMap);
178             }
179         }
180     }
181
182     
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) {
188                 continue;
189             }
190             supportingGroups.add(groups[0]);
191             LocalPermission p = new LocalPermission(groups[0]);
192
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());
200                 }
201
202                 User<LocalPermission> usr = null;
203                 byte[] password = null;
204                 if (userPass.length > 1) {
205                     password = access.decrypt(userPass[1], true).getBytes();
206                 }
207                 usr = getUser(userName, password);
208                 if (usr == null) {
209                     usr = new User<>(new ConfigPrincipal(userName, password));
210                     addUser(usr);
211                 }
212                 else {
213                     usr.principal = new ConfigPrincipal(userName, password);
214                 }
215                 usr.add(p);
216                 access.log(Level.INIT, "Local User:", usr.principal);
217             }
218         }
219     }
220
221 }