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 2012-2016 ForgeRock AS.
016 */
017package org.forgerock.opendj.ldap.controls;
018
019import static com.forgerock.opendj.ldap.CoreMessages.ERR_AUTHZIDRESP_CONTROL_BAD_OID;
020import static com.forgerock.opendj.ldap.CoreMessages.ERR_AUTHZIDRESP_NO_CONTROL_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 response 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 authorization identity is specified using an authorization ID, or
036 * {@code authzId}, as defined in RFC 4513 section 5.2.1.8.
037 * <p>
038 * The following excerpt shows how to get the authorization identity established
039 * when binding to the directory server.
040 *
041 * <pre>
042 * Connection connection = ...;
043 * String bindDN = ...;
044 * String bindPassword = ...;
045 *
046 * BindRequest request =
047 *         Requests.newSimpleBindRequest(bindDN, bindPassword.toCharArray())
048 *             .addControl(AuthorizationIdentityRequestControl
049 *                     .newControl(true));
050 *
051 * BindResult result = connection.bind(request);
052 * AuthorizationIdentityResponseControl control =
053 *         result.getControl(AuthorizationIdentityResponseControl.DECODER,
054 *                 new DecodeOptions());
055 * // Authorization ID returned: control.getAuthorizationID()
056 * </pre>
057 *
058 * @see AuthorizationIdentityRequestControl
059 * @see org.forgerock.opendj.ldap.requests.WhoAmIExtendedRequest
060 * @see <a href="http://tools.ietf.org/html/rfc3829">RFC 3829 - Lightweight
061 *      Directory Access Protocol (LDAP) Authorization Identity Request and
062 *      Response Controls </a>
063 * @see <a href="http://tools.ietf.org/html/rfc4532">RFC 4532 - Lightweight
064 *      Directory Access Protocol (LDAP) "Who am I?" Operation </a>
065 * @see <a href="http://tools.ietf.org/html/rfc4513#section-5.2.1.8">RFC 4513 -
066 *      SASL Authorization Identities (authzId) </a>
067 */
068public final class AuthorizationIdentityResponseControl implements Control {
069
070    /** The OID for the authorization identity response control. */
071    public static final String OID = "2.16.840.1.113730.3.4.15";
072
073    /**
074     * Creates a new authorization identity response control using the provided
075     * authorization ID.
076     *
077     * @param authorizationID
078     *            The authorization ID for this control.
079     * @return The new control.
080     * @throws NullPointerException
081     *             If {@code authorizationID} was {@code null}.
082     */
083    public static AuthorizationIdentityResponseControl newControl(final String authorizationID) {
084        return new AuthorizationIdentityResponseControl(false, authorizationID);
085    }
086
087    /** The authorization ID for this control. */
088    private final String authorizationID;
089
090    private final boolean isCritical;
091
092    /** A decoder which can be used for decoding the authorization identity response control. */
093    public static final ControlDecoder<AuthorizationIdentityResponseControl> DECODER =
094            new ControlDecoder<AuthorizationIdentityResponseControl>() {
095
096                @Override
097                public AuthorizationIdentityResponseControl decodeControl(final Control control,
098                        final DecodeOptions options) throws DecodeException {
099                    Reject.ifNull(control);
100
101                    if (control instanceof AuthorizationIdentityResponseControl) {
102                        return (AuthorizationIdentityResponseControl) control;
103                    }
104
105                    if (!control.getOID().equals(OID)) {
106                        final LocalizableMessage message =
107                                ERR_AUTHZIDRESP_CONTROL_BAD_OID.get(control.getOID(), OID);
108                        throw DecodeException.error(message);
109                    }
110
111                    if (!control.hasValue()) {
112                        // The response control must always have a value.
113                        final LocalizableMessage message = ERR_AUTHZIDRESP_NO_CONTROL_VALUE.get();
114                        throw DecodeException.error(message);
115                    }
116
117                    final String authID = control.getValue().toString();
118                    return new AuthorizationIdentityResponseControl(control.isCritical(), authID);
119                }
120
121                @Override
122                public String getOID() {
123                    return OID;
124                }
125            };
126
127    /** Prevent direct instantiation. */
128    private AuthorizationIdentityResponseControl(final boolean isCritical,
129            final String authorizationID) {
130        Reject.ifNull(authorizationID);
131        this.isCritical = isCritical;
132        this.authorizationID = authorizationID;
133    }
134
135    /**
136     * Returns the authorization ID of the user. The authorization ID usually
137     * has the form "dn:" immediately followed by the distinguished name of the
138     * user, or "u:" followed by a user ID string, but other forms are
139     * permitted.
140     *
141     * @return The authorization ID of the user.
142     */
143    public String getAuthorizationID() {
144        return authorizationID;
145    }
146
147    @Override
148    public String getOID() {
149        return OID;
150    }
151
152    @Override
153    public ByteString getValue() {
154        return ByteString.valueOfUtf8(authorizationID);
155    }
156
157    @Override
158    public boolean hasValue() {
159        return true;
160    }
161
162    @Override
163    public boolean isCritical() {
164        return isCritical;
165    }
166
167    @Override
168    public String toString() {
169        final StringBuilder builder = new StringBuilder();
170        builder.append("AuthorizationIdentityResponseControl(oid=");
171        builder.append(getOID());
172        builder.append(", criticality=");
173        builder.append(isCritical());
174        builder.append(", authzID=\"");
175        builder.append(authorizationID);
176        builder.append("\")");
177        return builder.toString();
178    }
179
180}