Update AAF Version 1.0.0
[aaf/cadi.git] / aaf / src / main / java / com / att / cadi / aaf / v2_0 / AAFLurPerm.java
1 /*******************************************************************************\r
2  * ============LICENSE_START====================================================\r
3  * * org.onap.aaf\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
10  * * \r
11  *  *      http://www.apache.org/licenses/LICENSE-2.0\r
12  * * \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
19  * *\r
20  * * ECOMP is a trademark and service mark of AT&T Intellectual Property.\r
21  * *\r
22  ******************************************************************************/\r
23 package com.att.cadi.aaf.v2_0;\r
24 \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
29 \r
30 import com.att.aft.dme2.api.DME2Exception;\r
31 import com.att.cadi.AbsUserCache;\r
32 import com.att.cadi.Access;\r
33 import com.att.cadi.Access.Level;\r
34 import com.att.cadi.CachedPrincipal.Resp;\r
35 import com.att.cadi.CadiException;\r
36 import com.att.cadi.Permission;\r
37 import com.att.cadi.User;\r
38 import com.att.cadi.aaf.AAFPermission;\r
39 import com.att.cadi.client.Future;\r
40 import com.att.cadi.client.Rcli;\r
41 import com.att.cadi.client.Retryable;\r
42 import com.att.cadi.lur.LocalPermission;\r
43 import com.att.inno.env.APIException;\r
44 import com.att.inno.env.util.Split;\r
45 \r
46 import aaf.v2_0.Perm;\r
47 import aaf.v2_0.Perms;\r
48 \r
49 /**\r
50  * Use AAF Service as Permission Service.\r
51  * \r
52  * This Lur goes after AAF Permissions, which are elements of Roles, not the Roles themselves.\r
53  * \r
54  * If you want a simple Role Lur, use AAFRoleLur\r
55  * \r
56  *\r
57  */\r
58 public class AAFLurPerm extends AbsAAFLur<AAFPermission> {\r
59         /**\r
60          *  Need to be able to transmutate a Principal into either ATTUID or MechID, which are the only ones accepted at this\r
61          *  point by AAF.  There is no "domain", aka, no "@att.com" in "ab1234@att.com".  \r
62          *  \r
63          *  The only thing that matters here for AAF is that we don't waste calls with IDs that obviously aren't valid.\r
64          *  Thus, we validate that the ID portion follows the rules before we waste time accessing AAF remotely\r
65          * @throws APIException \r
66          * @throws URISyntaxException \r
67          * @throws DME2Exception \r
68          */\r
69         // Package on purpose\r
70         AAFLurPerm(AAFCon<?> con) throws CadiException, DME2Exception, URISyntaxException, APIException {\r
71                 super(con);\r
72         }\r
73 \r
74         // Package on purpose\r
75         AAFLurPerm(AAFCon<?> con, AbsUserCache<AAFPermission> auc) throws DME2Exception, URISyntaxException, APIException {\r
76                 super(con,auc);\r
77         }\r
78 \r
79         protected User<AAFPermission> loadUser(Principal p)  {\r
80                 // Note: The rules for AAF is that it only stores permissions for ATTUID and MechIDs, which don't \r
81                 // have domains.  We are going to make the Transitive Class (see this.transmutative) to convert\r
82                 Principal principal = transmutate.mutate(p);\r
83                 if(principal==null)return null; // if not a valid Transmutated credential, don't bother calling...\r
84                 return loadUser(p, p.getName());\r
85         }\r
86         \r
87         protected User<AAFPermission> loadUser(String name) {\r
88                 return loadUser((Principal)null, name);\r
89         }\r
90         \r
91         private User<AAFPermission> loadUser(final Principal prin, final String name) {\r
92                 \r
93                 //TODO Create a dynamic way to declare domains supported.\r
94                 final long start = System.nanoTime();\r
95                 final boolean[] success = new boolean[]{false};\r
96                 \r
97 //              new Exception("loadUser").printStackTrace();\r
98                 try {\r
99                         return aaf.best(new Retryable<User<AAFPermission>>() {\r
100                                 @Override\r
101                                 public User<AAFPermission> code(Rcli<?> client) throws CadiException, ConnectException, APIException {\r
102                                         Future<Perms> fp = client.read("/authz/perms/user/"+name,aaf.permsDF);\r
103                                         \r
104                                         // In the meantime, lookup User, create if necessary\r
105                                         User<AAFPermission> user = getUser(name);\r
106                                         Principal p;\r
107                                         if(prin == null) {\r
108                                                 p = new Principal() {// Create a holder for lookups\r
109                                                         private String n = name;\r
110                                                         public String getName() {\r
111                                                                 return n;\r
112                                                         }\r
113                                                 };\r
114                                         } else {\r
115                                                 p = prin;\r
116                                         }\r
117                                         \r
118                                         if(user==null) {\r
119                                                 addUser(user = new User<AAFPermission>(p,aaf.userExpires)); // no password\r
120                                         }\r
121                                         \r
122                                         // OK, done all we can, now get content\r
123                                         if(fp.get(aaf.timeout)) {\r
124                                                 success[0]=true;\r
125                                                 Map<String, Permission> newMap = user.newMap();\r
126                                                 boolean willLog = aaf.access.willLog(Level.DEBUG);\r
127                                                 for(Perm perm : fp.value.getPerm()) {\r
128                                                         user.add(newMap,new AAFPermission(perm.getType(),perm.getInstance(),perm.getAction()));\r
129                                                         if(willLog) {\r
130                                                                 aaf.access.log(Level.DEBUG, name,"has '",perm.getType(),'|',perm.getInstance(),'|',perm.getAction(),'\'');\r
131                                                         }\r
132                                                 }\r
133                                                 user.setMap(newMap);\r
134                                                 user.renewPerm();\r
135                                         } else {\r
136                                                 int code;\r
137                                                 switch(code=fp.code()) {\r
138                                                         case 401:\r
139                                                                 aaf.access.log(Access.Level.ERROR, code, "Unauthorized to make AAF calls");\r
140                                                                 break;\r
141                                                         default:\r
142                                                                 aaf.access.log(Access.Level.ERROR, code, fp.body());\r
143                                                 }\r
144                                         }\r
145 \r
146                                         return user;\r
147                                 }\r
148                         });\r
149                 } catch (Exception e) {\r
150                         aaf.access.log(e,"Calling","/authz/perms/user/"+name);\r
151                         success[0]=false;\r
152                         return null;\r
153                 } finally {\r
154                         float time = (System.nanoTime()-start)/1000000f;\r
155                         aaf.access.log(Level.INFO, success[0]?"Loaded":"Load Failure",name,"from AAF in",time,"ms");\r
156                 }\r
157         }\r
158 \r
159         public Resp reload(User<AAFPermission> user) {\r
160                 final String name = user.principal.getName();\r
161                 long start = System.nanoTime();\r
162                 boolean success = false;\r
163                 try {\r
164                         Future<Perms> fp = aaf.client(AAFCon.AAF_LATEST_VERSION).read(\r
165                                         "/authz/perms/user/"+name,\r
166                                         aaf.permsDF\r
167                                         );\r
168                         \r
169                         // OK, done all we can, now get content\r
170                         if(fp.get(aaf.timeout)) {\r
171                                 success = true;\r
172                                 Map<String,Permission> newMap = user.newMap(); \r
173                                 boolean willLog = aaf.access.willLog(Level.DEBUG);\r
174                                 for(Perm perm : fp.value.getPerm()) {\r
175                                         user.add(newMap, new AAFPermission(perm.getType(),perm.getInstance(),perm.getAction()));\r
176                                         if(willLog) {\r
177                                                 aaf.access.log(Level.DEBUG, name,"has",perm.getType(),perm.getInstance(),perm.getAction());\r
178                                         }\r
179                                 }\r
180                                 user.renewPerm();\r
181                                 return Resp.REVALIDATED;\r
182                         } else {\r
183                                 int code;\r
184                                 switch(code=fp.code()) {\r
185                                         case 401:\r
186                                                 aaf.access.log(Access.Level.ERROR, code, "Unauthorized to make AAF calls");\r
187                                                 break;\r
188                                         default:\r
189                                                 aaf.access.log(Access.Level.ERROR, code, fp.body());\r
190                                 }\r
191                                 return Resp.UNVALIDATED;\r
192                         }\r
193                 } catch (Exception e) {\r
194                         aaf.access.log(e,"Calling","/authz/perms/user/"+name);\r
195                         return Resp.INACCESSIBLE;\r
196                 } finally {\r
197                         float time = (System.nanoTime()-start)/1000000f;\r
198                         aaf.access.log(Level.AUDIT, success?"Reloaded":"Reload Failure",name,"from AAF in",time,"ms");\r
199                 }\r
200         }\r
201 \r
202         @Override\r
203         protected boolean isCorrectPermType(Permission pond) {\r
204                 return pond instanceof AAFPermission;\r
205         }\r
206 \r
207         /* (non-Javadoc)\r
208          * @see com.att.cadi.Lur#createPerm(java.lang.String)\r
209          */\r
210         @Override\r
211         public Permission createPerm(String p) {\r
212                 String[] params = Split.split('|', p);\r
213                 if(params.length==3) {\r
214                         return new AAFPermission(params[0],params[1],params[2]);\r
215                 } else {\r
216                         return new LocalPermission(p);\r
217                 }\r
218         }\r
219         \r
220 }\r