520d7ab77e3880707ee0ab3b7544c34f58cbb53e
[aaf/cadi.git] / aaf / src / main / java / org / onap / aaf / 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 org.onap.aaf.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 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
42 \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
46 \r
47 import aaf.v2_0.Perm;\r
48 import aaf.v2_0.Perms;\r
49 \r
50 /**\r
51  * Use AAF Service as Permission Service.\r
52  * \r
53  * This Lur goes after AAF Permissions, which are elements of Roles, not the Roles themselves.\r
54  * \r
55  * If you want a simple Role Lur, use AAFRoleLur\r
56  * \r
57  *\r
58  */\r
59 public class AAFLurPerm extends AbsAAFLur<AAFPermission> {\r
60         /**\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
63          *  \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
69          */\r
70         // Package on purpose\r
71         AAFLurPerm(AAFCon<?> con) throws CadiException, DME2Exception, URISyntaxException, APIException {\r
72                 super(con);\r
73         }\r
74 \r
75         // Package on purpose\r
76         AAFLurPerm(AAFCon<?> con, AbsUserCache<AAFPermission> auc) throws DME2Exception, URISyntaxException, APIException {\r
77                 super(con,auc);\r
78         }\r
79 \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
86         }\r
87         \r
88         protected User<AAFPermission> loadUser(String name) {\r
89                 return loadUser((Principal)null, name);\r
90         }\r
91         \r
92         private User<AAFPermission> loadUser(final Principal prin, final String name) {\r
93                 \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
97                 \r
98 //              new Exception("loadUser").printStackTrace();\r
99                 try {\r
100                         return aaf.best(new Retryable<User<AAFPermission>>() {\r
101                                 @Override\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
104                                         \r
105                                         // In the meantime, lookup User, create if necessary\r
106                                         User<AAFPermission> user = getUser(name);\r
107                                         Principal p;\r
108                                         if(prin == null) {\r
109                                                 p = new Principal() {// Create a holder for lookups\r
110                                                         private String n = name;\r
111                                                         public String getName() {\r
112                                                                 return n;\r
113                                                         }\r
114                                                 };\r
115                                         } else {\r
116                                                 p = prin;\r
117                                         }\r
118                                         \r
119                                         if(user==null) {\r
120                                                 addUser(user = new User<AAFPermission>(p,aaf.userExpires)); // no password\r
121                                         }\r
122                                         \r
123                                         // OK, done all we can, now get content\r
124                                         if(fp.get(aaf.timeout)) {\r
125                                                 success[0]=true;\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
130                                                         if(willLog) {\r
131                                                                 aaf.access.log(Level.DEBUG, name,"has '",perm.getType(),'|',perm.getInstance(),'|',perm.getAction(),'\'');\r
132                                                         }\r
133                                                 }\r
134                                                 user.setMap(newMap);\r
135                                                 user.renewPerm();\r
136                                         } else {\r
137                                                 int code;\r
138                                                 switch(code=fp.code()) {\r
139                                                         case 401:\r
140                                                                 aaf.access.log(Access.Level.ERROR, code, "Unauthorized to make AAF calls");\r
141                                                                 break;\r
142                                                         default:\r
143                                                                 aaf.access.log(Access.Level.ERROR, code, fp.body());\r
144                                                 }\r
145                                         }\r
146 \r
147                                         return user;\r
148                                 }\r
149                         });\r
150                 } catch (Exception e) {\r
151                         aaf.access.log(e,"Calling","/authz/perms/user/"+name);\r
152                         success[0]=false;\r
153                         return null;\r
154                 } finally {\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
157                 }\r
158         }\r
159 \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
164                 try {\r
165                         Future<Perms> fp = aaf.client(AAFCon.AAF_LATEST_VERSION).read(\r
166                                         "/authz/perms/user/"+name,\r
167                                         aaf.permsDF\r
168                                         );\r
169                         \r
170                         // OK, done all we can, now get content\r
171                         if(fp.get(aaf.timeout)) {\r
172                                 success = true;\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
177                                         if(willLog) {\r
178                                                 aaf.access.log(Level.DEBUG, name,"has",perm.getType(),perm.getInstance(),perm.getAction());\r
179                                         }\r
180                                 }\r
181                                 user.renewPerm();\r
182                                 return Resp.REVALIDATED;\r
183                         } else {\r
184                                 int code;\r
185                                 switch(code=fp.code()) {\r
186                                         case 401:\r
187                                                 aaf.access.log(Access.Level.ERROR, code, "Unauthorized to make AAF calls");\r
188                                                 break;\r
189                                         default:\r
190                                                 aaf.access.log(Access.Level.ERROR, code, fp.body());\r
191                                 }\r
192                                 return Resp.UNVALIDATED;\r
193                         }\r
194                 } catch (Exception e) {\r
195                         aaf.access.log(e,"Calling","/authz/perms/user/"+name);\r
196                         return Resp.INACCESSIBLE;\r
197                 } finally {\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
200                 }\r
201         }\r
202 \r
203         @Override\r
204         protected boolean isCorrectPermType(Permission pond) {\r
205                 return pond instanceof AAFPermission;\r
206         }\r
207 \r
208         /* (non-Javadoc)\r
209          * @see com.att.cadi.Lur#createPerm(java.lang.String)\r
210          */\r
211         @Override\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
216                 } else {\r
217                         return new LocalPermission(p);\r
218                 }\r
219         }\r
220         \r
221 }\r