001    /**
002     * Copyright (c) 2000-2013 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.security.ldap;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.security.pacl.DoPrivileged;
020    import com.liferay.portal.kernel.util.PropsKeys;
021    import com.liferay.portal.model.Contact;
022    import com.liferay.portal.model.User;
023    import com.liferay.portal.model.UserGroup;
024    import com.liferay.portal.security.auth.AuthSettingsUtil;
025    import com.liferay.portal.service.UserGroupLocalServiceUtil;
026    import com.liferay.portal.service.UserLocalServiceUtil;
027    import com.liferay.portal.util.PrefsPropsUtil;
028    
029    import java.io.Serializable;
030    
031    import java.util.List;
032    import java.util.Map;
033    import java.util.Properties;
034    
035    import javax.naming.Binding;
036    import javax.naming.CompositeName;
037    import javax.naming.Name;
038    import javax.naming.NameNotFoundException;
039    import javax.naming.directory.Attribute;
040    import javax.naming.directory.Attributes;
041    import javax.naming.directory.ModificationItem;
042    import javax.naming.directory.SchemaViolationException;
043    import javax.naming.ldap.LdapContext;
044    
045    /**
046     * @author Michael C. Han
047     * @author Brian Wing Shun Chan
048     * @author Marcellus Tavares
049     * @author Wesley Gong
050     */
051    @DoPrivileged
052    public class PortalLDAPExporterImpl implements PortalLDAPExporter {
053    
054            public void exportToLDAP(
055                            Contact contact, Map<String, Serializable> contactExpandoAttributes)
056                    throws Exception {
057    
058                    long companyId = contact.getCompanyId();
059    
060                    if (!AuthSettingsUtil.isLDAPAuthEnabled(companyId) ||
061                            !LDAPSettingsUtil.isExportEnabled(companyId)) {
062    
063                            return;
064                    }
065    
066                    User user = UserLocalServiceUtil.getUserByContactId(
067                            contact.getContactId());
068    
069                    if (user.isDefaultUser()) {
070                            return;
071                    }
072    
073                    long ldapServerId = PortalLDAPUtil.getLdapServerId(
074                            companyId, user.getScreenName(), user.getEmailAddress());
075    
076                    LdapContext ldapContext = PortalLDAPUtil.getContext(
077                            ldapServerId, companyId);
078    
079                    try {
080                            if (ldapContext == null) {
081                                    return;
082                            }
083    
084                            Properties contactMappings = LDAPSettingsUtil.getContactMappings(
085                                    ldapServerId, companyId);
086                            Properties contactExpandoMappings =
087                                    LDAPSettingsUtil.getContactExpandoMappings(
088                                            ldapServerId, companyId);
089    
090                            Binding binding = PortalLDAPUtil.getUser(
091                                    ldapServerId, contact.getCompanyId(), user.getScreenName(),
092                                    user.getEmailAddress());
093    
094                            if (binding == null) {
095                                    Properties userMappings = LDAPSettingsUtil.getUserMappings(
096                                            ldapServerId, companyId);
097    
098                                    binding = addUser(
099                                            ldapServerId, ldapContext, user, userMappings);
100                            }
101    
102                            Name name = new CompositeName();
103    
104                            name.add(
105                                    PortalLDAPUtil.getNameInNamespace(
106                                            ldapServerId, companyId, binding));
107    
108                            Modifications modifications =
109                                    _portalToLDAPConverter.getLDAPContactModifications(
110                                            contact, contactExpandoAttributes, contactMappings,
111                                            contactExpandoMappings);
112    
113                            if (modifications == null) {
114                                    return;
115                            }
116    
117                            ModificationItem[] modificationItems = modifications.getItems();
118    
119                            ldapContext.modifyAttributes(name, modificationItems);
120                    }
121                    finally {
122                            if (ldapContext != null) {
123                                    ldapContext.close();
124                            }
125                    }
126            }
127    
128            public void exportToLDAP(
129                            long userId, long userGroupId, LDAPOperation ldapOperation)
130                    throws Exception {
131    
132                    User user = UserLocalServiceUtil.getUser(userId);
133    
134                    long companyId = user.getCompanyId();
135    
136                    if (!AuthSettingsUtil.isLDAPAuthEnabled(companyId) ||
137                            !LDAPSettingsUtil.isExportEnabled(companyId) ||
138                            !LDAPSettingsUtil.isExportGroupEnabled(companyId)) {
139    
140                            return;
141                    }
142    
143                    long ldapServerId = PortalLDAPUtil.getLdapServerId(
144                            companyId, user.getScreenName(), user.getEmailAddress());
145    
146                    LdapContext ldapContext = PortalLDAPUtil.getContext(
147                            ldapServerId, companyId);
148    
149                    if (ldapContext == null) {
150                            return;
151                    }
152    
153                    UserGroup userGroup = UserGroupLocalServiceUtil.getUserGroup(
154                            userGroupId);
155    
156                    Properties groupMappings = LDAPSettingsUtil.getGroupMappings(
157                            ldapServerId, companyId);
158                    Properties userMappings = LDAPSettingsUtil.getUserMappings(
159                            ldapServerId, companyId);
160    
161                    Binding binding = PortalLDAPUtil.getGroup(
162                            ldapServerId, companyId, userGroup.getName());
163    
164                    try {
165                            if (binding == null) {
166                                    if (ldapOperation == LDAPOperation.ADD) {
167                                            addGroup(
168                                                    ldapServerId, ldapContext, userGroup, user,
169                                                    groupMappings, userMappings);
170                                    }
171    
172                                    return;
173                            }
174    
175                            Name name = new CompositeName();
176    
177                            name.add(
178                                    PortalLDAPUtil.getNameInNamespace(
179                                            ldapServerId, companyId, binding));
180    
181                            Modifications modifications =
182                                    _portalToLDAPConverter.getLDAPGroupModifications(
183                                            ldapServerId, userGroup, user, groupMappings, userMappings,
184                                            ldapOperation);
185    
186                            ModificationItem[] modificationItems = modifications.getItems();
187    
188                            ldapContext.modifyAttributes(name, modificationItems);
189                    }
190                    catch (SchemaViolationException sve) {
191                            String fullGroupDN = PortalLDAPUtil.getNameInNamespace(
192                                    ldapServerId, companyId, binding);
193    
194                            Attributes attributes = PortalLDAPUtil.getGroupAttributes(
195                                    ldapServerId, companyId, ldapContext, fullGroupDN, true);
196    
197                            Attribute groupMembers = attributes.get(
198                                    groupMappings.getProperty(GroupConverterKeys.USER));
199    
200                            if ((groupMembers != null) && (groupMembers.size() == 1)) {
201                                    ldapContext.unbind(fullGroupDN);
202                            }
203                    }
204                    finally {
205                            if (ldapContext != null) {
206                                    ldapContext.close();
207                            }
208                    }
209            }
210    
211            public void exportToLDAP(
212                            User user, Map<String, Serializable> userExpandoAttributes)
213                    throws Exception {
214    
215                    long companyId = user.getCompanyId();
216    
217                    if (!AuthSettingsUtil.isLDAPAuthEnabled(companyId) ||
218                            !LDAPSettingsUtil.isExportEnabled(companyId)) {
219    
220                            return;
221                    }
222    
223                    long ldapServerId = PortalLDAPUtil.getLdapServerId(
224                            companyId, user.getScreenName(), user.getEmailAddress());
225    
226                    LdapContext ldapContext = PortalLDAPUtil.getContext(
227                            ldapServerId, companyId);
228    
229                    try {
230                            if (ldapContext == null) {
231                                    return;
232                            }
233    
234                            Properties userMappings = LDAPSettingsUtil.getUserMappings(
235                                    ldapServerId, companyId);
236                            Properties userExpandoMappings =
237                                    LDAPSettingsUtil.getUserExpandoMappings(
238                                            ldapServerId, companyId);
239    
240                            Binding binding = PortalLDAPUtil.getUser(
241                                    ldapServerId, user.getCompanyId(), user.getScreenName(),
242                                    user.getEmailAddress());
243    
244                            if (binding == null) {
245                                    binding = addUser(
246                                            ldapServerId, ldapContext, user, userMappings);
247                            }
248    
249                            Name name = new CompositeName();
250    
251                            name.add(
252                                    PortalLDAPUtil.getNameInNamespace(
253                                            ldapServerId, companyId, binding));
254    
255                            Modifications modifications =
256                                    _portalToLDAPConverter.getLDAPUserModifications(
257                                            user, userExpandoAttributes, userMappings,
258                                            userExpandoMappings);
259    
260                            if (modifications == null) {
261                                    return;
262                            }
263    
264                            ModificationItem[] modificationItems = modifications.getItems();
265    
266                            ldapContext.modifyAttributes(name, modificationItems);
267    
268                            if (!LDAPSettingsUtil.isExportGroupEnabled(companyId)) {
269                                    return;
270                            }
271    
272                            List<UserGroup> userGroups =
273                                    UserGroupLocalServiceUtil.getUserUserGroups(user.getUserId());
274    
275                            for (UserGroup userGroup : userGroups) {
276                                    exportToLDAP(
277                                            user.getUserId(), userGroup.getUserGroupId(),
278                                            LDAPOperation.ADD);
279                            }
280    
281                            Modifications groupModifications =
282                                    _portalToLDAPConverter.getLDAPUserGroupModifications(
283                                            ldapServerId, userGroups, user, userMappings);
284    
285                            ModificationItem[] groupModificationItems =
286                                    groupModifications.getItems();
287    
288                            if (groupModificationItems.length > 0) {
289                                    ldapContext.modifyAttributes(name, groupModificationItems);
290                            }
291                    }
292                    catch (NameNotFoundException nnfe) {
293                            if (PrefsPropsUtil.getBoolean(
294                                            companyId, PropsKeys.LDAP_AUTH_REQUIRED)) {
295    
296                                    throw nnfe;
297                            }
298    
299                            _log.error(nnfe, nnfe);
300                    }
301                    finally {
302                            if (ldapContext != null) {
303                                    ldapContext.close();
304                            }
305                    }
306            }
307    
308            public void setPortalToLDAPConverter(
309                    PortalToLDAPConverter portalToLDAPConverter) {
310    
311                    _portalToLDAPConverter = portalToLDAPConverter;
312            }
313    
314            protected Binding addGroup(
315                            long ldapServerId, LdapContext ldapContext, UserGroup userGroup,
316                            User user, Properties groupMappings, Properties userMappings)
317                    throws Exception {
318    
319                    Name name = new CompositeName();
320    
321                    name.add(
322                            _portalToLDAPConverter.getGroupDNName(
323                                    ldapServerId, userGroup, groupMappings));
324    
325                    Attributes attributes = _portalToLDAPConverter.getLDAPGroupAttributes(
326                            ldapServerId, userGroup, user, groupMappings, userMappings);
327    
328                    ldapContext.bind(name, new PortalLDAPContext(attributes));
329    
330                    Binding binding = PortalLDAPUtil.getGroup(
331                            ldapServerId, userGroup.getCompanyId(), userGroup.getName());
332    
333                    return binding;
334            }
335    
336            protected Binding addUser(
337                            long ldapServerId, LdapContext ldapContext, User user,
338                            Properties userMappings)
339                    throws Exception {
340    
341                    Name name = new CompositeName();
342    
343                    name.add(
344                            _portalToLDAPConverter.getUserDNName(
345                                    ldapServerId, user, userMappings));
346    
347                    Attributes attributes = _portalToLDAPConverter.getLDAPUserAttributes(
348                            ldapServerId, user, userMappings);
349    
350                    ldapContext.bind(name, new PortalLDAPContext(attributes));
351    
352                    Binding binding = PortalLDAPUtil.getUser(
353                            ldapServerId, user.getCompanyId(), user.getScreenName(),
354                            user.getEmailAddress());
355    
356                    return binding;
357            }
358    
359            private static Log _log = LogFactoryUtil.getLog(
360                    PortalLDAPExporterImpl.class);
361    
362            private PortalToLDAPConverter _portalToLDAPConverter;
363    
364    }