Package de.danet.an.workflow.rmsimpls.ldaprmsra

Source Code of de.danet.an.workflow.rmsimpls.ldaprmsra.LdapRmsManagedConnection

/*
* This file is part of the WfMOpen project.
* Copyright (C) 2001-2005 Danet GmbH (www.danet.de), BU BTS.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
* $Id: LdapRmsManagedConnection.java 2589 2007-11-06 13:57:41Z drmlipp $
*
* $Log$
* Revision 1.4.4.1  2007/11/05 20:14:12  mlipp
* Added authentication properties.
*
* Revision 1.4  2007/09/02 22:19:53  mlipp
* Made LDAP EIS RA realy work.
*
* Revision 1.3  2007/05/17 21:52:59  mlipp
* Refactored resource adaptors.
*
* Revision 1.2  2006/09/29 12:32:07  drmlipp
* Consistently using WfMOpen as projct name now.
*
* Revision 1.1  2006/09/24 20:57:16  mlipp
* Moved RMS implementations in own sub-package.
*
* Revision 1.1  2006/07/11 08:59:55  drmlipp
* Started LDAP RMS RA.
*
*/
package de.danet.an.workflow.rmsimpls.ldaprmsra;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Hashtable;
import java.util.List;

import javax.naming.Binding;
import javax.naming.InvalidNameException;
import javax.naming.NameNotFoundException;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.NotContextException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import javax.resource.ResourceException;
import javax.resource.spi.CommException;
import javax.resource.spi.ConnectionRequestInfo;
import javax.security.auth.Subject;

import de.danet.an.util.ra.ConnectionSupport;
import de.danet.an.util.ra.FactoryConfigurationError;
import de.danet.an.util.ra.ManagedConnectionFactorySupport;
import de.danet.an.util.ra.ManagedConnectionSupport;
import de.danet.an.workflow.rmsimpls.eisrms.aci.RmsEntry;

/**
* This class provides the managed connection used by the resource adapter
* for the properties files based RMS.
* @author Michael Lipp
*/
public class LdapRmsManagedConnection extends ManagedConnectionSupport {

    private static final org.apache.commons.logging.Log logger
        = org.apache.commons.logging.LogFactory
            .getLog(LdapRmsManagedConnection.class);

    private LdapRmsManagedConnectionFactory factory = null;
    private InitialLdapContext ctx = null;
   
    /**
     * Create a new instance.
     * @param mcf the managed connection factory
     * @param subject the subject
     */
    public LdapRmsManagedConnection
        (ManagedConnectionFactorySupport mcf, Subject subject) {
        super (mcf, subject);
        factory = (LdapRmsManagedConnectionFactory)mcf;
        Hashtable env = new Hashtable ();
        env.put("java.naming.factory.initial",
                factory.getJavaNamingFactoryInitial());
        env.put("java.naming.provider.url", factory.getJavaNamingProviderUrl());
        env.put("java.naming.security.authentication",
                factory.getJavaNamingSecurityAuthentication());
        if (factory.getJavaNamingSecurityPrincipal() != null
            && factory.getJavaNamingSecurityPrincipal().length() > 0) {
            env.put ("java.naming.security.principal",
                     factory.getJavaNamingSecurityPrincipal());
            env.put ("java.naming.security.credentials",
                     factory.getJavaNamingSecurityCredentials());
        }
        if (logger.isDebugEnabled ()) {
            logger.debug ("Logging into LDAP server, env=" + env);
        }
        try {
            ctx = new InitialLdapContext(env, null);
        } catch (NamingException e) {
            throw new FactoryConfigurationError
                ("Cannot create LDAP connection: " + e.getMessage (), e);
        }
    }

    /* (non-Javadoc)
     * Comment copied from interface or superclass.
     */
    protected void doDestroy() {
        try {
            ctx.close();
        } catch (NamingException e) {
            logger.debug
                ("Problem closing ldap context (ignored): " + e.getMessage());
        }
        ctx = null;
    }

