Merge "Add INFO.yaml file"
[aaf/authz.git] / cadi / aaf / src / main / java / org / onap / aaf / cadi / aaf / v2_0 / AAFAuthn.java
1 /**
2  * ============LICENSE_START====================================================
3  * org.onap.aaf
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
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
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====================================================
19  *
20  */
21
22 package org.onap.aaf.cadi.aaf.v2_0;
23
24 import java.io.IOException;
25
26 import org.onap.aaf.cadi.AbsUserCache;
27 import org.onap.aaf.cadi.CachedPrincipal;
28 import org.onap.aaf.cadi.CadiException;
29 import org.onap.aaf.cadi.User;
30 import org.onap.aaf.cadi.aaf.AAFPermission;
31 import org.onap.aaf.cadi.client.Future;
32 import org.onap.aaf.cadi.client.Rcli;
33 import org.onap.aaf.cadi.config.Config;
34 import org.onap.aaf.cadi.lur.ConfigPrincipal;
35
36 public class AAFAuthn<CLIENT> extends AbsUserCache<AAFPermission> {
37         private AAFCon<CLIENT> con;
38         private String realm;
39         
40         /**
41          * Configure with Standard AAF properties, Stand alone
42          * @param con
43          * @throws Exception ..
44          */
45         // Package on purpose
46         AAFAuthn(AAFCon<CLIENT> con) throws Exception {
47                 super(con.access,con.cleanInterval,con.highCount,con.usageRefreshTriggerCount);
48                 this.con = con;
49         }
50
51         /**
52          * Configure with Standard AAF properties, but share the Cache (with AAF Lur)
53          * @param con
54          * @throws Exception 
55          */
56         // Package on purpose
57         AAFAuthn(AAFCon<CLIENT> con, AbsUserCache<AAFPermission> cache) {
58                 super(cache);
59                 this.con = con;
60         }
61         
62         /**
63          * Return Native Realm of AAF Instance.
64          * 
65          * @return
66          */
67         public String getRealm() {
68                 return realm;
69         }
70
71         /**
72          * Returns null if ok, or an Error String;
73          * 
74          * Convenience function.  Passes "null" for State object
75          */
76         public String validate(String user, String password) throws IOException, CadiException {
77                 return validate(user,password,null);
78         }
79         
80         /**
81          * Returns null if ok, or an Error String;
82          * 
83          * For State Object, you may put in HTTPServletRequest or AuthzTrans, if available.  Otherwise,
84          * leave null
85          * 
86          * @param user
87          * @param password
88          * @return
89          * @throws IOException 
90          * @throws CadiException 
91          * @throws Exception
92          */
93         public String validate(String user, String password, Object state) throws IOException, CadiException {
94                 password = access.decrypt(password, false);
95                 byte[] bytes = password.getBytes();
96                 User<AAFPermission> usr = getUser(user,bytes);
97
98                 if(usr != null && !usr.permExpired()) {
99                         if(usr.principal==null) {
100                                 return "User already denied";
101                         } else {
102                                 return null; // good
103                         }
104                 }
105
106                 AAFCachedPrincipal cp = new AAFCachedPrincipal(this,con.app, user, bytes, con.cleanInterval);
107                 // Since I've relocated the Validation piece in the Principal, just revalidate, then do Switch
108                 // Statement
109                 switch(cp.revalidate(state)) {
110                         case REVALIDATED:
111                                 if(usr!=null) {
112                                         usr.principal = cp;
113                                 } else {
114                                         addUser(new User<AAFPermission>(cp,con.timeout));
115                                 }
116                                 return null;
117                         case INACCESSIBLE:
118                                 return "AAF Inaccessible";
119                         case UNVALIDATED:
120                                 addUser(new User<AAFPermission>(user,bytes,con.timeout));
121                                 return "User/Pass combo invalid for " + user;
122                         case DENIED:
123                                 return "AAF denies API for " + user;
124                         default: 
125                                 return "AAFAuthn doesn't handle Principal " + user;
126                 }
127         }
128         
129         private class AAFCachedPrincipal extends ConfigPrincipal implements CachedPrincipal {
130                 private long expires,timeToLive;
131
132                 public AAFCachedPrincipal(AAFAuthn<?> aaf, String app, String name, byte[] pass, int timeToLive) {
133                         super(name,pass);
134                         this.timeToLive = timeToLive;
135                         expires = timeToLive + System.currentTimeMillis();
136                 }
137
138                 public Resp revalidate(Object state) {
139                         try {
140                                 Miss missed = missed(getName(),getCred());
141                                 if(missed==null || missed.mayContinue()) {
142                                         Rcli<CLIENT> client = con.client(Config.AAF_DEFAULT_VERSION).forUser(con.basicAuth(getName(), new String(getCred())));
143                                         Future<String> fp = client.read(
144                                                         "/authn/basicAuth",
145                                                         "text/plain"
146                                                         );
147                                         if(fp.get(con.timeout)) {
148                                                 expires = System.currentTimeMillis() + timeToLive;
149                                                 addUser(new User<AAFPermission>(this, expires));
150                                                 return Resp.REVALIDATED;
151                                         } else {
152                                                 addMiss(getName(), getCred());
153                                                 return Resp.UNVALIDATED;
154                                         }
155                                 } else {
156                                         return Resp.UNVALIDATED;
157                                 }
158                         } catch (Exception e) {
159                                 con.access.log(e);
160                                 return Resp.INACCESSIBLE;
161                         }
162                 }
163
164                 public long expires() {
165                         return expires;
166                 }
167         };
168
169 }