2 * ============LICENSE_START====================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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====================================================
22 package org.onap.aaf.cadi.aaf.v2_0;
24 import java.io.IOException;
26 import java.util.ArrayList;
27 import java.util.List;
29 import org.onap.aaf.cadi.AbsUserCache;
30 import org.onap.aaf.cadi.Access;
31 import org.onap.aaf.cadi.CachedPrincipal;
32 import org.onap.aaf.cadi.CadiException;
33 import org.onap.aaf.cadi.User;
34 import org.onap.aaf.cadi.aaf.AAFPermission;
35 import org.onap.aaf.cadi.client.Future;
36 import org.onap.aaf.cadi.client.Rcli;
37 import org.onap.aaf.cadi.lur.ConfigPrincipal;
39 import aaf.v2_0.CredRequest;
41 public class AAFAuthn<CLIENT> extends AbsUserCache<AAFPermission> {
42 private AAFCon<CLIENT> con;
46 * Configure with Standard AAF properties, Stand alone
48 * @throws Exception ..
51 AAFAuthn(AAFCon<CLIENT> con) {
52 super(con.access,con.cleanInterval,con.highCount,con.usageRefreshTriggerCount);
57 * Configure with Standard AAF properties, but share the Cache (with AAF Lur)
62 AAFAuthn(AAFCon<CLIENT> con, AbsUserCache<AAFPermission> cache) {
68 * Return Native Realm of AAF Instance.
72 public String getRealm() {
77 * Returns null if ok, or an Error String;
79 * Convenience function. Passes "null" for State object
81 public String validate(String user, String password) throws IOException {
82 return validate(user,password,null);
86 * Returns null if ok, or an Error String;
88 * For State Object, you may put in HTTPServletRequest or AuthzTrans, if available. Otherwise,
95 * @throws CadiException
98 public String validate(String user, String password, Object state) throws IOException {
99 password = access.decrypt(password, false);
100 byte[] bytes = password.getBytes();
101 User<AAFPermission> usr = getUser(user,bytes);
103 if (usr != null && !usr.permExpired()) {
104 if (usr.principal==null) {
105 return "User already denied";
111 AAFCachedPrincipal cp = new AAFCachedPrincipal(user, bytes, con.cleanInterval);
112 // Since I've relocated the Validation piece in the Principal, just revalidate, then do Switch
114 switch(cp.revalidate(state)) {
119 addUser(new User<AAFPermission>(cp,con.timeout));
123 return "AAF Inaccessible";
125 addUser(new User<AAFPermission>(user,bytes,con.timeout));
126 return "user/pass combo invalid for " + user;
128 return "AAF denies API for " + user;
130 return "AAFAuthn doesn't handle Principal " + user;
134 private class AAFCachedPrincipal extends ConfigPrincipal implements CachedPrincipal {
135 private long expires;
136 private long timeToLive;
138 private AAFCachedPrincipal(String name, byte[] pass, int timeToLive) {
140 this.timeToLive = timeToLive;
141 expires = timeToLive + System.currentTimeMillis();
144 public Resp revalidate(Object state) {
146 try { // these SHOULD be AAFConHttp and AAFLocator objects, but put in a try anyway to be safe
147 AAFConHttp forceCastCon = (AAFConHttp) con;
148 AAFLocator forceCastLoc = (AAFLocator) forceCastCon.hman().loc;
149 maxRetries = forceCastLoc.maxIters();
150 } catch (Exception e) {
151 access.log(Access.Level.DEBUG, e);
153 List<URI> attemptedUris = new ArrayList<>();
155 for (int retries = 0;; retries++) {
157 Miss missed = missed(getName(), getCred());
158 if (missed == null || missed.mayContinue()) {
159 CredRequest cr = new CredRequest();
161 cr.setPassword(new String(getCred()));
162 Rcli<CLIENT> client = con.clientIgnoreAlreadyAttempted(attemptedUris);
163 thisUri = client.getURI();
164 Future<String> fp = client.readPost("/authn/validate", con.credReqDF, cr);
165 //Rcli<CLIENT> client = con.client().forUser(con.basicAuth(getName(), new String(getCred())));
166 //Future<String> fp = client.read(
167 // "/authn/basicAuth",
170 if (fp.get(con.timeout)) {
171 expires = System.currentTimeMillis() + timeToLive;
172 addUser(new User<AAFPermission>(this, expires));
173 return Resp.REVALIDATED;
175 addMiss(getName(), getCred());
176 return Resp.UNVALIDATED;
179 return Resp.UNVALIDATED;
181 } catch (Exception e) {
182 if (thisUri != null) {
183 attemptedUris.add(thisUri);
186 if (retries > maxRetries) {
187 return Resp.INACCESSIBLE;
193 public long expires() {