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