View Javadoc

1   /*
2    * Copyright 2000-2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.apache.jetspeed.om.security.ldap;
18  
19  import java.io.ByteArrayInputStream;
20  import java.io.ByteArrayOutputStream;
21  import java.io.ObjectInputStream;
22  import java.io.ObjectOutputStream;
23  import java.text.SimpleDateFormat;
24  import java.util.Date;
25  import java.util.Enumeration;
26  import java.util.Hashtable;
27  import java.util.TimeZone;
28  import java.util.Vector;
29  import javax.naming.Context;
30  import javax.naming.Name;
31  import javax.naming.NameNotFoundException;
32  import javax.naming.NameParser;
33  import javax.naming.NamingEnumeration;
34  import javax.naming.NamingException;
35  import javax.naming.OperationNotSupportedException;
36  import javax.naming.directory.Attribute;
37  import javax.naming.directory.Attributes;
38  import javax.naming.directory.BasicAttribute;
39  import javax.naming.directory.BasicAttributes;
40  import javax.naming.directory.DirContext;
41  import javax.naming.directory.ModificationItem;
42  import javax.naming.directory.SearchControls;
43  
44  import org.apache.jetspeed.services.ldap.LDAPURL;
45  import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
46  import org.apache.jetspeed.services.logging.JetspeedLogger;
47  import org.apache.jetspeed.util.Base64;
48  
49  
50  /***
51   * The Base LDAP Object extending DirContext.
52   *
53   * @author <a href="mailto:ender@kilicoglu.nom.tr">Ender Kilicoglu</a>
54   * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a> 
55   * @author <a href="mailto:sami.leino@netorek.fi">Sami Leino</a>
56   * 
57   * @version $Id: BaseLDAPObject.java,v 1.8 2004/02/23 03:12:13 jford Exp $
58   */
59  
60  public class BaseLDAPObject implements DirContext
61  {
62      // Constants
63      protected final static String OK                = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
64      protected final static String LDAP_DATE_PATTERN = "yyyyMMddmmHHss'Z'";
65  	
66  	// Instance variables
67      protected LDAPURL ldapurl                       = null;
68      protected boolean updated                       = false;
69      protected String name                           = null;
70      protected String Id                             = null;
71      protected Attributes myAttrs                    = null;
72      protected boolean isNew                         = false;
73      protected BasicAttributes rmAttrs               = new BasicAttributes();
74  
75      /***
76       * Static initialization of the logger for this class
77       */    
78      private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(BaseLDAPObject.class.getName());    
79      
80      /***
81       * <p>Creates an "LDAP-safe" ID from a String so that
82       * the generated ID is as similar as possible to the 
83       * original value. For example, value "Ryhmä" ("group" 
84       * in Finnish language) would be converted to "ryhma".
85       * If the value contains an unknown character, it will
86       * be replaced by letter 'X'.</p> 
87       */   
88  	public String createId(String value)
89  	{
90  		value = value.replace('å', 'a');
91  		value = value.replace('ä', 'a');
92  		value = value.replace('ö', 'o');
93  		value = value.replace('Å', 'A');
94  		value = value.replace('Ä', 'A');
95  		value = value.replace('Ö', 'O');
96  		StringBuffer buf = new StringBuffer(); 
97  
98  		for (int i=0; i < value.length(); i++)
99  		{
100 			char currentChar = value.charAt(i);
101 			if (isOK(currentChar)) buf.append(currentChar);		
102 			else buf.append('X');
103 		}
104 
105 		return buf.toString();
106 	}
107 	
108     /***
109      * <p>Checks if the specified character can be used
110      * in LDAP attribute name.</p> 
111      */   
112 	public boolean isOK(char value)
113 	{
114 		for (int i=0; i < OK.length(); i++)
115 		{
116 			if (value == OK.charAt(i)) return true;
117 		}
118 
119 		return false;
120 	}
121 
122     /***
123      * <p>Set's the objectClass for this object.</p>
124      * 
125      */
126     public void setObjectClass(String name)
127     {
128         Attribute oc = new BasicAttribute("objectclass");
129         oc.add(name);
130         myAttrs.put(oc);
131     }
132 
133     /***
134      * <p>Set's multiple objectClasses for this object.</p>
135      * 
136      */
137     public void setObjectClasses(String[] names)
138     {
139         Attribute oc = new BasicAttribute("objectclass");
140 		for (int i=0; i < names.length; i++)
141 		{
142 	        oc.add(names[i]);
143 		}
144         myAttrs.put(oc);
145     }
146 
147     protected String formatDate(Date date)
148     {
149         if (date == null)
150         {
151             date = new Date();
152         }
153 
154         SimpleDateFormat formatter = new SimpleDateFormat(LDAP_DATE_PATTERN);
155 		formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
156 		return formatter.format(date);
157     }
158 
159     protected Date parseDate(String value)
160     {
161 		return parseDate(value, true);
162 	}
163 	
164     protected Date parseDate(String value, boolean initializeIfNotSet)
165     {
166         try
167         {
168             SimpleDateFormat parser = new SimpleDateFormat(LDAP_DATE_PATTERN);
169 			parser.setTimeZone(TimeZone.getTimeZone("GMT"));
170             return parser.parse(value);
171         }
172         catch (Exception e)
173         {
174         	logger.warn("Could not parse date '" + value + "'");
175     		if (initializeIfNotSet) return new Date();
176     		else return null;
177         }
178     }
179 
180     protected String serializePerm(Hashtable permStorage)
181     throws Exception
182     {
183         ByteArrayOutputStream baos = new ByteArrayOutputStream();
184         ObjectOutputStream os = new ObjectOutputStream(baos);
185         os.writeObject(permStorage);
186         return Base64.encodeAsString(baos.toByteArray());
187     }
188 
189     protected Hashtable deserializePerm(String permStorageContentsEncoded)
190     throws Exception
191     {
192         byte[] decoded = Base64.decodeAsByteArray(permStorageContentsEncoded);
193         ByteArrayInputStream bais = new ByteArrayInputStream(decoded);
194         ObjectInputStream is = new ObjectInputStream(bais);
195         return (Hashtable)is.readObject();
196     }
197 
198     /***
199     * Updated Function
200     *
201     * Return State of updated property
202     *
203     * @return boolean updated property value
204     */
205     public boolean getupdated()
206     {
207         return this.updated;
208     }
209 
210     /***
211      * ID Function
212      *
213      * Return Value of ID property
214      *
215      * @return String ID property value
216      */
217     public String getId()
218     {
219         return Id;
220     }
221 
222     /***
223     * ID Function
224     *
225     * Set Value of ID property
226     *
227     * @param Id ID property value
228     */
229     public void setId(String Id)
230     {
231         this.Id = Id;
232     }
233 
234     public String getName()
235     {
236         return name;
237     }
238 
239     public void setName(String name)
240     {
241 //         throw new java.lang.UnsupportedOperationException();
242     }
243 
244     public LDAPURL getldapurl()
245     {
246         return ldapurl;
247     }
248 
249     public void setLdapUrl(LDAPURL url)
250     {
251         ldapurl = url;
252     }
253 
254     public boolean isNew()
255     {
256         return isNew;
257     }
258 
259 //UTIL Funcs
260 
261     protected void removeutil(String field, boolean updatable)
262 	{
263         myAttrs.remove(field);
264 
265         if (updatable)
266 		{
267             rmAttrs.remove(field);
268         }
269     }
270     protected void setutil(String field, String value)
271     {
272         myAttrs.remove(field);
273         if (value == null || value.length() == 0) value = " ";
274         myAttrs.put(field, value);
275         updated = true;
276     }
277 
278     protected void setutil(String field, Vector values)
279     {
280     	setutil(field, values, false);
281     }
282 
283     protected void setutil(String field, Vector values, boolean create)
284     {
285         myAttrs.remove(field);
286 
287 		if (values == null || (values.size() == 0 && create))
288 		{
289 			updated = true;
290 			return;
291 		}
292 		        
293 		Attribute attr = new BasicAttribute(field);
294         for(Enumeration enum = values.elements(); enum.hasMoreElements();)
295         {
296         	String nextValue = (String)enum.nextElement();
297             attr.add(nextValue);
298         }
299 
300         myAttrs.put(attr);
301         updated = true;
302     }
303 
304     protected void setutil(String field, Object value)
305     {
306         myAttrs.remove(field);
307         myAttrs.put(field, value);
308         updated = true;
309     }
310 
311     protected String getutil(String field)
312     {
313 		return getutil(field, myAttrs);
314     }
315 
316     protected Vector getutil(String field, boolean empty)
317     {
318 		return getutil(field, myAttrs, empty);
319 	}
320 
321     protected String getutil(String field, Attributes attrs)
322     {
323         if (attrs.get(field) == null)
324         {
325             return new String("");
326         }
327         else
328         {
329             try
330             {
331                 return attrs.get(field).getAll().next().toString();
332             }
333             catch (NamingException e)
334             {
335                 logger.warn( "getUtil(): " + e.getMessage(), e );
336                 return new String("");
337             }
338         }
339     }
340 
341     protected String fastgetutil(String field, Attributes attrs)
342 	throws NamingException
343     {
344 		Attribute values = attrs.get(field);
345         if (values == null) return new String("");
346 
347 		NamingEnumeration e = values.getAll();
348 		if (e == null || !e.hasMore()) return new String("");
349 
350 		return e.next().toString();
351     }
352 
353     protected Vector getutil(String field, Attributes attrs, boolean empty)
354     {
355         Vector values= null;
356         String temp;
357 
358         if (empty)
359         {
360             values = new Vector();
361         }
362 
363         if (!(attrs.get(field) == null))
364 	{
365             try
366             {
367                 for(NamingEnumeration enum = attrs.get(field).getAll(); enum.hasMore(); )
368                 {
369                     temp = (String)enum.nextElement();
370 
371                     if (null != temp)
372                     {
373                         values.add(temp);
374                     }
375                 }
376             }
377             catch (NamingException e)
378             {
379                 logger.warn( "getUtil(): " + e.getMessage(), e );
380             }
381         }
382 
383         return values;
384     }
385 
386     public Attributes getAttributes(String name) throws NamingException 
387 	{
388         if (! name.equals(""))
389 		{
390             throw new NameNotFoundException();
391         }
392 
393         return myAttrs;
394     }
395 
396     public Attributes getAttributes(Name name) throws NamingException
397 	{
398         return getAttributes(name.toString());
399     }
400 
401     public Attributes getAttributes(String name, String[] ids) throws NamingException
402 	{
403         if (!name.equals(""))
404 		{
405             throw new NameNotFoundException();
406         }
407 
408         Attributes answer = new BasicAttributes(true);
409         Attribute target;
410 
411         for (int i = 0; i < ids.length; i++)
412 		{
413             target = myAttrs.get(ids[i]);
414             if (target != null)
415 			{
416                 answer.put(target);
417             }
418         }
419         return answer;
420     }
421 
422     public Attributes getAttributes(Name name, String[] ids) throws NamingException
423     {
424         return getAttributes(name.toString(), ids);
425     }
426 
427     public String toString()
428 	{
429         return ldapurl.getUrl();
430     }
431 
432 // not used for this example
433 
434     public Object lookup(Name name) throws NamingException 
435     {        
436 		throw new OperationNotSupportedException();
437     }
438 
439     public String getNameInNamespace() throws NamingException 
440     {
441         throw new OperationNotSupportedException();
442     }
443 
444     public Object lookup(String name) throws NamingException 
445     {
446         throw new OperationNotSupportedException();
447     }
448 
449     public void bind(Name name, Object obj) throws NamingException 
450     {
451         throw new OperationNotSupportedException();
452     }
453 
454     public void bind(String name, Object obj) throws NamingException 
455     {
456         throw new OperationNotSupportedException();
457     }
458 
459     public void rebind(Name name, Object obj) throws NamingException 
460     {
461         throw new OperationNotSupportedException();
462     }
463 
464     public void rebind(String name, Object obj) throws NamingException 
465     {
466         throw new OperationNotSupportedException();
467     }
468 
469     public void unbind(Name name) throws NamingException 
470     {
471         throw new OperationNotSupportedException();
472     }
473 
474     public void unbind(String name) throws NamingException 
475     {
476         throw new OperationNotSupportedException();
477     }
478 
479     public void rename(Name oldName, Name newName) throws NamingException 
480     {
481         throw new OperationNotSupportedException();
482     }
483 
484     public void rename(String oldName, String newName) throws NamingException 
485     {
486         throw new OperationNotSupportedException();
487     }
488 
489     public NamingEnumeration list(Name name) throws NamingException 
490     {
491         throw new OperationNotSupportedException();
492     }
493 
494     public NamingEnumeration list(String name) throws NamingException 
495     {
496         throw new OperationNotSupportedException();
497     }
498 
499     public NamingEnumeration listBindings(Name name) throws NamingException 
500     {
501         throw new OperationNotSupportedException();
502     }
503 
504     public NamingEnumeration listBindings(String name) throws NamingException 
505     {
506         throw new OperationNotSupportedException();
507     }
508 
509     public void destroySubcontext(Name name) throws NamingException 
510     {
511         throw new OperationNotSupportedException();
512     }
513 
514     public void destroySubcontext(String name) throws NamingException 
515     {
516         throw new OperationNotSupportedException();
517     }
518 
519     public Context createSubcontext(Name name) throws NamingException 
520     {
521         throw new OperationNotSupportedException();
522     }
523 
524     public Context createSubcontext(String name) throws NamingException 
525     {
526         throw new OperationNotSupportedException();
527     }
528 
529     public Object lookupLink(Name name) throws NamingException 
530     {
531         throw new OperationNotSupportedException();
532     }
533 
534     public Object lookupLink(String name) throws NamingException 
535     {
536         throw new OperationNotSupportedException();
537     }
538 
539     public NameParser getNameParser(Name name) throws NamingException 
540     {
541         throw new OperationNotSupportedException();
542     }
543 
544     public NameParser getNameParser(String name) throws NamingException 
545     {
546         throw new OperationNotSupportedException();
547     }
548 
549     public String composeName(String name, String prefix)
550                 throws NamingException 
551     {
552         throw new OperationNotSupportedException();
553     }
554 
555     public Name composeName(Name name, Name prefix)
556                 throws NamingException 
557     {
558         throw new OperationNotSupportedException();
559     }
560 
561     public Object addToEnvironment(String propName, Object propVal)
562         throws NamingException 
563     {
564         throw new OperationNotSupportedException();
565     }
566 
567     public Object removeFromEnvironment(String propName)
568         throws NamingException 
569     {
570         throw new OperationNotSupportedException();
571     }
572 
573     public Hashtable getEnvironment() throws NamingException 
574     {
575         throw new OperationNotSupportedException();
576     }
577 
578     public void close() throws NamingException 
579     {
580         throw new OperationNotSupportedException();
581     }
582 
583 // -- DirContext
584 
585     public void modifyAttributes(Name name, int mod_op, Attributes attrs)
586         throws NamingException    
587     {
588         throw new OperationNotSupportedException();
589     }
590 
591     public void modifyAttributes(String name, int mod_op, Attributes attrs)
592         throws NamingException    
593     {
594         throw new OperationNotSupportedException();
595     }
596 
597     public void modifyAttributes(Name name, ModificationItem[] mods)
598         throws NamingException    
599     {
600         throw new OperationNotSupportedException();
601     }
602 
603     public void modifyAttributes(String name, ModificationItem[] mods)
604         throws NamingException    
605     {
606         throw new OperationNotSupportedException();
607     }
608 
609     public void bind(Name name, Object obj, Attributes attrs)
610         throws NamingException    
611     {
612         throw new OperationNotSupportedException();
613     }
614 
615     public void bind(String name, Object obj, Attributes attrs)
616         throws NamingException    
617     {
618         throw new OperationNotSupportedException();
619     }
620 
621     public void rebind(Name name, Object obj, Attributes attrs)
622         throws NamingException    
623     {
624         throw new OperationNotSupportedException();
625     }
626 
627     public void rebind(String name, Object obj, Attributes attrs)
628         throws NamingException    
629     {
630         throw new OperationNotSupportedException();
631     }
632 
633     public DirContext createSubcontext(Name name, Attributes attrs)
634         throws NamingException    
635     {
636         throw new OperationNotSupportedException();
637     }
638 
639     public DirContext createSubcontext(String name, Attributes attrs)
640         throws NamingException    
641     {
642         throw new OperationNotSupportedException();
643     }
644 
645     public DirContext getSchema(Name name) throws NamingException    
646     {
647         throw new OperationNotSupportedException();
648     }
649 
650     public DirContext getSchema(String name) throws NamingException    
651     {
652         throw new OperationNotSupportedException();
653     }
654 
655     public DirContext getSchemaClassDefinition(Name name)
656         throws NamingException    
657     {
658         throw new OperationNotSupportedException();
659     }
660 
661     public DirContext getSchemaClassDefinition(String name)
662         throws NamingException    
663     {
664         throw new OperationNotSupportedException();
665     }
666 
667     public NamingEnumeration search(Name name,
668                                     Attributes matchingAttributes,
669                                     String[] attributesToReturn)
670         throws NamingException    
671     {
672         throw new OperationNotSupportedException();
673     }
674 
675     public NamingEnumeration search(String name,
676                                     Attributes matchingAttributes,
677                                     String[] attributesToReturn)
678         throws NamingException    
679     {
680         throw new OperationNotSupportedException();
681     }
682 
683     public NamingEnumeration search(Name name,
684                                     Attributes matchingAttributes)
685         throws NamingException    
686     {
687         throw new OperationNotSupportedException();
688     }
689 
690     public NamingEnumeration search(String name,
691                                     Attributes matchingAttributes)
692         throws NamingException    
693     {
694         throw new OperationNotSupportedException();
695     }
696     public NamingEnumeration search(Name name,
697                                     String filter,
698                                     SearchControls cons)
699         throws NamingException    
700     {
701         throw new OperationNotSupportedException();
702     }
703 
704     public NamingEnumeration search(String name,
705                                     String filter,
706                                     SearchControls cons)
707         throws NamingException    
708     {
709         throw new OperationNotSupportedException();
710 	}
711 
712     public NamingEnumeration search(Name name,
713                                     String filterExpr,
714                                     Object[] filterArgs,
715                                     SearchControls cons)
716         throws NamingException    
717     {
718         throw new OperationNotSupportedException();
719 	}
720 
721     public NamingEnumeration search(String name,
722                                     String filterExpr,
723                                     Object[] filterArgs,
724                                     SearchControls cons)
725         throws NamingException    
726     {
727 		throw new OperationNotSupportedException();
728 	}
729 
730 }