Improved multi Proxy DNSLocator based
[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.lur.ConfigPrincipal;
33
34 import aaf.v2_0.CredRequest;
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) {
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 {
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 {
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(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;
131         private long timeToLive;
132
133         private AAFCachedPrincipal(String name, byte[] pass, int timeToLive) {
134             super(name,pass);
135             this.timeToLive = timeToLive;
136             expires = timeToLive + System.currentTimeMillis();
137         }
138
139         public Resp revalidate(Object state) {
140             try {
141                 Miss missed = missed(getName(),getCred());
142                 if (missed==null || missed.mayContinue()) {
143                         CredRequest cr = new CredRequest();
144                         cr.setId(getName());
145                         cr.setPassword(new String(getCred()));
146                         Future<String> fp = con.client().readPost("/authn/validate", con.credReqDF, cr);
147                     //Rcli<CLIENT> client = con.client().forUser(con.basicAuth(getName(), new String(getCred())));
148                     //Future<String> fp = client.read(
149                     //        "/authn/basicAuth",
150                     //        "text/plain"
151                     //       );
152                      if (fp.get(con.timeout)) {
153                         expires = System.currentTimeMillis() + timeToLive;
154                         addUser(new User<AAFPermission>(this, expires));
155                         return Resp.REVALIDATED;
156                     } else {
157                         addMiss(getName(), getCred());
158                         return Resp.UNVALIDATED;
159                     }
160                 } else {
161                     return Resp.UNVALIDATED;
162                 }
163             } catch (Exception e) {
164                 con.access.log(e);
165                 return Resp.INACCESSIBLE;
166             }
167         }
168
169         public long expires() {
170             return expires;
171         }
172     }
173
174 }