001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.kernel.ldap;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.util.CharPool;
019    import com.liferay.portal.kernel.util.DateFormatFactoryUtil;
020    import com.liferay.portal.kernel.util.StringPool;
021    import com.liferay.portal.kernel.util.StringUtil;
022    import com.liferay.portal.kernel.util.Validator;
023    
024    import java.text.DateFormat;
025    
026    import java.util.Date;
027    import java.util.Properties;
028    import java.util.regex.Matcher;
029    import java.util.regex.Pattern;
030    
031    import javax.naming.NamingException;
032    import javax.naming.directory.Attribute;
033    import javax.naming.directory.Attributes;
034    
035    /**
036     * @author Toma Bedolla
037     * @author Michael Young
038     * @author Brian Wing Shun Chan
039     * @author James Lefeu
040     */
041    public class LDAPUtil {
042    
043            public static Object getAttributeObject(
044                            Attributes attributes, Properties properties, String key)
045                    throws NamingException {
046    
047                    String id = properties.getProperty(key);
048    
049                    return getAttributeObject(attributes, id);
050            }
051    
052            public static Object getAttributeObject(
053                            Attributes attributes, Properties properties, String key,
054                            Object defaultValue)
055                    throws NamingException {
056    
057                    String id = properties.getProperty(key);
058    
059                    return getAttributeObject(attributes, id, defaultValue);
060            }
061    
062            public static Object getAttributeObject(Attributes attributes, String id)
063                    throws NamingException {
064    
065                    return getAttributeObject(attributes, id, null);
066            }
067    
068            public static Object getAttributeObject(
069                            Attributes attributes, String id, Object defaultValue)
070                    throws NamingException {
071    
072                    if (Validator.isNull(id)) {
073                            return defaultValue;
074                    }
075    
076                    Attribute attribute = attributes.get(id);
077    
078                    if (attribute == null) {
079                            return defaultValue;
080                    }
081    
082                    Object object = attribute.get();
083    
084                    if (object == null) {
085                            return defaultValue;
086                    }
087    
088                    return object;
089            }
090    
091            public static String getAttributeString(
092                            Attributes attributes, Properties properties, String key)
093                    throws NamingException {
094    
095                    String id = properties.getProperty(key);
096    
097                    return getAttributeString(attributes, id);
098            }
099    
100            public static String getAttributeString(
101                            Attributes attributes, Properties properties, String key,
102                            String defaultValue)
103                    throws NamingException {
104    
105                    String id = properties.getProperty(key);
106    
107                    return getAttributeString(attributes, id, defaultValue);
108            }
109    
110            public static String getAttributeString(Attributes attributes, String id)
111                    throws NamingException {
112    
113                    return getAttributeString(attributes, id, StringPool.BLANK);
114            }
115    
116            public static String getAttributeString(
117                            Attributes attributes, String id, String defaultValue)
118                    throws NamingException {
119    
120                    if (Validator.isNull(id)) {
121                            return defaultValue;
122                    }
123    
124                    Attribute attribute = attributes.get(id);
125    
126                    if (attribute == null) {
127                            return defaultValue;
128                    }
129    
130                    Object object = attribute.get();
131    
132                    if (object == null) {
133                            return defaultValue;
134                    }
135    
136                    return object.toString();
137            }
138    
139            public static String[] getAttributeStringArray(
140                            Attributes attributes, Properties properties, String key)
141                    throws NamingException {
142    
143                    String id = properties.getProperty(key);
144    
145                    return getAttributeStringArray(attributes, id);
146            }
147    
148            public static String[] getAttributeStringArray(
149                            Attributes attributes, String id)
150                    throws NamingException {
151    
152                    if (Validator.isNull(id)) {
153                            return null;
154                    }
155    
156                    Attribute attribute = attributes.get(id);
157    
158                    if (attribute == null) {
159                            return new String[0];
160                    }
161    
162                    int size = attribute.size();
163    
164                    if (size == 0) {
165                            return null;
166                    }
167    
168                    String[] array = new String[size];
169    
170                    for (int i = 0; i < size; i++) {
171                            Object object = attribute.get(i);
172    
173                            if (object == null) {
174                                    array[i] = StringPool.BLANK;
175                            }
176                            else {
177                                    array[i] = object.toString();
178                            }
179                    }
180    
181                    return array;
182            }
183    
184            public static String getFullProviderURL(String baseURL, String baseDN) {
185                    return baseURL + StringPool.SLASH + baseDN;
186            }
187    
188            public static boolean isValidFilter(String filter) {
189                    if (Validator.isNull(filter)) {
190                            return true;
191                    }
192    
193                    filter = filter.trim();
194    
195                    if (filter.equals(StringPool.STAR)) {
196                            return true;
197                    }
198    
199                    filter = StringUtil.replace(filter, StringPool.SPACE, StringPool.BLANK);
200    
201                    if (!filter.startsWith(StringPool.OPEN_PARENTHESIS) ||
202                            !filter.endsWith(StringPool.CLOSE_PARENTHESIS)) {
203    
204                            return false;
205                    }
206    
207                    int count = 0;
208    
209                    for (int i = 0; i < filter.length(); i++) {
210                            char c = filter.charAt(i);
211    
212                            if (c == CharPool.CLOSE_PARENTHESIS) {
213                                    count--;
214                            }
215                            else if (c == CharPool.OPEN_PARENTHESIS) {
216                                    count++;
217                            }
218    
219                            if (count < 0) {
220                                    return false;
221                            }
222                    }
223    
224                    if (count > 0) {
225                            return false;
226                    }
227    
228                    // Cannot have two filter types in a sequence
229    
230                    Matcher matcher = _pattern1.matcher(filter);
231    
232                    if (matcher.matches()) {
233                            return false;
234                    }
235    
236                    // Cannot have a filter type after an opening parenthesis
237    
238                    matcher = _pattern2.matcher(filter);
239    
240                    if (matcher.matches()) {
241                            return false;
242                    }
243    
244                    // Cannot have an attribute without a filter type or extensible
245    
246                    matcher = _pattern3.matcher(filter);
247    
248                    if (matcher.matches()) {
249                            return false;
250                    }
251    
252                    matcher = _pattern4.matcher(filter);
253    
254                    if (matcher.matches()) {
255                            return false;
256                    }
257    
258                    return true;
259            }
260    
261            public static Date parseDate(String date) throws Exception {
262                    String format = "yyyyMMddHHmmss";
263    
264                    if (date.endsWith("Z")) {
265                            if (date.indexOf(CharPool.PERIOD) != -1) {
266                                    format = "yyyyMMddHHmmss.S'Z'";
267                            }
268                            else {
269                                    format = "yyyyMMddHHmmss'Z'";
270                            }
271                    }
272                    else if ((date.indexOf(CharPool.DASH) != -1) ||
273                                     (date.indexOf(CharPool.PLUS) != -1)) {
274    
275                            if (date.indexOf(CharPool.PERIOD) != -1) {
276                                    format = "yyyyMMddHHmmss.SSSZ";
277                            }
278                            else {
279                                    format = "yyyyMMddHHmmssZ";
280                            }
281                    }
282                    else if (date.indexOf(CharPool.PERIOD) != -1) {
283                            format = "yyyyMMddHHmmss.S";
284                    }
285    
286                    DateFormat dateFormat = DateFormatFactoryUtil.getSimpleDateFormat(
287                            format);
288    
289                    return dateFormat.parse(date);
290            }
291    
292            public static void validateFilter(String filter) throws PortalException {
293                    if (!isValidFilter(filter)) {
294                            throw new LDAPFilterException("Invalid filter " + filter);
295                    }
296            }
297    
298            public static void validateFilter(String filter, String filterPropertyName)
299                    throws PortalException {
300    
301                    if (!isValidFilter(filter)) {
302                            throw new LDAPFilterException(
303                                    "Invalid filter " + filter + " defined by " +
304                                            filterPropertyName);
305                    }
306            }
307    
308            private static final Pattern _pattern1 = Pattern.compile(
309                    ".*[~<>]*=[~<>]*=.*");
310            private static final Pattern _pattern2 = Pattern.compile("\\([~<>]*=.*");
311            private static final Pattern _pattern3 = Pattern.compile("\\([^~<>=]*\\)");
312            private static final Pattern _pattern4 = Pattern.compile(
313                    ".*[^~<>=]*[~<>]*=\\)");
314    
315    }