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