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.mail.util;
016    
017    import com.liferay.mail.model.Filter;
018    import com.liferay.portal.kernel.io.unsync.UnsyncBufferedReader;
019    import com.liferay.portal.kernel.log.Log;
020    import com.liferay.portal.kernel.log.LogFactoryUtil;
021    import com.liferay.portal.kernel.process.ProcessUtil;
022    import com.liferay.portal.kernel.util.FileUtil;
023    import com.liferay.portal.kernel.util.ListUtil;
024    import com.liferay.portal.kernel.util.PropsKeys;
025    import com.liferay.portal.kernel.util.StringBundler;
026    import com.liferay.portal.kernel.util.StringUtil;
027    import com.liferay.portal.util.PropsUtil;
028    
029    import java.io.File;
030    import java.io.FileReader;
031    
032    import java.util.List;
033    import java.util.concurrent.Future;
034    
035    /**
036     * @author Brian Wing Shun Chan
037     */
038    public class SendmailHook implements Hook {
039    
040            @Override
041            public void addForward(
042                    long companyId, long userId, List<Filter> filters,
043                    List<String> emailAddresses, boolean leaveCopy) {
044    
045                    try {
046                            if (emailAddresses != null) {
047                                    String home = PropsUtil.get(PropsKeys.MAIL_HOOK_SENDMAIL_HOME);
048    
049                                    File file = new File(home + "/" + userId + "/.forward");
050    
051                                    if (!emailAddresses.isEmpty()) {
052                                            StringBundler sb = new StringBundler(
053                                                    emailAddresses.size() * 2);
054    
055                                            for (int i = 0; i < emailAddresses.size(); i++) {
056                                                    String emailAddress = emailAddresses.get(i);
057    
058                                                    sb.append(emailAddress);
059                                                    sb.append("\n");
060                                            }
061    
062                                            FileUtil.write(file, sb.toString());
063                                    }
064                                    else {
065                                            file.delete();
066                                    }
067                            }
068                    }
069                    catch (Exception e) {
070                            _log.error(e, e);
071                    }
072            }
073    
074            @Override
075            public void addUser(
076                    long companyId, long userId, String password, String firstName,
077                    String middleName, String lastName, String emailAddress) {
078    
079                    // Get add user command
080    
081                    String addUserCmd = PropsUtil.get(
082                            PropsKeys.MAIL_HOOK_SENDMAIL_ADD_USER);
083    
084                    // Replace userId
085    
086                    addUserCmd = StringUtil.replace(
087                            addUserCmd, "%1%", String.valueOf(userId));
088    
089                    try {
090                            Future<?> future = ProcessUtil.execute(
091                                    ProcessUtil.LOGGING_OUTPUT_PROCESSOR, addUserCmd);
092    
093                            future.get();
094                    }
095                    catch (Exception e) {
096                            _log.error(e, e);
097                    }
098    
099                    updatePassword(companyId, userId, password);
100                    updateEmailAddress(companyId, userId, emailAddress);
101            }
102    
103            @Override
104            public void addVacationMessage(
105                    long companyId, long userId, String emailAddress,
106                    String vacationMessage) {
107            }
108    
109            @Override
110            public void deleteEmailAddress(long companyId, long userId) {
111                    updateEmailAddress(companyId, userId, "");
112            }
113    
114            @Override
115            public void deleteUser(long companyId, long userId) {
116                    deleteEmailAddress(companyId, userId);
117    
118                    // Get delete user command
119    
120                    String deleteUserCmd = PropsUtil.get(
121                            PropsKeys.MAIL_HOOK_SENDMAIL_DELETE_USER);
122    
123                    // Replace userId
124    
125                    deleteUserCmd = StringUtil.replace(
126                            deleteUserCmd, "%1%", String.valueOf(userId));
127    
128                    try {
129                            Future<?> future = ProcessUtil.execute(
130                                    ProcessUtil.LOGGING_OUTPUT_PROCESSOR, deleteUserCmd);
131    
132                            future.get();
133                    }
134                    catch (Exception e) {
135                            _log.error(e, e);
136                    }
137            }
138    
139            @Override
140            public void updateBlocked(
141                    long companyId, long userId, List<String> blocked) {
142    
143                    String home = PropsUtil.get(PropsKeys.MAIL_HOOK_SENDMAIL_HOME);
144    
145                    File file = new File(home + "/" + userId + "/.procmailrc");
146    
147                    if (ListUtil.isEmpty(blocked)) {
148                            file.delete();
149    
150                            return;
151                    }
152    
153                    StringBundler sb = new StringBundler(blocked.size() * 9 + 3);
154    
155                    sb.append("ORGMAIL /var/spool/mail/$LOGNAME\n");
156                    sb.append("MAILDIR $HOME/\n");
157                    sb.append("SENDMAIL /usr/smin/sendmail\n");
158    
159                    for (int i = 0; i < blocked.size(); i++) {
160                            String emailAddress = blocked.get(i);
161    
162                            sb.append("\n");
163                            sb.append(":0\n");
164                            sb.append("* ^From.*");
165                            sb.append(emailAddress);
166                            sb.append("\n");
167                            sb.append("{\n");
168                            sb.append(":0\n");
169                            sb.append("/dev/null\n");
170                            sb.append("}\n");
171                    }
172    
173                    try {
174                            FileUtil.write(file, sb.toString());
175                    }
176                    catch (Exception e) {
177                            _log.error(e, e);
178                    }
179            }
180    
181            @Override
182            public void updateEmailAddress(
183                    long companyId, long userId, String emailAddress) {
184    
185                    try {
186                            String virtusertable = PropsUtil.get(
187                                    PropsKeys.MAIL_HOOK_SENDMAIL_VIRTUSERTABLE);
188    
189                            StringBundler sb = new StringBundler();
190    
191                            try (FileReader fileReader = new FileReader(virtusertable);
192                                            UnsyncBufferedReader unsyncBufferedReader =
193                                                    new UnsyncBufferedReader(fileReader)) {
194    
195                                    for (String s = unsyncBufferedReader.readLine(); s != null;
196                                                    s = unsyncBufferedReader.readLine()) {
197    
198                                            if (!s.endsWith(" " + userId)) {
199                                                    sb.append(s);
200                                                    sb.append('\n');
201                                            }
202                                    }
203    
204                                    if ((emailAddress != null) && !emailAddress.equals("")) {
205                                            sb.append(emailAddress);
206                                            sb.append(" ");
207                                            sb.append(userId);
208                                            sb.append('\n');
209                                    }
210                            }
211    
212                            FileUtil.write(virtusertable, sb.toString());
213    
214                            String virtusertableRefreshCmd = PropsUtil.get(
215                                    PropsKeys.MAIL_HOOK_SENDMAIL_VIRTUSERTABLE_REFRESH);
216    
217                            Future<?> future = ProcessUtil.execute(
218                                    ProcessUtil.LOGGING_OUTPUT_PROCESSOR, virtusertableRefreshCmd);
219    
220                            future.get();
221                    }
222                    catch (Exception e) {
223                            _log.error(e, e);
224                    }
225            }
226    
227            @Override
228            public void updatePassword(long companyId, long userId, String password) {
229    
230                    // Get change password command
231    
232                    String changePasswordCmd = PropsUtil.get(
233                            PropsKeys.MAIL_HOOK_SENDMAIL_CHANGE_PASSWORD);
234    
235                    // Replace userId
236    
237                    changePasswordCmd = StringUtil.replace(
238                            changePasswordCmd, "%1%", String.valueOf(userId));
239    
240                    // Replace password
241    
242                    changePasswordCmd = StringUtil.replace(
243                            changePasswordCmd, "%2%", password);
244    
245                    try {
246                            Future<?> future = ProcessUtil.execute(
247                                    ProcessUtil.LOGGING_OUTPUT_PROCESSOR, changePasswordCmd);
248    
249                            future.get();
250                    }
251                    catch (Exception e) {
252                            _log.error(e, e);
253                    }
254            }
255    
256            private static final Log _log = LogFactoryUtil.getLog(SendmailHook.class);
257    
258    }