    /* (non-Javadoc)
     * Comment copied from interface or superclass.
     */
    protected ConnectionSupport createConnection
        (Subject subject, ConnectionRequestInfo cxRequestInfo) {
        return new LdapRmsConnection ();
    }

    /* (non-Javadoc)
     * @see de.danet.an.workflow.rmsimpls.eisrms.aci.RmsConnection#findResource
     */
    public RmsEntry lookupUserByAccountName(String name)
        throws ResourceException, NameNotFoundException {
        return searchResource (RmsEntry.RESOURCE_TYPE_USER, name);
    }

    /* (non-Javadoc)
     * @see de.danet.an.workflow.rmsimpls.eisrms.aci.RmsConnection#lookupResource
     */
    public RmsEntry lookupResource(String key)
        throws ResourceException, NameNotFoundException {
        String dn = key.substring(2);
        int resType = 0;
        if (key.startsWith(RmsEntry.RESOURCE_TYPE_USER + "/")) {
            resType = RmsEntry.RESOURCE_TYPE_USER;
        } else if (key.startsWith(RmsEntry.RESOURCE_TYPE_GROUP + "/")) {
            resType = RmsEntry.RESOURCE_TYPE_GROUP;
        } else if (key.startsWith(RmsEntry.RESOURCE_TYPE_ROLE + "/")) {
            resType = RmsEntry.RESOURCE_TYPE_ROLE;
        } else {
            throw new IllegalArgumentException
                ("Resource with invalid key " + key);
        }
        String rna = factory
            .getQueryInfos(resType).getResourceNameAttribute();
        try {
            Attributes pd = ctx.getAttributes(dn);
            String name = dn;
            if (pd.get(rna) != null) {
                name = (String)pd.get(rna).get();
            }
            return new RmsEntry (resType, key, name);
        } catch (InvalidNameException e) {
            throw (NameNotFoundException)
                (new NameNotFoundException
                 ("Unknown LDAP resource \"" + dn + "\": "
                  + e.getMessage())).initCause(e);
        } catch (NotContextException e) {
            throw (NameNotFoundException)
                (new NameNotFoundException
                 ("Unknown LDAP resource \"" + dn + "\": "
                  + e.getMessage())).initCause(e);
        } catch (NamingException e) {
            throw (ResourceException)
                (new ResourceException
                 ("Problem accessing LDAP: " + e.getMessage())).initCause(e);
        }
    }

    /* (non-Javadoc)
     * @see de.danet.an.workflow.rmsimpls.eisrms.aci.RmsConnection#listResources()
     */
    public Collection listResources() throws ResourceException {
        List result = new ArrayList ();
        listResourceType
            (result, factory.getQueryInfos(RmsEntry.RESOURCE_TYPE_USER));
        listResourceType
            (result, factory.getQueryInfos(RmsEntry.RESOURCE_TYPE_GROUP));
        listResourceType
            (result, factory.getQueryInfos(RmsEntry.RESOURCE_TYPE_ROLE));
        return result;
    }

    private void listResourceType (List result, QueryInfos qi)
        throws ResourceException {
        if (qi.getCtxDN() == null) {
            return;
        }
        try {
            NamingEnumeration resources = null;
            if (qi.getFilter() == null) {
                resources = ctx.listBindings (qi.getCtxDN());
            } else {
                SearchControls ctrls = new SearchControls ();
                ctrls.setReturningObjFlag (true);
                ctrls.setReturningAttributes
                (new String[] { qi.getSearchAttribute(),
                        qi.getResourceNameAttribute() });
                resources = ctx.search
                    (qi.getCtxDN(), qi.getFilter(), ctrls);
            }
            while (resources.hasMore()) {
                Binding b = (Binding)resources.next();
                result.add (resourceFromBinding (b, qi));
            }
        } catch (NameNotFoundException e) {
            logger.warn
                ("Cannot access configured context \"" + qi.getCtxDN() + "\"");
        } catch (InvalidNameException e) {
            logger.warn
                ("Cannot access configured context \"" + qi.getCtxDN() + "\"");
        } catch (NotContextException e) {
            logger.warn
                ("Cannot access configured context \"" + qi.getCtxDN() + "\"");
        } catch (NamingException e) {
            throw (CommException)
                (new CommException
                 ("Problem accessing LDAP: " + e.getMessage())).initCause(e);
        }
    }
   
