--- /dev/null
+package aa;
+
+//import aa.*;
+import java.io.*;
+import java.util.*;
+import java.util.zip.*;
+import java.util.jar.*;
+
+/**
+ * A class for managing local attributes
+ */
+public class AAAttributes{
+
+ Class[] attrClasses = new Class[1];
+
+ /**
+ * Sole constructor. Takes a directory name in the local file system
+ * where attribute classes reside
+ */
+
+ public AAAttributes(String jarFileName)
+ throws AAException{
+
+ try{
+
+ JarFile jf = new JarFile(jarFileName);
+ Vector attrs = new Vector();
+ Enumeration en = jf.entries();
+ while(en.hasMoreElements()){
+ JarEntry je = (JarEntry)en.nextElement();
+ String filename = (String)je.getName();
+ if(filename.endsWith(".class")){
+ String name = filename.substring(0, filename.lastIndexOf(".class"));
+ Class attr = Class.forName(name);
+ attrs.add(attr);
+ }
+ }
+ attrClasses = (Class[])attrs.toArray(attrClasses);
+ }catch(Exception e){
+ throw new AAException("Failed to get the list of attribute classes: "+e);
+ }
+ }
+
+
+ public Class[] listClasses(){
+ return attrClasses;
+ }
+
+ public String[] list(){
+ String[] a = new String[attrClasses.length];
+ for(int i=0; i<a.length; i++){
+ a[i] = attrClasses[i].getName();
+ }
+ return a;
+ }
+}
--- /dev/null
+package aa;
+
+public class AAException extends Exception{
+ String msg;
+ public AAException(String s){
+ msg = s;
+ }
+ public String toString(){
+ return msg;
+ }
+}
--- /dev/null
+package aa;
+
+public class AAPermissionException extends Exception{
+ String msg;
+ AAPermissionException(String s){
+ msg = s;
+ }
+ public String toString(){
+ return msg;
+ }
+}
--- /dev/null
+package aa;
+
+//import aa.*;
+import java.io.*;
+import java.util.*;
+import java.lang.reflect.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import javax.naming.*;
+import javax.naming.directory.*;
+import edu.internet2.middleware.shibboleth.*;
+import edu.internet2.middleware.eduPerson.*;
+import org.w3c.dom.*;
+import org.opensaml.*;
+
+public class AAResponder{
+
+ //HandleRepositoryFactory hrf;
+ ArpFactory arpFactory;
+ Arp adminArp;
+ DirContext ctx;
+ String domain;
+
+ public AAResponder(/*HandleRepositoryFactory*/String hrf, ArpFactory arpFactory, DirContext ctx, String domain)
+ throws AAException{
+
+ //this.hrf = hrf;
+ this.arpFactory = arpFactory;
+ adminArp = arpFactory.getInstance("admin", true);
+ if(adminArp.isNew())
+ throw new AAException("Admin Arp not found! ");
+ this.ctx = ctx;
+ this.domain = domain;
+ }
+
+
+ public SAMLAttribute[] getReleaseAttributes(String uidSyntax, String handle, String sharName, String url)
+ throws AAException/*,HandleException*/ {
+
+ DirContext userCtx = null;
+ //HandleEntry he = hrf.getHandleEntry(handle);
+ String userName = "foo"; //he.getUsername();
+ if(userName == null)
+ throw new AAException("user name is null");
+
+ try{
+ if(uidSyntax == null)
+ uidSyntax = "";
+ userCtx = (DirContext)ctx.lookup(uidSyntax+"="+userName);
+ }catch(NamingException e){
+ throw new AAException("Cannot lookup context for "+userName+" :"+e);
+ }
+
+
+
+ Set s = getCombinedReleaseSet(adminArp, sharName, url, userName);
+ // go throu the set and find values for each attribute
+ try{
+ Vector sAttrs = new Vector();
+ Iterator it = s.iterator();
+ while(it.hasNext()){
+ ArpAttribute aAttr = (ArpAttribute)it.next();
+ Attribute dAttr = aAttr.getDirAttribute(userCtx, true);
+ if(dAttr != null){
+ SAMLAttribute sAttr = jndi2saml(dAttr);
+ sAttrs.add(sAttr);
+ }
+ }
+ SAMLAttribute[] sa = new SAMLAttribute[sAttrs.size()];
+ return (SAMLAttribute[])sAttrs.toArray(sa);
+ }catch(NamingException e){
+ throw new AAException("Bad Contexted for getting Attribute Values: "+e);
+ }
+ }
+
+
+ private Set getCombinedReleaseSet(Arp admin, String sharName, String url, String userName)
+ throws AAException {
+
+ Set adminSet;
+ Set userSet;
+
+
+ Arp userArp = arpFactory.getInstance(userName, false);
+ if(userArp.isNew()){
+ // no user ARP just use the admin
+ // only go throu and drop the exclude ones
+ adminSet = getReleaseSet(adminArp, sharName, url, adminArp);
+ Iterator it = adminSet.iterator();
+ while(it.hasNext()){
+ ArpAttribute attr = (ArpAttribute)it.next();
+ if(attr.mustExclude())
+ adminSet.remove(attr);
+ }
+ return adminSet;
+ }
+
+ adminSet = getReleaseSet(adminArp, sharName, url, adminArp);
+ userSet = getReleaseSet(userArp, sharName, url, adminArp);
+ // combine the two
+ Iterator it = adminSet.iterator();
+ while(it.hasNext()){
+ ArpAttribute aAttr = (ArpAttribute)it.next();
+ if(aAttr.mustExclude()){
+ userSet.remove(aAttr); // ok if not there
+ adminSet.remove(aAttr);
+ }
+ if(userSet.contains(aAttr)){
+ // in both. Combine filters
+ ArpFilter f = combineFilters(aAttr, getAttr(userSet, aAttr));
+ System.out.println("debug: Combine filters: "+
+ aAttr.getFilter()+ " AND "+
+ getAttr(userSet, aAttr).getFilter()+
+ " = " + f);
+ if(f != null)
+ aAttr.setFilter(f, true); // force it
+ userSet.remove(aAttr);
+ }
+ }
+ adminSet.addAll(userSet);
+ return adminSet;
+
+ }
+
+
+ private Set getReleaseSet(Arp arp, String sharName, String url, Arp admin)
+ throws AAException{
+
+ boolean usingDefault = false;
+
+ System.out.println("debug: using ARP: "+arp);
+
+ ArpShar shar = arp.getShar(sharName);
+ if(shar == null){
+ shar = admin.getDefaultShar();
+ usingDefault = true;
+ }
+ if(shar == null)
+ throw new AAException("No default SHAR.");
+
+ System.out.println("debug:\t using shar: "+shar+(usingDefault?"(default)":""));
+ System.out.println("debug:\t using url: "+url);
+
+ if(url == null || url.length() == 0)
+ throw new AAException("Given url to AA is null or blank");
+
+ ArpResource resource = shar.bestFit(url);
+ System.out.println("debug:\t\t best fit is: "+resource);
+ if(resource == null){
+ if(usingDefault)
+ return new HashSet(); // empty set
+
+ shar = admin.getDefaultShar();
+ if(shar == null)
+ throw new AAException("No default SHAR.");
+
+ resource = shar.bestFit(url);
+ if(resource == null)
+ return new HashSet(); // empty set
+ }
+ Set s = new HashSet();
+ ArpAttribute[] attrs = resource.getAttributes();
+ for(int i=0; i<attrs.length; i++){
+ System.out.println("debug:\t\t\t attribute: "+attrs[i]+" FILTER: "+attrs[i].getFilter());
+ s.add(attrs[i]);
+ }
+ return s;
+ }
+
+ private ArpFilter combineFilters(ArpAttribute attr1, ArpAttribute attr2){
+
+ ArpFilter filt1 = attr1.getFilter();
+ ArpFilter filt2 = attr2.getFilter();
+
+ if(filt1 == null)
+ return filt2;
+
+ if(filt2 == null)
+ return filt1;
+
+ ArpFilterValue[] fv1Array = filt1.getFilterValues();
+
+ for(int i=0; i<fv1Array.length; i++){
+ ArpFilterValue afv = fv1Array[i];
+
+ if(afv.mustInclude()){ // cannot be filtered out
+ filt2.removeFilterValue(afv); // ok if not there
+ }else{
+ filt2.addAFilterValue(afv);
+ }
+ }
+
+ return filt2;
+
+ }
+
+
+ private ArpAttribute getAttr(Set s, ArpAttribute a){
+ Iterator it = s.iterator();
+ while(it.hasNext()){
+ ArpAttribute attr = (ArpAttribute)it.next();
+ if(attr.equals(a))
+ return attr;
+ }
+ return null;
+ }
+
+ private SAMLAttribute jndi2saml(Attribute jAttr)
+ throws NamingException, AAException{
+
+ if(jAttr == null)
+ return null;
+
+ String id = jAttr.getID();
+ Vector vals = new Vector();
+
+ NamingEnumeration ne = jAttr.getAll();
+ while(ne.hasMore())
+ vals.add(ne.next());
+
+
+ String[] scopes = { this.domain };
+ Object[] args = new Object[2];
+ args[0] = scopes;
+ args[1] = vals.toArray();
+
+ try{
+ Class attrClass = Class.forName(id);
+ Constructor[] cons = attrClass.getConstructors();
+ System.out.println("Got constructors for "+attrClass);
+ System.out.println("number of constructors "+cons.length);
+ System.out.println("first constructor is "+cons[0]);
+ return (SAMLAttribute)cons[0].newInstance(args);
+ }catch(Exception e){
+ throw new AAException("Failed to read the class for attribute "+id+" :"+e);
+ }
+
+ }
+}
--- /dev/null
+package aa;
+
+import java.util.*;
+import java.io.IOException;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import edu.internet2.middleware.shibboleth.*;
+import org.w3c.dom.*;
+import org.opensaml.*;
+
+
+public class AASaml {
+
+ String[] policies = { Constants.POLICY_CLUBSHIB };
+ String protocol = SAMLBinding.SAML_SOAP_HTTPS;
+ String myName;
+ StringBuffer sharName;
+ String resource;
+ String reqID;
+ SAMLSubject sub;
+ SAMLBinding binding;
+
+
+ public AASaml(HttpServletRequest req, String myName)
+ throws SAMLException{
+
+ binding = SAMLBindingFactory.getInstance(protocol, policies);
+ this.myName = myName;
+ sharName=new StringBuffer();
+ SAMLRequest sReq = binding.receive(req, sharName);
+ SAMLAttributeQuery q = (SAMLAttributeQuery)sReq.getQuery();
+ resource = q.getResource();
+ reqID = sReq.getRequestId();
+ sub = q.getSubject();
+ }
+
+ public String getHandle(){
+ return sub.getName();
+ }
+
+ public String getResource(){
+ return resource;
+ }
+
+ public String getIssuer(){
+ return sub.getConfirmationData();
+ }
+
+ public String getShar(){
+ return sharName.toString();
+ }
+
+
+ public void respond(HttpServletResponse resp, SAMLAttribute[] attrs, SAMLException exception)
+ throws IOException{
+
+ SAMLException ourSE = null;
+ SAMLResponse sResp = null;
+
+ try{
+
+ SAMLSubject rSubject = new SAMLSubject(sub.getName(),
+ sub.getNameQualifier(),
+ sub.getFormat(),
+ sub.getConfirmationMethods(),
+ sub.getConfirmationData());
+
+ SAMLStatement sStatement = new SAMLAttributeStatement(rSubject, attrs);
+ SAMLStatement[] statements = new SAMLStatement[1];
+ statements[0] = sStatement;
+ Date now = new Date();
+ Date then = null;
+ if(attrs != null && attrs.length > 0){
+ long min = attrs[0].getLifetime();
+ for(int i = 1; i < attrs.length; i++){
+ long t = attrs[i].getLifetime();
+ if(t > 0 && t < min)
+ min = t;
+ }
+ if(min > 0)
+ then = new Date(now.getTime() + min);
+ }
+ SAMLCondition[] conditions = new SAMLCondition[1];
+ conditions[0] = new SAMLAudienceRestrictionCondition(policies);
+ SAMLAssertion sAssertion = new SAMLAssertion(myName,
+ now,
+ then,
+ conditions,
+ statements,
+ /* sig */ null);
+ SAMLAssertion[] assertions= new SAMLAssertion[1];
+ assertions[0] = sAssertion;
+
+ sResp = new SAMLResponse(reqID,
+ /* recipient URL*/ null,
+ /* sig */ null,
+ assertions,
+ exception);
+ }catch (SAMLException se) {
+ ourSE = se;
+ }finally{
+ binding.respond(resp,sResp,ourSE);
+ }
+ }
+
+}
--- /dev/null
+package aa;
+
+import java.io.*;
+import java.util.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import javax.naming.*;
+import javax.naming.directory.*;
+import org.opensaml.*;
+import org.w3c.dom.*;
+import edu.internet2.middleware.shibboleth.*;
+import edu.internet2.middleware.eduPerson.*;
+
+
+
+
+public class AAServlet extends HttpServlet {
+
+ String myName;
+ String dirUrl;
+ String uidSyntax;
+ String arpFactoryMethod;
+ String arpFactoryData;
+ String ctxFactory;
+ AAResponder responder;
+ //HandleRepositoryFactory hrf;
+ ArpFactory arpFactory;
+
+
+ public void init(ServletConfig conf)
+ throws ServletException{
+
+ try{
+ super.init(conf);
+ myName = getInitParameter("domain");
+ dirUrl = getInitParameter("dirUrl");
+ uidSyntax = getInitParameter("ldapUserDnPhrase");
+ ctxFactory = getInitParameter("ctxFactoryClass");
+ if(ctxFactory == null)
+ ctxFactory = "com.sun.jndi.ldap.LdapCtxFactory";
+ arpFactoryMethod = getInitParameter("arpFactoryMethod");
+ arpFactoryData = getInitParameter("arpFactoryData");
+
+ //hrf = HandleRepositoryFactory.getInstance(Constants.POLICY_CLUBSHIB, this);
+ arpFactory = ArpRepository.getInstance(arpFactoryMethod, arpFactoryData);
+
+ Hashtable env = new Hashtable(11);
+ env.put(Context.INITIAL_CONTEXT_FACTORY, ctxFactory);
+
+ env.put(Context.PROVIDER_URL, dirUrl);
+ DirContext ctx = new InitialDirContext(env);
+
+ responder = new AAResponder(/*hrf*/ null, arpFactory, ctx, myName);
+ // }catch(HandleException he){
+ // throw new ServletException("Init failed: "+he);
+ }catch(NamingException ne){
+ throw new ServletException("Init failed: "+ne);
+ }catch(AAException ae){
+ throw new ServletException("Init failed: "+ae);
+ }
+ }
+
+ public void doGet(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+ resp.setContentType("text/html");
+ PrintWriter out = resp.getWriter();
+ out.println("<HTML><BODY> Sorry! GET is not supported. </BODY></HTML>");
+ return;
+ }
+
+ public void doPost(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+
+ SAMLAttribute[] attrs = null;
+ SAMLException ourSE = null;
+ AASaml saml = null;
+
+ try{
+ saml = new AASaml(req, myName);
+ String resource = saml.getResource();
+ String handle = saml.getHandle();
+ String shar = saml.getShar();
+ String issuedBy = saml.getIssuer();
+ System.err.println("AA debug: handle:"+handle);
+ System.err.println("AA debug: issuer:"+issuedBy);
+ System.err.println("AA debug: shar:"+shar);
+
+ attrs = responder.getReleaseAttributes(uidSyntax, handle, shar, resource);
+ System.err.println("AA debug: got attributes");
+
+ }catch (org.opensaml.SAMLException se) {
+ ourSE = se;
+ // }catch (HandleException he) {
+ // ourSE = new org.opensaml.SAMLException(org.opensaml.SAMLException.RESPONDER,"Bad Handle or Handle Service Problem: "+he);
+ }catch (Exception e) {
+ ourSE = new org.opensaml.SAMLException(org.opensaml.SAMLException.RESPONDER,"AA Failed with: "+e);
+ }finally{
+
+ if(saml == null)
+ throw new ServletException("AA failed to build a request: "+ourSE);
+ saml.respond(resp, attrs, ourSE);
+ }
+ }
+
+}
--- /dev/null
+package aa;
+
+import java.util.*;
+import java.io.*;
+import java.security.acl.*;
+
+public class AA_Acl implements java.security.acl.Acl, Serializable{
+
+ HashSet positives;
+ HashSet negatives;
+ HashSet owners;
+ String name;
+
+ AA_Acl(String name, java.security.Principal root){
+ positives = new HashSet();
+ negatives = new HashSet();
+ owners = new HashSet();
+ this.name = name;
+ owners.add(root);
+ }
+
+ AA_Acl(Collection p, Collection n, String name, java.security.Principal root){
+ positives = new HashSet(p);
+ negatives = new HashSet(n);
+ owners = new HashSet();
+ this.name = name;
+ owners.add(root);
+ }
+
+ /////// Methods //////////
+
+ public boolean addEntry(java.security.Principal p, AclEntry entry)throws NotOwnerException{
+
+ if(this.isOwner(p) == false)
+ throw new NotOwnerException();
+ if(entry.isNegative()){
+ if(negatives.contains(entry)){
+ return false;
+ }else{
+ negatives.add(entry);
+ return true;
+ }
+ }else{ // is positive ACL
+ if(positives.contains(entry)){
+ return false;
+ }else{
+ positives.add(entry);
+ return true;
+ }
+ }
+ }
+
+ public boolean checkPermission(java.security.Principal user, java.security.acl.Permission perm){
+ for(Iterator it = positives.iterator(); it.hasNext();){
+ AclEntry entry = (AclEntry)it.next();
+ java.security.Principal p = entry.getPrincipal();
+ if(p.equals(user)){
+ if(entry.checkPermission(perm)){
+ //make sure it is not in negative list
+ for(Iterator it2 = negatives.iterator(); it2.hasNext();){
+ AclEntry entry2 = (AclEntry)it2.next();
+ java.security.Principal p2 = entry2.getPrincipal();
+ if(p2.equals(user)){
+ if(entry2.checkPermission(perm)){
+ return false; // in both list
+ }
+ continue;
+ }
+ }
+ // not in negative list
+ return true; // give permission
+ }else{
+ continue;
+ }
+ }else{
+ continue;
+ }
+ }
+ return false; // not in any positive entry
+ }
+
+ public Enumeration entries(){
+ return new AclEntryEnumeration(positives, negatives);
+ }
+
+ public String getName(){
+ return name;
+ }
+
+ public Enumeration getPermissions(java.security.Principal user){
+ return new AclPermissionEnumeration(user, positives, negatives);
+ }
+
+ public boolean removeEntry(java.security.Principal caller, AclEntry entry)
+ throws NotOwnerException{
+
+ if(this.isOwner(caller) == false)
+ throw new NotOwnerException();
+ if(entry.isNegative()){
+ if(negatives.contains(entry)){
+ negatives.remove(entry);
+ return true;
+ }else{
+ return false;
+ }
+ }else{ // is positive ACL
+ if(positives.contains(entry)){
+ positives.remove(entry);
+ return true;
+ }else{
+ return false;
+ }
+ }
+ }
+
+
+ public void setName(java.security.Principal caller, String name)
+ throws NotOwnerException{
+ if(this.isOwner(caller) == false)
+ throw new NotOwnerException();
+ this.name = name;
+ }
+
+ public String toString(){
+ return name+
+ "{"
+ +positives
+ +"}{"
+ +negatives
+ +"}";
+
+ }
+
+ /////////// Owner methods ///////////////
+ public boolean addOwner(java.security.Principal caller, java.security.Principal owner)
+ throws NotOwnerException{
+ if(owners.contains(caller) == false)
+ throw new NotOwnerException();
+ return owners.add(owner);
+ }
+
+ public boolean deleteOwner(java.security.Principal caller, java.security.Principal owner)
+ throws NotOwnerException,
+ LastOwnerException{
+ if(owners.contains(caller) == false)
+ throw new NotOwnerException();
+ return owners.remove(owner);
+ }
+
+ public boolean isOwner(java.security.Principal owner){
+ return owners.contains(owner);
+ }
+
+
+}
+
+class AclEntryEnumeration implements java.util.Enumeration{
+ HashSet entries;
+ Iterator it;
+
+ AclEntryEnumeration(HashSet p, HashSet n){
+ entries = p;
+ entries.addAll(n);
+ it = entries.iterator();
+ }
+
+ public boolean hasMoreElements(){
+ return it.hasNext();
+ }
+
+ public Object nextElement(){
+ return it.next();
+ }
+}
+
+
+
+class AclPermissionEnumeration implements java.util.Enumeration{
+ HashSet permissions;
+ Iterator it;
+
+ AclPermissionEnumeration(java.security.Principal user, HashSet p, HashSet n){
+ permissions = new HashSet();
+ // go throu entries and find the one for this user
+ for(Iterator i = p.iterator(); i.hasNext();){
+ AclEntry ae = (AclEntry)i.next();
+ if(ae.getPrincipal().equals(user)){
+ // go throu permissions and add it to enum
+ for(Enumeration j=ae.permissions(); j.hasMoreElements();){
+ permissions.add((Permission)j.nextElement());
+ }
+ }
+ }
+ // now go throu negatives and either add it or remove positve one
+ for(Iterator i = n.iterator(); i.hasNext();){
+ AclEntry ae = (AclEntry)i.next();
+ if(ae.getPrincipal().equals(user)){
+ // go throu permissions and check it
+ for(Enumeration j=ae.permissions(); j.hasMoreElements();){
+ Permission perm = (Permission)j.nextElement();
+ if(permissions.contains(perm)){
+ permissions.remove(perm);
+ }else{
+ permissions.add(perm);
+ }
+ }
+ }
+ }
+
+ it = permissions.iterator();
+ }
+
+ public boolean hasMoreElements(){
+ return it.hasNext();
+ }
+
+ public Object nextElement(){
+ return it.next();
+ }
+}
+
+
+
+
+
--- /dev/null
+package aa;
+
+import java.util.*;
+import java.io.*;
+import java.security.acl.*;
+import java.security.*;
+
+public class AA_AclEntry implements java.security.acl.AclEntry, Serializable{
+
+ HashSet permissions;
+ boolean isNegative;
+ Principal principal;
+
+ AA_AclEntry(Principal p){
+ permissions = new HashSet();
+ isNegative = false;
+ principal = p;
+ }
+
+ AA_AclEntry(Collection c, boolean n, Principal p){
+ permissions = new HashSet(c);
+ isNegative = n;
+ principal = p;
+ }
+
+ /////// Methods //////////
+
+ public boolean addPermission(java.security.acl.Permission p){
+ return permissions.add(p);
+ }
+
+ public boolean checkPermission(java.security.acl.Permission p){
+ if(permissions.contains(new AA_Permission(AA_Permission.ALL)))
+ return true;
+ boolean rc = permissions.contains(p);
+ return rc;
+ }
+
+ public Object clone(){
+ return new AA_AclEntry(permissions, isNegative, principal);
+ }
+
+ public Principal getPrincipal(){
+ return principal;
+ }
+
+ public boolean isNegative(){
+ return isNegative;
+ }
+
+ public Enumeration permissions(){
+ return new PermissionsEnumeration(permissions);
+ }
+
+ public boolean removePermission(java.security.acl.Permission p){
+ return permissions.remove(p);
+ }
+
+ public void setNegativePermissions(){
+ isNegative = true;
+ }
+
+ public boolean setPrincipal(Principal p){
+ if(principal != null){
+ return false;
+ }else{
+ principal = p;
+ return true;
+ }
+ }
+
+ public String toString(){
+ return (isNegative?"-":"+")
+ +principal
+ +"("
+ +permissions
+ +")";
+ }
+
+ public boolean equals(Object o){
+ AclEntry ae = (AclEntry)o;
+ if(this.principal.equals(ae.getPrincipal()) &&
+ (ae.isNegative() == isNegative))
+ return true;
+ return false;
+ }
+
+ public int hashCode(){
+ return principal.hashCode();
+ }
+
+
+}
+
+class PermissionsEnumeration implements java.util.Enumeration{
+ HashSet perms;
+ Iterator it;
+
+ PermissionsEnumeration(HashSet p){
+ perms = p;
+ it = perms.iterator();
+ }
+
+ public boolean hasMoreElements(){
+ return it.hasNext();
+ }
+
+ public Object nextElement(){
+ return it.next();
+ }
+}
+
+
+
+
+
--- /dev/null
+package aa;
+
+import java.security.*;
+import java.io.*;
+
+public class AA_Identity implements java.security.Principal, Serializable{
+
+ String ident;
+
+ public AA_Identity(String ident){
+ this.ident = ident;
+ }
+
+ /////// Methods //////////
+
+ public boolean equals(Object o){
+ return (ident.equalsIgnoreCase(o.toString()));
+ }
+
+ public String getName(){
+ return ident;
+ }
+
+ public String toString(){
+ return ident;
+ }
+ public int hashCode(){
+ return ident.hashCode();
+ }
+}
+
+
+
+
+
--- /dev/null
+package aa;
+
+import java.security.acl.*;
+import java.io.*;
+public class AA_Permission implements java.security.acl.Permission, Serializable{
+
+ protected static int LOOKUP = 0;
+ protected static int READ = 1;
+ protected static int WRITE = 2;
+ protected static int INSERT = 3;
+ protected static int DELETE = 4;
+ protected static int ALL = 5;
+
+ protected static String names[] = {
+ "LOOKUP",
+ "READ",
+ "WRITE",
+ "INSERT",
+ "DELETE",
+ "ALL"};
+
+
+ int permission;
+
+ AA_Permission(int p){
+ permission = p;
+ }
+
+ /////// Methods //////////
+
+ public boolean equals(Object o){
+ return (permission == ((AA_Permission)o).getIntVal());
+ }
+
+ public int getIntVal(){
+ return permission;
+ }
+
+ public String toString(){
+ return names[permission];
+ }
+ public int hashCode(){
+ return permission+1;
+ }
+}
+
+
+
+
+
--- /dev/null
+package aa;
+
+import java.io.*;
+import java.util.*;
+import java.security.Principal;
+import java.security.acl.*;
+
+public class Arp extends ArpCore implements Serializable{
+
+ // Attributes
+ protected String name;
+ protected boolean isAdmin;
+ private boolean everWritten = false;
+ private Date lastRead;
+ private boolean hasDefaultShar = false;
+ private ArpShar defaultShar;
+
+ // Associations
+ protected Vector shars;
+
+ // Constructors
+ public Arp(String name, boolean isAdmin)
+ throws NotOwnerException{
+
+ this.name = name;
+ this.isAdmin = isAdmin;
+ shars = new Vector();
+ makeAcl("arpAcl");
+ }
+
+ // Operations
+ public boolean isNew(){
+ return !everWritten;
+ }
+
+ public void setNew(boolean b){
+ everWritten = !b;
+ }
+
+ public void setLastRead(Date d){
+ lastRead = d;
+ }
+
+ public Date getLastRead(){
+ return lastRead;
+ }
+
+ /**
+ * Add a new SHAR to the list of SHARs for this ARP.
+ * returns false and does not replace if SHAR already exists.
+ */
+ public boolean addAShar(String name, boolean isDefault)
+ throws NotOwnerException,AAPermissionException, AAException{
+
+ if(isDefault && hasDefaultShar)
+ throw new AAException("Already has a Default SHAR");
+
+ ArpShar newShar = new ArpShar(name, isDefault);
+ if(shars.contains(newShar))
+ return false; // already there
+ if(! insertPermitted())
+ throw new AAPermissionException("No INSERT right for "+getCaller());
+ shars.add(newShar);
+ if(isDefault){
+ hasDefaultShar = true;
+ defaultShar = newShar;
+ }
+ return true;
+ }
+
+ /**
+ * Add the given SHAR to the list of SHARs for this ARP.
+ * returns false and does not replace if SHAR already exists.
+ */
+ public boolean addAShar(ArpShar shar)
+ throws AAPermissionException, AAException{
+
+ return addAShar(shar, false);
+ }
+
+ /**
+ * Adds the given shar to the shars for this Arp.
+ * if force flag is true and shar already exists
+ * then replaces the existing reource otherwise leaves the existing
+ * shar untouched.
+ * returns false if reource already existed.
+ * Throws AAPermissionException if caller is not permitted to insert or replace.
+ */
+ public boolean addAShar(ArpShar shar, boolean force)
+ throws AAPermissionException, AAException {
+
+ if(shars.contains(shar)){
+ if(force){
+ if(! replacePermitted())
+ throw new AAPermissionException("No replace right for "+getCaller());
+ shars.remove(shar);
+ shars.add(shar);
+ }
+ return false; // already there
+ }
+ if(! insertPermitted())
+ throw new AAPermissionException("No INSERT right for "+getCaller());
+ if(shar.isDefault() && hasDefaultShar)
+ throw new AAException("Already has a Default SHAR");
+
+ shars.add(shar);
+ if(shar.isDefault()){
+ hasDefaultShar = true;
+ defaultShar = shar;
+ }
+ return true;
+ }
+
+
+
+ public boolean removeAShar(String name)
+ throws NotOwnerException, AAPermissionException{
+
+ ArpShar newShar = new ArpShar(name, false);
+ if(shars.contains(newShar)){
+ if(! removePermitted())
+ throw new AAPermissionException("No DELETE rights for "+getCaller());
+ shars.remove(newShar);
+ if(hasDefaultShar && newShar.equals(defaultShar)){
+ defaultShar = null;
+ hasDefaultShar = false;
+ }
+ return true;
+ }
+ return false; // not found
+ }
+
+
+ public ArpShar getShar(String name) {
+ Enumeration en = shars.elements();
+ while(en.hasMoreElements()){
+ ArpShar aShar = (ArpShar)en.nextElement();
+ if(aShar.getName().equals(name))
+ return aShar;
+ }
+ return null;
+ }
+
+ public ArpShar[] getShars() {
+ int len = shars.size();
+ ArpShar[] a = new ArpShar[len];
+ for(int i = 0; i < len; i++)
+ a[i] = (ArpShar)shars.get(i);
+ return a;
+ }
+
+ public ArpShar getDefaultShar(){
+ return defaultShar;
+ }
+
+ public String getName(){
+ return name;
+ }
+
+ //public void setAcl(Acl acl){
+ //this.acl = acl;
+ //}
+
+ // public String urlToShar(String url) {
+ // }
+
+ public String toString(){
+ return name+(isAdmin?"(admin)":"");
+ }
+
+ public boolean isAdmin(){
+ return isAdmin;
+ }
+
+ public boolean equals(Object arp){
+ return name.equals(((Arp)arp).getName());
+ }
+
+} /* end class Arp */
--- /dev/null
+package aa;
+
+import java.io.*;
+import java.util.*;
+import javax.naming.directory.*;
+
+public class ArpAttribute implements Serializable{
+
+ // Attributes
+ protected String ID;
+ protected boolean exclude;
+
+ // Associations
+ protected ArpFilter filter;
+
+ // Constructor
+ public ArpAttribute(String ID, boolean exclude){
+ this.ID = ID;
+ this.exclude = exclude;
+ }
+
+ // Operations
+ public Attribute getDirAttribute(DirContext ctx, boolean doFilter)
+ throws javax.naming.NamingException{
+
+ String[] ids = new String[1];
+ ids[0] = ID;
+ Attributes attrs = ctx.getAttributes("", ids);
+ Attribute attr = attrs.get(ID);
+
+ if(doFilter && hasFilter()){
+ ArpFilterValue[] fvArray = filter.getFilterValues();
+ for(int i=0; i < fvArray.length; i++){
+ if(fvArray[i].mustInclude())
+ ; //skip. do not filter.
+ else
+ attr.remove(fvArray[i].getValue());
+ }
+ }
+ return attr;
+ }
+
+
+ public String getName(){
+ return ID;
+ }
+
+ /**
+ * lists all known attribute names. Probably by consulting a
+ * database or LDAP schemas
+ */
+ public String[] list(){
+ return null;
+ }
+
+ public boolean hasFilter(){
+ if(filter == null)
+ return false;
+ return true;
+ }
+
+ public ArpFilter getFilter(){
+ return filter;
+ }
+
+ /**
+ * sets a filter for this attribute. returns true if succeeds
+ * returns false if there is already a filter set.
+ * If flag Force is true it replaces the existing filter,
+ * otherwise does not replace the existing filter.
+ */
+ public boolean setFilter(ArpFilter filter, boolean force){
+ if(hasFilter()){
+ if(force)
+ this.filter = filter;
+ return false;
+ }
+ this.filter = filter;
+ return true;
+ }
+
+ public boolean mustExclude(){
+ return exclude;
+ }
+
+ public boolean equals(Object attr){
+ return ID.equals(((ArpAttribute)attr).getName());
+ }
+
+ public int hashCode(){
+ return ID.hashCode();
+ }
+
+ public String toString(){
+ return ID+(exclude?"(exclude)":"");
+ }
+
+} /* end class ArpAttribute */
--- /dev/null
+package aa;
+
+import java.util.Enumeration;
+import java.security.Principal;
+import java.security.acl.*;
+import java.io.Serializable;
+
+public class ArpCore implements Serializable{
+
+ // Attributes
+ protected String userEnv = "user.name";
+ protected Acl acl;
+
+ // Associations
+
+ // Constructors
+
+
+ // Operations
+ public Principal getCaller(){
+ // return new KerberosPrincipal(System.getProperty(userEnv));
+ return new AA_Identity(System.getProperty(userEnv));
+ }
+
+ public void makeAcl(String name)throws NotOwnerException{
+ Principal owner = getCaller();
+ acl = new AA_Acl(name, owner);
+ AclEntry entry = new AA_AclEntry(owner);
+ entry.addPermission(new AA_Permission(AA_Permission.ALL));
+ acl.addEntry(owner, entry);
+ }
+
+
+ public Acl getAcl(){
+ return acl;
+ }
+
+ public void setAcl(String user, String permit)
+ throws AAPermissionException, NotOwnerException{
+
+ Principal prince = new AA_Identity(user);
+ if(permit.equalsIgnoreCase("NONE")){
+ setAcl(prince, null);
+ return;
+ }
+ String[] permitNames = AA_Permission.names;
+ for(int i=0; i < permitNames.length; i++){
+ if(permitNames[i].equalsIgnoreCase(permit)){
+ setAcl(prince, new AA_Permission(i));
+ return;
+ }
+ }
+ throw new AAPermissionException("No such ACL: "+permit);
+ }
+
+ public void setAcl(Principal user, Permission permit)
+ throws NotOwnerException, AAPermissionException{
+
+ if(!setAclPermitted())
+ throw new AAPermissionException("ALL access is needed to set ACL.");
+ if(permit == null){
+ AclEntry entry = getAclEntry(user);
+ if(entry == null)
+ throw new AAPermissionException("No ACL entry found for user: "+user);
+ if(!acl.removeEntry(getCaller(), entry))
+ throw new AAPermissionException("No ACL entry found. System Eror");
+ return;
+ }
+
+ if(acl.checkPermission(user, permit))
+ return; // already has it
+ AclEntry entry = getAclEntry(user);
+ if(entry == null){
+ entry = new AA_AclEntry(user);
+ entry.addPermission(permit);
+ acl.addEntry(getCaller(), entry);
+ }else{
+ entry.addPermission(permit);
+ }
+ return;
+ }
+
+ private AclEntry getAclEntry(Principal user){
+ AclEntry entry = null;
+
+ Enumeration en = acl.entries();
+ while(en.hasMoreElements()){
+ entry = (AclEntry)en.nextElement();
+ if(entry.getPrincipal().equals(user))
+ return entry;
+ }
+ return null;
+ }
+
+
+ /**
+ * Check to see if caller has permission to remove and insert (i.e replace) for this object.
+ * Returns true if permitted.
+ */
+
+ public boolean replacePermitted(){
+ Permission rm = new AA_Permission(AA_Permission.DELETE);
+ Permission add = new AA_Permission(AA_Permission.INSERT);
+ Principal user = getCaller();
+ if(acl.checkPermission(user, rm) && acl.checkPermission(user, add))
+ return true;
+ return false;
+ }
+
+ public boolean insertPermitted(){
+ Permission add = new AA_Permission(AA_Permission.INSERT);
+ if(acl.checkPermission(getCaller(), add))
+ return true;
+ return false;
+ }
+
+ public boolean removePermitted(){
+ Permission rm = new AA_Permission(AA_Permission.DELETE);
+ if(acl.checkPermission(getCaller(), rm))
+ return true;
+ return false;
+ }
+
+ public boolean setAclPermitted(){
+ Permission all = new AA_Permission(AA_Permission.ALL);
+ if(acl.checkPermission(getCaller(), all))
+ return true;
+ return false;
+ }
+
+
+
+
+
+} /* end class ArpCore */
--- /dev/null
+package aa;
+
+public interface ArpFactory{
+
+
+ /**
+ * Returns an Arp instance. It tries to retrieve the Arp from a repository
+ * If not found then creates a new emplty Arp.
+ * Arp can be check by its isNew() to see how it was generated
+ */
+
+ public Arp getInstance(String arpName, boolean isDefault)
+ throws AAException;
+
+
+ /**
+ * Writes the given ARP back to the repository.
+ */
+
+ public void write(Arp arp) throws AAException;
+
+ /**
+ * Rereads the ARP if the version on storage is newer
+ * than the one in memory.
+ */
+
+ public Arp reread(Arp arp) throws AAException;
+
+ /**
+ * Permanently removes the given ARP from the repository
+ */
+
+ public void remove(Arp arp) throws AAException;
+
+}
+
--- /dev/null
+package aa;
+
+import java.io.*;
+import java.util.Date;
+import java.security.acl.*;
+import java.security.Principal;
+//import javax.security.auth.kerberos.KerberosPrincipal;
+
+public class ArpFileFactory implements ArpFactory{
+
+ static String dataStore;
+
+ public ArpFileFactory(String pathData){
+ dataStore = pathData;
+ }
+
+ /**
+ * returns an Arp instance. It tries to retrieve the Arp from file system
+ * If not found then creates a new emplty Arp.
+ * Arp can be check by its isNew() to see how it was generated
+ */
+
+ public Arp getInstance(String arpName, boolean isAdmin)
+ throws AAException{
+ try{
+ String fileName = dataStore+System.getProperty("file.separator")+arpName;
+
+ FileInputStream f = new FileInputStream(fileName);
+ ObjectInput s = new ObjectInputStream(f);
+ Arp arp = (Arp)s.readObject();
+ if(!arpName.equals(arp.getName()))
+ throw new AAException("Wrong ARP name. ARP maybe renamed in datastore. ");
+ arp.setNew(false);
+ arp.setLastRead(new Date());
+ return arp;
+
+ }catch(FileNotFoundException e){
+ // check the IO error to make sure "file not found"
+ try{
+ Arp arp = new Arp(arpName, isAdmin);
+ arp.setNew(true);
+ arp.setLastRead(new Date());
+ return arp;
+ }catch(NotOwnerException noe){
+ throw new AAException("Cannot create an ARP. Not owner.");
+ }
+
+ }catch(IOException fe){
+ throw new AAException("Reading ARP failed: "+fe);
+ }catch(ClassNotFoundException ce){
+ throw new AAException("ARP retrival failed: "+ce);
+ }catch(Exception oe){
+ throw new AAException(oe.toString());
+ }
+ }
+
+ public void write(Arp arp) throws AAException{
+ // XXX do we need to check any permissions?
+ try{
+ String fileName = dataStore+System.getProperty("file.separator")+arp.getName();
+ FileOutputStream f = new FileOutputStream(fileName);
+ ObjectOutput s = new ObjectOutputStream(f);
+ arp.setNew(false);
+ s.writeObject(arp);
+ s.flush();
+ }catch(IOException e){
+ throw new AAException("IO Problem:"+e);
+ }
+ }
+
+ /**
+ * Reread the arp from file system if the copy on disk
+ * is newer than the copy in memory.
+ */
+
+ public Arp reread(Arp arp) throws AAException{
+ String fileName = dataStore+System.getProperty("file.separator")+arp.getName();
+ File file = new File(fileName);
+ if(file == null)
+ throw new AAException("Arp not found on disk while trying to re-read. :"+arp);
+ Date timeStamp = new Date(file.lastModified());
+ if(timeStamp.after(arp.getLastRead())){
+ return getInstance(arp.getName(), arp.isAdmin());
+ }
+ return arp; // return the old one.
+ }
+
+ public void remove(Arp arp) throws AAException{
+ try{
+ String fileName = dataStore+System.getProperty("file.separator")+arp.getName();
+ File f = new File(fileName);
+ f.delete();
+ }catch(Exception e){
+ throw new AAException("IO Problem:"+e);
+ }
+ }
+}
+
--- /dev/null
+package aa;
+
+import java.io.*;
+import java.util.*;
+public class ArpFilter implements Serializable{
+
+
+ // Associations
+ protected Vector values;
+
+ // Constructor
+ public ArpFilter(){
+ values = new Vector();
+ }
+
+ // Operations
+ public ArpFilterValue[] getFilterValues() {
+ ArpFilterValue[] afva = new ArpFilterValue[values.size()];
+ return (ArpFilterValue[])values.toArray(afva);
+ }
+
+ public boolean addAFilterValue(ArpFilterValue afv) {
+ return addAFilterValue(afv, false);
+ }
+
+ /**
+ * Adds the given value to the values for this Filter.
+ * if force flag is true and value already exists
+ * then replaces the existing reource otherwise leaves the existing
+ * value untouched.
+ * returns false if reource already existed.
+ */
+ public boolean addAFilterValue(ArpFilterValue afv, boolean force) {
+ if(values.contains(afv)){
+ if(force){
+ values.remove(afv);
+ values.add(afv);
+ }
+ return false; // already there
+ }
+ values.add(afv);
+ return true;
+ }
+
+ public boolean removeFilterValue(ArpFilterValue afv) {
+ if(values.contains(afv)){
+ values.remove(afv);
+ return true;
+ }
+ return false; // not found
+ }
+
+ public boolean contains(ArpFilterValue afv) {
+ return values.contains(afv);
+ }
+
+ public ArpFilterValue[] getInclusions() {
+ Vector incs = new Vector();
+ Enumeration en = values.elements();
+ while(en.hasMoreElements()){
+ ArpFilterValue afv = (ArpFilterValue)en.nextElement();
+ if(afv.mustInclude())
+ incs.add(afv);
+ }
+ return (ArpFilterValue[])incs.toArray();
+ }
+
+
+ public String toString(){
+ StringBuffer buf = new StringBuffer();
+ Enumeration en = values.elements();
+ while(en.hasMoreElements()){
+ buf.append((ArpFilterValue)en.nextElement());
+ buf.append(", ");
+ }
+ return buf.toString();
+ }
+
+
+} /* end class ArpFilter */
--- /dev/null
+package aa;
+
+import java.io.*;
+public class ArpFilterValue implements Serializable{
+
+
+ // Associations
+ protected Object value;
+ protected boolean include;
+
+
+ // Constructor
+ public ArpFilterValue(Object value, boolean include){
+ this.value = value;
+ this.include = include;
+ }
+
+ // Operations
+
+ public boolean mustInclude(){
+ return include;
+ }
+
+ public Object getValue(){
+ return value;
+ }
+
+ public boolean equlas(Object afv){
+ return value.equals(((ArpFilterValue)afv).getValue());
+ }
+
+ public String toString(){
+ return value+(include?"(include)":"");
+ }
+
+} /* end class ArpFilterValue */
--- /dev/null
+package aa;
+
+public class ArpRepository{
+
+
+ /**
+ * This is a method to allow implementation of different
+ * repositories for ARPs. e.g. File system, SQL database, or LDAP
+ * It returns an implementation based on the given method.
+ * It passes the given data string to the implementation. Data string is
+ * opeque and only meaningful to the specific implementation.
+ * e.g. it might be a directory path to file system implementation.
+ */
+
+ public static ArpFactory getInstance(String method, String pathData)
+ throws AAException{
+ if(method.equalsIgnoreCase("file"))
+ return new ArpFileFactory(pathData);
+ else
+ throw new AAException("Unknown repository or not implemented yet:" +method);
+
+ }
+}
+
--- /dev/null
+package aa;
+
+import java.io.*;
+import java.util.*;
+import java.security.acl.*;
+
+public class ArpResource extends ArpCore implements Serializable{
+
+ // Attributes
+ protected String name;
+
+ // Associations
+ protected TName tName;
+ protected Vector attributes;
+ protected AA_Acl acl;
+
+ // constructor
+ public ArpResource(String name) throws NotOwnerException{
+ this.name = name;
+ tName = new TName(name);
+ attributes = new Vector();
+ makeAcl("resourceAcl");
+ }
+
+ // Operations
+ public String toString() {
+ return name+" ["+tName+"]";
+ }
+
+
+ public boolean addAnAttribute(String name, boolean exclude)
+ throws AAPermissionException{
+
+ if(attributes.contains(new ArpAttribute(name, exclude)))
+ return false; // already there
+ if(! insertPermitted())
+ throw new AAPermissionException("No INSERT right for "+getCaller());
+ attributes.add(new ArpAttribute(name, exclude));
+ return true;
+ }
+
+ public boolean addAnAttribute(ArpAttribute attr)
+ throws AAPermissionException{
+ return addAnAttribute(attr, false);
+ }
+
+ /**
+ * Adds the given attribute to the attributes for this Resource.
+ * if force flag is true and attribute already exists
+ * then replaces the existing reource otherwise leaves the existing
+ * attribute untouched.
+ * returns false if reource already existed.
+ */
+ public boolean addAnAttribute(ArpAttribute attr, boolean force)
+ throws AAPermissionException {
+
+ if(attributes.contains(attr)){
+ if(force){
+ if(! replacePermitted())
+ throw new AAPermissionException("No replace right for "+getCaller());
+ attributes.remove(attr);
+ attributes.add(attr);
+ }
+ return false; // already there
+ }
+ if(! insertPermitted())
+ throw new AAPermissionException("No INSERT right for "+getCaller());
+ attributes.add(attr);
+ return true;
+ }
+
+ public boolean removeAnAttribute(String name)
+ throws AAPermissionException {
+
+ if(attributes.contains(new ArpAttribute(name, false))){
+ if(! insertPermitted())
+ throw new AAPermissionException("No DELETE right for "+getCaller());
+ attributes.remove(new ArpAttribute(name, false));
+ return true;
+ }
+ return false; // not found
+ }
+
+ public ArpAttribute getAttribute(String name) {
+ Enumeration en = attributes.elements();
+ while(en.hasMoreElements()){
+ ArpAttribute aAttribute = (ArpAttribute)en.nextElement();
+ if(aAttribute.getName().equals(name))
+ return aAttribute;
+ }
+ return null;
+ }
+
+ public ArpAttribute[] getAttributes() {
+ int len = attributes.size();
+ ArpAttribute[] a = new ArpAttribute[len];
+ for(int i = 0; i < len; i++)
+ a[i] = (ArpAttribute)attributes.get(i);
+ return a;
+ }
+
+
+ public int fit(String resrcName) {
+ TName tn = new TName(resrcName);
+ return tName.compare(tn);
+ }
+
+ public TName getTName(){
+ return tName;
+ }
+
+ public String getName(){
+ return name;
+ }
+
+ public boolean equals(Object rsrc){
+ return name.equals(((ArpResource)rsrc).getName());
+ }
+
+} /* end class ArpResource */
--- /dev/null
+package aa;
+
+import java.io.*;
+import java.util.*;
+import java.security.acl.*;
+
+public class ArpShar extends ArpCore implements Serializable{
+
+ // Attributes
+ protected String name;
+ protected boolean isDefault;
+
+ // Associations
+ protected Vector resources;
+ protected AA_Acl acl;
+
+ // Construstor
+ public ArpShar(String name, boolean isDefault)throws NotOwnerException{
+ this.name = name;
+ this.isDefault = isDefault;
+ resources = new Vector();
+ makeAcl("sharAcl");
+ }
+
+ // Operations
+ public String toString() {
+ return name+(isDefault?"(default)":"");
+ }
+
+ public boolean isDefault(){
+ return isDefault;
+ }
+
+ public boolean addAResource(String url)
+ throws NotOwnerException,AAPermissionException{
+
+ if(resources.contains(new ArpResource(url)))
+ return false; // already there
+
+ if(! insertPermitted())
+ throw new AAPermissionException("No INSERT right for "+getCaller());
+
+ resources.add(new ArpResource(url));
+ return true;
+ }
+
+ /**
+ * Adds a given resource to the resources for this Shar.
+ * Does not replace if resource already exists.
+ * returns false if resource already exists.
+ */
+
+ public boolean addAResource(ArpResource rsrc)
+ throws AAPermissionException{
+ return addAResource(rsrc, false);
+ }
+
+ /**
+ * Adds the given resource to the resources for this Shar.
+ * if force flag is true and resource already exists
+ * then replaces the existing reource otherwise leaves the existing
+ * resource untouched.
+ * returns false if reource already existed.
+ */
+ public boolean addAResource(ArpResource rsrc, boolean force)
+ throws AAPermissionException{
+
+ if(resources.contains(rsrc)){
+ if(force){
+ if(! replacePermitted())
+ throw new AAPermissionException("No replace right for "+getCaller());
+ resources.remove(rsrc);
+ resources.add(rsrc);
+ }
+ return false; // already there
+ }
+ if(! insertPermitted())
+ throw new AAPermissionException("No INSERT right for "+getCaller());
+ resources.add(rsrc);
+ return true;
+ }
+
+ public boolean removeAResource(String url)
+ throws NotOwnerException, AAPermissionException{
+ if(resources.contains(new ArpResource(url))){
+ if(! removePermitted())
+ throw new AAPermissionException("No DELETE right for "+getCaller());
+ resources.remove(new ArpResource(url));
+ return true;
+ }
+ return false; // not found
+ }
+
+ public ArpResource getResource(String url) {
+ Enumeration en = resources.elements();
+ while(en.hasMoreElements()){
+ ArpResource aResource = (ArpResource)en.nextElement();
+ if(aResource.getName().equals(url))
+ return aResource;
+ }
+ return null;
+ }
+
+ public ArpResource[] getResources() {
+ int len = resources.size();
+ ArpResource[] a = new ArpResource[len];
+ for(int i = 0; i < len; i++)
+ a[i] = (ArpResource)resources.get(i);
+ return a;
+ }
+
+
+ /**
+ * Go throu all resource objects and find the one that
+ * best matches the given url. This is based on comparison
+ * of TNames of urls provided by fit method of ArpResource.
+ *
+ * returns an ArpResource or null if no match found;
+ */
+ public ArpResource bestFit(String url) {
+
+ ArpResource[] ara = new ArpResource[resources.size()];
+ ara = (ArpResource[])resources.toArray(ara);
+ int bestScore = 0;
+ ArpResource bestResource = null;
+ for(int i=0; i < ara.length; i++){
+ int score = ara[i].fit(url);
+ if(score > bestScore){
+ bestScore = score;
+ bestResource = ara[i];
+ }
+ }
+ return bestResource;
+ }
+
+ public String getName(){
+ return name;
+ }
+
+ public boolean equals(Object shar){
+ return name.equals(((ArpShar)shar).getName());
+ }
+
+} /* end class ArpShar */
--- /dev/null
+package aa;
+
+import java.io.*;
+import java.util.*;
+class TName implements Serializable{
+
+ // Attributes
+ private String name;
+ private String[] tokens;
+ final static String WILD = "*";
+
+ // Associations
+ protected ArpResource myArpResource;
+
+ // Constructors
+ /**
+ * This class is a tokenized reprezentation of a URL so
+ * URLs can be compared against each other and see what is
+ * the best match or best fit.
+ */
+ TName(String url){
+ // break down the url and store it in a String[]
+ if(url.startsWith("http://"))
+ url = url.substring(7);
+ if(url.startsWith("https://"))
+ url = url.substring(8);
+
+ int i = 0;
+ StringTokenizer slash = new StringTokenizer(url, ":/\\");
+ if(slash.hasMoreTokens()){
+ // first element generally host name
+ String hostname = slash.nextToken();
+ StringTokenizer dot = new StringTokenizer(hostname, ".");
+ int count = dot.countTokens();
+ tokens = new String[count+slash.countTokens()];
+ for(int n = count; n > 0; n--){
+ tokens[n-1] = dot.nextToken();
+ }
+ i += count;
+ }
+ while(slash.hasMoreTokens()){
+ tokens[i++] = slash.nextToken();
+ }
+ }
+
+ // Operations
+ public String[] getTokens() {
+ return tokens;
+ }
+
+ public int compare(TName t){
+ String[] gTokens = t.getTokens();
+ int len = tokens.length;
+ int glen = gTokens.length;
+ if(len == 0 || glen == 0)
+ return 0;
+ for(int i=0; i<Math.min(len, glen); i++){
+ if(tokens[i].equalsIgnoreCase(gTokens[i]))
+ continue;
+ if(tokens[i].equals(WILD) || gTokens[i].equals(WILD))
+ continue;
+ return 0;
+ }
+ return Math.min(len,glen);
+ }
+
+ public String toString(){
+ StringBuffer buf = new StringBuffer();
+ int len =tokens.length;
+ for(int i = 0; i < len-1; i++){
+ buf.append(tokens[i]);
+ buf.append(", ");
+ }
+ if(len > 0)
+ buf.append(tokens[len-1]); // add the last one
+ return buf.toString();
+ }
+} /* end class TName */
--- /dev/null
+CP=.:/afs/andrew/acs/asg/shibboleth/runtime/java/v2/lib/xercesImpl.jar:/afs/andrew/acs/asg/shibboleth/runtime/java/v2/lib/xmlParserAPIs.jar:/afs/andrew/acs/asg/shibboleth/runtime/java/v2/lib/shibboleth.jar:/afs/andrew/acs/asg/shibboleth/runtime/java/v2/lib/opensaml.jar:/usr/www/tomcat/lib/servlet.jar:/usr/java/jre/lib/rt.jar:../../lib/jndi.jar
+
+INSTDIR=/afs/andrew/acs/asg/shibboleth/cmu/beta/lib
+
+all:
+ javac -g -classpath ${CP} *.java
+
+docs:
+ javadoc -classpath ${CP} -d /usr/www/tree/aa *java
+
+jar: all
+ mkdir aa;
+ cp *.class aa;
+ jar -cvf aa.jar aa;
+ rm -fr aa
+
+install: jar
+ cp aa.jar ${INSTDIR}
+