Add Multi-Realm class handling
[aaf/cadi.git] / shiro / src / main / java / org / onap / aaf / cadi / shiro / AAFRealm.java
index 0fc962f..52bf354 100644 (file)
 package org.onap.aaf.cadi.shiro;
 
 import java.io.IOException;
-import java.io.PrintStream;
 import java.security.Principal;
 import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
-import java.util.TreeMap;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentSkipListSet;
 
-
-import org.apache.log4j.PropertyConfigurator;
 import org.apache.shiro.authc.AuthenticationException;
 import org.apache.shiro.authc.AuthenticationInfo;
 import org.apache.shiro.authc.AuthenticationToken;
@@ -55,93 +53,186 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public class AAFRealm extends AuthorizingRealm {
-       
-       final static  Logger logger =  LoggerFactory.getLogger(AAFRealm.class);
-       
        public static final String AAF_REALM = "AAFRealm";
+       private static final Logger logger =  LoggerFactory.getLogger(AAFRealm.class);
+       private static Singleton singleton = Singleton.singleton();
        
-       private PropAccess access;
-       private AAFCon<?> acon;
-       private AAFAuthn<?> authn;
-       private HashSet<Class<? extends AuthenticationToken>> supports;
-       private AAFLurPerm authz;
-       private MapBathConverter mbc;
-       private Map<String,String> idMap;
-       
-
-       /**
-        * 
-        * There appears to be no configuration objects or references available for CADI to start with.
-        *  
-        */
-       public AAFRealm () {
-               access = new PropAccess(); // pick up cadi_prop_files from VM_Args
-               mbc = null;
-               idMap = null;
-               String cadi_prop_files = access.getProperty(Config.CADI_PROP_FILES);
-               if(cadi_prop_files==null) {
-                       String msg = Config.CADI_PROP_FILES + " in VM Args is required to initialize AAFRealm.";
-                       logger.info(msg);
-                       throw new RuntimeException(msg);
-               } else {
-                       try {
-                               acon = AAFCon.newInstance(access);
-                               authn = acon.newAuthn();
-                               authz = acon.newLur(authn);
-                               
-                               final String csv = access.getProperty(Config.CADI_BATH_CONVERT);
-                               if(csv!=null) {
-                                       try {
-                                               mbc = new MapBathConverter(access, new CSV(csv));
-                                               logger.info("MapBathConversion enabled with file "+csv);
-                                               idMap = new TreeMap<String,String>();
-                                               // Load 
-                                               for(Entry<String, String> es : mbc.map().entrySet()) {
-                                                       String oldID = es.getKey();
-                                                       if(oldID.startsWith("Basic ")) {
-                                                               oldID = Symm.base64noSplit.decode(oldID.substring(6));
-                                                               int idx = oldID.indexOf(':');
-                                                               if(idx>=0) {
-                                                                       oldID = oldID.substring(0, idx);
+       private static class Singleton {
+               private AAFCon<?> acon;
+               private AAFAuthn<?> authn;
+               private Set<Class<? extends AuthenticationToken>> supports;
+               private AAFLurPerm authz;
+               private MapBathConverter mbc;
+               private Map<String,String> idMap;
+               private Singleton() {
+                       mbc = null;
+                       idMap = null;
+                       String cadi_prop_files = access.getProperty(Config.CADI_PROP_FILES);
+                       if(cadi_prop_files==null) {
+                               String msg = Config.CADI_PROP_FILES + " in VM Args is required to initialize AAFRealm.";
+                               access.log(Level.INFO,msg);
+                               throw new RuntimeException(msg);
+                       } else {
+                               try {
+                                       acon = AAFCon.newInstance(access);
+                                       authn = acon.newAuthn();
+                                       authz = acon.newLur(authn);
+                                       
+                                       final String csv = access.getProperty(Config.CADI_BATH_CONVERT);
+                                       if(csv!=null) {
+                                               try {
+                                                       mbc = new MapBathConverter(access, new CSV(csv));
+                                                       access.log(Level.INFO, "MapBathConversion enabled with file ",csv);
+                                                       idMap = new ConcurrentHashMap<String,String>();
+                                                       // Load 
+                                                       for(Entry<String, String> es : mbc.map().entrySet()) {
+                                                               String oldID = es.getKey();
+                                                               if(oldID.startsWith("Basic ")) {
+                                                                       oldID = Symm.base64noSplit.decode(oldID.substring(6));
+                                                                       int idx = oldID.indexOf(':');
+                                                                       if(idx>=0) {
+                                                                               oldID = oldID.substring(0, idx);
+                                                                       }
                                                                }
-                                                       }
-                                                       String newID = es.getValue();
-                                                       if(newID.startsWith("Basic ")) {
-                                                               newID = Symm.base64noSplit.decode(newID.substring(6));
-                                                               int idx = newID.indexOf(':');
-                                                               if(idx>=0) {
-                                                                       newID = newID.substring(0, idx);
+                                                               String newID = es.getValue();
+                                                               if(newID.startsWith("Basic ")) {
+                                                                       newID = Symm.base64noSplit.decode(newID.substring(6));
+                                                                       int idx = newID.indexOf(':');
+                                                                       if(idx>=0) {
+                                                                               newID = newID.substring(0, idx);
+                                                                       }
                                                                }
+                                                               idMap.put(oldID,newID);
+                                                               
                                                        }
-                                                       idMap.put(oldID,newID);
-                                                       
+                                               } catch (IOException e) {
+                                                       access.log(e);
                                                }
-                                       } catch (IOException e) {
-                                               logger.info(e.getMessage(), e);
                                        }
+                               } catch (APIException | CadiException | LocatorException e) {
+                                       String msg = "Cannot initiate AAFRealm";
+                                       access.log(Level.ERROR,e,msg);
+                                       throw new RuntimeException(msg,e);
                                }
-                       } catch (APIException | CadiException | LocatorException e) {
-                               String msg = "Cannot initiate AAFRealm";
-                               logger.info(msg + " "+ e.getMessage(), e);
-                               throw new RuntimeException(msg,e);
                        }
+                       supports = new ConcurrentSkipListSet<>();
+                       supports.add(UsernamePasswordToken.class);
                }
-               supports = new HashSet<Class<? extends AuthenticationToken>>();
-               supports.add(UsernamePasswordToken.class);
-       }
+               
+               public static synchronized Singleton singleton() {
+                       if(singleton==null) {
+                               singleton = new Singleton();
+                       }
+                       return singleton;
+               }
+
+               // pick up cadi_prop_files from VM_Args
+               private final PropAccess access = new PropAccess() {
+                       @Override
+                       public void log(Exception e, Object... elements) {
+                               logger.error(buildMsg(Level.ERROR, elements).toString(),e);
+                       }
+               
+                       @Override
+                       public void log(Level level, Object... elements) {
+                               if(willLog(level)) {
+                                       String str = buildMsg(level, elements).toString();
+                                       switch(level) {
+                                               case WARN:
+                                               case AUDIT:
+                                                       logger.warn(str);
+                                                       break;
+                                               case DEBUG:
+                                                       logger.debug(str);
+                                                       break;
+                                               case ERROR:
+                                                       logger.warn(str);
+                                                       break;
+                                               case INFO:
+                                               case INIT:
+                                                       logger.info(str);
+                                                       break;
+                                               case NONE:
+                                                       break;
+                                               case TRACE:
+                                                       logger.trace(str);
+                                                       break;
+                                       }
+                               }
+                       }
+               
+                       @Override
+                       public void printf(Level level, String fmt, Object... elements) {
+                               if(willLog(level)) {
+                                       String str = String.format(fmt, elements);
+                                       switch(level) {
+                                               case WARN:
+                                               case AUDIT:
+                                                       logger.warn(str);
+                                                       break;
+                                               case DEBUG:
+                                                       logger.debug(str);
+                                                       break;
+                                               case ERROR:
+                                                       logger.warn(str);
+                                                       break;
+                                               case INFO:
+                                               case INIT:
+                                                       logger.info(str);
+                                                       break;
+                                               case NONE:
+                                                       break;
+                                               case TRACE:
+                                                       logger.trace(str);
+                                                       break;
+                                       }
+                               }
+                       }
+               
+                       @Override
+                       public boolean willLog(Level level) {
+                               if(super.willLog(level)) {
+                                       switch(level) {
+                                               case AUDIT:
+                                                       return logger.isWarnEnabled();
+                                               case DEBUG:
+                                                       return logger.isDebugEnabled();
+                                               case ERROR:
+                                                       return logger.isErrorEnabled();
+                                               case INFO:
+                                               case INIT:
+                                                       return logger.isInfoEnabled();
+                                               case NONE:
+                                                       return false;
+                                               case TRACE:
+                                                       return logger.isTraceEnabled();
+                                               case WARN:
+                                                       return logger.isWarnEnabled();
+                               
+                                       }
+                               }
+                               return false;
+                       }
+               };
+       }               
+       
+       /**
+        * 
+        * There appears to be no configuration objects or references available for CADI to start with.
+        *  
+        */
 
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
-               logger.info("AAFRealm.doGetAuthenticationInfo :"+token);
                final UsernamePasswordToken upt = (UsernamePasswordToken)token;
                final String user = upt.getUsername();
                String authUser = user; 
                final String password=new String(upt.getPassword());
                String authPassword = password;
-               if(mbc!=null) {
+               if(singleton.mbc!=null) {
                        try {
                                final String oldBath = "Basic " + Symm.base64noSplit.encode(user+':'+password);
-                               String bath = mbc.convert(access, oldBath);
+                               String bath = singleton.mbc.convert(singleton.access, oldBath);
                                if(bath!=oldBath) {
                                        bath = Symm.base64noSplit.decode(bath.substring(6));
                                        int colon = bath.indexOf(':');
@@ -151,26 +242,23 @@ public class AAFRealm extends AuthorizingRealm {
                                        }
                                }
                        } catch (IOException e) {
-
-                               logger.info(e.getMessage(), e);
-
+                               singleton.access.log(e);
                        } 
                }
                String err;
                try {
-                       err = authn.validate(authUser,authPassword);
+                       err = singleton.authn.validate(authUser,authPassword);
+                       if(err != null) {
+                               singleton.access.log(Level.INFO, err);
+                               throw new AuthenticationException(err);
+                       }
+
                } catch (IOException e) {
-                       err = "Credential cannot be validated";
-                       logger.info(e.getMessage(), e);
+                       singleton.access.log(e,"Credential cannot be validated");
                }
                
-               if(err != null) {
-                       logger.info(err);
-                       throw new AuthenticationException(err);
-               }
-
            return new AAFAuthenticationInfo(
-                       access,
+                       singleton.access,
                        user,
                        password
            );
@@ -182,7 +270,6 @@ public class AAFRealm extends AuthorizingRealm {
                if(ai instanceof AAFAuthenticationInfo) {
                        if(!((AAFAuthenticationInfo)ai).matches(atoken)) {
                                throw new AuthenticationException("Credentials do not match");
-
                        }
                        
                } else {
@@ -198,9 +285,9 @@ public class AAFRealm extends AuthorizingRealm {
        protected AAFAuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
                Principal bait = (Principal)principals.getPrimaryPrincipal();
                Principal newBait = bait;
-               if(idMap!=null) {
-                       final String newID = idMap.get(bait.getName());
-                       logger.info("Successful authentication attempt by " +bait.getName()); 
+               if(singleton.idMap!=null) {
+                       final String newID = singleton.idMap.get(bait.getName());
+                       singleton.access.printf(Level.INFO,"Successful authentication attempt by %s",bait.getName()); 
                        if(newID!=null) {
                                newBait = new Principal() {
                                        @Override
@@ -211,14 +298,13 @@ public class AAFRealm extends AuthorizingRealm {
                        }
                }
                List<Permission> pond = new ArrayList<>();
-               authz.fishAll(newBait,pond);
-               return new AAFAuthorizationInfo(access,bait,pond);
-       
+               singleton.authz.fishAll(newBait,pond);
+               return new AAFAuthorizationInfo(singleton.access,bait,pond);
        }
 
        @Override
        public boolean supports(AuthenticationToken token) {
-               return supports.contains(token.getClass());
+               return singleton.supports.contains(token.getClass());
        }
 
        @Override