Package anvil.server.ldap

Source Code of anvil.server.ldap.LDAPCitizen

/*
* $Id: LDAPCitizen.java,v 1.14 2002/09/16 08:05:06 jkl Exp $
*
* Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
*
* Use is subject to license terms, as defined in
* Anvil Sofware License, Version 1.1. See LICENSE
* file, or http://njet.org/license-1.1.txt
*/
package anvil.server.ldap;

import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Connection;
import java.io.IOException;
import java.util.Map;
import java.util.Hashtable;
import java.util.List;
import java.util.Enumeration;
import java.util.ArrayList;
import java.util.Iterator;
import java.security.PermissionCollection;
import java.security.Permissions;
import java.security.Permission;

import anvil.java.security.PermissionCollectionCombiner;
import anvil.java.util.BindingEnumeration;
import anvil.java.util.EnumerationToIterator;
import anvil.core.Any;
import anvil.core.Array;
import anvil.core.AnyString;
import anvil.core.Serialization;
import anvil.Log;
import anvil.core.UnserializationException;
import anvil.core.Serialization;
import anvil.database.ConnectionManager;
import anvil.database.PooledConnection;
import anvil.core.AnyString;
import anvil.server.Citizen;
import anvil.server.Realm;
import anvil.server.Tribe;
import anvil.server.Zone;
import anvil.server.OperationFailedException;
import anvil.server.CitizenNotFoundException;

import javax.naming.*;
import javax.naming.directory.*;

/**
* class LDAPCitizen
* Citizen is based on inetorgperson ldap object schema. It has special use for following
* inetorgperson attributes:
* <li>description - used to save user permission information
* <li>physicalDeliveryOfficeName - used to save user attributes
*
* One shouldn't alter these values unless he's familar with the format.
*
* User attributes that are specified in inetorgperson schema has "ctz." prefix when
* accessed through getAttribute() - except userPassword of course (use verifyCredentials() and
* setCredentials()).
*
* (Anvil script examle:)<br>
* <code>
* realm = context.getRealm("myRealm");
* citizen = realm.getCitizen("foo@njet.org");
* println "Common name: ", citizen["ctz.cn"];
* println "Shoe size: ", citizen["shoeSize"];
* </code>
*
* Note. Because Citizen implements Namespace inferface you can access user attributes as they were
* member fields of citizen object.
*
* @author: Simo Tuokko
*/

public class LDAPCitizen implements Citizen
{
  public static final String OTHERS_ATTR = "physicalDeliveryOfficeName";

  private String username = null;
  private String dn = null;
  private String fullDN = null;
  private String password = null;
 
  private Log       log;
  private LDAPRealm realm;

  private PermissionCollection _permissions = null;
  private PermissionCollection _combined = null;
  private boolean hasPermissions = false;
  private Tribe[] _groups = null;

  private boolean _modified    = false;
  private Array   _toBeDeleted = new Array();
  private Array   _cache       = new Array();
  private Array   _cacheOrig   = null;
 
  final static AttributeMapping ATTRMAP_C = new AttributeMapping();
  final static AttributeMapping ATTRMAP_L = new AttributeMapping(true);
 
  public LDAPCitizen(LDAPRealm realm, String username)
    throws CitizenNotFoundException, OperationFailedException 
  {
    this.realm = realm;
    this.log = realm.getLog();
    this.username = username;
    this.dn = "uid="+username+",ou=users";
    this.fullDN = realm.createUserDN(username);
 
    //get password and id
    PooledConnection connImpl = null;
    DirContext ctx = null;
    boolean citizenFound = false;
 
    try {
      connImpl = realm.getConnection();
      ctx = (DirContext)connImpl.getConnection();
 
      //todo: use ctx.getAttributes()
      NamingEnumeration enu = ctx.search("ou=users", "(uid="+username+")", new SearchControls());
 
      if (enu.hasMore()) {
        SearchResult s = (SearchResult)enu.next();
        Attributes attrs = s.getAttributes();
        Attribute passAt = attrs.get("facsimileTelephoneNumber");
        if (passAt != null) {
          password = (String)passAt.get();
        }
       
        NamingEnumeration attrEnu = attrs.getAll();
        for (; attrEnu.hasMoreElements(); ) {
          Attribute a = (Attribute)attrEnu.nextElement();
          String id = a.getID();
          if (ATTRMAP_L.containsKey(a.getID())) {
            _cache.put( new AnyString((String)ATTRMAP_L.get(id)), new AnyString(a.get().toString()) );

          } else if (OTHERS_ATTR.equals(id)) {
            try {
              Array others = (Array)Serialization.unserialize(null, a.get().toString());
              _cache.union(others);

            } catch(UnserializationException ioe) {
              throw new OperationFailedException("Data unserialization failed: "+ioe);
            }

          } else {
            //System.err.println("Load: Unknown attr: "+id+" = "+a.get());
          }
        }
       
        citizenFound = true;
        _cacheOrig = (Array)_cache.clone();
      }

    } catch (Exception e) {
      throw new OperationFailedException("Creating of citizen failed", e);
     
    } finally {
      LDAPRealm.cleanupContext(connImpl);
    }
    if (!citizenFound) {     
      throw new CitizenNotFoundException(username);
    }
  }


