mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Nicolas Capponi
12.29.2015 407bb81fb935e713a4a1ae1b9189b81488a944d5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
 * or http://forgerock.org/license/CDDLv1.0.html.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at legal-notices/CDDLv1_0.txt.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Copyright 2006-2010 Sun Microsystems, Inc.
 *      Portions Copyright 2011-2014 ForgeRock AS
 */
package org.opends.server.api;
import org.forgerock.i18n.LocalizableMessage;
 
 
 
 
import java.util.HashSet;
import java.util.List;
import java.util.Set;
 
import org.opends.server.admin.std.server.GroupImplementationCfg;
import org.opends.server.core.ServerContext;
import org.forgerock.opendj.config.server.ConfigException;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.InitializationException;
import org.opends.server.types.MemberList;
import org.opends.server.types.SearchFilter;
import org.forgerock.opendj.ldap.SearchScope;
 
 
 
/**
 * This class defines the set of methods that must be implemented by a
 * Directory Server group.  It is expected that there will be a number
 * of different types of groups (e.g., legacy static and dynamic
 * groups, as well as enhanced groups and virtual static groups).  The
 * following operations may be performed on an OpenDS group:
 * <UL>
 *   <LI>Determining whether a given user is a member of this
 *       group</LI>
 *   <LI>Determining the set of members for this group, optionally
 *       filtered based on some set of criteria.</LI>
 *   <LI>Retrieving or updating the set of nested groups for this
 *       group, if the underlying group type supports nesting).</LI>
 *   <LI>Updating the set of members for this group, if the underlying
 *       group type provides the ability to explicitly add or remove
 *       members.</LI>
 * </UL>
 *
 * @param  <T>  The type of configuration handled by this group
 *              implementation.
 */
@org.opends.server.types.PublicAPI(
     stability=org.opends.server.types.StabilityLevel.VOLATILE,
     mayInstantiate=false,
     mayExtend=true,
     mayInvoke=true)
public abstract class Group<T extends GroupImplementationCfg>
{
  /**
   * Initializes a "shell" instance of this group implementation that
   * may be used to identify and instantiate instances of this type of
   * group in the directory data.
   *
   * @param  configuration  The configuration for this group
   *                        implementation.
   *
   * @throws  ConfigException  If there is a problem with the provided
   *                           configuration entry.
   *
   * @throws  InitializationException  If a problem occurs while
   *                                   attempting to initialize this
   *                                   group implementation that is
   *                                   not related to the server
   *                                   configuration.
   */
  public abstract void initializeGroupImplementation(T configuration)
         throws ConfigException, InitializationException;
 
 
 
  /**
   * Indicates whether the provided configuration is acceptable for
   * this group implementation.  It should be possible to call this
   * method on an uninitialized group implementation instance in order
   * to determine whether the group implementation would be able to
   * use the provided configuration.
   * <BR><BR>
   * Note that implementations which use a subclass of the provided
   * configuration class will likely need to cast the configuration
   * to the appropriate subclass type.
   *
   * @param  configuration        The group implementation
   *                              configuration for which to make the
   *                              determination.
   * @param  unacceptableReasons  A list that may be used to hold the
   *                              reasons that the provided
   *                              configuration is not acceptable.
   *
   * @return  {@code true} if the provided configuration is acceptable
   *          for this group implementation, or {@code false} if not.
   */
  public boolean isConfigurationAcceptable(
                      GroupImplementationCfg configuration,
                      List<LocalizableMessage> unacceptableReasons)
  {
    // This default implementation does not perform any special
    // validation.  It should be overridden by group implementations
    // that wish to perform more detailed validation.
    return true;
  }
 
 
 
  /**
   * Performs any necessary finalization that may be needed whenever
   * this group implementation is taken out of service within the
   * Directory Server (e.g., if it is disabled or the server is
   * shutting down).
   */
  public void finalizeGroupImplementation()
  {
    // No implementation is required by default.
  }
 
 
 
  /**
   * Creates a new group of this type based on the definition
   * contained in the provided entry.  This method must be designed so
   * that it may be invoked on the "shell" instance created using the
   * default constructor and initialized with the
   * {@code initializeGroupImplementation} method.
   *
   * @param serverContext
   *            The server context.
   * @param  groupEntry  The entry containing the definition for the
   *                     group to be created.
   *
   * @return  The group instance created from the definition in the
   *          provided entry.
   *
   * @throws  DirectoryException  If a problem occurs while trying to
   *                              create the group instance.
   */
  public abstract Group<T> newInstance(ServerContext serverContext, Entry groupEntry)
         throws DirectoryException;
 
 
 
  /**
   * Retrieves a search filter that may be used to identify entries
   * containing definitions for groups of this type in the Directory
   * Server.  This method must be designed so that it may be invoked
   * on the "shell" instance created using the default constructor and
   * initialized with the {@code initializeGroupImplementation}
   * method.
   *
   * @return  A search filter that may be used to identify entries
   *          containing definitions for groups of this type in the
   *          Directory Server.
   *
   * @throws  DirectoryException  If a problem occurs while trying to
   *                              locate all of the applicable group
   *                              definition entries.
   */
  public abstract SearchFilter getGroupDefinitionFilter()
         throws DirectoryException;
 
 
 
