Merge "Sonar fixes related to exceptions"
[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) {
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                                         Rcli<CLIENT> client = con.client(Config.AAF_DEFAULT_VERSION).forUser(con.basicAuth(getName(), new String(getCred())));
144                                         Future<String> fp = client.read(
145                                                         "/authn/basicAuth",
146                                                         "text/plain"
147                                                         );
148                                         if(fp.get(con.timeout)) {
149                                                 expires = System.currentTimeMillis() + timeToLive;
150                                                 addUser(new User<AAFPermission>(this, expires));
151                                                 return Resp.REVALIDATED;
152                                         } else {
153                                                 addMiss(getName(), getCred());
154                                                 return Resp.UNVALIDATED;
155                                         }
156                                 } else {
157                                         return Resp.UNVALIDATED;
158                                 }
159                         } catch (Exception e) {
160                                 con.access.log(e);
161                                 return Resp.INACCESSIBLE;
162                         }
163                 }
164
165                 public long expires() {
166                         return expires;
167                 }
168         }
169
170 }