Create and prepare non-deploy release 2.7.1
[aaf/authz.git] / cadi / aaf / src / main / java / org / onap / aaf / cadi / aaf / v2_0 / AAFAuthn.java
index 216468c..dbb9d5c 100644 (file)
@@ -7,9 +7,9 @@
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 package org.onap.aaf.cadi.aaf.v2_0;
 
 import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
 
 import org.onap.aaf.cadi.AbsUserCache;
+import org.onap.aaf.cadi.Access;
 import org.onap.aaf.cadi.CachedPrincipal;
 import org.onap.aaf.cadi.CadiException;
 import org.onap.aaf.cadi.User;
 import org.onap.aaf.cadi.aaf.AAFPermission;
 import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
 import org.onap.aaf.cadi.lur.ConfigPrincipal;
 
 import aaf.v2_0.CredRequest;
@@ -36,7 +41,7 @@ import aaf.v2_0.CredRequest;
 public class AAFAuthn<CLIENT> extends AbsUserCache<AAFPermission> {
     private AAFCon<CLIENT> con;
     private String realm;
-    
+
     /**
      * Configure with Standard AAF properties, Stand alone
      * @param con
@@ -51,17 +56,17 @@ public class AAFAuthn<CLIENT> extends AbsUserCache<AAFPermission> {
     /**
      * Configure with Standard AAF properties, but share the Cache (with AAF Lur)
      * @param con
-     * @throws Exception 
+     * @throws Exception
      */
     // Package on purpose
     AAFAuthn(AAFCon<CLIENT> con, AbsUserCache<AAFPermission> cache) {
         super(cache);
         this.con = con;
     }
-    
+
     /**
      * Return Native Realm of AAF Instance.
-     * 
+     *
      * @return
      */
     public String getRealm() {
@@ -70,24 +75,24 @@ public class AAFAuthn<CLIENT> extends AbsUserCache<AAFPermission> {
 
     /**
      * Returns null if ok, or an Error String;
-     * 
+     *
      * Convenience function.  Passes "null" for State object
      */
     public String validate(String user, String password) throws IOException {
         return validate(user,password,null);
     }
-    
+
     /**
      * Returns null if ok, or an Error String;
-     * 
+     *
      * For State Object, you may put in HTTPServletRequest or AuthzTrans, if available.  Otherwise,
      * leave null
-     * 
+     *
      * @param user
      * @param password
      * @return
-     * @throws IOException 
-     * @throws CadiException 
+     * @throws IOException
+     * @throws CadiException
      * @throws Exception
      */
     public String validate(String user, String password, Object state) throws IOException {
@@ -121,11 +126,11 @@ public class AAFAuthn<CLIENT> extends AbsUserCache<AAFPermission> {
                 return "user/pass combo invalid for " + user;
             case DENIED:
                 return "AAF denies API for " + user;
-            default: 
+            default:
                 return "AAFAuthn doesn't handle Principal " + user;
         }
     }
-    
+
     private class AAFCachedPrincipal extends ConfigPrincipal implements CachedPrincipal {
         private long expires;
         private long timeToLive;
@@ -137,32 +142,51 @@ public class AAFAuthn<CLIENT> extends AbsUserCache<AAFPermission> {
         }
 
         public Resp revalidate(Object state) {
-            try {
-                Miss missed = missed(getName(),getCred());
-                if (missed==null || missed.mayContinue()) {
-                       CredRequest cr = new CredRequest();
-                       cr.setId(getName());
-                       cr.setPassword(new String(getCred()));
-                       Future<String> fp = con.client().readPost("/authn/validate", con.credReqDF, cr);
-                    //Rcli<CLIENT> client = con.client().forUser(con.basicAuth(getName(), new String(getCred())));
-                    //Future<String> fp = client.read(
-                    //        "/authn/basicAuth",
-                    //        "text/plain"
-                    //       );
-                     if (fp.get(con.timeout)) {
-                        expires = System.currentTimeMillis() + timeToLive;
-                        addUser(new User<AAFPermission>(this, expires));
-                        return Resp.REVALIDATED;
+            int maxRetries = 15;
+            try { // these SHOULD be AAFConHttp and AAFLocator objects, but put in a try anyway to be safe
+                AAFConHttp forceCastCon = (AAFConHttp) con;
+                AAFLocator forceCastLoc = (AAFLocator) forceCastCon.hman().loc;
+                maxRetries = forceCastLoc.maxIters();
+            } catch (Exception e) {
+                access.log(Access.Level.DEBUG, e);
+            }
+            List<URI> attemptedUris = new ArrayList<>();
+            URI thisUri = null;
+            for (int retries = 0;; retries++) {
+                try {
+                    Miss missed = missed(getName(), getCred());
+                    if (missed == null || missed.mayContinue()) {
+                        CredRequest cr = new CredRequest();
+                        cr.setId(getName());
+                        cr.setPassword(new String(getCred()));
+                        Rcli<CLIENT> client = con.clientIgnoreAlreadyAttempted(attemptedUris);
+                        thisUri = client.getURI();
+                        Future<String> fp = client.readPost("/authn/validate", con.credReqDF, cr);
+                        //Rcli<CLIENT> client = con.client().forUser(con.basicAuth(getName(), new String(getCred())));
+                        //Future<String> fp = client.read(
+                        //        "/authn/basicAuth",
+                        //        "text/plain"
+                        //       );
+                        if (fp.get(con.timeout)) {
+                            expires = System.currentTimeMillis() + timeToLive;
+                            addUser(new User<AAFPermission>(this, expires));
+                            return Resp.REVALIDATED;
+                        } else {
+                            addMiss(getName(), getCred());
+                            return Resp.UNVALIDATED;
+                        }
                     } else {
-                        addMiss(getName(), getCred());
                         return Resp.UNVALIDATED;
                     }
-                } else {
-                    return Resp.UNVALIDATED;
+                } catch (Exception e) {
+                    if (thisUri != null)  {
+                        attemptedUris.add(thisUri);
+                    }
+                    con.access.log(e);
+                    if (retries > maxRetries) {
+                        return Resp.INACCESSIBLE;
+                    }
                 }
-            } catch (Exception e) {
-                con.access.log(e);
-                return Resp.INACCESSIBLE;
             }
         }