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