001/*
002 * Copyright 2012-2021 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright 2012-2021 Ping Identity Corporation
007 *
008 * Licensed under the Apache License, Version 2.0 (the "License");
009 * you may not use this file except in compliance with the License.
010 * You may obtain a copy of the License at
011 *
012 *    http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing, software
015 * distributed under the License is distributed on an "AS IS" BASIS,
016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017 * See the License for the specific language governing permissions and
018 * limitations under the License.
019 */
020/*
021 * Copyright (C) 2012-2021 Ping Identity Corporation
022 *
023 * This program is free software; you can redistribute it and/or modify
024 * it under the terms of the GNU General Public License (GPLv2 only)
025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
026 * as published by the Free Software Foundation.
027 *
028 * This program is distributed in the hope that it will be useful,
029 * but WITHOUT ANY WARRANTY; without even the implied warranty of
030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
031 * GNU General Public License for more details.
032 *
033 * You should have received a copy of the GNU General Public License
034 * along with this program; if not, see <http://www.gnu.org/licenses>.
035 */
036package com.unboundid.ldap.sdk.unboundidds.controls;
037
038
039
040import java.util.ArrayList;
041import java.util.Collections;
042import java.util.Iterator;
043import java.util.List;
044
045import com.unboundid.asn1.ASN1Element;
046import com.unboundid.asn1.ASN1Long;
047import com.unboundid.asn1.ASN1OctetString;
048import com.unboundid.asn1.ASN1Sequence;
049import com.unboundid.asn1.ASN1Set;
050import com.unboundid.ldap.sdk.Attribute;
051import com.unboundid.ldap.sdk.Control;
052import com.unboundid.ldap.sdk.BindResult;
053import com.unboundid.ldap.sdk.DecodeableControl;
054import com.unboundid.ldap.sdk.LDAPException;
055import com.unboundid.ldap.sdk.ResultCode;
056import com.unboundid.util.Debug;
057import com.unboundid.util.NotMutable;
058import com.unboundid.util.NotNull;
059import com.unboundid.util.Nullable;
060import com.unboundid.util.StaticUtils;
061import com.unboundid.util.ThreadSafety;
062import com.unboundid.util.ThreadSafetyLevel;
063
064import static com.unboundid.ldap.sdk.unboundidds.controls.ControlMessages.*;
065
066
067
068/**
069 * This class provides a response control that may be included in the response
070 * to a successful bind operation in order to provide information about custom
071 * resource limits for the user, including size limit, time limit, idle time
072 * limit, lookthrough limit, equivalent authorization user DN, and client
073 * connection policy name.
074 * <BR>
075 * <BLOCKQUOTE>
076 *   <B>NOTE:</B>  This class, and other classes within the
077 *   {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only
078 *   supported for use against Ping Identity, UnboundID, and
079 *   Nokia/Alcatel-Lucent 8661 server products.  These classes provide support
080 *   for proprietary functionality or for external specifications that are not
081 *   considered stable or mature enough to be guaranteed to work in an
082 *   interoperable way with other types of LDAP servers.
083 * </BLOCKQUOTE>
084 * <BR>
085 * The criticality for this control should be {@code false}.  It must have a
086 * value with the following encoding:
087 * <PRE>
088 *   USER_RESOURCE_LIMITS_VALUE ::= SEQUENCE {
089 *     sizeLimit                      [0] INTEGER OPTIONAL,
090 *     timeLimitSeconds               [1] INTEGER OPTIONAL,
091 *     idleTimeLimitSeconds           [2] INTEGER OPTIONAL,
092 *     lookthroughLimit               [3] INTEGER OPTIONAL,
093 *     equivalentAuthzUserDN          [4] LDAPDN OPTIONAL,
094 *     clientConnectionPolicyName     [5] OCTET STRING OPTIONAL,
095 *     groupDNs                       [6] SET OF OCTET STRING OPTIONAL,
096 *     privilegeNames                 [7] SET OF OCTET STRING OPTIONAL,
097 *     otherAttributes                [8] PartialAttributeList OPTIONAL,
098 *     ... }
099 * </PRE>
100 *
101 * @see GetUserResourceLimitsRequestControl
102 */
103@NotMutable()
104@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
105public final class GetUserResourceLimitsResponseControl
106       extends Control
107       implements DecodeableControl
108{
109  /**
110   * The OID (1.3.6.1.4.1.30221.2.5.26) for the get user resource limits
111   * response control.
112   */
113  @NotNull public static final String GET_USER_RESOURCE_LIMITS_RESPONSE_OID =
114       "1.3.6.1.4.1.30221.2.5.26";
115
116
117
118  /**
119   * The BER type for the value element used to specify the size limit.
120   */
121  private static final byte TYPE_SIZE_LIMIT = (byte) 0x80;
122
123
124
125  /**
126   * The BER type for the value element used to specify the time limit.
127   */
128  private static final byte TYPE_TIME_LIMIT = (byte) 0x81;
129
130
131
132  /**
133   * The BER type for the value element used to specify the idle time limit.
134   */
135  private static final byte TYPE_IDLE_TIME_LIMIT = (byte) 0x82;
136
137
138
139  /**
140   * The BER type for the value element used to specify the lookthrough limit.
141   */
142  private static final byte TYPE_LOOKTHROUGH_LIMIT = (byte) 0x83;
143
144
145
146  /**
147   * The BER type for the value element used to specify the equivalent
148   * authorization user DN.
149   */
150  private static final byte TYPE_EQUIVALENT_AUTHZ_USER_DN = (byte) 0x84;
151
152
153
154  /**
155   * The BER type for the value element used to specify the client connection
156   * policy name.
157   */
158  private static final byte TYPE_CLIENT_CONNECTION_POLICY_NAME = (byte) 0x85;
159
160
161
162  /**
163   * The BER type for the value element used to specify the DNs of groups in
164   * which the user is a member.
165   */
166  private static final byte TYPE_GROUP_DNS = (byte) 0xA6;
167
168
169
170  /**
171   * The BER type for the value element used to specify the set of user
172   * privilege names.
173   */
174  private static final byte TYPE_PRIVILEGE_NAMES = (byte) 0xA7;
175
176
177
178  /**
179   * The BER type for the value element used to specify additional attributes
180   * that may be included in the future.
181   */
182  private static final byte TYPE_OTHER_ATTRIBUTES = (byte) 0xA8;
183
184
185
186  /**
187   * The serial version UID for this serializable class.
188   */
189  private static final long serialVersionUID = -5261978490319320250L;
190
191
192
193  // The set of other select attributes from the user entry.
194  @NotNull private final List<Attribute> otherAttributes;
195
196  // The set of group DNs for the user.
197  @Nullable private final List<String> groupDNs;
198
199  // The set of privilege names for the user.
200  @Nullable private final List<String> privilegeNames;
201
202  // The custom idle time limit for the user.
203  @Nullable private final Long idleTimeLimitSeconds;
204
205  // The custom lookthrough limit for the user.
206  @Nullable private final Long lookthroughLimit;
207
208  // The custom size limit for the user.
209  @Nullable private final Long sizeLimit;
210
211  // The custom time limit for the user, in seconds.
212  @Nullable private final Long timeLimitSeconds;
213
214  // The name of the client connection policy selected for the user.
215  @Nullable private final String clientConnectionPolicyName;
216
217  // The DN of a user with equivalent authorization rights for use in servers
218  // in an entry-balancing environment in which the user's entry does not exist.
219  @Nullable private final String equivalentAuthzUserDN;
220
221
222
223  /**
224   * Creates a new empty control instance that is intended to be used only for
225   * decoding controls via the {@code DecodeableControl} interface.
226   */
227  GetUserResourceLimitsResponseControl()
228  {
229    otherAttributes            = null;
230    groupDNs                   = null;
231    privilegeNames             = null;
232    idleTimeLimitSeconds       = null;
233    lookthroughLimit           = null;
234    sizeLimit                  = null;
235    timeLimitSeconds           = null;
236    clientConnectionPolicyName = null;
237    equivalentAuthzUserDN      = null;
238  }
239
240
241
242  /**
243   * Creates a new get user resource limits response control with the provided
244   * information.
245   *
246   * @param  sizeLimit                   The custom size limit for the user.
247   *                                     It may be less than or equal to zero
248   *                                     if no size limit should be enforced for
249   *                                     the user.  It may be {@code null} if
250   *                                     there is no custom size limit or it is
251   *                                     not to be included in the control.
252   * @param  timeLimitSeconds            The custom time limit for the user, in
253   *                                     seconds.  It may be less than or equal
254   *                                     to zero if no time limit should be
255   *                                     enforced for the user.  It may be
256   *                                     {@code null} if there is no custom time
257   *                                     limit or it is not to be included in
258   *                                     the control.
259   * @param  idleTimeLimitSeconds        The custom idle time limit for the
260   *                                     user, in seconds.  It may be less than
261   *                                     or equal to zero if no idle time limit
262   *                                     should be enforced for the user.  It
263   *                                     may be {@code null} if there is no
264   *                                     custom idle time limit or it is not to
265   *                                     be included in the control.
266   * @param  lookthroughLimit            The custom lookthrough limit for the
267   *                                     user.  It may be less than or equal to
268   *                                     zero if no lookthrough limit should
269   *                                     be enforced for the user.  It may be
270   *                                     {@code null} if there is no custom
271   *                                     lookthrough limit for the user or it is
272   *                                     not to be included in the control.
273   * @param  equivalentAuthzUserDN       The DN of a user with equivalent
274   *                                     authorization rights for use in servers
275   *                                     in an entry-balancing environment in
276   *                                     which the user's entry does not exist.
277   *                                     It may be an empty string if the
278   *                                     equivalent authorization should be
279   *                                     anonymous, or {@code null} if there is
280   *                                     no custom equivalent authorization user
281   *                                     DN or it is not to be included in the
282   *                                     control.
283   * @param  clientConnectionPolicyName  The name of the client connection
284   *                                     policy that has been assigned to the
285   *                                     user, or {@code null} if the client
286   *                                     connection policy name is not to be
287   *                                     included in the control.
288   */
289  public GetUserResourceLimitsResponseControl(@Nullable final Long sizeLimit,
290              @Nullable final Long timeLimitSeconds,
291              @Nullable final Long idleTimeLimitSeconds,
292              @Nullable final Long lookthroughLimit,
293              @Nullable final String equivalentAuthzUserDN,
294              @Nullable final String clientConnectionPolicyName)
295  {
296    this(sizeLimit, timeLimitSeconds, idleTimeLimitSeconds, lookthroughLimit,
297         equivalentAuthzUserDN, clientConnectionPolicyName, null, null, null);
298  }
299
300
301
302  /**
303   * Creates a new get user resource limits response control with the provided
304   * information.
305   *
306   * @param  sizeLimit                   The custom size limit for the user.
307   *                                     It may be less than or equal to zero
308   *                                     if no size limit should be enforced for
309   *                                     the user.  It may be {@code null} if
310   *                                     there is no custom size limit or it is
311   *                                     not to be included in the control.
312   * @param  timeLimitSeconds            The custom time limit for the user, in
313   *                                     seconds.  It may be less than or equal
314   *                                     to zero if no time limit should be
315   *                                     enforced for the user.  It may be
316   *                                     {@code null} if there is no custom time
317   *                                     limit or it is not to be included in
318   *                                     the control.
319   * @param  idleTimeLimitSeconds        The custom idle time limit for the
320   *                                     user, in seconds.  It may be less than
321   *                                     or equal to zero if no idle time limit
322   *                                     should be enforced for the user.  It
323   *                                     may be {@code null} if there is no
324   *                                     custom idle time limit or it is not to
325   *                                     be included in the control.
326   * @param  lookthroughLimit            The custom lookthrough limit for the
327   *                                     user.  It may be less than or equal to
328   *                                     zero if no lookthrough limit should
329   *                                     be enforced for the user.  It may be
330   *                                     {@code null} if there is no custom
331   *                                     lookthrough limit for the user or it is
332   *                                     not to be included in the control.
333   * @param  equivalentAuthzUserDN       The DN of a user with equivalent
334   *                                     authorization rights for use in servers
335   *                                     in an entry-balancing environment in
336   *                                     which the user's entry does not exist.
337   *                                     It may be an empty string if the
338   *                                     equivalent authorization should be
339   *                                     anonymous, or {@code null} if there is
340   *                                     no custom equivalent authorization user
341   *                                     DN or it is not to be included in the
342   *                                     control.
343   * @param  clientConnectionPolicyName  The name of the client connection
344   *                                     policy that has been assigned to the
345   *                                     user, or {@code null} if the client
346   *                                     connection policy name is not to be
347   *                                     included in the control.
348   * @param  groupDNs                    The DNs of the groups in which the user
349   *                                     is a member.  It may be {@code null} if
350   *                                     group membership is not known, or
351   *                                     empty if the user isn't a member of any
352   *                                     groups.
353   * @param  privilegeNames              The names of the privileges assigned to
354   *                                     the user.  It may be {@code null} if
355   *                                     the privilege names are not known, or
356   *                                     empty if the  user doesn't have any
357   *                                     privileges.
358   * @param  otherAttributes             A set of additional attributes from the
359   *                                     user's entry.  It may be {@code null}
360   *                                     or empty if no additional attributes
361   *                                     are needed.
362   */
363  public GetUserResourceLimitsResponseControl(@Nullable final Long sizeLimit,
364              @Nullable final Long timeLimitSeconds,
365              @Nullable final Long idleTimeLimitSeconds,
366              @Nullable final Long lookthroughLimit,
367              @Nullable final String equivalentAuthzUserDN,
368              @Nullable final String clientConnectionPolicyName,
369              @Nullable final List<String> groupDNs,
370              @Nullable final List<String> privilegeNames,
371              @Nullable final List<Attribute> otherAttributes)
372  {
373    super(GET_USER_RESOURCE_LIMITS_RESPONSE_OID, false,
374         encodeValue(sizeLimit, timeLimitSeconds, idleTimeLimitSeconds,
375              lookthroughLimit, equivalentAuthzUserDN,
376              clientConnectionPolicyName, groupDNs, privilegeNames,
377              otherAttributes));
378
379    if ((sizeLimit == null) || (sizeLimit > 0L))
380    {
381      this.sizeLimit = sizeLimit;
382    }
383    else
384    {
385      this.sizeLimit = -1L;
386    }
387
388    if ((timeLimitSeconds == null) || (timeLimitSeconds > 0L))
389    {
390      this.timeLimitSeconds = timeLimitSeconds;
391    }
392    else
393    {
394      this.timeLimitSeconds = -1L;
395    }
396
397    if ((idleTimeLimitSeconds == null) || (idleTimeLimitSeconds > 0L))
398    {
399      this.idleTimeLimitSeconds = idleTimeLimitSeconds;
400    }
401    else
402    {
403      this.idleTimeLimitSeconds = -1L;
404    }
405
406    if ((lookthroughLimit == null) || (lookthroughLimit > 0L))
407    {
408      this.lookthroughLimit = lookthroughLimit;
409    }
410    else
411    {
412      this.lookthroughLimit = -1L;
413    }
414
415    this.equivalentAuthzUserDN      = equivalentAuthzUserDN;
416    this.clientConnectionPolicyName = clientConnectionPolicyName;
417
418    if (groupDNs == null)
419    {
420      this.groupDNs = null;
421    }
422    else
423    {
424      this.groupDNs =
425           Collections.unmodifiableList(new ArrayList<>(groupDNs));
426    }
427
428    if (privilegeNames == null)
429    {
430      this.privilegeNames = null;
431    }
432    else
433    {
434      this.privilegeNames =
435           Collections.unmodifiableList(new ArrayList<>(privilegeNames));
436    }
437
438    if (otherAttributes == null)
439    {
440      this.otherAttributes = Collections.emptyList();
441    }
442    else
443    {
444      this.otherAttributes =
445           Collections.unmodifiableList(new ArrayList<>(otherAttributes));
446    }
447  }
448
449
450
451  /**
452   * Encodes the provided information into an octet string suitable for use as
453   * the value of a get user resource limits response control.
454   *
455   * @param  sizeLimit                   The custom size limit for the user.
456   *                                     It may be less than or equal to zero
457   *                                     if no size limit should be enforced for
458   *                                     the user.  It may be {@code null} if
459   *                                     there is no custom size limit or it is
460   *                                     not to be included in the control.
461   * @param  timeLimitSeconds            The custom time limit for the user, in
462   *                                     seconds.  It may be less than or equal
463   *                                     to zero if no time limit should be
464   *                                     enforced for the user.  It may be
465   *                                     {@code null} if there is no custom time
466   *                                     limit or it is not to be included in
467   *                                     the control.
468   * @param  idleTimeLimitSeconds        The custom idle time limit for the
469   *                                     user, in seconds.  It may be less than
470   *                                     or equal to zero if no idle time limit
471   *                                     should be enforced for the user.  It
472   *                                     may be {@code null} if there is no
473   *                                     custom idle time limit or it is not to
474   *                                     be included in the control.
475   * @param  lookthroughLimit            The custom lookthrough limit for the
476   *                                     user.  It may be less than or equal to
477   *                                     zero if no lookthrough limit should
478   *                                     be enforced for the user.  It may be
479   *                                     {@code null} if there is no custom
480   *                                     lookthrough limit for the user or it is
481   *                                     not to be included in the control.
482   * @param  equivalentAuthzUserDN       The DN of a user with equivalent
483   *                                     authorization rights for use in servers
484   *                                     in an entry-balancing environment in
485   *                                     which the user's entry does not exist.
486   * @param  clientConnectionPolicyName  The name of the client connection
487   *                                     policy that has been assigned to the
488   *                                     user, or {@code null} if the client
489   *                                     connection policy name is not to be
490   *                                     included in the control.
491   * @param  groupDNs                    The DNs of the groups in which the user
492   *                                     is a member.  It may be {@code null} if
493   *                                     group membership is not known, or
494   *                                     empty if the user isn't a member of any
495   *                                     groups.
496   * @param  privilegeNames              The names of the privileges assigned to
497   *                                     the user.  It may be {@code null} if
498   *                                     the privilege names are not known, or
499   *                                     empty if the  user doesn't have any
500   *                                     privileges.
501   * @param  otherAttributes             A set of additional attributes from the
502   *                                     user's entry.  It may be {@code null}
503   *                                     or empty if no additional attributes
504   *                                     are needed.
505   *
506   * @return  The octet string which may be used as the value of a get user
507   *          resource limits response control
508   */
509  @NotNull()
510  private static ASN1OctetString encodeValue(@Nullable final Long sizeLimit,
511              @Nullable final Long timeLimitSeconds,
512              @Nullable final Long idleTimeLimitSeconds,
513              @Nullable final Long lookthroughLimit,
514              @Nullable final String equivalentAuthzUserDN,
515              @Nullable final String clientConnectionPolicyName,
516              @Nullable final List<String> groupDNs,
517              @Nullable final List<String> privilegeNames,
518              @Nullable final List<Attribute> otherAttributes)
519  {
520    final ArrayList<ASN1Element> elements = new ArrayList<>(10);
521
522    if (sizeLimit != null)
523    {
524      if (sizeLimit > 0L)
525      {
526        elements.add(new ASN1Long(TYPE_SIZE_LIMIT, sizeLimit));
527      }
528      else
529      {
530        elements.add(new ASN1Long(TYPE_SIZE_LIMIT, -1L));
531      }
532    }
533
534    if (timeLimitSeconds != null)
535    {
536      if (timeLimitSeconds > 0L)
537      {
538        elements.add(new ASN1Long(TYPE_TIME_LIMIT, timeLimitSeconds));
539      }
540      else
541      {
542        elements.add(new ASN1Long(TYPE_TIME_LIMIT, -1L));
543      }
544    }
545
546    if (idleTimeLimitSeconds != null)
547    {
548      if (idleTimeLimitSeconds > 0L)
549      {
550        elements.add(new ASN1Long(TYPE_IDLE_TIME_LIMIT, idleTimeLimitSeconds));
551      }
552      else
553      {
554        elements.add(new ASN1Long(TYPE_IDLE_TIME_LIMIT, -1L));
555      }
556    }
557
558    if (lookthroughLimit != null)
559    {
560      if (lookthroughLimit > 0L)
561      {
562        elements.add(new ASN1Long(TYPE_LOOKTHROUGH_LIMIT, lookthroughLimit));
563      }
564      else
565      {
566        elements.add(new ASN1Long(TYPE_LOOKTHROUGH_LIMIT, -1L));
567      }
568    }
569
570    if (equivalentAuthzUserDN != null)
571    {
572      elements.add(new ASN1OctetString(TYPE_EQUIVALENT_AUTHZ_USER_DN,
573           equivalentAuthzUserDN));
574    }
575
576    if (clientConnectionPolicyName != null)
577    {
578      elements.add(new ASN1OctetString(TYPE_CLIENT_CONNECTION_POLICY_NAME,
579           clientConnectionPolicyName));
580    }
581
582    if (groupDNs != null)
583    {
584      final ArrayList<ASN1Element> dnElements =
585           new ArrayList<>(groupDNs.size());
586      for (final String s : groupDNs)
587      {
588        dnElements.add(new ASN1OctetString(s));
589      }
590
591      elements.add(new ASN1Set(TYPE_GROUP_DNS, dnElements));
592    }
593
594    if (privilegeNames != null)
595    {
596      final ArrayList<ASN1Element> privElements =
597           new ArrayList<>(privilegeNames.size());
598      for (final String s : privilegeNames)
599      {
600        privElements.add(new ASN1OctetString(s));
601      }
602
603      elements.add(new ASN1Set(TYPE_PRIVILEGE_NAMES, privElements));
604    }
605
606    if ((otherAttributes != null) && (! otherAttributes.isEmpty()))
607    {
608      final ArrayList<ASN1Element> attrElements =
609           new ArrayList<>(otherAttributes.size());
610      for (final Attribute a : otherAttributes)
611      {
612        attrElements.add(a.encode());
613      }
614
615      elements.add(new ASN1Sequence(TYPE_OTHER_ATTRIBUTES, attrElements));
616    }
617
618    return new ASN1OctetString(new ASN1Sequence(elements).encode());
619  }
620
621
622
623  /**
624   * Creates a new get user resource limits response control decoded from the
625   * given generic control contents.
626   *
627   * @param  oid         The OID for the control.
628   * @param  isCritical  Indicates whether this control should be marked
629   *                     critical.
630   * @param  value       The value for the control.  It may be {@code null} if
631   *                     the control to decode does not have a value.
632   *
633   * @throws  LDAPException  If a problem occurs while attempting to decode the
634   *                         generic control as a get user resource limits
635   *                         response control.
636   */
637  public GetUserResourceLimitsResponseControl(@NotNull final String oid,
638              final boolean isCritical,
639              @Nullable final ASN1OctetString value)
640         throws LDAPException
641  {
642    super(oid, isCritical, value);
643
644    if (value == null)
645    {
646      throw new LDAPException(ResultCode.DECODING_ERROR,
647           ERR_GET_USER_RESOURCE_LIMITS_RESPONSE_MISSING_VALUE.get());
648    }
649
650
651    List<Attribute> oa   = Collections.emptyList();
652    List<String>    gd   = null;
653    List<String>    pn   = null;
654    Long            sL   = null;
655    Long            tL   = null;
656    Long            iTL  = null;
657    Long            lL   = null;
658    String          eAUD = null;
659    String          cCPN = null;
660
661    try
662    {
663      final ASN1Element[] elements =
664           ASN1Sequence.decodeAsSequence(value.getValue()).elements();
665      for (final ASN1Element e : elements)
666      {
667        switch (e.getType())
668        {
669          case TYPE_SIZE_LIMIT:
670            sL = ASN1Long.decodeAsLong(e).longValue();
671            break;
672          case TYPE_TIME_LIMIT:
673            tL = ASN1Long.decodeAsLong(e).longValue();
674            break;
675          case TYPE_IDLE_TIME_LIMIT:
676            iTL = ASN1Long.decodeAsLong(e).longValue();
677            break;
678          case TYPE_LOOKTHROUGH_LIMIT:
679            lL = ASN1Long.decodeAsLong(e).longValue();
680            break;
681          case TYPE_EQUIVALENT_AUTHZ_USER_DN:
682            eAUD = ASN1OctetString.decodeAsOctetString(e).stringValue();
683            break;
684          case TYPE_CLIENT_CONNECTION_POLICY_NAME:
685            cCPN = ASN1OctetString.decodeAsOctetString(e).stringValue();
686            break;
687          case TYPE_GROUP_DNS:
688            final ASN1Element[] groupElements =
689                 ASN1Set.decodeAsSet(e).elements();
690            gd = new ArrayList<>(groupElements.length);
691            for (final ASN1Element pe : groupElements)
692            {
693              gd.add(ASN1OctetString.decodeAsOctetString(pe).stringValue());
694            }
695            gd = Collections.unmodifiableList(gd);
696            break;
697          case TYPE_PRIVILEGE_NAMES:
698            final ASN1Element[] privElements =
699                 ASN1Set.decodeAsSet(e).elements();
700            pn = new ArrayList<>(privElements.length);
701            for (final ASN1Element pe : privElements)
702            {
703              pn.add(ASN1OctetString.decodeAsOctetString(pe).stringValue());
704            }
705            pn = Collections.unmodifiableList(pn);
706            break;
707          case TYPE_OTHER_ATTRIBUTES:
708            final ASN1Element[] attrElemnets =
709                 ASN1Sequence.decodeAsSequence(e).elements();
710            oa = new ArrayList<>(attrElemnets.length);
711            for (final ASN1Element ae : attrElemnets)
712            {
713              oa.add(Attribute.decode(ASN1Sequence.decodeAsSequence(ae)));
714            }
715            oa = Collections.unmodifiableList(oa);
716            break;
717          default:
718            // No action will be taken.  It may be the case that a future
719            // version of the control could return additional information.
720            break;
721        }
722      }
723    }
724    catch (final Exception e)
725    {
726      Debug.debugException(e);
727      throw new LDAPException(ResultCode.DECODING_ERROR,
728           ERR_GET_USER_RESOURCE_LIMITS_RESPONSE_CANNOT_DECODE_VALUE.get(
729                StaticUtils.getExceptionMessage(e)),
730           e);
731    }
732
733    otherAttributes            = oa;
734    groupDNs                   = gd;
735    privilegeNames             = pn;
736    sizeLimit                  = sL;
737    timeLimitSeconds           = tL;
738    idleTimeLimitSeconds       = iTL;
739    lookthroughLimit           = lL;
740    equivalentAuthzUserDN      = eAUD;
741    clientConnectionPolicyName = cCPN;
742  }
743
744
745
746  /**
747   * {@inheritDoc}
748   */
749  @Override()
750  @NotNull()
751  public GetUserResourceLimitsResponseControl decodeControl(
752              @NotNull final String oid,
753              final boolean isCritical,
754              @Nullable final ASN1OctetString value)
755         throws LDAPException
756  {
757    return new GetUserResourceLimitsResponseControl(oid, isCritical, value);
758  }
759
760
761
762  /**
763   * Extracts a get user resource limits response control from the provided
764   * result.
765   *
766   * @param  result  The bind result from which to retrieve the get user
767   *                 resource limits response control.
768   *
769   * @return  The get user resource limits response control contained in the
770   *          provided result, or {@code null} if the result did not contain a
771   *          get user resource limits response control.
772   *
773   * @throws  LDAPException  If a problem is encountered while attempting to
774   *                         decode the get user resource limits response
775   *                         control contained in the provided result.
776   */
777  @Nullable()
778  public static GetUserResourceLimitsResponseControl get(
779                     @NotNull final BindResult result)
780         throws LDAPException
781  {
782    final Control c =
783         result.getResponseControl(GET_USER_RESOURCE_LIMITS_RESPONSE_OID);
784    if (c == null)
785    {
786      return null;
787    }
788
789    if (c instanceof GetUserResourceLimitsResponseControl)
790    {
791      return (GetUserResourceLimitsResponseControl) c;
792    }
793    else
794    {
795      return new GetUserResourceLimitsResponseControl(c.getOID(),
796           c.isCritical(), c.getValue());
797    }
798  }
799
800
801
802  /**
803   * Retrieves the custom size limit for the user, if available.
804   *
805   * @return  The custom size limit for the user, -1 if no size limit should be
806   *          enforced for the user, or {@code null} if no custom size limit
807   *          was included in the control.
808   */
809  @Nullable()
810  public Long getSizeLimit()
811  {
812    return sizeLimit;
813  }
814
815
816
817  /**
818   * Retrieves the custom time limit for the user in seconds, if available.
819   *
820   * @return  The custom time limit for the user in seconds, -1 if no time limit
821   *          should be enforced for the user, or {@code null} if no custom time
822   *          limit was included in the control.
823   */
824  @Nullable()
825  public Long getTimeLimitSeconds()
826  {
827    return timeLimitSeconds;
828  }
829
830
831
832  /**
833   * Retrieves the custom idle time limit for the user in seconds, if available.
834   *
835   * @return  The custom idle time limit for the user in seconds, -1 if no idle
836   *          time limit should be enforced for the user, or {@code null} if no
837   *          custom idle time limit was included in the control.
838   */
839  @Nullable()
840  public Long getIdleTimeLimitSeconds()
841  {
842    return idleTimeLimitSeconds;
843  }
844
845
846
847  /**
848   * Retrieves the custom lookthrough limit for the user, if available.
849   *
850   * @return  The custom lookthrough limit for the user, -1 if no lookthrough
851   *          limit should be enforced for the user, or {@code null} if no
852   *          custom lookthrough limit was included in the control.
853   */
854  @Nullable()
855  public Long getLookthroughLimit()
856  {
857    return lookthroughLimit;
858  }
859
860
861
862  /**
863   * Retrieves the equivalent authorization user DN, for use in servers in an
864   * entry-balancing environment in which the user's entry does not exist.
865   *
866   * @return  The equivalent authorization user DN for the user, an empty string
867   *          if the equivalent authorization is anonymous, or {@code null} if
868   *          no equivalent authorization user DN was included in the control.
869   */
870  @Nullable()
871  public String getEquivalentAuthzUserDN()
872  {
873    return equivalentAuthzUserDN;
874  }
875
876
877
878  /**
879   * Retrieves the name of the client connection policy that has been assigned
880   * to the user, if available.
881   *
882   * @return  The name of the client connection policy that has been assigned to
883   *          the user, or {@code null} if the client connection policy name was
884   *          not included in the control.
885   */
886  @Nullable()
887  public String getClientConnectionPolicyName()
888  {
889    return clientConnectionPolicyName;
890  }
891
892
893
894  /**
895   * Retrieves the DNs of any groups in which the user is a member.
896   *
897   * @return  The DNs of any groups in which the user is a member, an empty list
898   *          if the user is not a member of any groups, or {@code null} if the
899   *           set of group DNs is not known.
900   */
901  @Nullable()
902  public List<String> getGroupDNs()
903  {
904    return groupDNs;
905  }
906
907
908
909  /**
910   * Retrieves the names of any privileges assigned to the user.
911   *
912   * @return  The names of any privileges assigned to the user, an empty list if
913   *          the user is known to have no privileges, or {@code null} if the
914   *          set of user privileges is not known.
915   */
916  @Nullable()
917  public List<String> getPrivilegeNames()
918  {
919    return privilegeNames;
920  }
921
922
923
924  /**
925   * Retrieves a list containing additional attributes from the user's entry.
926   *
927   * @return  A list containing additional attributes from the user's entry, or
928   *          an empty list if no additional attributes were provided.
929   */
930  @NotNull
931  public List<Attribute> getOtherAttributes()
932  {
933    return otherAttributes;
934  }
935
936
937
938  /**
939   * Retrieves the "other" attribute with the specified name.
940   *
941   * @param  name  The name of the "other" attribute to retrieve.  It must not
942   *               be {@code null}.
943   *
944   * @return  The "other" attribute with the specified name, or {@code null} if
945   *          there is no such "other" attribute.
946   */
947  @Nullable()
948  public Attribute getOtherAttribute(@NotNull final String name)
949  {
950    for (final Attribute a : otherAttributes)
951    {
952      if (a.getName().equalsIgnoreCase(name))
953      {
954        return a;
955      }
956    }
957
958    return null;
959  }
960
961
962
963  /**
964   * {@inheritDoc}
965   */
966  @Override()
967  @NotNull()
968  public String getControlName()
969  {
970    return INFO_CONTROL_NAME_GET_USER_RESOURCE_LIMITS_RESPONSE.get();
971  }
972
973
974
975  /**
976   * {@inheritDoc}
977   */
978  @Override()
979  public void toString(@NotNull final StringBuilder buffer)
980  {
981    buffer.append("GetUserResourceLimitsResponseControl(");
982
983    boolean added = false;
984    if (sizeLimit != null)
985    {
986      buffer.append("sizeLimit=");
987      buffer.append(sizeLimit);
988      added = true;
989    }
990
991    if (timeLimitSeconds != null)
992    {
993      if (added)
994      {
995        buffer.append(", ");
996      }
997
998      buffer.append("timeLimitSeconds=");
999      buffer.append(timeLimitSeconds);
1000      added = true;
1001    }
1002
1003    if (idleTimeLimitSeconds != null)
1004    {
1005      if (added)
1006      {
1007        buffer.append(", ");
1008      }
1009
1010      buffer.append("idleTimeLimitSeconds=");
1011      buffer.append(idleTimeLimitSeconds);
1012      added = true;
1013    }
1014
1015    if (lookthroughLimit != null)
1016    {
1017      if (added)
1018      {
1019        buffer.append(", ");
1020      }
1021
1022      buffer.append("lookthroughLimit=");
1023      buffer.append(lookthroughLimit);
1024      added = true;
1025    }
1026
1027    if (equivalentAuthzUserDN != null)
1028    {
1029      if (added)
1030      {
1031        buffer.append(", ");
1032      }
1033
1034      buffer.append("equivalentAuthzUserDN=\"");
1035      buffer.append(equivalentAuthzUserDN);
1036      buffer.append('"');
1037      added = true;
1038    }
1039
1040    if (clientConnectionPolicyName != null)
1041    {
1042      if (added)
1043      {
1044        buffer.append(", ");
1045      }
1046
1047      buffer.append("clientConnectionPolicyName=\"");
1048      buffer.append(clientConnectionPolicyName);
1049      buffer.append('"');
1050      added = true;
1051    }
1052
1053    if (groupDNs != null)
1054    {
1055      if (added)
1056      {
1057        buffer.append(", ");
1058      }
1059
1060      buffer.append("groupDNs={");
1061
1062      final Iterator<String> dnIterator = groupDNs.iterator();
1063      while (dnIterator.hasNext())
1064      {
1065        buffer.append('"');
1066        buffer.append(dnIterator.next());
1067        buffer.append('"');
1068
1069        if (dnIterator.hasNext())
1070        {
1071          buffer.append(", ");
1072        }
1073      }
1074
1075      buffer.append('}');
1076      added = true;
1077    }
1078
1079    if (privilegeNames != null)
1080    {
1081      if (added)
1082      {
1083        buffer.append(", ");
1084      }
1085
1086      buffer.append("privilegeNames={");
1087
1088      final Iterator<String> privilegeIterator = privilegeNames.iterator();
1089      while (privilegeIterator.hasNext())
1090      {
1091        buffer.append('"');
1092        buffer.append(privilegeIterator.next());
1093        buffer.append('"');
1094
1095        if (privilegeIterator.hasNext())
1096        {
1097          buffer.append(", ");
1098        }
1099      }
1100
1101      buffer.append('}');
1102      added = true;
1103    }
1104
1105    if (! otherAttributes.isEmpty())
1106    {
1107      if (added)
1108      {
1109        buffer.append(", ");
1110      }
1111
1112      buffer.append("otherAttributes={");
1113
1114      final Iterator<Attribute> attrIterator = otherAttributes.iterator();
1115      while (attrIterator.hasNext())
1116      {
1117        attrIterator.next().toString(buffer);
1118
1119        if (attrIterator.hasNext())
1120        {
1121          buffer.append(", ");
1122        }
1123      }
1124
1125      buffer.append('}');
1126    }
1127
1128    buffer.append("')");
1129  }
1130}