001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions Copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2010 Sun Microsystems, Inc.
015 * Portions Copyright 2016 ForgeRock AS.
016 */
017package org.forgerock.opendj.ldap.controls;
018
019import static com.forgerock.opendj.ldap.CoreMessages.ERR_AUTHZIDREQ_CONTROL_BAD_OID;
020import static com.forgerock.opendj.ldap.CoreMessages.ERR_AUTHZIDREQ_CONTROL_HAS_VALUE;
021
022import org.forgerock.i18n.LocalizableMessage;
023import org.forgerock.opendj.ldap.ByteString;
024import org.forgerock.opendj.ldap.DecodeException;
025import org.forgerock.opendj.ldap.DecodeOptions;
026
027import org.forgerock.util.Reject;
028
029/**
030 * The authorization request control as defined in RFC 3829. The authorization
031 * identity control extends the Lightweight Directory Access Protocol (LDAP)
032 * bind operation with a mechanism for requesting and returning the
033 * authorization identity it establishes.
034 * <p>
035 * The following excerpt shows how to get the authorization identity established
036 * when binding to the directory server.
037 *
038 * <pre>
039 * Connection connection = ...;
040 * String bindDN = ...;
041 * String bindPassword = ...;
042 *
043 * BindRequest request =
044 *         Requests.newSimpleBindRequest(bindDN, bindPassword.toCharArray())
045 *             .addControl(AuthorizationIdentityRequestControl
046 *                     .newControl(true));
047 *
048 * BindResult result = connection.bind(request);
049 * AuthorizationIdentityResponseControl control =
050 *         result.getControl(AuthorizationIdentityResponseControl.DECODER,
051 *                 new DecodeOptions());
052 * // Authorization ID returned: control.getAuthorizationID()
053 * </pre>
054 *
055 * @see AuthorizationIdentityResponseControl
056 * @see org.forgerock.opendj.ldap.requests.WhoAmIExtendedRequest
057 * @see <a href="http://tools.ietf.org/html/rfc3829">RFC 3829 - Lightweight
058 *      Directory Access Protocol (LDAP) Authorization Identity Request and
059 *      Response Controls </a>
060 * @see <a href="http://tools.ietf.org/html/rfc4532">RFC 4532 - Lightweight
061 *      Directory Access Protocol (LDAP) "Who am I?" Operation </a>
062 */
063public final class AuthorizationIdentityRequestControl implements Control {
064    /** The OID for the authorization identity request control. */
065    public static final String OID = "2.16.840.1.113730.3.4.16";
066
067    private final boolean isCritical;
068
069    private static final AuthorizationIdentityRequestControl CRITICAL_INSTANCE =
070            new AuthorizationIdentityRequestControl(true);
071
072    private static final AuthorizationIdentityRequestControl NONCRITICAL_INSTANCE =
073            new AuthorizationIdentityRequestControl(false);
074
075    /** A decoder which can be used for decoding the authorization identity request control. */
076    public static final ControlDecoder<AuthorizationIdentityRequestControl> DECODER =
077            new ControlDecoder<AuthorizationIdentityRequestControl>() {
078
079                @Override
080                public AuthorizationIdentityRequestControl decodeControl(final Control control,
081                        final DecodeOptions options) throws DecodeException {
082                    Reject.ifNull(control);
083
084                    if (control instanceof AuthorizationIdentityRequestControl) {
085                        return (AuthorizationIdentityRequestControl) control;
086                    }
087
088                    if (!control.getOID().equals(OID)) {
089                        final LocalizableMessage message =
090                                ERR_AUTHZIDREQ_CONTROL_BAD_OID.get(control.getOID(), OID);
091                        throw DecodeException.error(message);
092                    }
093
094                    if (control.hasValue()) {
095                        final LocalizableMessage message = ERR_AUTHZIDREQ_CONTROL_HAS_VALUE.get();
096                        throw DecodeException.error(message);
097                    }
098
099                    return control.isCritical() ? CRITICAL_INSTANCE : NONCRITICAL_INSTANCE;
100                }
101
102                @Override
103                public String getOID() {
104                    return OID;
105                }
106            };
107
108    /**
109     * Creates a new authorization identity request control having the provided
110     * criticality.
111     *
112     * @param isCritical
113     *            {@code true} if it is unacceptable to perform the operation
114     *            without applying the semantics of this control, or
115     *            {@code false} if it can be ignored.
116     * @return The new control.
117     */
118    public static AuthorizationIdentityRequestControl newControl(final boolean isCritical) {
119        return isCritical ? CRITICAL_INSTANCE : NONCRITICAL_INSTANCE;
120    }
121
122    /** Prevent direct instantiation. */
123    private AuthorizationIdentityRequestControl(final boolean isCritical) {
124        this.isCritical = isCritical;
125    }
126
127    @Override
128    public String getOID() {
129        return OID;
130    }
131
132    @Override
133    public ByteString getValue() {
134        return null;
135    }
136
137    @Override
138    public boolean hasValue() {
139        return false;
140    }
141
142    @Override
143    public boolean isCritical() {
144        return isCritical;
145    }
146
147    @Override
148    public String toString() {
149        final StringBuilder builder = new StringBuilder();
150        builder.append("AuthorizationIdentityRequestControl(oid=");
151        builder.append(getOID());
152        builder.append(", criticality=");
153        builder.append(isCritical());
154        builder.append(")");
155        return builder.toString();
156    }
157
158}