001: /*
002: * $Id: LdapUsergroup.java 640 2006-04-22 19:42:46Z wrh2 $
003: *
004: * Filename : LdapUsergroup.java
005: * Created : 24.06.2004
006: * Project : VQWiki
007: * copyright (c) 2004 by SinnerSchrader
008: */
009: package vqwiki.users;
010:
011: import java.util.ArrayList;
012: import java.util.Collections;
013: import java.util.Comparator;
014: import java.util.Hashtable;
015: import java.util.List;
016: import java.util.StringTokenizer;
017:
018: import javax.naming.Context;
019: import javax.naming.NamingEnumeration;
020: import javax.naming.NamingException;
021: import javax.naming.directory.Attributes;
022: import javax.naming.directory.BasicAttribute;
023: import javax.naming.directory.BasicAttributes;
024: import javax.naming.directory.DirContext;
025: import javax.naming.directory.InitialDirContext;
026: import javax.naming.directory.SearchResult;
027:
028: import org.apache.log4j.Logger;
029:
030: import vqwiki.Environment;
031: import vqwiki.servlets.beans.SelectorBean;
032:
033: /**
034: * Use an LDAP server as usergroup.
035: *
036: * @version $Revision: 640 $ - $Date: 2006-04-22 21:42:46 +0200 (za, 22 apr 2006) $
037: * @author SinnerSchrader (tobsch)
038: */
039: public class LdapUsergroup extends Usergroup {
040:
041: private static final Logger logger = Logger
042: .getLogger(LdapUsergroup.class);
043: private Environment environment = null;
044:
045: /**
046: * Get the email address of an user by its user-ID
047: * @param uid The user-ID of this user
048: * @return The email address of this user
049: * @see vqwiki.users.Usergroup#getKnownEmailById(java.lang.String)
050: */
051: public String getKnownEmailById(String id) {
052: if (id == null) {
053: return null;
054: }
055: return getAttributeByID(
056: id,
057: environment
058: .getStringSetting(Environment.PROPERTY_USERGROUP_MAIL_FIELD));
059: }
060:
061: /**
062: * Get the full name of an user by its user-ID
063: * @param uid The user-ID of this user
064: * @return The full name of this user
065: * @see vqwiki.users.Usergroup#getFullnameById(java.lang.String)
066: */
067: public String getFullnameById(String id) {
068: if (id == null) {
069: return null;
070: }
071: String returnValue = getAttributeByID(
072: id,
073: environment
074: .getStringSetting(Environment.PROPERTY_USERGROUP_FULLNAME_FIELD));
075: if (returnValue == null || "".equals(returnValue)) {
076: returnValue = id;
077: }
078: return returnValue;
079: }
080:
081: /**
082: * Get an instance of the user group class.
083: * @return Instance to the user group class
084: * @see vqwiki.users.Usergroup#getInstance()
085: */
086: public static Usergroup getInstance() {
087: LdapUsergroup lug = new LdapUsergroup();
088: lug.environment = Environment.getInstance();
089: return lug;
090: }
091:
092: /**
093: * Get a list of all users.
094: * @return List of all users. The list contains SelectorBeans with the user-ID as key and the full
095: * username as label.
096: * @see vqwiki.servlets.beans.SelectorBean
097: * @see vqwiki.users.Usergroup#getListOfAllUsers()
098: */
099: public List getListOfAllUsers() {
100: List list = new ArrayList();
101: String userIdField = environment
102: .getStringSetting(Environment.PROPERTY_USERGROUP_USERID_FIELD);
103: String fullnameField = environment
104: .getStringSetting(Environment.PROPERTY_USERGROUP_FULLNAME_FIELD);
105: try {
106: DirContext ctx = connect();
107: String searchString = environment
108: .getStringSetting(Environment.PROPERTY_USERGROUP_BASIC_SEARCH);
109: Attributes matchAttrs = new BasicAttributes(true);
110: fillSearchRestrictions(matchAttrs);
111: NamingEnumeration answer = ctx.search(searchString,
112: matchAttrs);
113: for (; answer.hasMoreElements();) {
114: try {
115: SearchResult searchResult = (SearchResult) answer
116: .nextElement();
117: Attributes sr = searchResult.getAttributes();
118: SelectorBean bean = new SelectorBean();
119: bean.setKey(sr.get(userIdField).get().toString());
120: bean.setLabel(sr.get(fullnameField).get()
121: .toString());
122: list.add(bean);
123: } catch (Exception e) {
124: logger.error("Cannot add a member", e);
125: }
126: }
127: } catch (Exception e) {
128: logger.error("Cannot create member list", e);
129: }
130: logger.debug("List created with " + list.size() + " entries");
131: Collections.sort(list, new Comparator() {
132: public int compare(Object o1, Object o2) {
133: SelectorBean bean1 = (SelectorBean) o1;
134: SelectorBean bean2 = (SelectorBean) o2;
135: return bean1.getLabel().compareToIgnoreCase(
136: bean2.getLabel());
137: }
138: });
139: return list;
140: }
141:
142: /**
143: * Get the user details of this user by its user-ID. The user details is a string, which is
144: * set in the admin section. It contains some placeholders, which are replaced by values from
145: * the user repository
146: * @param uid The user-ID of this user
147: * @return The user details section
148: * @see vqwiki.users.Usergroup#getUserDetails(java.lang.String)
149: */
150: public String getUserDetails(String id) {
151: if (id == null) {
152: return null;
153: }
154: String details = environment
155: .getStringSetting(Environment.PROPERTY_USERGROUP_DETAILVIEW);
156: // get attributes from user
157: Attributes searchAttributes;
158: try {
159: DirContext ctx = connect();
160: searchAttributes = getAttributesOfUser(id, ctx);
161: if (searchAttributes == null)
162: return "Cannot find user";
163: } catch (NamingException ne) {
164: return "Cannot find user";
165: }
166: // go through text for all the attrib
167: String searchChar = "@@";
168: int beginning = details.indexOf(searchChar);
169: int end;
170: int lastCopied = 0;
171: StringBuffer result = new StringBuffer();
172: while (beginning != -1) {
173: end = details.indexOf(searchChar, beginning + 1);
174: if (end != -1) {
175: String token = details.substring(beginning
176: + searchChar.length(), end);
177: String replacement;
178: try {
179: replacement = searchAttributes.get(token).get()
180: .toString();
181: } catch (NamingException ne) {
182: replacement = "";
183: } catch (NullPointerException ne) {
184: replacement = "";
185: }
186: result.append(details.substring(lastCopied, beginning));
187: result.append(replacement);
188: lastCopied = end + searchChar.length();
189: beginning = details.indexOf(searchChar, end + 1);
190: } else {
191: beginning = -1;
192: }
193: }
194: result.append(details.substring(lastCopied));
195: return result.toString();
196: }
197:
198: /**
199: * Contains the repository valid (already confirmed) email addresses?
200: * If yes, then we can skip the registration process and the user is automatically registered.
201: * @return true, if so. false otherwise.
202: * @see vqwiki.users.Usergroup#isEmailValidated()
203: */
204: public boolean isEmailValidated() {
205: return true;
206: }
207:
208: /**
209: * Get an (LDAP) Attribute by its name
210: * @param id The uid (user-ID)
211: * @param attribute The name of the attribtue to get
212: * @return The content of that attribute (as string) or an empty string.
213: */
214: private String getAttributeByID(String id, String attribute) {
215: if (id == null) {
216: return null;
217: }
218: Attributes searchAttributes = null;
219: try {
220: DirContext ctx = connect();
221: searchAttributes = getAttributesOfUser(id, ctx);
222: return searchAttributes.get(attribute).get().toString();
223: } catch (Exception e) {
224: }
225: return "";
226: }
227:
228: /**
229: * Get all Attributes of a user
230: * @param id The uid (user-ID)
231: * @param ctx The LDAP context
232: * @return The attributes of that user.
233: * @throws NamingException If an exception occured while asking for the attribtues
234: */
235: private Attributes getAttributesOfUser(String id, DirContext ctx)
236: throws NamingException {
237: if (id == null) {
238: return null;
239: }
240: Attributes searchAttributes;
241: String searchString = environment
242: .getStringSetting(Environment.PROPERTY_USERGROUP_BASIC_SEARCH);
243: Attributes matchAttrs = new BasicAttributes(true);
244: fillSearchRestrictions(matchAttrs);
245: matchAttrs
246: .put(new BasicAttribute(
247: environment
248: .getStringSetting(Environment.PROPERTY_USERGROUP_USERID_FIELD),
249: id));
250: NamingEnumeration answer = ctx.search(searchString, matchAttrs);
251: SearchResult searchResult = (SearchResult) answer.nextElement();
252: searchAttributes = searchResult.getAttributes();
253: return searchAttributes;
254: }
255:
256: /**
257: * Connect to the LDAP server and return a context
258: * @return The Context to work with
259: * @throws NamingException if an exception occured during connecting
260: */
261: private DirContext connect() throws NamingException {
262: Hashtable env = new Hashtable();
263: env
264: .put(
265: Context.INITIAL_CONTEXT_FACTORY,
266: environment
267: .getStringSetting(Environment.PROPERTY_USERGROUP_FACTORY));
268: env.put(Context.PROVIDER_URL, environment
269: .getStringSetting(Environment.PROPERTY_USERGROUP_URL));
270: String username = environment
271: .getStringSetting(Environment.PROPERTY_USERGROUP_USERNAME);
272: String password = environment.getUserGroupPassword();
273: if (username != null && !"".equals(username)) {
274: env.put(Context.SECURITY_AUTHENTICATION, "simple");
275: env.put(Context.SECURITY_PRINCIPAL, username); // specify the username
276: env.put(Context.SECURITY_CREDENTIALS, password); // specify the password
277: }
278: DirContext ctx = new InitialDirContext(env);
279: return ctx;
280: }
281:
282: /**
283: * If there are any restrictions to the search, they are filled in here.
284: * @param matchAttrs the list of attributes containing the search restrictions.
285: */
286: private void fillSearchRestrictions(Attributes matchAttrs) {
287: String searchRestrictions = environment
288: .getStringSetting(Environment.PROPERTY_USERGROUP_SEARCH_RESTRICTIONS);
289: StringTokenizer commaTokenizer = new StringTokenizer(
290: searchRestrictions, ",");
291: for (; commaTokenizer.hasMoreTokens();) {
292: String token = commaTokenizer.nextToken();
293: int ePos = token.indexOf("=");
294: if (ePos != -1) {
295: String key = token.substring(0, ePos);
296: String value = token.substring(ePos + 1);
297: matchAttrs.put(new BasicAttribute(key, value));
298: }
299: }
300: }
301: }
302:
303: /*
304: * Log:
305: *
306: * $Log$
307: * Revision 1.5 2006/04/22 19:42:46 wrh2
308: * VQW-78: Allow option to not store passwords as plain text.
309: *
310: * Revision 1.4 2006/04/20 01:32:17 wrh2
311: * Use standard variable name for logger (VQW-73).
312: *
313: * Revision 1.3 2006/04/20 00:14:40 wrh2
314: * Coding style updates (VQW-73).
315: *
316: * Revision 1.2 2004/07/02 10:19:28 mrgadget4711
317: * MOD: Better cope with null as identifier
318: *
319: * Revision 1.1 2004/06/28 09:37:19 mrgadget4711
320: * Classes for User groups
321: *
322: * ------------END------------
323: */
|