View Javadoc

1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *  
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *  
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License. 
18   *  
19   */
20  package org.apache.directory.server.core.interceptor.context;
21   
22  
23  import java.util.Collection;
24  import java.util.Collections;
25  import java.util.HashMap;
26  import java.util.List;
27  import java.util.Map;
28  
29  import javax.naming.ldap.Control;
30  
31  import org.apache.commons.lang.NotImplementedException;
32  import org.apache.directory.server.core.CoreSession;
33  import org.apache.directory.server.core.ReferralHandlingMode;
34  import org.apache.directory.server.core.authn.LdapPrincipal;
35  import org.apache.directory.server.core.entry.ClonedServerEntry;
36  import org.apache.directory.server.core.entry.ServerEntry;
37  import org.apache.directory.shared.ldap.constants.AuthenticationLevel;
38  import org.apache.directory.shared.ldap.entry.Modification;
39  import org.apache.directory.shared.ldap.message.MessageTypeEnum;
40  import org.apache.directory.shared.ldap.name.LdapDN;
41  import org.apache.directory.shared.ldap.util.StringTools;
42  
43  
44  /**
45   * A Bind context used for Interceptors. It contains all the informations
46   * needed for the bind operation, and used by all the interceptors
47   *
48   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
49   * @version $Rev$, $Date$
50   */
51  public class BindOperationContext implements OperationContext
52  {
53      /** The password */
54      private byte[] credentials;
55  
56      /** The SASL mechanism */
57      private String saslMechanism;
58      
59      /** The SASL identifier */
60      private String saslAuthId;
61      
62      private static final Control[] EMPTY_CONTROLS = new Control[0];
63  
64      /** The DN associated with the context */
65      private LdapDN dn;
66      
67      /** The associated request's controls */
68      private Map<String, Control> requestControls = new HashMap<String, Control>(4);
69  
70      /** The associated response's controls */
71      private Map<String, Control> responseControls = new HashMap<String, Control>(4);
72  
73      /** A flag to tell that this is a collateral operation */
74      private boolean collateralOperation;
75      
76      /** the Interceptors bypassed by this operation */
77      private Collection<String> bypassed;
78      
79      private CoreSession session;
80      
81      private LdapPrincipal authorizedPrincipal;
82      
83      private OperationContext next;
84      
85      private OperationContext previous;
86  
87      private ReferralHandlingMode referralHandlingMode;
88  
89      private ClonedServerEntry entry;
90  
91      
92      /**
93       * Creates a new instance of BindOperationContext.
94       */
95      public BindOperationContext( CoreSession session )
96      {
97          this.session = session;
98      }
99  
100     
101     /**
102      * @return The authentication level. One of :
103      * <li>ANONYMOUS</li>
104      * <li>SIMPLE</li>
105      * <li>STRONG (sasl)</li>
106      * <li>INVALID</li>
107      */
108     public AuthenticationLevel getAuthenticationLevel()
109     {
110         if ( ( saslMechanism == null ) )
111         {
112         	if ( dn.isEmpty() )
113         	{
114         		if ( StringTools.isEmpty( credentials ) )
115         		{
116         			// Dn and Credentials are empty, this is an anonymous authent
117         			return AuthenticationLevel.NONE;
118         		}
119         		else
120         		{
121         			// If we have a password but no DN, this is invalid 
122         			return AuthenticationLevel.INVALID;
123         		}
124         	}
125         	else if ( StringTools.isEmpty( credentials ) )
126         	{
127         		return AuthenticationLevel.UNAUTHENT;
128         	}
129         	else
130         	{
131         		return AuthenticationLevel.SIMPLE;
132         	}
133         }
134         else
135         {
136             return AuthenticationLevel.STRONG;
137         }
138     }
139     
140     
141     /**
142      * @return the SASL mechanisms
143      */
144     public String getSaslMechanism()
145     {
146         return saslMechanism;
147     }
148 
149     
150     public void setSaslMechanism( String saslMechanism )
151     {
152         this.saslMechanism = saslMechanism;
153     }
154 
155     
156     /**
157      * @return The principal password
158      */
159     public byte[] getCredentials()
160     {
161         return credentials;
162     }
163 
164     
165     public void setCredentials( byte[] credentials )
166     {
167         this.credentials = credentials;
168     }
169 
170     
171     /**
172      * @return The SASL authentication ID
173      */
174     public String getSaslAuthId()
175     {
176         return saslAuthId;
177     }
178 
179 
180     public void setSaslAuthId( String saslAuthId )
181     {
182         this.saslAuthId = saslAuthId;
183     }
184     
185     
186     public boolean isSaslBind()
187     {
188         return saslMechanism != null;
189     }
190     
191     
192     /**
193      * @return the operation name
194      */
195     public String getName()
196     {
197         return MessageTypeEnum.BIND_REQUEST.name();
198     }
199 
200 
201     /**
202      * @see Object#toString()
203      */
204     public String toString()
205     {
206         return "BindContext for DN '" + getDn().getUpName() + "', credentials <" +
207             ( credentials != null ? StringTools.dumpBytes( credentials ) : "" ) + ">" +
208             ( saslMechanism != null ? ", saslMechanism : <" + saslMechanism + ">" : "" ) +
209             ( saslAuthId != null ? ", saslAuthId <" + saslAuthId + ">" : "" );
210     }
211 
212 
213     public CoreSession getSession()
214     {
215         return session;
216     }
217     
218     
219     public void setSession( CoreSession session )
220     {
221         this.session = session;
222     }
223 
224 
225     /**
226      * Tells if the current operation is considered a side effect of the
227      * current context
228      */
229     public boolean isCollateralOperation()
230     {
231         return collateralOperation;
232     }
233 
234 
235     public void setCollateralOperation( boolean collateralOperation )
236     {
237         this.collateralOperation = collateralOperation;
238     }
239 
240 
241     /**
242      * @return The associated DN
243      */
244     public LdapDN getDn()
245     {
246         return dn;
247     }
248 
249     
250     /**
251      * Set the context DN
252      *
253      * @param dn The DN to set
254      */
255     public void setDn( LdapDN dn )
256     {
257         this.dn = dn;
258     }
259 
260     
261     public void addRequestControl( Control requestControl )
262     {
263         requestControls.put( requestControl.getID(), requestControl );
264     }
265 
266     
267     public Control getRequestControl( String numericOid )
268     {
269         return requestControls.get( numericOid );
270     }
271 
272     
273     public boolean hasRequestControl( String numericOid )
274     {
275         return requestControls.containsKey( numericOid );
276     }
277 
278     
279     public boolean hasRequestControls()
280     {
281         return ! requestControls.isEmpty();
282     }
283 
284 
285     public void addResponseControl( Control responseControl )
286     {
287         responseControls.put( responseControl.getID(), responseControl );
288     }
289 
290 
291     public Control getResponseControl( String numericOid )
292     {
293         return responseControls.get( numericOid );
294     }
295 
296 
297     public boolean hasResponseControl( String numericOid )
298     {
299         return responseControls.containsKey( numericOid );
300     }
301 
302 
303     public Control[] getResponseControls()
304     {
305         if ( responseControls.isEmpty() )
306         {
307             return EMPTY_CONTROLS;
308         }
309         
310         return responseControls.values().toArray( EMPTY_CONTROLS );
311     }
312 
313 
314     public boolean hasResponseControls()
315     {
316         return ! responseControls.isEmpty();
317     }
318 
319 
320     public int getResponseControlCount()
321     {
322         return responseControls.size();
323     }
324 
325 
326     public void addRequestControls( Control[] requestControls )
327     {
328         for ( Control c : requestControls )
329         {
330             this.requestControls.put( c.getID(), c );
331         }
332     }
333 
334 
335     /**
336      * Gets the set of bypassed Interceptors.
337      *
338      * @return the set of bypassed Interceptors
339      */
340     public Collection<String> getByPassed()
341     {
342         if ( bypassed == null )
343         {
344             return Collections.emptyList();
345         }
346         
347         return Collections.unmodifiableCollection( bypassed );
348     }
349     
350     
351     /**
352      * Sets the set of bypassed Interceptors.
353      * 
354      * @param byPassed the set of bypassed Interceptors
355      */
356     public void setByPassed( Collection<String> byPassed )
357     {
358         this.bypassed = byPassed;
359     }
360 
361     
362     /**
363      * Checks to see if an Interceptor is bypassed for this operation.
364      *
365      * @param interceptorName the interceptorName of the Interceptor to check for bypass
366      * @return true if the Interceptor should be bypassed, false otherwise
367      */
368     public boolean isBypassed( String interceptorName )
369     {
370         return bypassed != null && bypassed.contains( interceptorName );
371     }
372 
373 
374     /**
375      * Checks to see if any Interceptors are bypassed by this operation.
376      *
377      * @return true if at least one bypass exists
378      */
379     public boolean hasBypass()
380     {
381         return bypassed != null && !bypassed.isEmpty();
382     }
383     
384     
385     public LookupOperationContext newLookupContext( LdapDN dn )
386     {
387         return new LookupOperationContext( session, dn );
388     }
389 
390 
391     public ClonedServerEntry lookup( LookupOperationContext opContext ) throws Exception
392     {
393         return session.getDirectoryService().getOperationManager().lookup( opContext );
394     }
395 
396 
397     public ClonedServerEntry lookup( LdapDN dn, Collection<String> byPassed ) throws Exception
398     {
399         LookupOperationContext opContext = newLookupContext( dn );
400         opContext.setByPassed( byPassed );
401         return session.getDirectoryService().getOperationManager().lookup( opContext );
402     }
403 
404 
405     public LdapPrincipal getEffectivePrincipal()
406     {
407         if ( authorizedPrincipal != null )
408         {
409             return authorizedPrincipal;
410         }
411         
412         return session.getEffectivePrincipal();
413     }
414     
415     
416     // -----------------------------------------------------------------------
417     // OperationContext Linked List Methods
418     // -----------------------------------------------------------------------
419     
420     
421     public boolean isFirstOperation()
422     {
423         return previous == null;
424     }
425     
426     
427     public OperationContext getFirstOperation()
428     {
429         if ( previous == null )
430         {
431             return this;
432         }
433         
434         return previous.getFirstOperation();
435     }
436     
437     
438     public OperationContext getLastOperation()
439     {
440         if ( next == null )
441         {
442             return this;
443         }
444         
445         return next.getLastOperation();
446     }
447     
448     
449     public OperationContext getNextOperation()
450     {
451         return next;
452     }
453     
454     
455     public OperationContext getPreviousOperation()
456     {
457         return previous;
458     }
459 
460 
461     public void add( ServerEntry entry, Collection<String> bypass ) throws Exception
462     {
463         throw new NotImplementedException();
464     }
465 
466 
467     public void delete( LdapDN dn, Collection<String> bypass ) throws Exception
468     {
469         throw new NotImplementedException();
470     }
471 
472 
473     public void modify( LdapDN dn, List<Modification> mods, Collection<String> bypass ) throws Exception
474     {
475         throw new NotImplementedException();
476     }
477 
478 
479     private void setup( AbstractOperationContext opContext )
480     {
481         opContext.setPreviousOperation( this );
482         next = opContext;
483         opContext.setByPassed( opContext.getByPassed() );
484         opContext.setAuthorizedPrincipal( authorizedPrincipal );
485     }
486     
487     
488     public boolean hasEntry( LdapDN dn, Collection<String> byPassed ) throws Exception
489     {
490         EntryOperationContext opContext = new EntryOperationContext( session, dn );
491         setup( opContext );
492         opContext.setByPassed( byPassed );
493         return session.getDirectoryService().getOperationManager().hasEntry( opContext );
494     }
495 
496 
497     public ReferralHandlingMode getReferralHandlingMode()
498     {
499         return referralHandlingMode;
500     }
501 
502 
503     public void setReferralHandlingMode( ReferralHandlingMode referralHandlingMode )
504     {
505         this.referralHandlingMode = referralHandlingMode;
506     }
507 
508 
509     public ClonedServerEntry getEntry()
510     {
511         return entry;
512     }
513 
514 
515     public void setEntry( ClonedServerEntry entry )
516     {
517         this.entry = entry;
518     }
519 }