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.aaf.v2_0;
24 import java.lang.reflect.Constructor;
25 import java.lang.reflect.InvocationTargetException;
26 import java.net.ConnectException;
27 import java.net.URISyntaxException;
28 import java.security.Principal;
31 import org.onap.aaf.cadi.AbsUserCache;
32 import org.onap.aaf.cadi.Access;
33 import org.onap.aaf.cadi.Access.Level;
34 import org.onap.aaf.cadi.CachedPrincipal.Resp;
35 import org.onap.aaf.cadi.CadiException;
36 import org.onap.aaf.cadi.Lur;
37 import org.onap.aaf.cadi.Permission;
38 import org.onap.aaf.cadi.User;
39 import org.onap.aaf.cadi.aaf.AAFPermission;
40 import org.onap.aaf.cadi.client.Future;
41 import org.onap.aaf.cadi.client.Holder;
42 import org.onap.aaf.cadi.client.Rcli;
43 import org.onap.aaf.cadi.client.Retryable;
44 import org.onap.aaf.cadi.config.Config;
45 import org.onap.aaf.cadi.lur.LocalPermission;
46 import org.onap.aaf.cadi.util.Timing;
47 import org.onap.aaf.misc.env.APIException;
48 import org.onap.aaf.misc.env.util.Split;
51 import aaf.v2_0.Perms;
54 * Use AAF Service as Permission Service.
56 * This Lur goes after AAF Permissions, which are elements of Roles, not the Roles themselves.
58 * If you want a simple Role Lur, use AAFRoleLur
63 public class AAFLurPerm extends AbsAAFLur<AAFPermission> {
64 private static final String ORG_OSAAF_CADI_OAUTH_O_AUTH2_LUR = "org.osaaf.cadi.oauth.OAuth2Lur";
67 * Need to be able to transmutate a Principal into either Person or AppID, which are the only ones accepted at this
68 * point by AAF. There is no "domain", aka, no "@att.com" in "ab1234@att.com".
70 * The only thing that matters here for AAF is that we don't waste calls with IDs that obviously aren't valid.
71 * Thus, we validate that the ID portion follows the rules before we waste time accessing AAF remotely
72 * @throws APIException
73 * @throws URISyntaxException
74 * @throws DME2Exception
77 AAFLurPerm(AAFCon<?> con) throws CadiException, APIException {
83 AAFLurPerm(AAFCon<?> con, AbsUserCache<AAFPermission> auc) throws APIException {
88 private void attachOAuth2(AAFCon<?> con) throws APIException {
90 Class<?> tmcls = Config.loadClass(access,"org.osaaf.cadi.oauth.TokenMgr");
92 if ((oauth2_url = con.access.getProperty(Config.CADI_OAUTH2_URL,null))!=null) {
94 Constructor<?> tmconst = tmcls.getConstructor(AAFCon.class,String.class);
95 Object tokMangr = tmconst.newInstance(con,oauth2_url);
96 @SuppressWarnings("unchecked")
97 Class<Lur> oa2cls = (Class<Lur>)Config.loadClass(access,ORG_OSAAF_CADI_OAUTH_O_AUTH2_LUR);
98 Constructor<Lur> oa2const = oa2cls.getConstructor(tmcls);
99 Lur oa2 = oa2const.newInstance(tokMangr);
100 setPreemptiveLur(oa2);
101 } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
102 throw new APIException(e);
105 access.log(Level.INIT, "Both cadi-oauth jar and Property",Config.CADI_OAUTH2_URL,"is required to initialize OAuth2");
110 protected User<AAFPermission> loadUser(final Principal principal) {
111 final String name = principal.getName();
112 final long start = System.nanoTime();
113 final Holder<Float> remote = new Holder<Float>(0f);
115 final boolean[] success = new boolean[]{false};
118 return aaf.best(new Retryable<User<AAFPermission>>() {
120 public User<AAFPermission> code(Rcli<?> client) throws CadiException, ConnectException, APIException {
121 final long remoteStart = System.nanoTime();
122 Future<Perms> fp = client.read("/authz/perms/user/"+name,aaf.permsDF);
124 // In the meantime, lookup User, create if necessary
125 User<AAFPermission> user = getUser(principal);
127 if (user!=null && user.principal == null) {
128 p = new Principal() {// Create a holder for lookups
129 private String n = name;
130 public String getName() {
139 addUser(user = new User<AAFPermission>(p,aaf.userExpires)); // no password
142 // OK, done all we can, now get content
143 boolean ok = fp.get(aaf.timeout);
144 remote.set(Timing.millis(remoteStart));
147 Map<String, Permission> newMap = user.newMap();
148 boolean willLog = aaf.access.willLog(Level.DEBUG);
149 for (Perm perm : fp.value.getPerm()) {
150 user.add(newMap,new AAFPermission(perm.getNs(),perm.getType(),perm.getInstance(),perm.getAction(),perm.getRoles()));
152 aaf.access.log(Level.DEBUG, name,"has '",perm.getType(),'|',perm.getInstance(),'|',perm.getAction(),'\'');
158 switch(code=fp.code()) {
160 aaf.access.log(Access.Level.ERROR, code, "Unauthorized to make AAF calls");
166 aaf.access.log(Access.Level.ERROR, code, fp.body());
173 } catch (Exception e) {
174 aaf.access.log(e,"Calling","/authz/perms/user/"+name);
178 aaf.access.printf(Level.INFO, "AAFLurPerm: %s %s perms from AAF in %f ms, remote=%f",
179 (success[0]?"Loaded":"Load Failure"),name,Timing.millis(start),remote.get());
183 public Resp reload(final User<AAFPermission> user) {
184 final String name = user.name;
185 long start = System.nanoTime();
186 final Holder<Float> remote = new Holder<Float>(0f);
187 final Holder<Boolean> success = new Holder<Boolean>(false);
189 Resp rv = aaf.best(new Retryable<Resp>() {
191 public Resp code(Rcli<?> client) throws CadiException, ConnectException, APIException {
192 final long remoteStart = System.nanoTime();
193 Future<Perms> fp = aaf.client().read(
194 "/authz/perms/user/"+name,
198 // OK, done all we can, now get content
199 boolean ok = fp.get(aaf.timeout);
200 remote.set(Timing.millis(remoteStart));
203 Map<String,Permission> newMap = user.newMap();
204 boolean willLog = aaf.access.willLog(Level.DEBUG);
205 for (Perm perm : fp.value.getPerm()) {
206 user.add(newMap, new AAFPermission(perm.getNs(),perm.getType(),perm.getInstance(),perm.getAction(),perm.getRoles()));
208 aaf.access.log(Level.DEBUG, name,"has",perm.getType(),perm.getInstance(),perm.getAction());
212 return Resp.REVALIDATED;
215 switch(code=fp.code()) {
217 aaf.access.log(Access.Level.ERROR, code, "Unauthorized to make AAF calls");
220 aaf.access.log(Access.Level.ERROR, code, fp.body());
222 return Resp.UNVALIDATED;
227 } catch (Exception e) {
228 aaf.access.log(e,"Calling","/authz/perms/user/"+name);
229 return Resp.INACCESSIBLE;
231 aaf.access.printf(Level.INFO, "AAFLurPerm: %s %s perms from AAF in %f ms (remote=%f)",
232 (success.get()?"Reloaded":"Reload Failure"),name,Timing.millis(start),remote.get());
237 protected boolean isCorrectPermType(Permission pond) {
238 return pond instanceof AAFPermission;
242 * @see org.onap.aaf.cadi.Lur#createPerm(java.lang.String)
245 public Permission createPerm(String p) {
246 String[] params = Split.split('|', p);
247 switch(params.length) {
249 return new AAFPermission(null,params[0],params[1],params[2]);
251 return new AAFPermission(params[0],params[1],params[2],params[3]);
253 return new LocalPermission(p);