  /**
   * Indicates whether the provided entry contains a valid definition
   * for this type of group.
   *
   * @param  entry  The entry for which to make the determination.
   *
   * @return  {@code true} if the provided entry does contain a valid
   *          definition for this type of group, or {@code false} if
   *          it does not.
   */
  public abstract boolean isGroupDefinition(Entry entry);
 
 
 
  /**
   * Retrieves the DN of the entry that contains the definition for
   * this group.
   *
   * @return  The DN of the entry that contains the definition for
   *          this group.
   */
  public abstract DN getGroupDN();
 
 
 
  /**
   * Sets the DN of the entry that contains the definition for
   * this group.
   *
   * @param  groupDN  The DN of the entry that contains the
   *                  definition for this group.
   */
  public abstract void setGroupDN(DN groupDN);
 
 
 
  /**
   * Indicates whether this group supports nesting other groups, such
   * that the members of the nested groups will also be considered
   * members of this group.
   *
   * @return  {@code true} if this group supports nesting other
   *          groups, or {@code false} if it does not.
   */
  public abstract boolean supportsNestedGroups();
 
 
 
  /**
   * Retrieves a list of the DNs of any nested groups whose members
   * should be considered members of this group.
   *
   * @return  A list of the DNs of any nested groups whose members
   *          should be considered members of this group.
   */
  public abstract List<DN> getNestedGroupDNs();
 
 
 
  /**
   * Attempts to add the provided group DN as a nested group within
   * this group.  The change should be committed to persistent storage
   * through an internal operation.
   *
   * @param  nestedGroupDN  The DN of the group that should be added
   *                        to the set of nested groups for this
   *                        group.
   *
   * @throws  UnsupportedOperationException  If this group does not
   *                                         support nesting.
   *
   * @throws  DirectoryException  If a problem occurs while attempting
   *                              to nest the provided group DN.
   */
  public abstract void addNestedGroup(DN nestedGroupDN)
         throws UnsupportedOperationException, DirectoryException;
 
 
 
  /**
   * Attempts to remove the provided group as a nested group within
   * this group.  The change should be committed to persistent storage
   * through an internal operation.
   *
   * @param  nestedGroupDN  The DN of the group that should be removed
   *                        from the set of nested groups for this
   *                        group.
   *
   * @throws  UnsupportedOperationException  If this group does not
   *                                         support nesting.
   *
   * @throws  DirectoryException  If a problem occurs while attempting
   *                              to nest the provided group DN.
   */
  public abstract void removeNestedGroup(DN nestedGroupDN)
         throws UnsupportedOperationException, DirectoryException;
 
 
 
  /**
   * Indicates whether the user with the specified DN is a member of
   * this group.  Note that this is a point-in-time determination and
   * the caller must not cache the result.
   *
   * @param  userDN  The DN of the user for which to make the
   *                 determination.
   *
   * @return  {@code true} if the specified user is currently a member
   *          of this group, or {@code false} if not.
   *
   * @throws  DirectoryException  If a problem occurs while attempting
   *                              to make the determination.
   */
  public boolean isMember(DN userDN)
         throws DirectoryException
  {
    if (userDN != null)
      return isMember(userDN, new HashSet<DN>());
    return false;
  }
 
 
 
  /**
   * Indicates whether the user with the specified DN is a member of
   * this group.  Note that this is a point-in-time determination and
   * the caller must not cache the result.  Also note that group
   * implementations that support nesting should use this version of
   * the method rather than the version that does not take a set of
   * DNs when attempting to determine whether a nested group includes
   * the target member.
   *
   * @param  userDN          The DN of the user for which to make the
   *                         determination.
   * @param  examinedGroups  A set of groups that have already been
   *                         examined in the process of making the
   *                         determination.  This provides a mechanism
   *                         to prevent infinite recursion due to
   *                         circular references (e.g., two groups
   *                         include each other as nested groups).
   *                         Each time a group instance is checked,
   *                         its DN should be added to the list, and
   *                         any DN already contained in the list
   *                         should be skipped.
   *
   * @return  {@code true} if the specified user is currently a member
   *          of this group, or {@code false} if not.
   *
   * @throws  DirectoryException  If a problem occurs while attempting
   *                              to make the determination.
   */
  public abstract boolean isMember(DN userDN, Set<DN> examinedGroups)
         throws DirectoryException;
 
 
 
  /**
   * Indicates whether the user described by the provided user entry
   * is a member of this group.  Note that this is a point-in-time
   * determination and the caller must not cache the result.
   *
   * @param  userEntry  The entry for the user for which to make the
   *                    determination.
   *
   * @return  {@code true} if the specified user is currently a member
   *          of this group, or {@code false} if not.
   *
   * @throws  DirectoryException  If a problem occurs while attempting
   *                              to make the determination.
   */
  public boolean isMember(Entry userEntry)
         throws DirectoryException
  {
    return isMember(userEntry, new HashSet<DN>());
  }
 
 
 