  public Any setVariable(String name, Any value) {
    if (name != null && value != null && !name.equals("ctz.username")) {
      Any anyName = Any.create(name);
      if (_toBeDeleted.containsKey(anyName)) {
        _toBeDeleted.remove(anyName);
      }
      _cache.put(Any.create(name), value);
      _modified = true;
    }
    return value;
  }


  public boolean deleteVariable(String name) {
    if (_cache.get(Any.create(name)) != null &&       
        !name.equals("ctz.username") &&
        !name.equals("ctz.surName")) {

      Any anyName = Any.create(name);
      _toBeDeleted.put(anyName, Any.TRUE);
      _cache.remove(anyName);
      _modified = true;
      return true;
    }
    return false;
  }


  public Any getVariable(String name) {
    Any value = _cache.get(Any.create(name));
    return (value != null) ? value : Any.UNDEFINED;
  }


  public Any checkVariable(String name) {
    return getVariable(name);
  }


  public BindingEnumeration getVariables() {
    return _cache.keysAndElements();
  }


  public Realm getRealm() {
    return realm;
  }
 

  public String getName() {
    return username;
  }
 

  public boolean verifyCredentials(String credential) {
    /*log.error("--in verify..");
    try {
      Hashtable probs = new Hashtable();
      probs.put("java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory");
      probs.put("java.naming.provider.url", "ldap://nuhapumppu:389/o=deftit.com");
      probs.put("java.naming.authentication", "simple");
      probs.put("java.naming.principal", dn);
      probs.put("java.naming.credentials", credential);
      Context c = new InitialDirContext(probs);
      log.error("--c: "+c);
    } catch(NamingException e) {
      log.error("LDAPCitizen.verifyCredential() failed: "+e);
      return false;
    }

    return true;*/
   
    return credential.equals(password);
  }
 

  public void setCredentials(String newCredentials) throws OperationFailedException {
    password = newCredentials;
    setVariable("ctz.fax", Any.create(newCredentials));
    commit();
  }
  public String getPassword() {
    return password;
  }
 

  public Tribe[] getParents() {
    if (_groups == null) {
      synchronized(this) {
        if (_groups == null) {
          _groups = realm.getMemberGroups(fullDN);
        }
      }
    }
    return _groups;
  }
 

  public void commit() throws OperationFailedException {
    if (!_modified) {
      return;
    }

    Any anyKey;
    String key;
    Any value;
    boolean ldapAttr;
    List mods = new ArrayList();
    Array others = new Array();
    boolean othersModified = false;

    //to be deleted
    if (_toBeDeleted.size() > 0) {
      for (BindingEnumeration de=_toBeDeleted.keysAndElements(); de.hasMoreElements(); ) {
        anyKey = (Any)de.nextKey();
        de.nextElement();
        key    = anyKey.toString();
        ldapAttr = LDAPCitizen.ATTRMAP_C.containsKey(key);
        if (ldapAttr) {
          key = (String)LDAPCitizen.ATTRMAP_C.get(key);
        }

        if (!ldapAttr) {
          othersModified = true;
        } else if (!key.equals("uid") && !key.equals("sn")) {
          mods.add(new ModificationItem(DirContext.REMOVE_ATTRIBUTE, new BasicAttribute(key)));
        }
      }
      _toBeDeleted.clear();
    }

    for (BindingEnumeration enum=_cache.keysAndElements(); enum.hasMoreElements(); ) {
      anyKey = (Any)enum.nextKey();
      key    = anyKey.toString();
      value  = (Any)enum.nextElement();
   
      ldapAttr = LDAPCitizen.ATTRMAP_C.containsKey(key);
      if (ldapAttr) {
        key = (String)LDAPCitizen.ATTRMAP_C.get(key);
      }
     
      //compare value to original
      Any orig = (Any)_cacheOrig.get(anyKey);

      if (orig == null || !orig.equals(value)) {
        if (!ldapAttr) {
          othersModified = true;
          others.put(anyKey, value);
        } else if (!key.equals("uid")) {
          int modType = (orig == null)? DirContext.ADD_ATTRIBUTE : DirContext.REPLACE_ATTRIBUTE;
          mods.add(new ModificationItem(modType, new BasicAttribute(key, value.toString())));
        }
        continue;
      }
     
      if (!ldapAttr) {
        others.put(anyKey, value);
      }
    } //for cache
   
    if (othersModified) {
      try {
        if (others.size() > 0) {
          mods.add(new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
            new BasicAttribute(OTHERS_ATTR, Serialization.serialize(null, others)))
          );
        } else {
          mods.add(new ModificationItem(DirContext.REMOVE_ATTRIBUTE, new BasicAttribute(OTHERS_ATTR)));
        }
      } catch(IOException ioe) {
        throw new OperationFailedException("Data serialization failed: "+ioe);
      }
    }
           
