1 /*******************************************************************************
\r
2 * ============LICENSE_START====================================================
\r
4 * * ===========================================================================
\r
5 * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
\r
6 * * ===========================================================================
\r
7 * * Licensed under the Apache License, Version 2.0 (the "License");
\r
8 * * you may not use this file except in compliance with the License.
\r
9 * * You may obtain a copy of the License at
\r
11 * * http://www.apache.org/licenses/LICENSE-2.0
\r
13 * * Unless required by applicable law or agreed to in writing, software
\r
14 * * distributed under the License is distributed on an "AS IS" BASIS,
\r
15 * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
16 * * See the License for the specific language governing permissions and
\r
17 * * limitations under the License.
\r
18 * * ============LICENSE_END====================================================
\r
20 * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
\r
22 ******************************************************************************/
\r
23 package org.onap.aaf.cadi.aaf.v2_0;
\r
25 import java.net.ConnectException;
\r
26 import java.net.URISyntaxException;
\r
27 import java.security.Principal;
\r
28 import java.util.Map;
\r
30 import org.onap.aaf.cadi.AbsUserCache;
\r
31 import org.onap.aaf.cadi.Access;
\r
32 import org.onap.aaf.cadi.CadiException;
\r
33 import org.onap.aaf.cadi.Permission;
\r
34 import org.onap.aaf.cadi.User;
\r
35 import org.onap.aaf.cadi.Access.Level;
\r
36 import org.onap.aaf.cadi.CachedPrincipal.Resp;
\r
37 import org.onap.aaf.cadi.aaf.AAFPermission;
\r
38 import org.onap.aaf.cadi.client.Future;
\r
39 import org.onap.aaf.cadi.client.Rcli;
\r
40 import org.onap.aaf.cadi.client.Retryable;
\r
41 import org.onap.aaf.cadi.lur.LocalPermission;
\r
43 import com.att.aft.dme2.api.DME2Exception;
\r
44 import org.onap.aaf.inno.env.APIException;
\r
45 import org.onap.aaf.inno.env.util.Split;
\r
47 import aaf.v2_0.Perm;
\r
48 import aaf.v2_0.Perms;
\r
51 * Use AAF Service as Permission Service.
\r
53 * This Lur goes after AAF Permissions, which are elements of Roles, not the Roles themselves.
\r
55 * If you want a simple Role Lur, use AAFRoleLur
\r
59 public class AAFLurPerm extends AbsAAFLur<AAFPermission> {
\r
61 * Need to be able to transmutate a Principal into either ATTUID or MechID, which are the only ones accepted at this
\r
62 * point by AAF. There is no "domain", aka, no "@att.com" in "ab1234@att.com".
\r
64 * The only thing that matters here for AAF is that we don't waste calls with IDs that obviously aren't valid.
\r
65 * Thus, we validate that the ID portion follows the rules before we waste time accessing AAF remotely
\r
66 * @throws APIException
\r
67 * @throws URISyntaxException
\r
68 * @throws DME2Exception
\r
70 // Package on purpose
\r
71 AAFLurPerm(AAFCon<?> con) throws CadiException, DME2Exception, URISyntaxException, APIException {
\r
75 // Package on purpose
\r
76 AAFLurPerm(AAFCon<?> con, AbsUserCache<AAFPermission> auc) throws DME2Exception, URISyntaxException, APIException {
\r
80 protected User<AAFPermission> loadUser(Principal p) {
\r
81 // Note: The rules for AAF is that it only stores permissions for ATTUID and MechIDs, which don't
\r
82 // have domains. We are going to make the Transitive Class (see this.transmutative) to convert
\r
83 Principal principal = transmutate.mutate(p);
\r
84 if(principal==null)return null; // if not a valid Transmutated credential, don't bother calling...
\r
85 return loadUser(p, p.getName());
\r
88 protected User<AAFPermission> loadUser(String name) {
\r
89 return loadUser((Principal)null, name);
\r
92 private User<AAFPermission> loadUser(final Principal prin, final String name) {
\r
94 //TODO Create a dynamic way to declare domains supported.
\r
95 final long start = System.nanoTime();
\r
96 final boolean[] success = new boolean[]{false};
\r
98 // new Exception("loadUser").printStackTrace();
\r
100 return aaf.best(new Retryable<User<AAFPermission>>() {
\r
102 public User<AAFPermission> code(Rcli<?> client) throws CadiException, ConnectException, APIException {
\r
103 Future<Perms> fp = client.read("/authz/perms/user/"+name,aaf.permsDF);
\r
105 // In the meantime, lookup User, create if necessary
\r
106 User<AAFPermission> user = getUser(name);
\r
109 p = new Principal() {// Create a holder for lookups
\r
110 private String n = name;
\r
111 public String getName() {
\r
120 addUser(user = new User<AAFPermission>(p,aaf.userExpires)); // no password
\r
123 // OK, done all we can, now get content
\r
124 if(fp.get(aaf.timeout)) {
\r
126 Map<String, Permission> newMap = user.newMap();
\r
127 boolean willLog = aaf.access.willLog(Level.DEBUG);
\r
128 for(Perm perm : fp.value.getPerm()) {
\r
129 user.add(newMap,new AAFPermission(perm.getType(),perm.getInstance(),perm.getAction()));
\r
131 aaf.access.log(Level.DEBUG, name,"has '",perm.getType(),'|',perm.getInstance(),'|',perm.getAction(),'\'');
\r
134 user.setMap(newMap);
\r
138 switch(code=fp.code()) {
\r
140 aaf.access.log(Access.Level.ERROR, code, "Unauthorized to make AAF calls");
\r
143 aaf.access.log(Access.Level.ERROR, code, fp.body());
\r
150 } catch (Exception e) {
\r
151 aaf.access.log(e,"Calling","/authz/perms/user/"+name);
\r
155 float time = (System.nanoTime()-start)/1000000f;
\r
156 aaf.access.log(Level.INFO, success[0]?"Loaded":"Load Failure",name,"from AAF in",time,"ms");
\r
160 public Resp reload(User<AAFPermission> user) {
\r
161 final String name = user.principal.getName();
\r
162 long start = System.nanoTime();
\r
163 boolean success = false;
\r
165 Future<Perms> fp = aaf.client(AAFCon.AAF_LATEST_VERSION).read(
\r
166 "/authz/perms/user/"+name,
\r
170 // OK, done all we can, now get content
\r
171 if(fp.get(aaf.timeout)) {
\r
173 Map<String,Permission> newMap = user.newMap();
\r
174 boolean willLog = aaf.access.willLog(Level.DEBUG);
\r
175 for(Perm perm : fp.value.getPerm()) {
\r
176 user.add(newMap, new AAFPermission(perm.getType(),perm.getInstance(),perm.getAction()));
\r
178 aaf.access.log(Level.DEBUG, name,"has",perm.getType(),perm.getInstance(),perm.getAction());
\r
182 return Resp.REVALIDATED;
\r
185 switch(code=fp.code()) {
\r
187 aaf.access.log(Access.Level.ERROR, code, "Unauthorized to make AAF calls");
\r
190 aaf.access.log(Access.Level.ERROR, code, fp.body());
\r
192 return Resp.UNVALIDATED;
\r
194 } catch (Exception e) {
\r
195 aaf.access.log(e,"Calling","/authz/perms/user/"+name);
\r
196 return Resp.INACCESSIBLE;
\r
198 float time = (System.nanoTime()-start)/1000000f;
\r
199 aaf.access.log(Level.AUDIT, success?"Reloaded":"Reload Failure",name,"from AAF in",time,"ms");
\r
204 protected boolean isCorrectPermType(Permission pond) {
\r
205 return pond instanceof AAFPermission;
\r
209 * @see com.att.cadi.Lur#createPerm(java.lang.String)
\r
212 public Permission createPerm(String p) {
\r
213 String[] params = Split.split('|', p);
\r
214 if(params.length==3) {
\r
215 return new AAFPermission(params[0],params[1],params[2]);
\r
217 return new LocalPermission(p);
\r