  /**
   * Indicates whether the user described by the provided user entry
   * is a member of this group.  Note that this is a point-in-time
   * determination and the caller must not cache the result.  Also
   * note that group implementations that support nesting should use
   * this version of the method rather than the version that does not
   * take a set of DNs when attempting to determine whether a nested
   * group includes the target member.
   *
   * @param  userEntry       The entry for the user for which to make
   *                         the determination.
   * @param  examinedGroups  A set of groups that have already been
   *                         examined in the process of making the
   *                         determination.  This provides a mechanism
   *                         to prevent infinite recursion due to
   *                         circular references (e.g., two groups
   *                         include each other as nested groups).
   *                         Each time a group instance is checked,
   *                         its DN should be added to the list, and
   *                         any DN already contained in the list
   *                         should be skipped.
   *
   * @return  {@code true} if the specified user is currently a member
   *          of this group, or {@code false} if not.
   *
   * @throws  DirectoryException  If a problem occurs while attempting
   *                              to make the determination.
   */
  public abstract boolean isMember(Entry userEntry,
                                   Set<DN> examinedGroups)
         throws DirectoryException;
 
 
 
  /**
   * Retrieves an iterator that may be used to cursor through the
   * entries of the members contained in this group.  Note that this
   * is a point-in-time determination, and the caller must not cache
   * the result.  Further, the determination should only include this
   * group and not members from nested groups.
   *
   * @return  An iterator that may be used to cursor through the
   *          entries of the members contained in this group.
   *
   * @throws  DirectoryException  If a problem occurs while attempting
   *                              to retrieve the set of members.
   */
  public MemberList getMembers()
         throws DirectoryException
  {
    return getMembers(null, null, null);
  }
 
 
 
  /**
   * Retrieves an iterator that may be used to cursor through the
   * entries of the members contained in this group.  It may
   * optionally retrieve a subset of the member entries based on a
   * given set of criteria.  Note that this is a point-in-time
   * determination, and the caller must not cache the result.
   *
   * @param  baseDN  The base DN that should be used when determining
   *                 whether a given entry will be returned.  If this
   *                 is {@code null}, then all entries will be
   *                 considered in the scope of the criteria.
   * @param  scope   The scope that should be used when determining
   *                 whether a given entry will be returned.  It must
   *                 not be {@code null} if the provided base DN is
   *                 not {@code null}.  The scope will be ignored if
   *                 no base DN is provided.
   * @param  filter  The filter that should be used when determining
   *                 whether a given entry will be returned.  If this
   *                 is {@code null}, then any entry in the scope of
   *                 the criteria will be included in the results.
   *
   * @return  An iterator that may be used to cursor through the
   *          entries of the members contained in this group.
   *
   * @throws  DirectoryException  If a problem occurs while attempting
   *                              to retrieve the set of members.
   */
  public abstract MemberList getMembers(DN baseDN, SearchScope scope,
                                        SearchFilter filter)
         throws DirectoryException;
 
 
 
  /**
   * Indicates whether it is possible to alter the member list for
   * this group (e.g., in order to add members to the group or remove
   * members from it).
   *
   * @return  {@code true} if it is possible to add members to this
   *          group, or {@code false} if not.
   */
  public abstract boolean mayAlterMemberList();
 
 
 
  /**
   * Attempts to add the provided user as a member of this group.  The
   * change should be committed to persistent storage through an
   * internal operation.
   *
   * @param  userEntry  The entry for the user to be added as a member
   *                    of this group.
   *
   * @throws  UnsupportedOperationException  If this group does not
   *                                         support altering the
   *                                         member list.
   *
   * @throws  DirectoryException  If a problem occurs while attempting
   *                              to add the provided user as a member
   *                              of this group.
   */
  public abstract void addMember(Entry userEntry)
         throws UnsupportedOperationException, DirectoryException;
 
 
 
  /**
   * Attempts to remove the specified user as a member of this group.
   * The change should be committed to persistent storage through an
   * internal operation.
   *
   * @param  userDN  The DN of the user to remove as a member of this
   *                 group.
   *
   * @throws  UnsupportedOperationException  If this group does not
   *                                         support altering the
   *                                         member list.
   *
   * @throws  DirectoryException  If a problem occurs while attempting
   *                              to remove the provided user as a
   *                              member of this group.
   */
  public abstract void removeMember(DN userDN)
         throws UnsupportedOperationException, DirectoryException;
 
 
 
  /**
   * Retrieves a string representation of this group.
   *
   * @return  A string representation of this group.
   */
  public String toString()
  {
    StringBuilder buffer = new StringBuilder();
    toString(buffer);
    return buffer.toString();
  }
 
 
 
  /**
   * Appends a string representation of this group to the provided
   * buffer.
   *
   * @param  buffer  The buffer to which the string representation
   *                 should be appended.
   */
  public abstract void toString(StringBuilder buffer);
}