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

neil_a_wilson
03.30.2007 938eec61d6c1bf9f62c9c3dad50086d02340f006
Update the proxied authorization control code to require that the controls have
a criticality of "true" as per the specification in RFC 4370.

OpenDS Issue Number: 741
2 files added
3 files modified
1178 ■■■■■ changed files
opends/src/server/org/opends/server/controls/ProxiedAuthV1Control.java 29 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/controls/ProxiedAuthV2Control.java 44 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/messages/ProtocolMessages.java 30 ●●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/controls/ProxiedAuthV1ControlTestCase.java 528 ●●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/controls/ProxiedAuthV2ControlTestCase.java 547 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/controls/ProxiedAuthV1Control.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2006 Sun Microsystems, Inc.
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 */
package org.opends.server.controls;
@@ -50,6 +50,7 @@
import static org.opends.server.messages.ProtocolMessages.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
import static org.opends.server.util.Validator.*;
@@ -86,7 +87,7 @@
   * provided information.
   *
   * @param  rawAuthorizationDN  The raw, unprocessed authorization DN from the
   *                             control value.
   *                             control value.  It must not be {@code null}.
   */
  public ProxiedAuthV1Control(ASN1OctetString rawAuthorizationDN)
  {
@@ -105,7 +106,8 @@
   * Creates a new instance of the proxied authorization v1 control with the
   * provided information.
   *
   * @param  authorizationDN  The authorization DN from the control value.
   * @param  authorizationDN  The authorization DN from the control value.  It
   *                          must not be {@code null}.
   */
  public ProxiedAuthV1Control(DN authorizationDN)
  {
@@ -156,7 +158,8 @@
   * authorization DN.
   *
   * @param  rawAuthorizationDN  The raw, unprocessed authorization DN to use in
   *                             the control value.
   *                             the control value.  It must not be
   *                             {@code null}.
   *
   * @return  The encoded control value.
   */
@@ -165,6 +168,8 @@
    assert debugEnter(CLASS_NAME, "encodeValue",
                      String.valueOf(rawAuthorizationDN));
    ensureNotNull(rawAuthorizationDN);
    ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(1);
    elements.add(rawAuthorizationDN);
@@ -178,7 +183,8 @@
   * provided control.
   *
   * @param  control  The generic control containing the information to use to
   *                  create this proxied authorization v1 control.
   *                  create this proxied authorization v1 control.  It must not
   *                  be {@code null}.
   *
   * @return  The proxied authorization v1 control decoded from the provided
   *          control.
@@ -191,6 +197,16 @@
  {
    assert debugEnter(CLASS_NAME, "decodeControl", String.valueOf(control));
    ensureNotNull(control);
    if (! control.isCritical())
    {
      int    msgID   = MSGID_PROXYAUTH1_CONTROL_NOT_CRITICAL;
      String message = getMessage(msgID);
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, msgID,
                              message);
    }
    if (! control.hasValue())
    {
      int    msgID   = MSGID_PROXYAUTH1_NO_CONTROL_VALUE;
@@ -293,12 +309,15 @@
   * Specifies the authorization DN for this proxied auth control.
   *
   * @param  authorizationDN  The authorizationDN for this proxied auth control.
   *                          It must not be {@code null}.
   */
  public void setAuthorizationDN(DN authorizationDN)
  {
    assert debugEnter(CLASS_NAME, "setAuthorizationDN",
                      String.valueOf(authorizationDN));
    ensureNotNull(authorizationDN);
    this.authorizationDN = authorizationDN;
    rawAuthorizationDN = new ASN1OctetString(authorizationDN.toString());
opends/src/server/org/opends/server/controls/ProxiedAuthV2Control.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2006 Sun Microsystems, Inc.
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 */
package org.opends.server.controls;
@@ -49,6 +49,7 @@
import static org.opends.server.messages.ProtocolMessages.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
import static org.opends.server.util.Validator.*;
@@ -84,10 +85,11 @@
   */
  public ProxiedAuthV2Control(ASN1OctetString authorizationID)
  {
    super(OID_PROXIED_AUTH_V2, true, encodeValue(authorizationID));
    super(OID_PROXIED_AUTH_V2, true, authorizationID);
    assert debugConstructor(CLASS_NAME, String.valueOf(authorizationID));
    ensureNotNull(authorizationID);
    this.authorizationID = authorizationID;
  }
@@ -118,36 +120,12 @@
  /**
   * Generates an encoded value for this control containing the provided
   * authorization ID.
   *
   * @param  authorizationID  The authorization ID to be encoded.
   *
   * @return  The encoded control value.
   */
  private static ASN1OctetString encodeValue(ASN1OctetString authorizationID)
  {
    assert debugEnter(CLASS_NAME, "encodeValue",
                      String.valueOf(authorizationID));
    if (authorizationID == null)
    {
      return new ASN1OctetString();
    }
    else
    {
      return authorizationID;
    }
  }
  /**
   * Creates a new proxied authorization v2 control from the contents of the
   * provided control.
   *
   * @param  control  The generic control containing the information to use to
   *                  create this proxied authorization v2 control.
   *                  create this proxied authorization v2 control.  It must not
   *                  be {@code null}.
   *
   * @return  The proxied authorization v2 control decoded from the provided
   *          control.
@@ -160,6 +138,16 @@
  {
    assert debugEnter(CLASS_NAME, "decodeControl", String.valueOf(control));
    ensureNotNull(control);
    if (! control.isCritical())
    {
      int    msgID   = MSGID_PROXYAUTH2_CONTROL_NOT_CRITICAL;
      String message = getMessage(msgID);
      throw new LDAPException(LDAPResultCode.PROTOCOL_ERROR, msgID,
                              message);
    }
    if (! control.hasValue())
    {
      int    msgID   = MSGID_PROXYAUTH2_NO_CONTROL_VALUE;
opends/src/server/org/opends/server/messages/ProtocolMessages.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2006 Sun Microsystems, Inc.
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 */
package org.opends.server.messages;
@@ -4210,6 +4210,24 @@
  /**
   * The message ID for the message that will be used if a proxied auth V1
   * control is not marked critical.  This does not take any arguments.
   */
  public static final int MSGID_PROXYAUTH1_CONTROL_NOT_CRITICAL =
       CATEGORY_MASK_PROTOCOL | SEVERITY_MASK_MILD_ERROR | 388;
  /**
   * The message ID for the message that will be used if a proxied auth V2
   * control is not marked critical.  This does not take any arguments.
   */
  public static final int MSGID_PROXYAUTH2_CONTROL_NOT_CRITICAL =
       CATEGORY_MASK_PROTOCOL | SEVERITY_MASK_MILD_ERROR | 389;
  /**
   * Associates a set of generic messages with the message IDs defined in this
   * class.
   */
@@ -5654,6 +5672,11 @@
                    "decode the control value:  %s.");
    registerMessage(MSGID_PROXYAUTH1_CONTROL_NOT_CRITICAL,
                    "Unwilling to process the request because it contains a " +
                    "proxied authorization V1 control which is not marked " +
                    "critical.  The proxied authorization control must " +
                    "always have a criticality of \"true\".");
    registerMessage(MSGID_PROXYAUTH1_NO_CONTROL_VALUE,
                    "Cannot decode the provided proxied authorization V1 " +
                    "control because it does not have a value.");
@@ -5677,6 +5700,11 @@
                    "is not allowed by the password policy configuration.");
    registerMessage(MSGID_PROXYAUTH2_CONTROL_NOT_CRITICAL,
                    "Unwilling to process the request because it contains a " +
                    "proxied authorization V2 control which is not marked " +
                    "critical.  The proxied authorization control must " +
                    "always have a criticality of \"true\".");
    registerMessage(MSGID_PROXYAUTH2_NO_CONTROL_VALUE,
                    "Cannot decode the provided proxied authorization V2 " +
                    "control because it does not have a value.");
opends/tests/unit-tests-testng/src/server/org/opends/server/controls/ProxiedAuthV1ControlTestCase.java
New file
@@ -0,0 +1,528 @@
/*
 * 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
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * 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
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  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
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.controls;
import java.util.ArrayList;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.opends.server.TestCaseUtils;
import org.opends.server.protocols.asn1.ASN1Element;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.asn1.ASN1Sequence;
import org.opends.server.protocols.ldap.LDAPException;
import org.opends.server.types.Control;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.DN;
import static org.testng.Assert.*;
import static org.opends.server.util.ServerConstants.*;
/**
 * This class contains a number of test cases for the proxied authorization v1
 * control.
 */
public class ProxiedAuthV1ControlTestCase
    extends ControlsTestCase
{
  /**
   * Make sure that the server is running.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @BeforeClass()
  public void startServer()
         throws Exception
  {
    TestCaseUtils.startServer();
  }
  /**
   * Tests the first constructor, which creates an instance of the control using
   * a raw, unprocessed DN.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testConstructor1()
         throws Exception
  {
    // Try a DN of "null", which is not valid and will fail on the attempt to
    // create the control
    ProxiedAuthV1Control proxyControl;
    try
    {
      proxyControl = new ProxiedAuthV1Control((ASN1OctetString) null);
      throw new AssertionError("Expected a failure when creating a proxied " +
                               "auth V1 control with a null octet string.");
    } catch (Throwable t) {}
    // Try an empty DN, which is acceptable.
    proxyControl = new ProxiedAuthV1Control(new ASN1OctetString(""));
    assertTrue(proxyControl.getOID().equals(OID_PROXIED_AUTH_V1));
    assertTrue(proxyControl.isCritical());
    assertTrue(proxyControl.hasValue());
    assertTrue(proxyControl.getAuthorizationDN().isNullDN());
    // Try a valid DN, which is acceptable.
    proxyControl =
         new ProxiedAuthV1Control(new ASN1OctetString("uid=test,o=test"));
    assertTrue(proxyControl.getOID().equals(OID_PROXIED_AUTH_V1));
    assertTrue(proxyControl.isCritical());
    assertTrue(proxyControl.hasValue());
    assertEquals(proxyControl.getAuthorizationDN(),
                 DN.decode("uid=test,o=test"));
    // Try an invalid DN, which will be initally accepted but will fail when
    // attempting to get the authorization DN.
    proxyControl = new ProxiedAuthV1Control(new ASN1OctetString("invalid"));
    assertTrue(proxyControl.getOID().equals(OID_PROXIED_AUTH_V1));
    assertTrue(proxyControl.isCritical());
    assertTrue(proxyControl.hasValue());
    try
    {
      proxyControl.getAuthorizationDN();
      throw new AssertionError("Expected a failure when creating a proxied " +
                               "auth V1 control with an invalid DN string.");
    } catch (Exception e) {}
  }
  /**
   * Tests the second constructor, which creates an instance of the control
   * using a processed DN.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testConstructor2()
         throws Exception
  {
    // Try a DN of "null", which is not valid and will fail on the attempt to
    // create the control
    ProxiedAuthV1Control proxyControl;
    try
    {
      proxyControl = new ProxiedAuthV1Control((DN) null);
      throw new AssertionError("Expected a failure when creating a proxied " +
                               "auth V1 control with a null octet string.");
    } catch (Throwable t) {}
    // Try an empty DN, which is acceptable.
    proxyControl = new ProxiedAuthV1Control(DN.nullDN());
    assertTrue(proxyControl.getOID().equals(OID_PROXIED_AUTH_V1));
    assertTrue(proxyControl.isCritical());
    assertTrue(proxyControl.hasValue());
    assertTrue(proxyControl.getAuthorizationDN().isNullDN());
    // Try a valid DN, which is acceptable.
    proxyControl =
         new ProxiedAuthV1Control(DN.decode("uid=test,o=test"));
    assertTrue(proxyControl.getOID().equals(OID_PROXIED_AUTH_V1));
    assertTrue(proxyControl.isCritical());
    assertTrue(proxyControl.hasValue());
    assertEquals(proxyControl.getAuthorizationDN(),
                 DN.decode("uid=test,o=test"));
  }
  /**
   * Tests the {@code decodeControl} method when the provided control is
   * {@code null}.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test(expectedExceptions = { AssertionError.class })
  public void testDecodeControlNull()
         throws Exception
  {
    ProxiedAuthV1Control.decodeControl(null);
  }
  /**
   * Tests the {@code decodeControl} method when the provided control has a
   * criticality of "false".
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test(expectedExceptions = { LDAPException.class })
  public void testDecodeControlNotCritical()
         throws Exception
  {
    ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(1);
    elements.add(new ASN1OctetString("uid=test,o=test"));
    ASN1Sequence valueSequence = new ASN1Sequence(elements);
    ASN1OctetString value = new ASN1OctetString(valueSequence.encode());
    Control c = new Control(OID_PROXIED_AUTH_V1, false, value);
    ProxiedAuthV1Control.decodeControl(c);
  }
  /**
   * Tests the {@code decodeControl} method when the provided control does not
   * have a value.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test(expectedExceptions = { LDAPException.class })
  public void testDecodeControlNoValue()
         throws Exception
  {
    Control c = new Control(OID_PROXIED_AUTH_V1, true, null);
    ProxiedAuthV1Control.decodeControl(c);
  }
  /**
   * Tests the {@code decodeControl} method when the control value is not a
   * sequence.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test(expectedExceptions = { LDAPException.class })
  public void testDecodeControlValueNotSequence()
         throws Exception
  {
    ASN1OctetString value = new ASN1OctetString("uid=test,o=test");
    Control c = new Control(OID_PROXIED_AUTH_V1, true, value);
    ProxiedAuthV1Control.decodeControl(c);
  }
  /**
   * Tests the {@code decodeControl} method when the control value is a sequence
   * with zero elements.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test(expectedExceptions = { LDAPException.class })
  public void testDecodeControlValueEmptySequence()
         throws Exception
  {
    ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(0);
    ASN1Sequence valueSequence = new ASN1Sequence(elements);
    ASN1OctetString value = new ASN1OctetString(valueSequence.encode());
    Control c = new Control(OID_PROXIED_AUTH_V1, true, value);
    ProxiedAuthV1Control.decodeControl(c);
  }
  /**
   * Tests the {@code decodeControl} method when the control value is a sequence
   * with multiple elements.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test(expectedExceptions = { LDAPException.class })
  public void testDecodeControlValueMultiElementSequence()
         throws Exception
  {
    ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(2);
    elements.add(new ASN1OctetString("uid=element1,o=test"));
    elements.add(new ASN1OctetString("uid=element2,o=test"));
    ASN1Sequence valueSequence = new ASN1Sequence(elements);
    ASN1OctetString value = new ASN1OctetString(valueSequence.encode());
    Control c = new Control(OID_PROXIED_AUTH_V1, true, value);
    ProxiedAuthV1Control.decodeControl(c);
  }
  /**
   * Tests the {@code decodeControl} method when the control value is a valid
   * octet string that contains an invalid DN.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test(expectedExceptions = { DirectoryException.class })
  public void testDecodeControlValueInvalidDN()
         throws Exception
  {
    ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(1);
    elements.add(new ASN1OctetString("invaliddn"));
    ASN1Sequence valueSequence = new ASN1Sequence(elements);
    ASN1OctetString value = new ASN1OctetString(valueSequence.encode());
    Control c = new Control(OID_PROXIED_AUTH_V1, true, value);
    ProxiedAuthV1Control proxyControl = ProxiedAuthV1Control.decodeControl(c);
    proxyControl.getAuthorizationDN();
  }
  /**
   * Tests the {@code decodeControl} method when the control value is a valid
   * octet string that contains an valid empty DN.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testDecodeControlValueEmptyDN()
         throws Exception
  {
    ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(1);
    elements.add(new ASN1OctetString(""));
    ASN1Sequence valueSequence = new ASN1Sequence(elements);
    ASN1OctetString value = new ASN1OctetString(valueSequence.encode());
    Control c = new Control(OID_PROXIED_AUTH_V1, true, value);
    ProxiedAuthV1Control proxyControl = ProxiedAuthV1Control.decodeControl(c);
    assertTrue(proxyControl.getAuthorizationDN().isNullDN());
  }
  /**
   * Tests the {@code decodeControl} method when the control value is a valid
   * octet string that contains an valid non-empty DN.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testDecodeControlValueNonEmptyDN()
         throws Exception
  {
    ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(1);
    elements.add(new ASN1OctetString("uid=test,o=test"));
    ASN1Sequence valueSequence = new ASN1Sequence(elements);
    ASN1OctetString value = new ASN1OctetString(valueSequence.encode());
    Control c = new Control(OID_PROXIED_AUTH_V1, true, value);
    ProxiedAuthV1Control proxyControl = ProxiedAuthV1Control.decodeControl(c);
    assertEquals(proxyControl.getAuthorizationDN(),
                 DN.decode("uid=test,o=test"));
  }
  /**
   * Tests the {@code getRawAuthorizationDN} and {@code setRawAuthorizationDN}
   * methods.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testGetAndSetRawAuthorizationDN()
         throws Exception
  {
    ProxiedAuthV1Control proxyControl =
         new ProxiedAuthV1Control(new ASN1OctetString(""));
    assertEquals(proxyControl.getRawAuthorizationDN(), new ASN1OctetString(""));
    proxyControl.setRawAuthorizationDN(new ASN1OctetString("uid=test,o=test"));
    assertEquals(proxyControl.getRawAuthorizationDN(),
                 new ASN1OctetString("uid=test,o=test"));
  }
  /**
   * Tests the {@code getAuthorizationDN} and {@code setRawAuthorizationDN}
   * methods.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testGetAndSetAuthorizationDN()
         throws Exception
  {
    ProxiedAuthV1Control proxyControl =
         new ProxiedAuthV1Control(DN.nullDN());
    assertEquals(proxyControl.getRawAuthorizationDN(), new ASN1OctetString(""));
    assertEquals(proxyControl.getAuthorizationDN(), DN.nullDN());
    proxyControl.setAuthorizationDN(DN.decode("uid=test,o=test"));
    assertEquals(proxyControl.getRawAuthorizationDN(),
                 new ASN1OctetString("uid=test,o=test"));
    assertEquals(proxyControl.getAuthorizationDN(),
                 DN.decode("uid=test,o=test"));
  }
  /**
   * Tests the {@code setRawAuthorizationDN} method when providing an
   * authorization DN that is {@code null}.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test(expectedExceptions = { AssertionError.class })
  public void testSetNullAuthorizationDN()
         throws Exception
  {
    ProxiedAuthV1Control proxyControl =
         new ProxiedAuthV1Control(DN.nullDN());
    proxyControl.setAuthorizationDN(null);
  }
  /**
   * Tests the {@code getValidatedAuthorizationDN} method for the null DN.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testGetValidatedAuthorizationDNNullDN()
         throws Exception
  {
    ProxiedAuthV1Control proxyControl =
         new ProxiedAuthV1Control(DN.nullDN());
    assertTrue(proxyControl.getValidatedAuthorizationDN().isNullDN());
  }
  /**
   * Tests the {@code getValidatedAuthorizationDN} method for a normal user
   * that exists in the directory data and doesn't have any restrictions on its
   * use.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testGetValidatedAuthorizationExistingNormalUser()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(true);
    TestCaseUtils.addEntry(
      "dn: uid=test,o=test",
      "objectClass: top",
      "objectClass: person",
      "objectClass: organizationalPerson",
      "objectClass: inetOrgPerson",
      "uid: test",
      "givenName: Test",
      "sn: User",
      "cn: Test User");
    ProxiedAuthV1Control proxyControl =
         new ProxiedAuthV1Control(DN.decode("uid=test,o=test"));
    assertEquals(proxyControl.getValidatedAuthorizationDN(),
                 DN.decode("uid=test,o=test"));
  }
  /**
   * Tests the {@code getValidatedAuthorizationDN} method for a user that
   * doesn't exist in the directory data.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test(expectedExceptions = { DirectoryException.class })
  public void testGetValidatedAuthorizationNonExistingNormalUser()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(true);
    ProxiedAuthV1Control proxyControl =
         new ProxiedAuthV1Control(DN.decode("uid=test,o=test"));
    proxyControl.getValidatedAuthorizationDN();
  }
  /**
   * Tests the {@code getValidatedAuthorizationDN} method for a disabled user.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test(expectedExceptions = { DirectoryException.class })
  public void testGetValidatedAuthorizationDisabledUser()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(true);
    TestCaseUtils.addEntry(
      "dn: uid=test,o=test",
      "objectClass: top",
      "objectClass: person",
      "objectClass: organizationalPerson",
      "objectClass: inetOrgPerson",
      "uid: test",
      "givenName: Test",
      "sn: User",
      "cn: Test User",
      "ds-pwp-account-disabled: true");
    ProxiedAuthV1Control proxyControl =
         new ProxiedAuthV1Control(DN.decode("uid=test,o=test"));
    proxyControl.getValidatedAuthorizationDN();
  }
  /**
   * Tests the {@code toString} methods.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testToString()
         throws Exception
  {
    // The default toString() calls the version that takes a string builder
    // argument, so we only need to use the default version to cover both cases.
    ProxiedAuthV1Control proxyControl =
         new ProxiedAuthV1Control(new ASN1OctetString("uid=test,o=test"));
    proxyControl.toString();
    proxyControl = new ProxiedAuthV1Control(DN.decode("uid=test,o=test"));
    proxyControl.toString();
  }
}
opends/tests/unit-tests-testng/src/server/org/opends/server/controls/ProxiedAuthV2ControlTestCase.java
New file
@@ -0,0 +1,547 @@
/*
 * 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
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * 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
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  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
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.controls;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.opends.server.TestCaseUtils;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.protocols.ldap.LDAPException;
import org.opends.server.types.Control;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.DN;
import static org.testng.Assert.*;
import static org.opends.server.util.ServerConstants.*;
/**
 * This class contains a number of test cases for the proxied authorization v2
 * control.
 */
public class ProxiedAuthV2ControlTestCase
    extends ControlsTestCase
{
  /**
   * Make sure that the server is running.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @BeforeClass()
  public void startServer()
         throws Exception
  {
    TestCaseUtils.startServer();
  }
  /**
   * Tests the constructor with a {@code null} authorization ID.
   */
  @Test(expectedExceptions = { AssertionError.class })
  public void testConstructorNullAuthzID()
  {
    ProxiedAuthV2Control proxyControl = new ProxiedAuthV2Control(null);
  }
  /**
   * Tests the constructor with an empty authorization ID.
   */
  @Test()
  public void testConstructorEmptyAuthzID()
  {
    ProxiedAuthV2Control proxyControl =
         new ProxiedAuthV2Control(new ASN1OctetString(""));
    assertEquals(proxyControl.getAuthorizationID(), new ASN1OctetString(""));
  }
  /**
   * Tests the constructor with a non-empty authorization ID using the "dn:"
   * form.
   */
  @Test()
  public void testConstructorNonEmptyAuthzIDDN()
  {
    ProxiedAuthV2Control proxyControl =
         new ProxiedAuthV2Control(new ASN1OctetString("dn:uid=test,o=test"));
    assertEquals(proxyControl.getAuthorizationID(),
                 new ASN1OctetString("dn:uid=test,o=test"));
  }
  /**
   * Tests the constructor with a non-empty authorization ID using the "u:"
   * form.
   */
  @Test()
  public void testConstructorNonEmptyAuthzIDUsername()
  {
    ProxiedAuthV2Control proxyControl =
         new ProxiedAuthV2Control(new ASN1OctetString("u:test"));
    assertEquals(proxyControl.getAuthorizationID(),
                 new ASN1OctetString("u:test"));
  }
  /**
   * Tests the {@code decodeControl} method with a {@code null} argument.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test(expectedExceptions = { AssertionError.class })
  public void testDecodeControlNull()
         throws Exception
  {
    ProxiedAuthV2Control.decodeControl(null);
  }
  /**
   * Tests the {@code decodeControl} method with a control that is not marked
   * critical.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test(expectedExceptions = { LDAPException.class })
  public void testDecodeControlNotCritical()
         throws Exception
  {
    Control c = new Control(OID_PROXIED_AUTH_V2, false,
                            new ASN1OctetString("u:test"));
    ProxiedAuthV2Control.decodeControl(c);
  }
  /**
   * Tests the {@code decodeControl} method with a control that does not have a
   * value.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test(expectedExceptions = { LDAPException.class })
  public void testDecodeControlNoValue()
         throws Exception
  {
    Control c = new Control(OID_PROXIED_AUTH_V2, true);
    ProxiedAuthV2Control.decodeControl(c);
  }
  /**
   * Tests the {@code decodeControl} method with a control encoded in the
   * standard from with the "dn:"-style value.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testDecodeControlDNValue()
         throws Exception
  {
    ASN1OctetString authzID = new ASN1OctetString("dn:uid=test,o=test");
    Control c = new Control(OID_PROXIED_AUTH_V2, true, authzID);
    ProxiedAuthV2Control proxyControl = ProxiedAuthV2Control.decodeControl(c);
    assertEquals(proxyControl.getAuthorizationID(), authzID);
  }
  /**
   * Tests the {@code decodeControl} method with a control encoded in the
   * standard from with the "u:"-style value.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testDecodeControlUsernameValue()
         throws Exception
  {
    ASN1OctetString authzID = new ASN1OctetString("u:test");
    Control c = new Control(OID_PROXIED_AUTH_V2, true, authzID);
    ProxiedAuthV2Control proxyControl = ProxiedAuthV2Control.decodeControl(c);
    assertEquals(proxyControl.getAuthorizationID(), authzID);
  }
  /**
   * Tests the {@code decodeControl} method with an invalid value (which doesn't
   * start with either "dn:" or "u:").
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test(expectedExceptions = { LDAPException.class })
  public void testDecodeControlInvalidValue()
         throws Exception
  {
    ASN1OctetString authzID = new ASN1OctetString("invalid");
    Control c = new Control(OID_PROXIED_AUTH_V2, true, authzID);
    ProxiedAuthV2Control proxyControl = ProxiedAuthV2Control.decodeControl(c);
    assertEquals(proxyControl.getAuthorizationID(), authzID);
  }
  /**
   * Tests the {@code decodeControl} method with a control encoded in the legacy
   * form (in which the value is wrapped by an extra octet string) with the
   * "dn:"-style value.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testDecodeControlLegacyDNValue()
         throws Exception
  {
    ASN1OctetString innerValue = new ASN1OctetString("dn:uid=test,o=test");
    ASN1OctetString outerValue = new ASN1OctetString(innerValue.encode());
    Control c = new Control(OID_PROXIED_AUTH_V2, true, outerValue);
    ProxiedAuthV2Control proxyControl = ProxiedAuthV2Control.decodeControl(c);
    assertEquals(proxyControl.getAuthorizationID(), innerValue);
  }
  /**
   * Tests the {@code decodeControl} method with a control encoded in the legacy
   * form (in which the value is wrapped by an extra octet string) with the
   * "u:"-style value.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testDecodeControlLegacyUsernameValue()
         throws Exception
  {
    ASN1OctetString innerValue = new ASN1OctetString("u:test");
    ASN1OctetString outerValue = new ASN1OctetString(innerValue.encode());
    Control c = new Control(OID_PROXIED_AUTH_V2, true, outerValue);
    ProxiedAuthV2Control proxyControl = ProxiedAuthV2Control.decodeControl(c);
    assertEquals(proxyControl.getAuthorizationID(), innerValue);
  }
  /**
   * Tests the {@code getAuthorizationID} and {@code setAuthorizationID}
   * methods.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testGetAndSetAuthorizationID()
         throws Exception
  {
    ProxiedAuthV2Control proxyControl =
         new ProxiedAuthV2Control(new ASN1OctetString("dn:uid=test,o=test"));
    assertEquals(proxyControl.getAuthorizationID(),
                 new ASN1OctetString("dn:uid=test,o=test"));
    proxyControl.setAuthorizationID(null);
    assertEquals(proxyControl.getAuthorizationID(), new ASN1OctetString(""));
    proxyControl.setAuthorizationID(new ASN1OctetString(""));
    assertEquals(proxyControl.getAuthorizationID(), new ASN1OctetString(""));
    proxyControl.setAuthorizationID(new ASN1OctetString("u:test"));
    assertEquals(proxyControl.getAuthorizationID(),
                 new ASN1OctetString("u:test"));
    proxyControl.setAuthorizationID(new ASN1OctetString("dn:uid=test,o=test"));
    assertEquals(proxyControl.getAuthorizationID(),
                 new ASN1OctetString("dn:uid=test,o=test"));
  }
  /**
   * Tests the {@code getValidatedAuthorizationDN} method with an empty
   * authorization ID string.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testGetValidatedAuthorizationDNEmptyAuthzID()
         throws Exception
  {
    ProxiedAuthV2Control proxyControl =
         new ProxiedAuthV2Control(new ASN1OctetString(""));
    assertEquals(proxyControl.getValidatedAuthorizationDN(), DN.nullDN());
  }
  /**
   * Tests the {@code getValidatedAuthorizationDN} method with an authorization
   * ID of "dn:".
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testGetValidatedAuthorizationDNEmptyAuthzIDDN()
         throws Exception
  {
    ProxiedAuthV2Control proxyControl =
         new ProxiedAuthV2Control(new ASN1OctetString("dn:"));
    assertEquals(proxyControl.getValidatedAuthorizationDN(), DN.nullDN());
  }
  /**
   * Tests the {@code getValidatedAuthorizationDN} method with an authorization
   * ID in the "dn:" form that points to a valid user.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testGetValidatedAuthorizationDNExistingUserDN()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(true);
    TestCaseUtils.addEntry(
      "dn: uid=test,o=test",
      "objectClass: top",
      "objectClass: person",
      "objectClass: organizationalPerson",
      "objectClass: inetOrgPerson",
      "uid: test",
      "givenName: Test",
      "sn: User",
      "cn: Test User");
    ProxiedAuthV2Control proxyControl =
         new ProxiedAuthV2Control(new ASN1OctetString("dn:uid=test,o=test"));
    assertEquals(proxyControl.getValidatedAuthorizationDN(),
                 DN.decode("uid=test,o=test"));
  }
  /**
   * Tests the {@code getValidatedAuthorizationDN} method with an authorization
   * ID in the "dn:" form that points to a user that doesn't exist.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test(expectedExceptions = { DirectoryException.class })
  public void testGetValidatedAuthorizationDNNonExistingUserDN()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(true);
    ProxiedAuthV2Control proxyControl =
         new ProxiedAuthV2Control(new ASN1OctetString("dn:uid=test,o=test"));
    proxyControl.getValidatedAuthorizationDN();
  }
  /**
   * Tests the {@code getValidatedAuthorizationDN} method with an authorization
   * ID in the "dn:" form that points to a valid user but whose account is
   * disabled.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test(expectedExceptions = { DirectoryException.class })
  public void testGetValidatedAuthorizationDNExistingDisabledUserDN()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(true);
    TestCaseUtils.addEntry(
      "dn: uid=test,o=test",
      "objectClass: top",
      "objectClass: person",
      "objectClass: organizationalPerson",
      "objectClass: inetOrgPerson",
      "uid: test",
      "givenName: Test",
      "sn: User",
      "cn: Test User",
      "ds-pwp-account-disabled: true");
    ProxiedAuthV2Control proxyControl =
         new ProxiedAuthV2Control(new ASN1OctetString("dn:uid=test,o=test"));
    proxyControl.getValidatedAuthorizationDN();
  }
  /**
   * Tests the {@code getValidatedAuthorizationDN} method with an authorization
   * ID of "u:".
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testGetValidatedAuthorizationDNEmptyAuthzIDUsername()
         throws Exception
  {
    ProxiedAuthV2Control proxyControl =
         new ProxiedAuthV2Control(new ASN1OctetString("u:"));
    assertEquals(proxyControl.getValidatedAuthorizationDN(), DN.nullDN());
  }
  /**
   * Tests the {@code getValidatedAuthorizationDN} method with an authorization
   * ID in the "u:" form that points to a valid user.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testGetValidatedAuthorizationDNExistingUserUsername()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(true);
    TestCaseUtils.addEntry(
      "dn: uid=test,o=test",
      "objectClass: top",
      "objectClass: person",
      "objectClass: organizationalPerson",
      "objectClass: inetOrgPerson",
      "uid: test",
      "givenName: Test",
      "sn: User",
      "cn: Test User");
    ProxiedAuthV2Control proxyControl =
         new ProxiedAuthV2Control(new ASN1OctetString("u:test"));
    assertEquals(proxyControl.getValidatedAuthorizationDN(),
                 DN.decode("uid=test,o=test"));
  }
  /**
   * Tests the {@code getValidatedAuthorizationDN} method with an authorization
   * ID in the "u:" form that points to a user that doesn't exist.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test(expectedExceptions = { DirectoryException.class })
  public void testGetValidatedAuthorizationDNNonExistingUserUsername()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(true);
    ProxiedAuthV2Control proxyControl =
         new ProxiedAuthV2Control(new ASN1OctetString("u:test"));
    proxyControl.getValidatedAuthorizationDN();
  }
  /**
   * Tests the {@code getValidatedAuthorizationDN} method with an authorization
   * ID in the "u:" form that points to a valid user but whose account is
   * disabled.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test(expectedExceptions = { DirectoryException.class })
  public void testGetValidatedAuthorizationDNExistingDisabledUserUsername()
         throws Exception
  {
    TestCaseUtils.initializeTestBackend(true);
    TestCaseUtils.addEntry(
      "dn: uid=test,o=test",
      "objectClass: top",
      "objectClass: person",
      "objectClass: organizationalPerson",
      "objectClass: inetOrgPerson",
      "uid: test",
      "givenName: Test",
      "sn: User",
      "cn: Test User",
      "ds-pwp-account-disabled: true");
    ProxiedAuthV2Control proxyControl =
         new ProxiedAuthV2Control(new ASN1OctetString("u:test"));
    proxyControl.getValidatedAuthorizationDN();
  }
  /**
   * Tests the {@code getValidatedAuthorizationDN} method with an invalid
   * authorization ID.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test(expectedExceptions = { DirectoryException.class })
  public void testGetValidatedAuthorizationDNInvalidAuthzID()
         throws Exception
  {
    ProxiedAuthV2Control proxyControl =
         new ProxiedAuthV2Control(new ASN1OctetString("invalid"));
    proxyControl.getValidatedAuthorizationDN();
  }
  /**
   * Tests the {@code toString} methods.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testToString()
         throws Exception
  {
    // The default toString() calls the version that takes a string builder
    // argument, so we only need to use the default version to cover both cases.
    ProxiedAuthV2Control proxyControl =
         new ProxiedAuthV2Control(new ASN1OctetString("dn:uid=test,o=test"));
    proxyControl.toString();
    proxyControl = new ProxiedAuthV2Control(new ASN1OctetString("u:test"));
    proxyControl.toString();
  }
}