AT&T 2.0.19 Code drop, stage 2

Issue-ID: AAF-197
Change-Id: Ifc93308f52c10d6ad82e99cd3ff5ddb900bf219a
Signed-off-by: Instrumental <jcgmisc@stl.gathman.org>
diff --git a/cadi/cass/.gitignore b/cadi/cass/.gitignore
new file mode 100644
index 0000000..2fd21f9
--- /dev/null
+++ b/cadi/cass/.gitignore
@@ -0,0 +1,4 @@
+/target/
+/.classpath
+/.settings/
+/target/
diff --git a/cadi/cass/.project b/cadi/cass/.project
new file mode 100644
index 0000000..8efd1f6
--- /dev/null
+++ b/cadi/cass/.project
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>cadi_cass</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+	</natures>
+</projectDescription>
diff --git a/cadi/cass/etc/cadi.properties b/cadi/cass/etc/cadi.properties
new file mode 100644
index 0000000..767fe5c
--- /dev/null
+++ b/cadi/cass/etc/cadi.properties
@@ -0,0 +1,45 @@
+##
+## AUTHZ API (authz-service) Properties
+##
+
+## DISCOVERY (DME2) Parameters on the Command Line
+AFT_LATITUDE=38.627345
+AFT_LONGITUDE=-90.193774
+AFT_ENVIRONMENT=AFTUAT
+
+# CADI 
+cadi_keyfile=/opt/app/aaf/common/com.att.aaf.keyfile
+cadi_loglevel=WARN
+
+# CASSANDRA Required for APP
+cass_group_name=com.att.aaf
+
+# CASSANDRA Optional
+cass_cluster_name=mithril
+
+# AAF Required for APP
+aaf_url=https://DME2RESOLVE/service=com.att.authz.AuthorizationService/version=2.0/envContext=DEV/routeOffer=BAU_SE
+DME2_EP_REGISTRY_CLASS=DME2FS
+AFT_DME2_EP_REGISTRY_FS_DIR=/Volumes/Data/src/authz/dme2reg
+
+aaf_default_realm=aaf.localized
+aaf_id=m12345@aaf.att.com
+aaf_password=enc:DuADW3_Y26NdHgDvN7Prt7vtDwYJM3Kvw9AOQ30lPV1
+cadi_loglevel=DEBUG
+
+# AAF Optional
+# Connection Time Out (milliseconds)
+aaf_conn_timeout=10000
+# User Cache Expiration (milliseconds)
+aaf_user_expires=600000
+# High count... Rough top number of objects held in Cache per cycle.  If high is reached, more are
+# recycled next time.  
+aaf_high_count=1000
+
+##
+## Localized Passwords
+##
+basic_realm=aaf.localized
+local_users=m01891@aaf.localized%DuADW3_Y26NdHgDvN7Prt7vtDwYJM3Kvw9AOQ30lPV1:/mithril/authz;\
+            m12345@aaf.localized%DuADW3_Y26NdHgDvN7Prt7vtDwYJM3Kvw9AOQ30lPV1:/mithril/authz;\
+            root@aaf.localized%DuADW3_Y26NdHgDvN7Prt7vtDwYJM3Kvw9AOQ30lPV1:/mithril
diff --git a/cadi/cass/pom.xml b/cadi/cass/pom.xml
new file mode 100644
index 0000000..9db57a4
--- /dev/null
+++ b/cadi/cass/pom.xml
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<parent>
+		<groupId>org.onap.aaf.cadi</groupId>
+		<artifactId>parent</artifactId>
+		<version>1.5.0-SNAPSHOT</version>
+		<relativePath>..</relativePath>
+	</parent>
+
+	<modelVersion>4.0.0</modelVersion>
+	<artifactId>aaf-cadi-cass</artifactId>
+	<name>AAF CADI Cassandra Library</name>
+	<packaging>jar</packaging>
+
+	<developers>
+		<developer>
+			<name>Jonathan Gathman</name>
+			<email>jonathan.gathman@att.com</email>
+			<organization>ATT</organization>
+			<roles>
+				<role>Architect</role>
+				<role>Lead Developer</role>
+			</roles>
+		</developer>
+		<developer>
+			<name>Gabe Maurer</name>
+			<email>gabe.maurer@att.com</email>
+			<organization>ATT</organization>
+			<roles>
+				<role>Developer</role>
+			</roles>
+		</developer>
+		<developer>
+			<name>Ian Howell</name>
+			<email>ian.howell@att.com</email>
+			<organization>ATT</organization>
+			<roles>
+				<role>Developer</role>
+			</roles>
+		</developer>
+	</developers>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.onap.aaf.cadi</groupId>
+			<artifactId>aaf-cadi-core</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.onap.aaf.cadi</groupId>
+			<artifactId>aaf-cadi-aaf</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.apache.cassandra</groupId>
+			<artifactId>cassandra-all</artifactId>
+			<version>2.1.14</version>
+			<scope>compile</scope>
+			<exclusions>
+				<exclusion>
+					<groupId>org.slf4j</groupId>
+					<artifactId>slf4j-log4j12</artifactId>
+				</exclusion>
+				<exclusion>
+					<groupId>log4j</groupId>
+					<artifactId>log4j</artifactId>
+				</exclusion>
+			</exclusions>
+		</dependency>
+
+	</dependencies>
+	<build>
+		<plugins />
+	</build>
+</project>
diff --git a/cadi/cass/src/main/java/com/att/aaf/cadi/cass/AAFAuthenticatedUser.java b/cadi/cass/src/main/java/com/att/aaf/cadi/cass/AAFAuthenticatedUser.java
new file mode 100644
index 0000000..3f08b1e
--- /dev/null
+++ b/cadi/cass/src/main/java/com/att/aaf/cadi/cass/AAFAuthenticatedUser.java
@@ -0,0 +1,109 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package com.att.aaf.cadi.cass;
+
+import java.security.Principal;
+
+import org.apache.cassandra.auth.AuthenticatedUser;
+import org.onap.aaf.cadi.Access;
+
+public class AAFAuthenticatedUser extends AuthenticatedUser implements Principal {
+	private boolean anonymous = false, supr=false, local=false;
+	private String fullName;
+//	private Access access;
+
+	public AAFAuthenticatedUser(Access access, String name) {
+		super(name);
+//		this.access = access;
+	    int endIndex = name.indexOf("@");
+	    if(endIndex >= 0) {
+	    	fullName = name;
+	    } else {
+	    	fullName = name + '@' + AAFBase.default_realm;
+	    }
+	}
+	
+	public String getFullName() {
+		return fullName;
+	}
+	
+	public String getName() {
+		return fullName;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.apache.cassandra.auth.AuthenticatedUser#isAnonymous()
+	 */
+	@Override
+	public boolean isAnonymous() {
+		return anonymous;
+	}
+
+	public void setAnonymous(boolean anon) {
+		anonymous = anon;
+	}
+
+	public boolean getAnonymous() {
+		return anonymous;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.apache.cassandra.auth.AuthenticatedUser#isSuper()
+	 */
+	@Override
+	public boolean isSuper() {
+		return supr;
+	}
+
+	public void setSuper(boolean supr) {
+		this.supr = supr;
+	}
+
+	public boolean getSuper() {
+		return supr;
+	}
+
+	/**
+	 * We check Local so we can compare with the right Lur.  This is AAF Plugin only.
+	 * @return
+	 */
+	public boolean isLocal() {
+		return local;
+	}
+	
+	public void setLocal(boolean val) {
+		local = val;
+	}
+
+	@Override
+	  public boolean equals(Object o) {
+		  if (this == o) return true;
+	      if (!(o instanceof AAFAuthenticatedUser)) return false;
+	      return ((AuthenticatedUser)o).getName().equals(this.getName());
+	  }
+
+	  @Override
+	  public int hashCode() {
+		  //access.log(Level.DEBUG, "AAFAuthentication hashcode ",getName().hashCode());
+	      return getName().hashCode();
+	  }  
+}
diff --git a/cadi/cass/src/main/java/com/att/aaf/cadi/cass/AAFAuthenticator.java b/cadi/cass/src/main/java/com/att/aaf/cadi/cass/AAFAuthenticator.java
new file mode 100644
index 0000000..1f50280
--- /dev/null
+++ b/cadi/cass/src/main/java/com/att/aaf/cadi/cass/AAFAuthenticator.java
@@ -0,0 +1,173 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package com.att.aaf.cadi.cass;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.cassandra.auth.AuthenticatedUser;
+import org.apache.cassandra.auth.IAuthenticator;
+import org.apache.cassandra.auth.ISaslAwareAuthenticator;
+import org.apache.cassandra.exceptions.AuthenticationException;
+import org.apache.cassandra.exceptions.InvalidRequestException;
+import org.apache.cassandra.exceptions.RequestExecutionException;
+import org.onap.aaf.cadi.Symm;
+import org.onap.aaf.cadi.Access.Level;
+import org.onap.aaf.cadi.CredVal.Type;
+import org.onap.aaf.cadi.config.Config;
+
+public class AAFAuthenticator extends AAFBase implements ISaslAwareAuthenticator  {
+
+	public boolean requireAuthentication() {
+		 return true;
+	 }
+	  
+	  /**
+	   * Invoked to authenticate an user
+	   */
+	  public AuthenticatedUser authenticate(Map<String, String> credentials) throws AuthenticationException {
+		    String username = (String)credentials.get("username");
+		    if (username == null) {
+		      throw new AuthenticationException("'username' is missing");
+		    }
+		    
+		    AAFAuthenticatedUser aau = new AAFAuthenticatedUser(access,username);
+		    String fullName=aau.getFullName();
+		    access.log(Level.DEBUG, "Authenticating", aau.getName(),"(", fullName,")");
+		    
+		    String password = (String)credentials.get("password");
+		    if (password == null) {
+		      throw new AuthenticationException("'password' is missing");
+		    } else if(password.startsWith("bsf:")) {
+		    	try {
+					password = Symm.base64noSplit.depass(password);
+				} catch (IOException e) {
+					throw new AuthenticationException("AAF bnf: Password cannot be decoded");
+				}
+	  		} else if(password.startsWith("enc:")) {
+				try {
+					password = access.decrypt(password, true);
+				} catch (IOException e) {
+					throw new AuthenticationException("AAF Encrypted Password cannot be decrypted");
+				}
+		    }
+		    
+		    if(localLur!=null) {
+		    	access.log(Level.DEBUG, "Validating",fullName, "with LocalTaf", password); 
+		    	if(localLur.validate(fullName, Type.PASSWORD, password.getBytes(),null)) {
+				    aau.setAnonymous(true);
+				    aau.setLocal(true);
+				    access.log(Level.DEBUG, fullName, "is authenticated locally"); 
+		    		return aau;
+		    	}
+		    }
+		    
+		    String aafResponse;
+		    try {
+		    	access.log(Level.DEBUG, "Validating",fullName, "with AAF");//, password); 
+		    	aafResponse = aafAuthn.validate(fullName, password,null);
+			    if(aafResponse != null) { // Reason for failing.
+			    	access.log(Level.AUDIT, "AAF reports ",fullName,":",aafResponse);
+			    	throw new AuthenticationException(aafResponse);
+			    }
+			    access.log(Level.AUDIT, fullName, "is authenticated"); //,password);
+			    // This tells Cassandra to skip checking it's own tables for User Entries.
+			    aau.setAnonymous(true);
+		    } catch (AuthenticationException ex) {
+		    	throw ex;
+		    } catch(Exception ex) {
+	    		access.log(ex,"Exception validating user");		    		
+	    		throw new AuthenticationException("Exception validating user");
+		    }
+		    
+		    return aau; 
+	  }
+	  
+	  public void create(String username, Map<IAuthenticator.Option, Object> options) throws InvalidRequestException, RequestExecutionException {
+		  access.log(Level.INFO,"Use AAF CLI to create user");
+	  }
+	  
+	  public void alter(String username, Map<IAuthenticator.Option, Object> options) throws RequestExecutionException {
+		  access.log(Level.INFO,"Use AAF CLI to alter user");
+	  }
+	  
+	  public void drop(String username) throws RequestExecutionException {
+		  access.log(Level.INFO,"Use AAF CLI to delete user");
+	  }
+	  
+	  public SaslAuthenticator newAuthenticator() {
+		  return new ISaslAwareAuthenticator.SaslAuthenticator() {
+		    private boolean complete = false;
+		    private Map<String, String> credentials;
+
+		    public byte[] evaluateResponse(byte[] clientResponse) throws AuthenticationException {
+		      this.credentials = decodeCredentials(clientResponse);
+		      this.complete = true;
+		      return null;
+		    }
+
+		    public boolean isComplete() {
+		      return this.complete;
+		    }
+
+		    public AuthenticatedUser getAuthenticatedUser() throws AuthenticationException {
+		      return AAFAuthenticator.this.authenticate(this.credentials);
+		    }
+
+		    private Map<String, String> decodeCredentials(byte[] bytes) throws AuthenticationException {
+		    	access.log(Level.DEBUG,"Decoding credentials from client token");
+		      byte[] user = null;
+		      byte[] pass = null;
+		      int end = bytes.length;
+		      for (int i = bytes.length - 1; i >= 0; i--)
+		      {
+		        if (bytes[i] != 0)
+		          continue;
+		        if (pass == null)
+		          pass = Arrays.copyOfRange(bytes, i + 1, end);
+		        else if (user == null)
+		          user = Arrays.copyOfRange(bytes, i + 1, end);
+		        end = i;
+		      }
+
+		      if (user == null)
+		        throw new AuthenticationException("Authentication ID must not be null");
+		      if (pass == null) {
+		        throw new AuthenticationException("Password must not be null");
+		      }
+		      Map<String,String> credentials = new HashMap<String,String>();
+		      try {
+		    	  credentials.put(IAuthenticator.USERNAME_KEY, new String(user, Config.UTF_8));
+		    	  credentials.put(IAuthenticator.PASSWORD_KEY, new String(pass, Config.UTF_8));
+				} catch (UnsupportedEncodingException e) {
+					throw new AuthenticationException(e.getMessage());
+				}
+		      return credentials;
+		    }
+		  };	  
+	  }
+
+}
+
diff --git a/cadi/cass/src/main/java/com/att/aaf/cadi/cass/AAFAuthorizer.java b/cadi/cass/src/main/java/com/att/aaf/cadi/cass/AAFAuthorizer.java
new file mode 100644
index 0000000..7353ee3
--- /dev/null
+++ b/cadi/cass/src/main/java/com/att/aaf/cadi/cass/AAFAuthorizer.java
@@ -0,0 +1,224 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package com.att.aaf.cadi.cass;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.cassandra.auth.AuthenticatedUser;
+import org.apache.cassandra.auth.IAuthorizer;
+import org.apache.cassandra.auth.IResource;
+import org.apache.cassandra.auth.Permission;
+import org.apache.cassandra.auth.PermissionDetails;
+import org.apache.cassandra.exceptions.RequestExecutionException;
+import org.apache.cassandra.exceptions.RequestValidationException;
+import org.onap.aaf.cadi.Access.Level;
+import org.onap.aaf.cadi.aaf.v2_0.AbsAAFLur;
+import org.onap.aaf.cadi.lur.LocalPermission;
+
+public class AAFAuthorizer extends AAFBase implements IAuthorizer {
+	// Returns every permission on the resource granted to the user.
+    public Set<Permission> authorize(AuthenticatedUser user, IResource resource) {
+    	String uname, rname;
+    	access.log(Level.DEBUG,"Authorizing",uname=user.getName(),"for",rname=resource.getName());
+
+    	Set<Permission> permissions;
+
+    	if(user instanceof AAFAuthenticatedUser) {
+	        AAFAuthenticatedUser aafUser = (AAFAuthenticatedUser) user;
+			aafUser.setAnonymous(false);
+			
+			if(aafUser.isLocal()) {
+				permissions = checkPermissions(aafUser, new LocalPermission(
+					rname.replaceFirst("data", cluster_name)
+				));
+			} else {
+		   		permissions = checkPermissions(
+		   				aafUser,
+		   				perm_type,
+		   				':'+rname.replaceFirst("data", cluster_name).replace('/', ':'));
+			}
+    	} else {
+    		permissions = Permission.NONE;
+    	}
+    	
+    	access.log(Level.INFO,"Permissions on",rname,"for",uname,':', permissions);
+
+        return permissions;
+    }
+    
+    /**
+     * Check only for Localized IDs (see cadi.properties)
+     * @param aau
+     * @param perm
+     * @return
+     */
+    private Set<Permission> checkPermissions(AAFAuthenticatedUser aau, LocalPermission perm) {
+    	if(localLur.fish(aau, perm)) {
+//        	aau.setSuper(true);
+        	return Permission.ALL;
+    	} else {
+    		return Permission.NONE;
+    	}
+    }
+    
+    /**
+     * Check remoted AAF Permissions
+     * @param aau
+     * @param type
+     * @param instance
+     * @return
+     */
+    private Set<Permission> checkPermissions(AAFAuthenticatedUser aau, String type, String instance) {
+		// Can perform ALL actions
+        PermHolder ph = new PermHolder(aau);
+        aafLur.fishOneOf(aau,ph,type,instance,actions);
+        return ph.permissions;
+    }   
+
+    private class PermHolder {
+    	private AAFAuthenticatedUser aau;
+		public PermHolder(AAFAuthenticatedUser aau) {
+    		this.aau = aau;
+    	}
+    	public Set<Permission> permissions = Permission.NONE;
+		public void mutable() {
+			if(permissions==Permission.NONE) {
+				permissions = new HashSet<Permission>();
+			}
+		}
+    };
+ 
+   /**
+    * This specialty List avoid extra Object Creation, and allows the Lur to do a Vistor on all appropriate Perms
+    */
+   private static final ArrayList<AbsAAFLur.Action<PermHolder>> actions = new ArrayList<AbsAAFLur.Action<PermHolder>>();
+   static {
+	   actions.add(new AbsAAFLur.Action<PermHolder>() {
+		public String getName() {
+			return "*";
+		}
+		
+		public boolean exec(PermHolder a) {
+        	a.aau.setSuper(true);
+        	a.permissions = Permission.ALL;
+			return true;
+		}
+	   });
+	   
+	   actions.add(new AbsAAFLur.Action<PermHolder>() {
+		public String getName() {
+			return "SELECT";
+		}
+		
+		public boolean exec(PermHolder ph) {
+			ph.mutable();
+        	ph.permissions.add(Permission.SELECT);
+			return false;
+		}
+	   });
+	   actions.add(new AbsAAFLur.Action<PermHolder>() {
+		public String getName() {
+			return "MODIFY";
+		}
+		
+		public boolean exec(PermHolder ph) {
+			ph.mutable();
+        	ph.permissions.add(Permission.MODIFY);
+			return false;
+		}
+	   });
+	   actions.add(new AbsAAFLur.Action<PermHolder>() {
+		public String getName() {
+			return "CREATE";
+		}
+		
+		public boolean exec(PermHolder ph) {
+			ph.mutable();
+        	ph.permissions.add(Permission.CREATE);
+			return false;
+		}
+	   });
+
+	   actions.add(new AbsAAFLur.Action<PermHolder>() {
+		public String getName() {
+			return "ALTER";
+		}
+		
+		public boolean exec(PermHolder ph) {
+			ph.mutable();
+        	ph.permissions.add(Permission.ALTER);
+			return false;
+		}
+	   });
+	   actions.add(new AbsAAFLur.Action<PermHolder>() {
+		public String getName() {
+			return "DROP";
+		}
+		
+		public boolean exec(PermHolder ph) {
+			ph.mutable();
+        	ph.permissions.add(Permission.DROP);
+			return false;
+		}
+	   });
+	   actions.add(new AbsAAFLur.Action<PermHolder>() {
+		public String getName() {
+			return "AUTHORIZE";
+		}
+		
+		public boolean exec(PermHolder ph) {
+			ph.mutable();
+        	ph.permissions.add(Permission.AUTHORIZE);
+			return false;
+		}
+	   });
+
+
+   }; 
+   
+   
+    public void grant(AuthenticatedUser performer, Set<Permission> permissions, IResource resource, String to) throws RequestExecutionException {
+    	access.log(Level.INFO, "Use AAF CLI to grant permission(s) to user/role");
+    }
+
+    public void revoke(AuthenticatedUser performer, Set<Permission> permissions, IResource resource, String from) throws RequestExecutionException {
+    	access.log(Level.INFO,"Use AAF CLI to revoke permission(s) for user/role");
+    }
+
+    public Set<PermissionDetails> list(AuthenticatedUser performer, Set<Permission> permissions, IResource resource, String of) throws RequestValidationException, RequestExecutionException {
+    	access.log(Level.INFO,"Use AAF CLI to find the list of permissions");
+    	return null;
+    }
+
+    // Called prior to deleting the user with DROP USER query. Internal hook, so no permission checks are needed here.
+    public void revokeAll(String droppedUser) {
+    	access.log(Level.INFO,"Use AAF CLI to revoke permission(s) for user/role");
+    }
+
+    // Called after a resource is removed (DROP KEYSPACE, DROP TABLE, etc.).
+    public void revokeAll(IResource droppedResource) {
+    	access.log(Level.INFO,"Use AAF CLI to delete the unused permission", droppedResource.getName());
+    }
+
+}
diff --git a/cadi/cass/src/main/java/com/att/aaf/cadi/cass/AAFBase.java b/cadi/cass/src/main/java/com/att/aaf/cadi/cass/AAFBase.java
new file mode 100644
index 0000000..b091cc9
--- /dev/null
+++ b/cadi/cass/src/main/java/com/att/aaf/cadi/cass/AAFBase.java
@@ -0,0 +1,193 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package com.att.aaf.cadi.cass;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.HashSet;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.cassandra.auth.DataResource;
+import org.apache.cassandra.auth.IAuthenticator;
+import org.apache.cassandra.config.DatabaseDescriptor;
+import org.apache.cassandra.exceptions.ConfigurationException;
+import org.onap.aaf.cadi.Access;
+import org.onap.aaf.cadi.Lur;
+import org.onap.aaf.cadi.PropAccess;
+import org.onap.aaf.cadi.Access.Level;
+import org.onap.aaf.cadi.aaf.AAFPermission;
+import org.onap.aaf.cadi.aaf.v2_0.AAFAuthn;
+import org.onap.aaf.cadi.aaf.v2_0.AAFCon;
+import org.onap.aaf.cadi.aaf.v2_0.AbsAAFLur;
+import org.onap.aaf.cadi.config.Config;
+import org.onap.aaf.cadi.config.SecurityInfoC;
+import org.onap.aaf.cadi.lur.EpiLur;
+import org.onap.aaf.cadi.lur.LocalLur;
+
+public abstract class AAFBase {
+	protected static final Set<IAuthenticator.Option> options;
+	protected static final Set<DataResource> dataResource;
+
+	static {
+		options = new HashSet<IAuthenticator.Option>();
+		options.add(IAuthenticator.Option.PASSWORD);
+		
+		dataResource = new HashSet<DataResource>();
+		dataResource.add(DataResource.columnFamily("system_auth", "credentials"));
+	}
+	
+	protected static Access access;
+	protected static LocalLur localLur;
+	protected static AAFCon<?> aafcon;
+	protected static AAFAuthn<?> aafAuthn;
+	protected static AbsAAFLur<AAFPermission> aafLur;
+	protected static String default_realm;
+    protected static String cluster_name;
+    protected static String perm_type;
+	private static boolean props_ok = false;
+	
+	/**
+	 * If you use your own Access Class, this must be called before 
+	 * "setup()" is invoked by Cassandra.
+	 * 
+	 * Otherwise, it will default to reading Properties CADI style.
+	 * 
+	 * @param access
+	 */
+	public static void setAccess(Access access) {
+		AAFBase.access = access;
+	}
+
+	
+    public void validateConfiguration() throws ConfigurationException {
+    	setup();
+    	if(!props_ok)  {
+    		throw new ConfigurationException("AAF not initialized");
+    	}
+    }
+    
+	@SuppressWarnings("unchecked")
+	public synchronized void setup() {
+		if(aafAuthn == null) {
+			try {
+				if(access==null) {
+					String value = System.getProperty(Config.CADI_PROP_FILES, "cadi.properties");
+					Properties initial = new Properties();
+					URL cadi_props = ClassLoader.getSystemResource(value);
+					if(cadi_props == null) {
+						File cp = new File(value);
+						if(cp.exists()) {
+							InputStream is = new FileInputStream(cp);
+							try {
+								initial.load(is);
+							} finally {
+								is.close();
+							}
+						} else {
+							System.out.printf("%s does not exist as File or in Classpath\n",value);
+							initial.setProperty(Config.CADI_PROP_FILES, value);
+						}
+					} else {
+						InputStream is = cadi_props.openStream();
+						try {
+							initial.load(is);
+						} finally {
+							is.close();
+						}
+					}
+					access = new PropAccess(initial);
+				}
+				props_ok = true;
+				if((perm_type = Config.logProp(access, "cass_group_name",null))==null) {
+					props_ok=false;
+				} else {
+					perm_type = perm_type + ".cass";
+				}
+				
+				if((cluster_name = Config.logProp(access,"cass_cluster_name",null))==null) {
+					if((cluster_name = DatabaseDescriptor.getClusterName())==null) {
+						props_ok=false;
+					}
+				}
+
+				if((default_realm = Config.logProp(access, Config.AAF_DEFAULT_REALM, null))==null) {
+					props_ok=false;
+				}
+				
+				if(props_ok==false) {
+					return;
+				}
+
+				// AAFLur has pool of DME clients as needed, and Caches Client lookups
+				SecurityInfoC<HttpURLConnection> si = SecurityInfoC.instance(access, HttpURLConnection.class);
+				Lur lur = Config.configLur(si,aafcon);
+				// Loop through to find AAFLur out of possible Lurs, to reuse AAFCon
+				if(lur instanceof EpiLur) {
+					EpiLur elur = (EpiLur)lur;
+					for(int i=0; (lur = elur.get(i))!=null;++i) {
+						if(lur instanceof AbsAAFLur) {
+							aafLur=(AbsAAFLur<AAFPermission>)lur;
+							aafcon = aafLur.aaf;
+							aafAuthn = aafLur.aaf.newAuthn(aafLur);
+							break;
+						} else if(lur instanceof LocalLur) {
+							localLur = (LocalLur)lur;
+						}
+					}
+				} else if(lur instanceof AbsAAFLur) {
+					aafLur=(AbsAAFLur<AAFPermission>)lur;
+					aafcon = aafLur.aaf;
+					aafAuthn = aafLur.aaf.newAuthn(aafLur);
+				}
+				if(aafAuthn==null) {
+					access.log(Level.INIT,"Failed to instantiate full AAF access");
+					props_ok = false;
+				}
+			} catch (Exception e) {
+				aafAuthn=null;
+				if(access!=null)access.log(e, "Failed to initialize AAF");
+				props_ok = false;
+			}
+		}		
+	}
+
+	public Set<DataResource> protectedResources() {
+		access.log(Level.DEBUG, "Data Resource asked for: it's",dataResource.isEmpty()?"":"not","empty");
+		return dataResource;
+	}
+	
+	public Set<IAuthenticator.Option> supportedOptions() {
+		access.log(Level.DEBUG, "supportedOptions() called");
+		return options;
+	}
+	  
+	public Set<IAuthenticator.Option> alterableOptions() {
+		access.log(Level.DEBUG, "alterableOptions() called");
+		return options;
+	}
+
+
+}
diff --git a/cadi/cass/src/test/java/org/onap/aaf/cadi/cass/JU_AAFAuthenticatedUserTest.java b/cadi/cass/src/test/java/org/onap/aaf/cadi/cass/JU_AAFAuthenticatedUserTest.java
new file mode 100644
index 0000000..2f19672
--- /dev/null
+++ b/cadi/cass/src/test/java/org/onap/aaf/cadi/cass/JU_AAFAuthenticatedUserTest.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * ============LICENSE_START====================================================
+ * * org.onap.aaf
+ * * ===========================================================================
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * * ===========================================================================
+ * * 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.
+ * * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ * * ============LICENSE_END====================================================
+ * *
+ * *
+ ******************************************************************************/
+package org.onap.aaf.cadi.cass;
+
+import static org.junit.Assert.*;
+
+import org.apache.cassandra.auth.AuthenticatedUser;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.att.aaf.cadi.cass.AAFAuthenticatedUser;
+
+public class JU_AAFAuthenticatedUserTest {
+
+	@Before
+	public void setUp() throws Exception {
+	}
+
+	@Test
+	public void test() {
+		AAFAuthenticatedUser user = new AAFAuthenticatedUser(null, "User1@aaf");
+		assertEquals(user.getFullName(),"User1@aaf");
+		assertEquals(user.getName(),"User1@aaf");
+		assertFalse(user.isAnonymous());
+		assertFalse(user.isSuper());
+		assertFalse(user.isLocal());
+		
+		
+		
+	}
+	
+	@Test
+	public void testone() {
+		AAFAuthenticatedUser user = new AAFAuthenticatedUser(null, "User2@aaf");
+		assertEquals(user.getFullName(),"User2@aaf");
+		assertEquals(user.getName(),"User2@aaf");
+		assertFalse(user.isAnonymous());
+		assertFalse(user.isSuper());
+		assertFalse(user.isLocal());
+		
+		
+		
+	}
+
+	@Test
+	public void testtwo() {
+		AAFAuthenticatedUser user = new AAFAuthenticatedUser(null, "onap@aaf");
+		assertEquals(user.getFullName(),"onap@aaf");
+		assertEquals(user.getName(),"onap@aaf");
+		assertFalse(user.isAnonymous());
+		assertFalse(user.isSuper());
+		assertFalse(user.isLocal());
+		
+		
+		
+	}
+	
+	@Test
+	public void testthree() {
+		AAFAuthenticatedUser user = new AAFAuthenticatedUser(null, "openecomp@aaf");
+		assertEquals(user.getFullName(),"openecomp@aaf");
+		assertEquals(user.getName(),"openecomp@aaf");
+		assertFalse(user.isAnonymous());
+		assertFalse(user.isSuper());
+		assertFalse(user.isLocal());
+		
+		
+		
+	}
+
+}
diff --git a/cadi/cass/src/test/java/org/onap/aaf/cadi/cass/JU_AAFAuthenticator.java b/cadi/cass/src/test/java/org/onap/aaf/cadi/cass/JU_AAFAuthenticator.java
new file mode 100644
index 0000000..2dcb033
--- /dev/null
+++ b/cadi/cass/src/test/java/org/onap/aaf/cadi/cass/JU_AAFAuthenticator.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * ============LICENSE_START====================================================
+ * * org.onap.aaf
+ * * ===========================================================================
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * * ===========================================================================
+ * * 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.
+ * * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ * * ============LICENSE_END====================================================
+ * *
+ * *
+ ******************************************************************************/
+package org.onap.aaf.cadi.cass;
+
+import static org.junit.Assert.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Test;
+import org.onap.aaf.cadi.Access;
+import org.onap.aaf.cadi.PropAccess;
+import org.onap.aaf.cadi.Access.Level;
+import org.apache.cassandra.auth.AuthenticatedUser;
+import org.apache.cassandra.exceptions.AuthenticationException;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+import com.att.aaf.cadi.cass.AAFAuthenticatedUser;
+import com.att.aaf.cadi.cass.AAFAuthenticator;
+import com.att.aaf.cadi.cass.AAFBase;
+
+import junit.framework.Assert;
+
+public class JU_AAFAuthenticator extends AAFBase
+{
+	
+
+	@Before
+	public void setUp()
+	{
+		
+	}
+
+	@After
+	public void tearDown()
+	{
+		
+	}
+	
+	@Test
+	public void checkRequiredAuth() {
+		AAFAuthenticator test = new AAFAuthenticator();
+		Assert.assertTrue(test.requireAuthentication());
+	}
+	//TODO: Call may be broken due to missing ATT specific code
+	@Test
+	public void checkAuthenticate()  throws AuthenticationException {
+		AuthenticatedUser user = new AuthenticatedUser("testUser");
+		AAFAuthenticator test = new AAFAuthenticator();	
+		Map<String, String> cred = new HashMap<String,String>();
+		cred.put("username", "testUser");
+		cred.put("password", "testPass");
+		String username = (String)cred.get("username");
+		Access access = new PropAccess();
+		AAFAuthenticatedUser aau = new AAFAuthenticatedUser(access,username);
+		String fullName=aau.getFullName();
+		access.log(Level.DEBUG, "Authenticating", aau.getName(),"(", fullName,")");
+		//test.authenticate(cred);
+		//Assert.assert
+		
+	}
+	
+	@Test(expected = AuthenticationException.class)
+	public void checkThrowsUser() throws AuthenticationException {
+		AAFAuthenticator test = new AAFAuthenticator();
+		Map<String, String> cred = new HashMap<String,String>();
+		cred.put("username", null);
+		Assert.assertNull(cred.get("username"));
+		test.authenticate(cred);
+	}
+	
+	@Test(expected = AuthenticationException.class)
+	public void checkThrowsPass() throws AuthenticationException {
+		AAFAuthenticator test = new AAFAuthenticator();
+		Map<String, String> cred = new HashMap<String,String>();
+		cred.put("username", "testUser");
+		cred.put("password", "bsf:");
+		Assert.assertNotNull(cred.get("password"));
+		test.authenticate(cred);
+		
+		cred.put("password", null);
+		Assert.assertNull(cred.get("password"));
+		test.authenticate(cred);
+	}
+
+
+
+}
diff --git a/cadi/cass/src/test/java/org/onap/aaf/cadi/cass/JU_AAFAuthorizerTest.java b/cadi/cass/src/test/java/org/onap/aaf/cadi/cass/JU_AAFAuthorizerTest.java
new file mode 100644
index 0000000..6f2e9da
--- /dev/null
+++ b/cadi/cass/src/test/java/org/onap/aaf/cadi/cass/JU_AAFAuthorizerTest.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * ============LICENSE_START====================================================
+ * * org.onap.aaf
+ * * ===========================================================================
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * * ===========================================================================
+ * * 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.
+ * * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ * * ============LICENSE_END====================================================
+ * *
+ * *
+ ******************************************************************************/
+package org.onap.aaf.cadi.cass;
+
+import static org.junit.Assert.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Test;
+import org.onap.aaf.cadi.Access;
+import org.onap.aaf.cadi.PropAccess;
+import org.onap.aaf.cadi.Access.Level;
+import org.apache.cassandra.auth.AuthenticatedUser;
+import org.apache.cassandra.exceptions.AuthenticationException;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+import com.att.aaf.cadi.cass.AAFAuthenticatedUser;
+import com.att.aaf.cadi.cass.AAFAuthenticator;
+import com.att.aaf.cadi.cass.AAFBase;
+
+import junit.framework.Assert;
+//TODO:DELETE THIS OLD TEST
+public class JU_AAFAuthorizerTest extends AAFBase
+{
+	
+
+	@Before
+	public void setUp()
+	{
+		
+	}
+
+	@After
+	public void tearDown()
+	{
+		
+	}
+	
+	@Test
+	public void checkRequiredAuth() {
+		AAFAuthenticator test = new AAFAuthenticator();
+		Assert.assertTrue(test.requireAuthentication());
+	}
+	
+	@Test
+	public void checkAuthenticate()  throws AuthenticationException {
+		AuthenticatedUser user = new AuthenticatedUser("testUser");
+		AAFAuthenticator test = new AAFAuthenticator();	
+		Map<String, String> cred = new HashMap<String,String>();
+		cred.put("username", "testUser");
+		cred.put("password", "testPass");
+		String username = (String)cred.get("username");
+		AAFAuthenticatedUser aau = new AAFAuthenticatedUser(access,username);
+		String fullName=aau.getFullName();
+		//access.log(Level.DEBUG, "Authenticating", aau.getName(),"(", fullName,")");
+		test.authenticate(cred);
+		//Assert.assert
+		
+	}
+	
+	@Test(expected = AuthenticationException.class)
+	public void checkThrowsUser() throws AuthenticationException {
+		AAFAuthenticator test = new AAFAuthenticator();
+		Map<String, String> cred = new HashMap<String,String>();
+		cred.put("username", null);
+		Assert.assertNull(cred.get("username"));
+		test.authenticate(cred);
+	}
+	
+	@Test(expected = AuthenticationException.class)
+	public void checkThrowsPass() throws AuthenticationException {
+		AAFAuthenticator test = new AAFAuthenticator();
+		Map<String, String> cred = new HashMap<String,String>();
+		cred.put("username", "testUser");
+		cred.put("password", "bsf:");
+		Assert.assertNotNull(cred.get("password"));
+		test.authenticate(cred);
+		
+		cred.put("password", null);
+		Assert.assertNull(cred.get("password"));
+		test.authenticate(cred);
+	}
+
+
+
+}
diff --git a/cadi/cass/src/test/java/org/onap/aaf/cadi/cass/JU_AAFBaseTest.java b/cadi/cass/src/test/java/org/onap/aaf/cadi/cass/JU_AAFBaseTest.java
new file mode 100644
index 0000000..4985486
--- /dev/null
+++ b/cadi/cass/src/test/java/org/onap/aaf/cadi/cass/JU_AAFBaseTest.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * ============LICENSE_START====================================================
+ * * org.onap.aaf
+ * * ===========================================================================
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * * ===========================================================================
+ * * 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.
+ * * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ * * ============LICENSE_END====================================================
+ * *
+ * *
+ ******************************************************************************/
+package org.onap.aaf.cadi.cass;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.aaf.cadi.Access;
+import org.onap.aaf.cadi.Lur;
+import org.onap.aaf.cadi.PropAccess;
+import org.onap.aaf.cadi.Access.Level;
+
+import junit.framework.Assert;
+
+import com.att.aaf.cadi.cass.AAFBase;
+
+import static org.junit.Assert.*;
+
+import org.apache.cassandra.exceptions.ConfigurationException;
+
+public class JU_AAFBaseTest
+{
+	
+	//TODO: REmove this file, no need for junit for abstract class
+	@Before
+	public void setUp()
+	{
+		
+	}
+
+	@After
+	public void tearDown()
+	{
+		
+	}
+
+	
+	@Test
+	public void test_method_setAccess_0_branch_0()
+	{
+		System.out.println("Now Testing Method:setAccess Branch:0");
+		
+		//Call Method
+		AAFBase.setAccess(null);
+		
+	}
+	
+	
+	
+
+}
diff --git a/cadi/cass/src/test/java/org/onap/aaf/cadi/cass/JU_CASS.java b/cadi/cass/src/test/java/org/onap/aaf/cadi/cass/JU_CASS.java
new file mode 100644
index 0000000..60fd548
--- /dev/null
+++ b/cadi/cass/src/test/java/org/onap/aaf/cadi/cass/JU_CASS.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * ============LICENSE_START====================================================
+ * * org.onap.aaf
+ * * ===========================================================================
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * * ===========================================================================
+ * * 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.
+ * * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ * * ============LICENSE_END====================================================
+ * *
+ * *
+ ******************************************************************************/
+package org.onap.aaf.cadi.cass;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.cassandra.auth.AuthenticatedUser;
+import org.apache.cassandra.auth.IResource;
+import org.apache.cassandra.auth.Permission;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.att.aaf.cadi.cass.AAFAuthenticator;
+import com.att.aaf.cadi.cass.AAFAuthorizer;
+
+public class JU_CASS {
+
+	private static AAFAuthenticator aa;
+	private static AAFAuthorizer an;
+
+	@BeforeClass
+	public static void setUpBeforeClass() throws Exception {
+		System.setProperty("cadi_prop_files", "etc/cadi.properties");
+		
+		aa = new AAFAuthenticator();
+		an = new AAFAuthorizer();
+
+		aa.setup();
+		an.setup(); // does nothing after aa.
+		
+		aa.validateConfiguration();
+		
+	}
+
+	@AfterClass
+	public static void tearDownAfterClass() throws Exception {
+	}
+
+	@Test
+	public void test() throws Exception {
+			Map<String,String> creds = new HashMap<String,String>();
+			creds.put("username", "XXX@NS");
+			creds.put("password", "enc:???");
+			AuthenticatedUser aaf = aa.authenticate(creds);
+
+			// Test out "aaf_default_domain
+			creds.put("username", "XX");
+			aaf = aa.authenticate(creds);
+			
+			IResource resource = new IResource() {
+				public String getName() {
+					return "data/authz";
+				}
+
+				public IResource getParent() {
+					return null;
+				}
+
+				public boolean hasParent() {
+					return false;
+				}
+
+				public boolean exists() {
+					return true;
+				}
+				
+			};
+			
+			Set<Permission> perms = an.authorize(aaf, resource);
+			
+			// Test out "AAF" access
+			creds.put("username", "XXX@NS");
+			creds.put("password", "enc:???");
+			aaf = aa.authenticate(creds);
+			perms = an.authorize(aaf, resource);
+			Assert.assertFalse(perms.isEmpty());
+
+			perms = an.authorize(aaf, resource);
+			Assert.assertFalse(perms.isEmpty());
+			
+	}
+
+}