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