    /* (non-Javadoc)
     * @see de.danet.an.workflow.rmsimpls.eisrms.aci.RmsConnection#authorizers
     */
    public Collection authorizers(String key) throws ResourceException {
        List result = new ArrayList ();
        if (!key.startsWith(RmsEntry.RESOURCE_TYPE_USER + "/")) {
            return result;
        }
        String dn = key.substring(2);
        String mka = factory.getQueryInfos(RmsEntry.RESOURCE_TYPE_USER)
            .getMemberAttribute();
        if (mka != null) {
            try {
                Attributes attrs
                    = ctx.getAttributes (dn, new String[] { mka });
                Attribute attr = attrs.get(mka);
                if (attr == null) {
                    throw new IllegalStateException
                        ("Configuration or data problem: " + dn
                         + " should have attribute \"" + mka + "\""
                         + " for use as member key.");
                }
                dn = (String)attr.get ();
            } catch (NameNotFoundException e) {
                throw (IllegalArgumentException)
                    (new IllegalArgumentException
                     ("Unknown LDAP resource \"" + dn + "\": "
                      + e.getMessage())).initCause(e);
            } catch (InvalidNameException e) {
                throw (IllegalArgumentException)
                    (new IllegalArgumentException
                     ("Unknown LDAP resource \"" + dn + "\": "
                      + e.getMessage())).initCause(e);
            } catch (NotContextException e) {
                throw (IllegalArgumentException)
                    (new IllegalArgumentException
                     ("Unknown LDAP resource \"" + dn + "\": "
                      + e.getMessage())).initCause(e);
            } catch (NamingException e) {
                throw (CommException)
                    (new CommException
                     ("Problem accessing LDAP: " + e.getMessage())).initCause(e);
            }
        }
        appendAuthorizers
            (result, factory.getQueryInfos(RmsEntry.RESOURCE_TYPE_GROUP), dn);
        appendAuthorizers
            (result, factory.getQueryInfos(RmsEntry.RESOURCE_TYPE_ROLE), dn);
        return result;
    }

    private void appendAuthorizers (List result, QueryInfos qi, String crit)
        throws ResourceException {
        if (qi.getCtxDN() == null) {
            return;
        }
        try {
            String filter = "(" + qi.getMemberAttribute() + "=" + crit + ")";
            SearchControls ctrls = new SearchControls ();
            ctrls.setReturningObjFlag (true);
            ctrls.setReturningAttributes
                (new String[] { qi.getSearchAttribute(),
                                qi.getResourceNameAttribute() });
                NamingEnumeration resources
                    = ctx.search (qi.getCtxDN(), filter, ctrls);
                while (resources.hasMore()) {
                    Binding b = (Binding)resources.next();
                    result.add (resourceFromBinding (b, qi));
                }
        } catch (NameNotFoundException e) {
            logger.warn
                ("Cannot access configured context \"" + qi.getCtxDN() + "\"");
        } catch (InvalidNameException e) {
            logger.warn
                ("Cannot access configured context \"" + qi.getCtxDN() + "\"");
        } catch (NotContextException e) {
            logger.warn
                ("Cannot access configured context \"" + qi.getCtxDN() + "\"");
        } catch (NamingException e) {
            throw (CommException)
                (new CommException
                 ("Problem accessing LDAP: " + e.getMessage())).initCause(e);
        }
    }

