001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
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                    catch (Exception e) {
116                            throw e;
117                    }
118                    finally {
119                            if (ldapContext != null) {
120                                    ldapContext.close();
121                            }
122                    }
123            }
124    
125            /**
126             * @deprecated
127             */
128            public void exportToLDAP(long userId, long userGroupId) throws Exception {
129                    exportToLDAP(userId, userGroupId, LDAPOperation.ADD);
130            }
131    
132            public void exportToLDAP(
133                            long userId, long userGroupId, LDAPOperation ldapOperation)
134                    throws Exception {
135    
136                    User user = UserLocalServiceUtil.getUser(userId);
137    
138                    long companyId = user.getCompanyId();
139    
140                    if (!AuthSettingsUtil.isLDAPAuthEnabled(companyId) ||
141                            !LDAPSettingsUtil.isExportEnabled(companyId) ||
142                            !LDAPSettingsUtil.isExportGroupEnabled(companyId)) {
143    
144                            return;
145                    }
146    
147                    long ldapServerId = PortalLDAPUtil.getLdapServerId(
148                            companyId, user.getScreenName(), user.getEmailAddress());
149    
150                    LdapContext ldapContext = PortalLDAPUtil.getContext(
151                            ldapServerId, companyId);
152    
153                    if (ldapContext == null) {
154                            return;
155                    }
156    
157                    UserGroup userGroup = UserGroupLocalServiceUtil.getUserGroup(
158                            userGroupId);
159    
160                    Properties groupMappings = LDAPSettingsUtil.getGroupMappings(
161                            ldapServerId, companyId);
162                    Properties userMappings = LDAPSettingsUtil.getUserMappings(
163                            ldapServerId, companyId);
164    
165                    Binding binding = PortalLDAPUtil.getGroup(
166                            ldapServerId, companyId, userGroup.getName());
167    
168                    try {
169                            if (binding == null) {
170                                    if (ldapOperation == LDAPOperation.ADD) {
171                                            addGroup(
172                                                    ldapServerId, ldapContext, userGroup, user,
173                                                    groupMappings, userMappings);
174                                    }
175    
176                                    return;
177                            }
178    
179                            Name name = new CompositeName();
180    
181                            name.add(
182                                    PortalLDAPUtil.getNameInNamespace(
183                                            ldapServerId, companyId, binding));
184    
185                            Modifications modifications =
186                                    _portalToLDAPConverter.getLDAPGroupModifications(
187                                            ldapServerId, userGroup, user, groupMappings, userMappings,
188                                            ldapOperation);
189    
190                            ModificationItem[] modificationItems = modifications.getItems();
191    
192                            ldapContext.modifyAttributes(name, modificationItems);
193                    }
194                    catch (SchemaViolationException sve) {
195                            String fullGroupDN = PortalLDAPUtil.getNameInNamespace(
196                                    ldapServerId, companyId, binding);
197    
198                            Attributes attributes = PortalLDAPUtil.getGroupAttributes(
199                                    ldapServerId, companyId, ldapContext, fullGroupDN, true);
200    
201                            Attribute groupMembers = attributes.get(
202                                    groupMappings.getProperty(GroupConverterKeys.USER));
203    
204                            if (groupMembers.size() == 1) {
205                                    ldapContext.unbind(fullGroupDN);
206                            }
207                    }
208                    catch (Exception e) {
209                            throw e;
210                    }
211                    finally {
212                            if (ldapContext != null) {
213                                    ldapContext.close();
214                            }
215                    }
216            }
217    
218            public void exportToLDAP(
219                            User user, Map<String, Serializable> userExpandoAttributes)
220                    throws Exception {
221    
222                    long companyId = user.getCompanyId();
223    
224                    if (!AuthSettingsUtil.isLDAPAuthEnabled(companyId) ||
225                            !LDAPSettingsUtil.isExportEnabled(companyId)) {
226    
227                            return;
228                    }
229    
230                    long ldapServerId = PortalLDAPUtil.getLdapServerId(
231                            companyId, user.getScreenName(), user.getEmailAddress());
232    
233                    LdapContext ldapContext = PortalLDAPUtil.getContext(
234                            ldapServerId, companyId);
235    
236                    try {
237                            if (ldapContext == null) {
238                                    return;
239                            }
240    
241                            Properties userMappings = LDAPSettingsUtil.getUserMappings(
242                                    ldapServerId, companyId);
243                            Properties userExpandoMappings =
244                                    LDAPSettingsUtil.getUserExpandoMappings(
245                                            ldapServerId, companyId);
246    
247                            Binding binding = PortalLDAPUtil.getUser(
248                                    ldapServerId, user.getCompanyId(), user.getScreenName(),
249                                    user.getEmailAddress());
250    
251                            if (binding == null) {
252                                    binding = addUser(
253                                            ldapServerId, ldapContext, user, userMappings);
254                            }
255    
256                            Name name = new CompositeName();
257    
258                            name.add(
259                                    PortalLDAPUtil.getNameInNamespace(
260                                            ldapServerId, companyId, binding));
261    
262                            Modifications modifications =
263                                    _portalToLDAPConverter.getLDAPUserModifications(
264                                            user, userExpandoAttributes, userMappings,
265                                            userExpandoMappings);
266    
267                            if (modifications == null) {
268                                    return;
269                            }
270    
271                            ModificationItem[] modificationItems = modifications.getItems();
272    
273                            ldapContext.modifyAttributes(name, modificationItems);
274    
275                            if (!LDAPSettingsUtil.isExportGroupEnabled(companyId)) {
276                                    return;
277                            }
278    
279                            List<UserGroup> userGroups =
280                                    UserGroupLocalServiceUtil.getUserUserGroups(user.getUserId());
281    
282                            for (UserGroup userGroup : userGroups) {
283                                    exportToLDAP(
284                                            user.getUserId(), userGroup.getUserGroupId(),
285                                            LDAPOperation.ADD);
286                            }
287    
288                            Modifications groupModifications =
289                                    _portalToLDAPConverter.getLDAPUserGroupModifications(
290                                            ldapServerId, userGroups, user, userMappings);
291    
292                            ModificationItem[] groupModificationItems =
293                                    groupModifications.getItems();
294    
295                            if (groupModificationItems.length > 0) {
296                                    ldapContext.modifyAttributes(name, groupModificationItems);
297                            }
298                    }
299                    catch (NameNotFoundException nnfe) {
300                            if (PrefsPropsUtil.getBoolean(
301                                            companyId, PropsKeys.LDAP_AUTH_REQUIRED)) {
302    
303                                    throw nnfe;
304                            }
305    
306                            _log.error(nnfe, nnfe);
307                    }
308                    catch (Exception e) {
309                            throw e;
310                    }
311                    finally {
312                            if (ldapContext != null) {
313                                    ldapContext.close();
314                            }
315                    }
316            }
317    
318            public void setPortalToLDAPConverter(
319                    PortalToLDAPConverter portalToLDAPConverter) {
320    
321                    _portalToLDAPConverter = portalToLDAPConverter;
322            }
323    
324            protected Binding addGroup(
325                            long ldapServerId, LdapContext ldapContext, UserGroup userGroup,
326                            User user, Properties groupMappings, Properties userMappings)
327                    throws Exception {
328    
329                    Name name = new CompositeName();
330    
331                    name.add(
332                            _portalToLDAPConverter.getGroupDNName(
333                                    ldapServerId, userGroup, groupMappings));
334    
335                    Attributes attributes = _portalToLDAPConverter.getLDAPGroupAttributes(
336                            ldapServerId, userGroup, user, groupMappings, userMappings);
337    
338                    ldapContext.bind(name, new PortalLDAPContext(attributes));
339    
340                    Binding binding = PortalLDAPUtil.getGroup(
341                            ldapServerId, userGroup.getCompanyId(), userGroup.getName());
342    
343                    return binding;
344            }
345    
346            protected Binding addUser(
347                            long ldapServerId, LdapContext ldapContext, User user,
348                            Properties userMappings)
349                    throws Exception {
350    
351                    Name name = new CompositeName();
352    
353                    name.add(
354                            _portalToLDAPConverter.getUserDNName(
355                                    ldapServerId, user, userMappings));
356    
357                    Attributes attributes = _portalToLDAPConverter.getLDAPUserAttributes(
358                            ldapServerId, user, userMappings);
359    
360                    ldapContext.bind(name, new PortalLDAPContext(attributes));
361    
362                    Binding binding = PortalLDAPUtil.getUser(
363                            ldapServerId, user.getCompanyId(), user.getScreenName(),
364                            user.getEmailAddress());
365    
366                    return binding;
367            }
368    
369            private static Log _log = LogFactoryUtil.getLog(
370                    PortalLDAPExporterImpl.class);
371    
372            private PortalToLDAPConverter _portalToLDAPConverter;
373    
374    }