ec0875c1af8c5293b1594741e6840ff49aa7bebf
[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.lur.ConfigPrincipal;
34
35 public class AAFAuthn<CLIENT> extends AbsUserCache<AAFPermission> {
36     private AAFCon<CLIENT> con;
37     private String realm;
38     
39     /**
40      * Configure with Standard AAF properties, Stand alone
41      * @param con
42      * @throws Exception ..
43      */
44     // Package on purpose
45     AAFAuthn(AAFCon<CLIENT> con) {
46         super(con.access,con.cleanInterval,con.highCount,con.usageRefreshTriggerCount);
47         this.con = con;
48     }
49
50     /**
51      * Configure with Standard AAF properties, but share the Cache (with AAF Lur)
52      * @param con
53      * @throws Exception 
54      */
55     // Package on purpose
56     AAFAuthn(AAFCon<CLIENT> con, AbsUserCache<AAFPermission> cache) {
57         super(cache);
58         this.con = con;
59     }
60     
61     /**
62      * Return Native Realm of AAF Instance.
63      * 
64      * @return
65      */
66     public String getRealm() {
67         return realm;
68     }
69
70     /**
71      * Returns null if ok, or an Error String;
72      * 
73      * Convenience function.  Passes "null" for State object
74      */
75     public String validate(String user, String password) throws IOException {
76         return validate(user,password,null);
77     }
78     
79     /**
80      * Returns null if ok, or an Error String;
81      * 
82      * For State Object, you may put in HTTPServletRequest or AuthzTrans, if available.  Otherwise,
83      * leave null
84      * 
85      * @param user
86      * @param password
87      * @return
88      * @throws IOException 
89      * @throws CadiException 
90      * @throws Exception
91      */
92     public String validate(String user, String password, Object state) throws IOException {
93         password = access.decrypt(password, false);
94         byte[] bytes = password.getBytes();
95         User<AAFPermission> usr = getUser(user,bytes);
96
97         if (usr != null && !usr.permExpired()) {
98             if (usr.principal==null) {
99                 return "User already denied";
100             } else {
101                 return null; // good
102             }
103         }
104
105         AAFCachedPrincipal cp = new AAFCachedPrincipal(user, bytes, con.cleanInterval);
106         // Since I've relocated the Validation piece in the Principal, just revalidate, then do Switch
107         // Statement
108         switch(cp.revalidate(state)) {
109             case REVALIDATED:
110                 if (usr!=null) {
111                     usr.principal = cp;
112                 } else {
113                     addUser(new User<AAFPermission>(cp,con.timeout));
114                 }
115                 return null;
116             case INACCESSIBLE:
117                 return "AAF Inaccessible";
118             case UNVALIDATED:
119                 addUser(new User<AAFPermission>(user,bytes,con.timeout));
120                 return "user/pass combo invalid for " + user;
121             case DENIED:
122                 return "AAF denies API for " + user;
123             default: 
124                 return "AAFAuthn doesn't handle Principal " + user;
125         }
126     }
127     
128     private class AAFCachedPrincipal extends ConfigPrincipal implements CachedPrincipal {
129         private long expires;
130         private long timeToLive;
131
132         private AAFCachedPrincipal(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().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 }