    /* (non-Javadoc)
     * @see de.danet.an.workflow.rmsimpls.eisrms.aci.RmsConnection#selectResources
     */
    public Collection selectResources(Object resSel) throws ResourceException {
        Collection res = new ArrayList();
        if (resSel == null || !(resSel instanceof String)) {
            return res;
        }
        String crit = (String)resSel;
        String selType = crit.substring(0, 1);
        int resType = 0;
        if (selType.equals("M") || selType.equals("U")) {
            resType = RmsEntry.RESOURCE_TYPE_USER;
        } else if (selType.equals("G")) {
            resType = RmsEntry.RESOURCE_TYPE_GROUP;
        } else if (selType.equals("R")) {
            resType = RmsEntry.RESOURCE_TYPE_ROLE;
        } else {
            return null;
        }
        try {
            res.add(searchResource (resType, crit.substring(2)));
        } catch (NameNotFoundException e) {
        }
        return res;
    }
   
    private RmsEntry searchResource (int resType, String crit)
        throws ResourceException, NameNotFoundException {
        QueryInfos qi = factory.getQueryInfos(resType);
        if (qi.getCtxDN() == null) {
            throw new IllegalArgumentException
                ("No context configured  for searching \"" + crit + "\"");
        }
        try {
            String filter = "(" + qi.getSearchAttribute() + "=" + crit + ")";
            if (qi.getFilter() != null) {
                filter = "(&" + qi.getFilter() + filter + ")";
            }
            SearchControls ctrls = new SearchControls ();
            ctrls.setReturningObjFlag (true);
            ctrls.setReturningAttributes
                (new String[] { qi.getSearchAttribute(),
                                qi.getResourceNameAttribute() });
            NamingEnumeration resources
                = ctx.search (qi.getCtxDN(), filter, ctrls);
            if (!resources.hasMore()) {
                throw (NameNotFoundException)
                    (new NameNotFoundException
                     ("No LDAP resource in context \""
                      + qi.getCtxDN() + "\" with \""
                      + qi.getSearchAttribute() + "=" + crit + "\""));
            }
            Binding b = (Binding)resources.next();
            return resourceFromBinding(b, qi);
        } catch (NameNotFoundException e) {
            throw (NameNotFoundException)
                (new NameNotFoundException
                 ("Unknown LDAP context \"" + qi.getCtxDN() + "\": "
                  + e.getMessage())).initCause(e);
        } catch (InvalidNameException e) {
            throw (NameNotFoundException)
                (new NameNotFoundException
                 ("Unknown LDAP context \"" + qi.getCtxDN() + "\": "
                  + e.getMessage())).initCause(e);
        } catch (NotContextException e) {
            throw (NameNotFoundException)
                (new NameNotFoundException
                 ("Unknown LDAP context \"" + qi.getCtxDN() + "\": "
                  + e.getMessage())).initCause(e);
        } catch (NamingException e) {
            throw (CommException)
                (new CommException
                 ("Problem accessing LDAP: " + e.getMessage())).initCause(e);
        }
    }
   
    private RmsEntry resourceFromBinding
        (Binding binding, QueryInfos qi) throws NamingException {
        DirContext resource = (DirContext)binding.getObject();
        String resDN = resource.getNameInNamespace();
        String resKey = qi.getResType() + "/" + resDN;
        Attributes attrs = null;
        if (binding instanceof SearchResult) {
            attrs = ((SearchResult)binding).getAttributes ();
        } else {
            attrs = resource.getAttributes
                ("", new String[] { qi.getResourceNameAttribute(),
                                    qi.getSearchAttribute() });
        }
        String resName = null;
        if (attrs.get(qi.getResourceNameAttribute()) != null) {
            resName = (String)attrs.get(qi.getResourceNameAttribute()).get();
        } else if (qi.getSearchAttribute() != null
               && attrs.get(qi.getSearchAttribute()) != null) {
            resName = (String)attrs.get(qi.getSearchAttribute()).get();
        }
        return new RmsEntry (qi.getResType(), resKey, resName);
    }
   
}
TOP

Related Classes of de.danet.an.workflow.rmsimpls.ldaprmsra.LdapRmsManagedConnection

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.