001/*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License").  You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
010 * or http://forgerock.org/license/CDDLv1.0.html.
011 * See the License for the specific language governing permissions
012 * and limitations under the License.
013 *
014 * When distributing Covered Code, include this CDDL HEADER in each
015 * file and include the License file at legal-notices/CDDLv1_0.txt.
016 * If applicable, add the following below this CDDL HEADER, with the
017 * fields enclosed by brackets "[]" replaced with your own identifying
018 * information:
019 *      Portions Copyright [yyyy] [name of copyright owner]
020 *
021 * CDDL HEADER END
022 *
023 *
024 *      Copyright 2008 Sun Microsystems, Inc.
025 */
026package org.forgerock.opendj.server.config.meta;
027
028
029
030import java.util.Collection;
031import java.util.SortedSet;
032import org.forgerock.opendj.config.AdministratorAction;
033import org.forgerock.opendj.config.AliasDefaultBehaviorProvider;
034import org.forgerock.opendj.config.BooleanPropertyDefinition;
035import org.forgerock.opendj.config.ClassPropertyDefinition;
036import org.forgerock.opendj.config.client.ConcurrentModificationException;
037import org.forgerock.opendj.config.client.ManagedObject;
038import org.forgerock.opendj.config.client.MissingMandatoryPropertiesException;
039import org.forgerock.opendj.config.client.OperationRejectedException;
040import org.forgerock.opendj.config.conditions.Conditions;
041import org.forgerock.opendj.config.DefaultBehaviorProvider;
042import org.forgerock.opendj.config.DefinedDefaultBehaviorProvider;
043import org.forgerock.opendj.config.GenericConstraint;
044import org.forgerock.opendj.config.IntegerPropertyDefinition;
045import org.forgerock.opendj.config.ManagedObjectAlreadyExistsException;
046import org.forgerock.opendj.config.ManagedObjectDefinition;
047import org.forgerock.opendj.config.PropertyOption;
048import org.forgerock.opendj.config.PropertyProvider;
049import org.forgerock.opendj.config.server.ConfigurationChangeListener;
050import org.forgerock.opendj.config.server.ServerManagedObject;
051import org.forgerock.opendj.config.StringPropertyDefinition;
052import org.forgerock.opendj.config.Tag;
053import org.forgerock.opendj.config.UndefinedDefaultBehaviorProvider;
054import org.forgerock.opendj.ldap.DN;
055import org.forgerock.opendj.ldap.LdapException;
056import org.forgerock.opendj.server.config.client.CharacterSetPasswordValidatorCfgClient;
057import org.forgerock.opendj.server.config.server.CharacterSetPasswordValidatorCfg;
058import org.forgerock.opendj.server.config.server.PasswordValidatorCfg;
059
060
061
062/**
063 * An interface for querying the Character Set Password Validator
064 * managed object definition meta information.
065 * <p>
066 * The Character Set Password Validator determines whether a proposed
067 * password is acceptable by checking whether it contains a sufficient
068 * number of characters from one or more user-defined character sets
069 * and ranges.
070 */
071public final class CharacterSetPasswordValidatorCfgDefn extends ManagedObjectDefinition<CharacterSetPasswordValidatorCfgClient, CharacterSetPasswordValidatorCfg> {
072
073  // The singleton configuration definition instance.
074  private static final CharacterSetPasswordValidatorCfgDefn INSTANCE = new CharacterSetPasswordValidatorCfgDefn();
075
076
077
078  // The "allow-unclassified-characters" property definition.
079  private static final BooleanPropertyDefinition PD_ALLOW_UNCLASSIFIED_CHARACTERS;
080
081
082
083  // The "character-set" property definition.
084  private static final StringPropertyDefinition PD_CHARACTER_SET;
085
086
087
088  // The "character-set-ranges" property definition.
089  private static final StringPropertyDefinition PD_CHARACTER_SET_RANGES;
090
091
092
093  // The "java-class" property definition.
094  private static final ClassPropertyDefinition PD_JAVA_CLASS;
095
096
097
098  // The "min-character-sets" property definition.
099  private static final IntegerPropertyDefinition PD_MIN_CHARACTER_SETS;
100
101
102
103  // Build the "allow-unclassified-characters" property definition.
104  static {
105      BooleanPropertyDefinition.Builder builder = BooleanPropertyDefinition.createBuilder(INSTANCE, "allow-unclassified-characters");
106      builder.setOption(PropertyOption.MANDATORY);
107      builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "allow-unclassified-characters"));
108      builder.setDefaultBehaviorProvider(new UndefinedDefaultBehaviorProvider<Boolean>());
109      PD_ALLOW_UNCLASSIFIED_CHARACTERS = builder.getInstance();
110      INSTANCE.registerPropertyDefinition(PD_ALLOW_UNCLASSIFIED_CHARACTERS);
111  }
112
113
114
115  // Build the "character-set" property definition.
116  static {
117      StringPropertyDefinition.Builder builder = StringPropertyDefinition.createBuilder(INSTANCE, "character-set");
118      builder.setOption(PropertyOption.MULTI_VALUED);
119      builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "character-set"));
120      builder.setDefaultBehaviorProvider(new AliasDefaultBehaviorProvider<String>(INSTANCE, "character-set"));
121      builder.setCaseInsensitive(false);
122      PD_CHARACTER_SET = builder.getInstance();
123      INSTANCE.registerPropertyDefinition(PD_CHARACTER_SET);
124  }
125
126
127
128  // Build the "character-set-ranges" property definition.
129  static {
130      StringPropertyDefinition.Builder builder = StringPropertyDefinition.createBuilder(INSTANCE, "character-set-ranges");
131      builder.setOption(PropertyOption.MULTI_VALUED);
132      builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "character-set-ranges"));
133      builder.setDefaultBehaviorProvider(new AliasDefaultBehaviorProvider<String>(INSTANCE, "character-set-ranges"));
134      builder.setCaseInsensitive(false);
135      PD_CHARACTER_SET_RANGES = builder.getInstance();
136      INSTANCE.registerPropertyDefinition(PD_CHARACTER_SET_RANGES);
137  }
138
139
140
141  // Build the "java-class" property definition.
142  static {
143      ClassPropertyDefinition.Builder builder = ClassPropertyDefinition.createBuilder(INSTANCE, "java-class");
144      builder.setOption(PropertyOption.MANDATORY);
145      builder.setOption(PropertyOption.ADVANCED);
146      builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.COMPONENT_RESTART, INSTANCE, "java-class"));
147      DefaultBehaviorProvider<String> provider = new DefinedDefaultBehaviorProvider<String>("org.opends.server.extensions.CharacterSetPasswordValidator");
148      builder.setDefaultBehaviorProvider(provider);
149      builder.addInstanceOf("org.opends.server.api.PasswordValidator");
150      PD_JAVA_CLASS = builder.getInstance();
151      INSTANCE.registerPropertyDefinition(PD_JAVA_CLASS);
152  }
153
154
155
156  // Build the "min-character-sets" property definition.
157  static {
158      IntegerPropertyDefinition.Builder builder = IntegerPropertyDefinition.createBuilder(INSTANCE, "min-character-sets");
159      builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "min-character-sets"));
160      builder.setDefaultBehaviorProvider(new AliasDefaultBehaviorProvider<Integer>(INSTANCE, "min-character-sets"));
161      PD_MIN_CHARACTER_SETS = builder.getInstance();
162      INSTANCE.registerPropertyDefinition(PD_MIN_CHARACTER_SETS);
163  }
164
165
166
167  // Register the tags associated with this managed object definition.
168  static {
169    INSTANCE.registerTag(Tag.valueOf("user-management"));
170  }
171
172
173
174  // Register the constraints associated with this managed object definition.
175  static {
176    INSTANCE.registerConstraint(new GenericConstraint(INSTANCE, 1, Conditions.or(Conditions.isPresent("character-set"), Conditions.isPresent("character-set-ranges"))));
177  }
178
179
180
181  /**
182   * Get the Character Set Password Validator configuration definition
183   * singleton.
184   *
185   * @return Returns the Character Set Password Validator
186   *         configuration definition singleton.
187   */
188  public static CharacterSetPasswordValidatorCfgDefn getInstance() {
189    return INSTANCE;
190  }
191
192
193
194  /**
195   * Private constructor.
196   */
197  private CharacterSetPasswordValidatorCfgDefn() {
198    super("character-set-password-validator", PasswordValidatorCfgDefn.getInstance());
199  }
200
201
202
203  /**
204   * {@inheritDoc}
205   */
206  public CharacterSetPasswordValidatorCfgClient createClientConfiguration(
207      ManagedObject<? extends CharacterSetPasswordValidatorCfgClient> impl) {
208    return new CharacterSetPasswordValidatorCfgClientImpl(impl);
209  }
210
211
212
213  /**
214   * {@inheritDoc}
215   */
216  public CharacterSetPasswordValidatorCfg createServerConfiguration(
217      ServerManagedObject<? extends CharacterSetPasswordValidatorCfg> impl) {
218    return new CharacterSetPasswordValidatorCfgServerImpl(impl);
219  }
220
221
222
223  /**
224   * {@inheritDoc}
225   */
226  public Class<CharacterSetPasswordValidatorCfg> getServerConfigurationClass() {
227    return CharacterSetPasswordValidatorCfg.class;
228  }
229
230
231
232  /**
233   * Get the "allow-unclassified-characters" property definition.
234   * <p>
235   * Indicates whether this password validator allows passwords to
236   * contain characters outside of any of the user-defined character
237   * sets and ranges.
238   * <p>
239   * If this is "false", then only those characters in the
240   * user-defined character sets and ranges may be used in passwords.
241   * Any password containing a character not included in any character
242   * set or range will be rejected.
243   *
244   * @return Returns the "allow-unclassified-characters" property definition.
245   */
246  public BooleanPropertyDefinition getAllowUnclassifiedCharactersPropertyDefinition() {
247    return PD_ALLOW_UNCLASSIFIED_CHARACTERS;
248  }
249
250
251
252  /**
253   * Get the "character-set" property definition.
254   * <p>
255   * Specifies a character set containing characters that a password
256   * may contain and a value indicating the minimum number of
257   * characters required from that set.
258   * <p>
259   * Each value must be an integer (indicating the minimum required
260   * characters from the set which may be zero, indicating that the
261   * character set is optional) followed by a colon and the characters
262   * to include in that set (for example,
263   * "3:abcdefghijklmnopqrstuvwxyz" indicates that a user password must
264   * contain at least three characters from the set of lowercase ASCII
265   * letters). Multiple character sets can be defined in separate
266   * values, although no character can appear in more than one
267   * character set.
268   *
269   * @return Returns the "character-set" property definition.
270   */
271  public StringPropertyDefinition getCharacterSetPropertyDefinition() {
272    return PD_CHARACTER_SET;
273  }
274
275
276
277  /**
278   * Get the "character-set-ranges" property definition.
279   * <p>
280   * Specifies a character range containing characters that a password
281   * may contain and a value indicating the minimum number of
282   * characters required from that range.
283   * <p>
284   * Each value must be an integer (indicating the minimum required
285   * characters from the range which may be zero, indicating that the
286   * character range is optional) followed by a colon and one or more
287   * range specifications. A range specification is 3 characters: the
288   * first character allowed, a minus, and the last character allowed.
289   * For example, "3:A-Za-z0-9". The ranges in each value should not
290   * overlap, and the characters in each range specification should be
291   * ordered.
292   *
293   * @return Returns the "character-set-ranges" property definition.
294   */
295  public StringPropertyDefinition getCharacterSetRangesPropertyDefinition() {
296    return PD_CHARACTER_SET_RANGES;
297  }
298
299
300
301  /**
302   * Get the "enabled" property definition.
303   * <p>
304   * Indicates whether the password validator is enabled for use.
305   *
306   * @return Returns the "enabled" property definition.
307   */
308  public BooleanPropertyDefinition getEnabledPropertyDefinition() {
309    return PasswordValidatorCfgDefn.getInstance().getEnabledPropertyDefinition();
310  }
311
312
313
314  /**
315   * Get the "java-class" property definition.
316   * <p>
317   * Specifies the fully-qualified name of the Java class that
318   * provides the password validator implementation.
319   *
320   * @return Returns the "java-class" property definition.
321   */
322  public ClassPropertyDefinition getJavaClassPropertyDefinition() {
323    return PD_JAVA_CLASS;
324  }
325
326
327
328  /**
329   * Get the "min-character-sets" property definition.
330   * <p>
331   * Specifies the minimum number of character sets and ranges that a
332   * password must contain.
333   * <p>
334   * This property should only be used in conjunction with optional
335   * character sets and ranges (those requiring zero characters). Its
336   * value must include any mandatory character sets and ranges (those
337   * requiring greater than zero characters). This is useful in
338   * situations where a password must contain characters from mandatory
339   * character sets and ranges, and characters from at least N optional
340   * character sets and ranges. For example, it is quite common to
341   * require that a password contains at least one non-alphanumeric
342   * character as well as characters from two alphanumeric character
343   * sets (lower-case, upper-case, digits). In this case, this property
344   * should be set to 3.
345   *
346   * @return Returns the "min-character-sets" property definition.
347   */
348  public IntegerPropertyDefinition getMinCharacterSetsPropertyDefinition() {
349    return PD_MIN_CHARACTER_SETS;
350  }
351
352
353
354  /**
355   * Managed object client implementation.
356   */
357  private static class CharacterSetPasswordValidatorCfgClientImpl implements
358    CharacterSetPasswordValidatorCfgClient {
359
360    // Private implementation.
361    private ManagedObject<? extends CharacterSetPasswordValidatorCfgClient> impl;
362
363
364
365    // Private constructor.
366    private CharacterSetPasswordValidatorCfgClientImpl(
367        ManagedObject<? extends CharacterSetPasswordValidatorCfgClient> impl) {
368      this.impl = impl;
369    }
370
371
372
373    /**
374     * {@inheritDoc}
375     */
376    public Boolean isAllowUnclassifiedCharacters() {
377      return impl.getPropertyValue(INSTANCE.getAllowUnclassifiedCharactersPropertyDefinition());
378    }
379
380
381
382    /**
383     * {@inheritDoc}
384     */
385    public void setAllowUnclassifiedCharacters(boolean value) {
386      impl.setPropertyValue(INSTANCE.getAllowUnclassifiedCharactersPropertyDefinition(), value);
387    }
388
389
390
391    /**
392     * {@inheritDoc}
393     */
394    public SortedSet<String> getCharacterSet() {
395      return impl.getPropertyValues(INSTANCE.getCharacterSetPropertyDefinition());
396    }
397
398
399
400    /**
401     * {@inheritDoc}
402     */
403    public void setCharacterSet(Collection<String> values) {
404      impl.setPropertyValues(INSTANCE.getCharacterSetPropertyDefinition(), values);
405    }
406
407
408
409    /**
410     * {@inheritDoc}
411     */
412    public SortedSet<String> getCharacterSetRanges() {
413      return impl.getPropertyValues(INSTANCE.getCharacterSetRangesPropertyDefinition());
414    }
415
416
417
418    /**
419     * {@inheritDoc}
420     */
421    public void setCharacterSetRanges(Collection<String> values) {
422      impl.setPropertyValues(INSTANCE.getCharacterSetRangesPropertyDefinition(), values);
423    }
424
425
426
427    /**
428     * {@inheritDoc}
429     */
430    public Boolean isEnabled() {
431      return impl.getPropertyValue(INSTANCE.getEnabledPropertyDefinition());
432    }
433
434
435
436    /**
437     * {@inheritDoc}
438     */
439    public void setEnabled(boolean value) {
440      impl.setPropertyValue(INSTANCE.getEnabledPropertyDefinition(), value);
441    }
442
443
444
445    /**
446     * {@inheritDoc}
447     */
448    public String getJavaClass() {
449      return impl.getPropertyValue(INSTANCE.getJavaClassPropertyDefinition());
450    }
451
452
453
454    /**
455     * {@inheritDoc}
456     */
457    public void setJavaClass(String value) {
458      impl.setPropertyValue(INSTANCE.getJavaClassPropertyDefinition(), value);
459    }
460
461
462
463    /**
464     * {@inheritDoc}
465     */
466    public Integer getMinCharacterSets() {
467      return impl.getPropertyValue(INSTANCE.getMinCharacterSetsPropertyDefinition());
468    }
469
470
471
472    /**
473     * {@inheritDoc}
474     */
475    public void setMinCharacterSets(Integer value) {
476      impl.setPropertyValue(INSTANCE.getMinCharacterSetsPropertyDefinition(), value);
477    }
478
479
480
481    /**
482     * {@inheritDoc}
483     */
484    public ManagedObjectDefinition<? extends CharacterSetPasswordValidatorCfgClient, ? extends CharacterSetPasswordValidatorCfg> definition() {
485      return INSTANCE;
486    }
487
488
489
490    /**
491     * {@inheritDoc}
492     */
493    public PropertyProvider properties() {
494      return impl;
495    }
496
497
498
499    /**
500     * {@inheritDoc}
501     */
502    public void commit() throws ManagedObjectAlreadyExistsException,
503        MissingMandatoryPropertiesException, ConcurrentModificationException,
504        OperationRejectedException, LdapException {
505      impl.commit();
506    }
507
508  }
509
510
511
512  /**
513   * Managed object server implementation.
514   */
515  private static class CharacterSetPasswordValidatorCfgServerImpl implements
516    CharacterSetPasswordValidatorCfg {
517
518    // Private implementation.
519    private ServerManagedObject<? extends CharacterSetPasswordValidatorCfg> impl;
520
521    // The value of the "allow-unclassified-characters" property.
522    private final boolean pAllowUnclassifiedCharacters;
523
524    // The value of the "character-set" property.
525    private final SortedSet<String> pCharacterSet;
526
527    // The value of the "character-set-ranges" property.
528    private final SortedSet<String> pCharacterSetRanges;
529
530    // The value of the "enabled" property.
531    private final boolean pEnabled;
532
533    // The value of the "java-class" property.
534    private final String pJavaClass;
535
536    // The value of the "min-character-sets" property.
537    private final Integer pMinCharacterSets;
538
539
540
541    // Private constructor.
542    private CharacterSetPasswordValidatorCfgServerImpl(ServerManagedObject<? extends CharacterSetPasswordValidatorCfg> impl) {
543      this.impl = impl;
544      this.pAllowUnclassifiedCharacters = impl.getPropertyValue(INSTANCE.getAllowUnclassifiedCharactersPropertyDefinition());
545      this.pCharacterSet = impl.getPropertyValues(INSTANCE.getCharacterSetPropertyDefinition());
546      this.pCharacterSetRanges = impl.getPropertyValues(INSTANCE.getCharacterSetRangesPropertyDefinition());
547      this.pEnabled = impl.getPropertyValue(INSTANCE.getEnabledPropertyDefinition());
548      this.pJavaClass = impl.getPropertyValue(INSTANCE.getJavaClassPropertyDefinition());
549      this.pMinCharacterSets = impl.getPropertyValue(INSTANCE.getMinCharacterSetsPropertyDefinition());
550    }
551
552
553
554    /**
555     * {@inheritDoc}
556     */
557    public void addCharacterSetChangeListener(
558        ConfigurationChangeListener<CharacterSetPasswordValidatorCfg> listener) {
559      impl.registerChangeListener(listener);
560    }
561
562
563
564    /**
565     * {@inheritDoc}
566     */
567    public void removeCharacterSetChangeListener(
568        ConfigurationChangeListener<CharacterSetPasswordValidatorCfg> listener) {
569      impl.deregisterChangeListener(listener);
570    }
571    /**
572     * {@inheritDoc}
573     */
574    public void addChangeListener(
575        ConfigurationChangeListener<PasswordValidatorCfg> listener) {
576      impl.registerChangeListener(listener);
577    }
578
579
580
581    /**
582     * {@inheritDoc}
583     */
584    public void removeChangeListener(
585        ConfigurationChangeListener<PasswordValidatorCfg> listener) {
586      impl.deregisterChangeListener(listener);
587    }
588
589
590
591    /**
592     * {@inheritDoc}
593     */
594    public boolean isAllowUnclassifiedCharacters() {
595      return pAllowUnclassifiedCharacters;
596    }
597
598
599
600    /**
601     * {@inheritDoc}
602     */
603    public SortedSet<String> getCharacterSet() {
604      return pCharacterSet;
605    }
606
607
608
609    /**
610     * {@inheritDoc}
611     */
612    public SortedSet<String> getCharacterSetRanges() {
613      return pCharacterSetRanges;
614    }
615
616
617
618    /**
619     * {@inheritDoc}
620     */
621    public boolean isEnabled() {
622      return pEnabled;
623    }
624
625
626
627    /**
628     * {@inheritDoc}
629     */
630    public String getJavaClass() {
631      return pJavaClass;
632    }
633
634
635
636    /**
637     * {@inheritDoc}
638     */
639    public Integer getMinCharacterSets() {
640      return pMinCharacterSets;
641    }
642
643
644
645    /**
646     * {@inheritDoc}
647     */
648    public Class<? extends CharacterSetPasswordValidatorCfg> configurationClass() {
649      return CharacterSetPasswordValidatorCfg.class;
650    }
651
652
653
654    /**
655     * {@inheritDoc}
656     */
657    public DN dn() {
658      return impl.getDN();
659    }
660
661  }
662}