001package org.intellimate.izou.support;
002
003import org.apache.logging.log4j.LogManager;
004import org.apache.logging.log4j.Logger;
005
006import javax.activation.DataHandler;
007import javax.activation.DataSource;
008import javax.activation.FileDataSource;
009import javax.mail.*;
010import javax.mail.internet.InternetAddress;
011import javax.mail.internet.MimeBodyPart;
012import javax.mail.internet.MimeMessage;
013import javax.mail.internet.MimeMultipart;
014import java.util.Properties;
015
016/**
017 * The SystemMail class can be used to send emails from the Izou to preferably the owner of the Izou in order
018 * to alert him about issues regarding Izou.
019 * <p>
020 *     It is meant to serve as an emergency communication, and not as a way to send general information. To do that you
021 *     can use the available addOns.
022 * </p>
023 */
024public class SystemMail {
025    private static boolean exists = false;
026    private final Logger logger = LogManager.getLogger(this.getClass());
027
028    /**
029     * Creates a SystemMail. There can only be one single SystemMail, so calling this method twice
030     * will cause an illegal access exception.
031     *
032     * @return a Mail object
033     * @throws IllegalAccessException thrown if this method is called more than once
034     */
035    public static SystemMail createSystemMail() throws IllegalAccessException {
036        if (!exists) {
037            SystemMail permissionManager = new SystemMail();
038            exists = true;
039            return permissionManager;
040        }
041
042        throw new IllegalAccessException("Cannot create more than one instance of Mail");
043    }
044
045    /**
046     * Creates a new SystemMail instance if and only if none has been created yet
047     *
048     * @throws IllegalAccessException thrown if this method is called more than once
049     */
050    private SystemMail() throws IllegalAccessException {
051        if (exists) {
052            throw new IllegalAccessException("Cannot create more than one instance of Mail");
053        }
054    }
055
056    /**
057     * Sends a mail to the address of {@code toAddress} with a subject of {@code subject} and a content of
058     * {@code content} with an attachment
059     *
060     * @param toAddress the address to send the mail to
061     * @param subject the subject of the email to send
062     * @param content the content of the email (without attachment)
063     * @param attachmentName the name of the attachment
064     * @param attachmentPath the file path to the attachment
065     */
066    public void sendMail(String toAddress, String subject, String content, String attachmentName,
067                          String attachmentPath) {
068        final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
069
070        logger.debug("Sending mail...");
071        Properties props = System.getProperties();
072        props.setProperty("mail.smtp.host", "smtp.gmail.com");
073        props.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY);
074        props.setProperty("mail.smtp.socketFactory.fallback", "false");
075        props.setProperty("mail.smtp.port", "465");
076        props.setProperty("mail.smtp.socketFactory.port", "465");
077        props.put("mail.smtp.auth", "true");
078        props.put("mail.debug", "true");
079        props.put("mail.store.protocol", "pop3");
080        props.put("mail.transport.protocol", "smtp");
081        final String username = "intellimate.izou@gmail.com";
082        final String password = "Karlskrone"; // TODO: hide this when password stuff is done
083
084        try{
085            Session session = Session.getDefaultInstance(props, new Authenticator() {
086                protected PasswordAuthentication getPasswordAuthentication() {
087                    return new PasswordAuthentication(username, password);
088                }
089            });
090
091            MimeMessage message = new MimeMessage(session);
092            message.setFrom(new InternetAddress(username));
093            message.addRecipient(Message.RecipientType.TO, new InternetAddress(toAddress));
094            message.setSubject(subject);
095
096            // Create the message part
097            BodyPart messageBodyPart = new MimeBodyPart();
098
099            // Now set the actual message
100            messageBodyPart.setText(content);
101
102            // Create a multipart message
103            Multipart multipart = new MimeMultipart();
104
105            // Set text message part
106            multipart.addBodyPart(messageBodyPart);
107
108            // Part two is attachment
109            messageBodyPart = new MimeBodyPart();
110            DataSource source = new FileDataSource(attachmentPath);
111            messageBodyPart.setDataHandler(new DataHandler(source));
112            messageBodyPart.setFileName(attachmentName);
113            multipart.addBodyPart(messageBodyPart);
114
115            // Send the complete message parts
116            message.setContent(multipart);
117
118            // Send message
119            Transport.send(message);
120
121            logger.debug("Mail sent successfully.");
122        } catch (MessagingException e) {
123            logger.error("Unable to send error report.", e);
124        }
125    }
126
127    /**
128     * Sends a mail to the address of {@code toAddress} with a subject of {@code subject} and a content of
129     * {@code content} WITHOUT an attachment
130     *
131     * @param toAddress the address to send the mail to
132     * @param subject the subject of the email to send
133     * @param content the content of the email (without attachment)
134     */
135    public void sendMail(String toAddress, String subject, String content) {
136        final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
137
138        logger.debug("Sending mail...");
139        Properties props = System.getProperties();
140        props.setProperty("mail.smtp.host", "smtp.gmail.com");
141        props.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY);
142        props.setProperty("mail.smtp.socketFactory.fallback", "false");
143        props.setProperty("mail.smtp.port", "465");
144        props.setProperty("mail.smtp.socketFactory.port", "465");
145        props.put("mail.smtp.auth", "true");
146        props.put("mail.debug", "true");
147        props.put("mail.store.protocol", "pop3");
148        props.put("mail.transport.protocol", "smtp");
149        final String username = "intellimate.izou@gmail.com";
150        final String password = "Karlskrone"; // TODO: hide this when password stuff is done
151
152        try{
153            Session session = Session.getDefaultInstance(props, new Authenticator() {
154                protected PasswordAuthentication getPasswordAuthentication() {
155                    return new PasswordAuthentication(username, password);
156                }
157            });
158
159            MimeMessage message = new MimeMessage(session);
160            message.setFrom(new InternetAddress(username));
161            message.addRecipient(Message.RecipientType.TO, new InternetAddress(toAddress));
162            message.setSubject(subject);
163            message.setText(content);
164
165            Transport.send(message);
166            logger.debug("Mail sent successfully.");
167        } catch (MessagingException e) {
168            logger.error("Unable to send mail.", e);
169        }
170    }
171}