    PooledConnection connImpl = null;
    DirContext ctx = null;

    if (mods.size() > 0) {
      try {
        connImpl = realm.getConnection();
        ctx = (DirContext)connImpl.getConnection();
        ctx.modifyAttributes(dn, (ModificationItem[])mods.toArray(new ModificationItem[mods.size()]));
       
      } catch (Exception e) {
        log.error("LDAPCitizen: Data commit failed", e);
     
      } finally {
        LDAPRealm.cleanupContext(connImpl);
      }

      _cacheOrig = (Array)_cache.clone();
    }
    _modified = false;
  }


  public PermissionCollection getCombinedPermissions() {
    if (!hasPermissions) {
      synchronized(this) {
        if (!hasPermissions) {
          hasPermissions = true;
          getParents();

          Permissions perms = new Permissions();
          for (int i=0; i<_groups.length; i++) {
            PermissionCollection groupCol = _groups[i].getCombinedPermissions();
            if (groupCol != null) {
              for (Enumeration enu = groupCol.elements(); enu.hasMoreElements(); ) {
                perms.add((Permission)enu.nextElement());
              }
            }
          }
          //combine own permissions
          for (Enumeration enu = getPermissions().elements(); enu.hasMoreElements(); ) {
            perms.add((Permission)enu.nextElement());
          }
         
          _combined = perms;
        }
      }
    }
   
    return _combined;
  }
 
 
  public PermissionCollection getPermissions() {
    if (_permissions == null) {
      synchronized(this) {
        if (_permissions == null) {
          _permissions = realm.loadPermissions(dn);
        }
      }
    }
    return _permissions;
  }


  public void addPermission(Permission perm) throws OperationFailedException {
    _permissions = realm.addPermission(perm, dn);
  }
 
 
  public void removePermission(Permission perm) throws OperationFailedException {
    _permissions = realm.removePermission(perm, dn);
  }


  public Iterator listPermissions() {
    if (_permissions != null) {
      return new EnumerationToIterator(_permissions.elements());
    } else {
      return BindingEnumeration.EMPTY;
    }
  }

 
  public void remove() throws OperationFailedException {
    PooledConnection connImpl = null;
    DirContext ctx = null;
 
    try {
      connImpl = realm.getConnection();
      ctx = (DirContext)connImpl.getConnection();
 
      ctx.unbind(dn);
      realm.removeCitizen(username);
      //this citizen no longer exists!
 
    } catch (NameNotFoundException e) {
      throw new OperationFailedException("User '"+username+"' not found!");

    } catch (Exception e) {
      throw new OperationFailedException(e.getMessage());
     
    } finally {
      LDAPRealm.cleanupContext(connImpl);
    }
  }


  String getDN() {
    return dn;
  }
 
 
  String getFullDN() {
    return fullDN;
  }
 
 
  void refreshPermissions() {
    hasPermissions = false;
    _groups = null;
  }


  public boolean equals(Object o) {
    if (o instanceof LDAPCitizen) {
      LDAPCitizen c = (LDAPCitizen)o;
      return (c.username.equals(username) && c.realm.equals(realm));
    }
    return false;
  }

 
  public String toString() {
    return "LDAPCitizen ("+dn+")";
  }
}
TOP

Related Classes of anvil.server.ldap.LDAPCitizen

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.