Java tutorial
/* * See the NOTICE file distributed with this work for additional * information regarding copyright ownership. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package com.xpn.xwiki.plugin.ldap; import java.text.MessageFormat; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xwiki.rendering.syntax.Syntax; import com.novell.ldap.LDAPAttribute; import com.novell.ldap.LDAPAttributeSet; import com.novell.ldap.LDAPConnection; import com.novell.ldap.LDAPEntry; import com.novell.ldap.LDAPException; import com.novell.ldap.LDAPSearchResults; import com.xpn.xwiki.XWikiContext; import com.xpn.xwiki.XWikiException; import com.xpn.xwiki.api.Api; import com.xpn.xwiki.doc.XWikiDocument; import com.xpn.xwiki.objects.BaseObject; import com.xpn.xwiki.objects.classes.BaseClass; import com.xpn.xwiki.plugin.XWikiDefaultPlugin; import com.xpn.xwiki.plugin.XWikiPluginInterface; @Deprecated public class LDAPPlugin extends XWikiDefaultPlugin implements XWikiPluginInterface { private static final Logger LOGGER = LoggerFactory.getLogger(LDAPPlugin.class); public LDAPPlugin(String name, String className, XWikiContext context) { super(name, className, context); init(context); } public String getName() { return "ldap"; } public Api getPluginApi(XWikiPluginInterface plugin, XWikiContext context) { return new LDAPPluginApi((LDAPPlugin) plugin, context); } public void flushCache() { } public void init(XWikiContext context) { super.init(context); } protected String getParam(String name, XWikiContext context) { String param = ""; try { param = context.getWiki().getXWikiPreference(name, context); } catch (Exception e) { } if (param == null || "".equals(param)) { try { param = context.getWiki() .Param("xwiki.authentication." + StringUtils.replace(name, "ldap_", "ldap.")); } catch (Exception e) { } } if (param == null) param = ""; return param; } protected int getLDAPPort(XWikiContext context) { try { return context.getWiki().getXWikiPreferenceAsInt("ldap_port", context); } catch (Exception e) { return (int) context.getWiki().ParamAsLong("xwiki.authentication.ldap.port", LDAPConnection.DEFAULT_PORT); } } public LDAPConnection connect(HashMap connection, XWikiContext context) throws LDAPException { int ldapPort; int ldapVersion = LDAPConnection.LDAP_V3; String ldapHost, ldapBindDN, ldapBindPassword; ldapHost = (connection == null) ? null : (String) connection.get("server"); if (ldapHost != null) { try { ldapPort = Integer.parseInt((String) connection.get("port")); } catch (Exception e) { ldapPort = 389; } ldapBindDN = (String) connection.get("bind_DN"); ldapBindPassword = (String) connection.get("bind_pass"); } else { ldapHost = getParam("ldap_server", context); ldapPort = getLDAPPort(context); ldapBindDN = getParam("ldap_bind_DN", context); ldapBindPassword = getParam("ldap_bind_pass", context); } return connect(ldapHost, ldapPort, ldapVersion, ldapBindDN, ldapBindPassword); } public LDAPConnection connect(String ldapHost, int ldapPort, int ldapVersion, String ldapBindDN, String ldapBindPassword) throws LDAPException { if (LOGGER.isDebugEnabled()) LOGGER.debug("LDAP Connect starting to " + ldapHost + " port " + ldapPort); LDAPConnection lc = new LDAPConnection(); try { lc.connect(ldapHost, ldapPort); if (LOGGER.isDebugEnabled()) LOGGER.debug("LDAP Connect successfull"); } catch (LDAPException e) { if (LOGGER.isErrorEnabled()) LOGGER.error("LDAP Connect failed with Exception " + e.getMessage()); throw e; } if (ldapBindDN != null) { if (LOGGER.isDebugEnabled()) LOGGER.debug("LDAP Bind starting to " + ldapBindDN); try { lc.bind(ldapVersion, ldapBindDN, ldapBindPassword.getBytes()); if (LOGGER.isDebugEnabled()) LOGGER.debug("LDAP Bind successfull"); } catch (LDAPException e) { if (LOGGER.isErrorEnabled()) LOGGER.error("LDAP Bind failed with Exception " + e.getMessage()); throw e; } } else { if (LOGGER.isDebugEnabled()) LOGGER.debug("LDAP Bind bypassed"); } return lc; } public HashMap search(String searchstr, String[] params, XWikiContext context) throws LDAPException { return search(searchstr, LDAPConnection.SCOPE_SUB, params, null, context); } public HashMap search(String searchstr, int scope, String[] params, XWikiContext context) throws LDAPException { return search(searchstr, scope, params, null, context); } public HashMap search(String searchstr, XWikiContext context) throws LDAPException { return search(searchstr, LDAPConnection.SCOPE_SUB, null, null, context); } public HashMap search(String searchstr, String[] params, HashMap connection, XWikiContext context) throws LDAPException { return search(searchstr, LDAPConnection.SCOPE_SUB, params, connection, context); } public HashMap search(String searchstr, HashMap connection, XWikiContext context) throws LDAPException { return search(searchstr, LDAPConnection.SCOPE_SUB, null, connection, context); } public HashMap search(String searchstr, int scope, String[] params, HashMap connection, XWikiContext context) throws LDAPException { HashMap hashmap = new HashMap(); String baseDN = (connection == null) ? getParam("ldap_base_DN", context) : (String) connection.get("base_DN"); LDAPConnection lc = connect(connection, context); try { LDAPSearchResults results = lc.search(baseDN, scope, searchstr, params, false); if (results == null) return hashmap; while (results.hasMore()) { LDAPEntry entry; try { entry = results.next(); } catch (LDAPException e) { LOGGER.debug("Error while reading ldap entry", e); // Exception is thrown, go for next entry continue; } HashMap entryhash = getEntryAsHashMap(entry); hashmap.put(entry.getDN(), entryhash); } return hashmap; } finally { lc.disconnect(); } } public HashMap getEntry(String dn, XWikiContext context) throws LDAPException { return getEntry(dn, null, context); } public HashMap getEntry(String dn, HashMap connection, XWikiContext context) throws LDAPException { LDAPConnection lc = connect(connection, context); try { LDAPEntry entry = lc.read(dn); return getEntryAsHashMap(entry); } finally { lc.disconnect(); } } public HashMap getEntryAsHashMap(LDAPEntry entry) { HashMap entryhash = new HashMap(); if (entry == null) return entryhash; entryhash.put("dn", entry.getDN()); LDAPAttributeSet attributeSet = entry.getAttributeSet(); Iterator allAttributes = attributeSet.iterator(); while (allAttributes.hasNext()) { LDAPAttribute attribute = (LDAPAttribute) allAttributes.next(); String attributeName = attribute.getName().toLowerCase(); if (attribute.size() <= 1) entryhash.put(attributeName, attribute.getStringValue()); else entryhash.put(attributeName, attribute.getStringValueArray()); } return entryhash; } /** * Method to create an XWiki user from LDAP information. Information is retrieved from the LDAP server specified in * the XWiki Preferences. Bind to the LDAP server can be done using Admin binding (in this case bindusernamd and * bindpassword are not used) or User binding (in this case bindusername and bindpassword are used) * * @param wikiname Wiki page name to use for the user. If null it will be generated from LDAP * @param uid UID to search user information in LDAP * @param bindusername bind username if binding is user binding * @param bindpassword bind password if binding is user binding * @param context XWiki Context * @return success or failure of create user * @throws XWikiException */ public boolean createUserFromLDAP(String wikiname, String uid, String bindusername, String bindpassword, XWikiContext context) throws XWikiException { if (LOGGER.isDebugEnabled()) LOGGER.debug("Check LDAP"); LDAPConnection lc = new LDAPConnection(); String foundDN; HashMap attributes = new HashMap(); try { if (LOGGER.isDebugEnabled()) LOGGER.debug("LDAP Password check for user " + uid); int ldapPort = getLDAPPort(context); int ldapVersion = LDAPConnection.LDAP_V3; String ldapHost = getParam("ldap_server", context); String bindDNFormat = getParam("ldap_bind_DN", context); String bindPasswordFormat = getParam("ldap_bind_pass", context); Object[] arguments = { bindusername, bindpassword }; String bindDN = MessageFormat.format(bindDNFormat, arguments); String bindPassword = MessageFormat.format(bindPasswordFormat, arguments); String baseDN = getParam("ldap_base_DN", context); // Connect and bind to LDAP server lc = connect(ldapHost, ldapPort, ldapVersion, bindDN, bindPassword); if (lc != null) { String searchquery = "(" + getParam("ldap_UID_attr", context) + "=" + uid + ")"; if (LOGGER.isDebugEnabled()) LOGGER.debug("LDAP searching for user with query " + searchquery); LDAPSearchResults searchResults = lc.search(baseDN, LDAPConnection.SCOPE_SUB, searchquery, null, // return // all // attributes false); // return attrs and values if (searchResults.hasMore()) { if (LOGGER.isDebugEnabled()) LOGGER.debug("LDAP searching found user"); LDAPEntry nextEntry = searchResults.next(); foundDN = nextEntry.getDN(); if (LOGGER.isDebugEnabled()) LOGGER.debug("LDAP searching found DN: " + foundDN); if (LOGGER.isDebugEnabled()) LOGGER.debug("LDAP adding user attributes"); LDAPAttributeSet attributeSet = nextEntry.getAttributeSet(); Iterator allAttributes = attributeSet.iterator(); while (allAttributes.hasNext()) { LDAPAttribute attribute = (LDAPAttribute) allAttributes.next(); String attributeName = attribute.getName(); Enumeration allValues = attribute.getStringValues(); if (allValues != null) { while (allValues.hasMoreElements()) { if (LOGGER.isDebugEnabled()) LOGGER.debug("LDAP adding user attribute " + attributeName); String Value = (String) allValues.nextElement(); attributes.put(attributeName, Value); } } } attributes.put("dn", foundDN); if (createUserFromLDAP(wikiname, attributes, context)) { if (LOGGER.isInfoEnabled()) { LOGGER.info("LDAP create user for user " + uid + " successfull"); } return true; } else { if (LOGGER.isInfoEnabled()) { LOGGER.info("LDAP create user for user " + uid + " failed"); } return false; } } else { if (LOGGER.isDebugEnabled()) LOGGER.debug("LDAP search user failed"); return false; } } else { if (LOGGER.isDebugEnabled()) { LOGGER.info("LDAP connect failed"); } return false; } } catch (LDAPException e) { if (LOGGER.isInfoEnabled()) LOGGER.info("LDAP create user for user " + uid + " failed with exception " + e.getMessage()); } catch (Throwable e) { if (LOGGER.isErrorEnabled()) LOGGER.error("LDAP create user for user " + uid + " failed with exception " + e.getMessage()); } finally { if (LOGGER.isDebugEnabled()) LOGGER.debug("LDAP create user in finally block"); try { lc.disconnect(); } catch (LDAPException e) { e.printStackTrace(); } } return false; } /** * Method allowing to create a user from LDAP attributes stored in a HashMap The mapping is declared in the XWiki * Parameters The 'name' mapping is used to define which ldap field to use to define the wiki page name All special * characters are cleared to generate the wiki page name * * @param wikiname Wiki page name to use. If null generate from ldap fields * @param attributes * @param context * @throws XWikiException */ public boolean createUserFromLDAP(String wikiname, HashMap attributes, XWikiContext context) throws XWikiException { String ldapFieldMapping = getParam("ldap_fields_mapping", context); if (LOGGER.isDebugEnabled()) LOGGER.debug("Ready to create user from LDAP with field " + ldapFieldMapping); if (ldapFieldMapping != null && ldapFieldMapping.length() > 0) { String[] fields = ldapFieldMapping.split(","); BaseClass bclass = context.getWiki().getUserClass(context); BaseObject bobj = new BaseObject(); bobj.setClassName(bclass.getName()); String fullwikiname = null; if (wikiname != null) { fullwikiname = "XWiki." + wikiname; bobj.setName(fullwikiname); } for (int i = 0; i < fields.length; i++) { String[] field = fields[i].split("="); if (2 == field.length) { String fieldName = field[0]; if (LOGGER.isDebugEnabled()) LOGGER.debug("Create user from LDAP looking at field " + fieldName); if (attributes.containsKey(field[1])) { String fieldValue; fieldValue = (String) attributes.get(field[1]); if ((wikiname == null) && (fieldName.equals("name"))) { wikiname = context.getWiki().clearName(fieldValue, true, true, context); fullwikiname = "XWiki." + wikiname; bobj.setName(fullwikiname); } else { LOGGER.debug("Create user from LDAP setting field " + fieldName); bobj.setStringValue(fieldName, fieldValue); } } } } if (wikiname != null && wikiname.length() > 0) { XWikiDocument doc = context.getWiki().getDocument(fullwikiname, context); doc.setParent(""); doc.addObject(bclass.getName(), bobj); if (!context.getWiki().getDefaultDocumentSyntax().equals(Syntax.XWIKI_1_0.toIdString())) { doc.setContent("{{include document=\"XWiki.XWikiUserSheet\"/}}"); doc.setSyntax(Syntax.XWIKI_2_0); } else { doc.setContent("#includeForm(\"XWiki.XWikiUserSheet\")"); doc.setSyntax(Syntax.XWIKI_1_0); } context.getWiki().protectUserPage(fullwikiname, "edit", doc, context); context.getWiki().saveDocument(doc, context.getMessageTool().get("core.comment.createdUser"), context); context.getWiki().setUserDefaultGroup(fullwikiname, context); return true; } } return false; } }