View Javadoc
1   /*
2    * Copyright 2019-2020 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.bremersee.data.ldaptive.transcoder;
18  
19  import java.util.Optional;
20  import lombok.ToString;
21  import lombok.extern.slf4j.Slf4j;
22  import org.ldaptive.transcode.AbstractStringValueTranscoder;
23  import org.springframework.util.StringUtils;
24  
25  /**
26   * The user account control value transcoder.
27   *
28   * @author Christian Bremer
29   */
30  @ToString
31  @Slf4j
32  public class UserAccountControlValueTranscoder extends AbstractStringValueTranscoder<Integer> {
33  
34    /**
35     * The attribute name in an active directory controller.
36     */
37    public static final String ATTRIBUTE_NAME = "userAccountControl";
38  
39    /**
40     * The bit map value of a disabled account.
41     */
42    public static final int ACCOUNT_DISABLED = 1 << 1;
43  
44    /**
45     * The bit map value of a normal account.
46     */
47    public static final int NORMAL_ACCOUNT = 1 << 9;
48  
49    /**
50     * The bit map value a password that doesn't expire.
51     */
52    public static final int DONT_EXPIRE_PASSWORD = 1 << 16;
53  
54    /**
55     * Gets user account control value.
56     *
57     * @param enabled the enabled
58     * @param existingValue the existing value
59     * @return the user account control value
60     */
61    public static int getUserAccountControlValue(Boolean enabled, Integer existingValue) {
62      int value = Optional.ofNullable(existingValue).orElse(0);
63      if ((value & NORMAL_ACCOUNT) != NORMAL_ACCOUNT) {
64        value = value + NORMAL_ACCOUNT;
65      }
66      if ((value & DONT_EXPIRE_PASSWORD) != DONT_EXPIRE_PASSWORD) {
67        value = value + DONT_EXPIRE_PASSWORD;
68      }
69      if (Boolean.FALSE.equals(enabled)) {
70        if ((value & ACCOUNT_DISABLED) != ACCOUNT_DISABLED) {
71          value = value + ACCOUNT_DISABLED;
72        }
73      } else {
74        if ((value & ACCOUNT_DISABLED) == ACCOUNT_DISABLED) {
75          value = value - ACCOUNT_DISABLED;
76        }
77      }
78      return value;
79    }
80  
81    /**
82     * Determines whether an account is enabled or not. If the user account control value is {@code null}, {@code true}
83     * will be returned (account is enabled).
84     *
85     * @param userAccountControlValue the user account control value (can be {@code null})
86     * @return the boolean
87     */
88    public static boolean isUserAccountEnabled(Integer userAccountControlValue) {
89      return isUserAccountEnabled(userAccountControlValue, true);
90    }
91  
92    /**
93     * Determines whether an account is enabled or not.
94     *
95     * @param userAccountControlValue the user account control value (can be {@code null})
96     * @param defaultValue the default value (will be returned, if user account control value is {@code null})
97     * @return the boolean
98     */
99    public static boolean isUserAccountEnabled(Integer userAccountControlValue, boolean defaultValue) {
100     return userAccountControlValue == null
101         ? defaultValue
102         : ((userAccountControlValue & ACCOUNT_DISABLED) != ACCOUNT_DISABLED);
103   }
104 
105   @Override
106   public Integer decodeStringValue(String value) {
107     return StringUtils.hasText(value)
108         ? Integer.parseInt(value)
109         : getUserAccountControlValue(true, 0);
110   }
111 
112   @Override
113   public String encodeStringValue(Integer value) {
114     return Optional.ofNullable(value)
115         .map(String::valueOf)
116         .orElseGet(() -> String.valueOf(getUserAccountControlValue(true, 0)));
117   }
118 
119   @Override
120   public Class<Integer> getType() {
121     return Integer.class;
122   }
123 }