annotate src/luan/modules/mail/MailSender.java @ 1765:1ffe1e06ea55

SSL for port 465
author Franklin Schmidt <fschmidt@gmail.com>
date Fri, 26 May 2023 10:29:55 -0600
parents 0c46edec25dd
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1586
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
1 package luan.modules.mail;
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
2
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
3 import java.io.IOException;
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
4 import java.net.Socket;
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
5 import java.util.Map;
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
6 import java.util.LinkedHashMap;
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
7 import java.util.List;
1765
1ffe1e06ea55 SSL for port 465
Franklin Schmidt <fschmidt@gmail.com>
parents: 1589
diff changeset
8 import javax.net.ssl.SSLSocket;
1ffe1e06ea55 SSL for port 465
Franklin Schmidt <fschmidt@gmail.com>
parents: 1589
diff changeset
9 import goodjava.io.IoUtils;
1586
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
10 import goodjava.mail.Message;
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
11 import goodjava.mail.Smtp;
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
12 import goodjava.mail.MailException;
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
13 import luan.Luan;
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
14 import luan.LuanTable;
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
15 import luan.LuanException;
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
16
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
17
1589
0c46edec25dd mail work
Franklin Schmidt <fschmidt@gmail.com>
parents: 1587
diff changeset
18 public final class MailSender {
1586
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
19 private final String host;
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
20 private final int port;
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
21 private final String username;
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
22 private final String password;
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
23
1589
0c46edec25dd mail work
Franklin Schmidt <fschmidt@gmail.com>
parents: 1587
diff changeset
24 public MailSender(LuanTable paramsTbl) throws LuanException {
1586
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
25 Map<Object,Object> params = paramsTbl.asMap();
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
26
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
27 String host = getString(params,"host");
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
28 if( host==null )
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
29 throw new LuanException( "parameter 'host' is required" );
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
30 this.host = host;
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
31
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
32 Object port = params.remove("port");
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
33 if( port==null )
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
34 throw new LuanException( "parameter 'port' is required" );
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
35 if( !(port instanceof Number) )
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
36 throw new LuanException( "parameter 'port' must be an integer" );
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
37 Integer i = Luan.asInteger(port);
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
38 if( i == null )
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
39 throw new LuanException( "parameter 'port' must be an integer" );
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
40 this.port = i;
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
41
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
42 this.username = getString(params,"username");
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
43 this.password = getString(params,"password");
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
44 if( this.username!=null && this.password==null )
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
45 throw new LuanException( "password required with username" );
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
46 if( this.username==null && this.password!=null )
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
47 throw new LuanException( "username required with password" );
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
48
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
49 if( !params.isEmpty() )
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
50 throw new LuanException( "unrecognized parameters: "+params );
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
51 }
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
52
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
53 private static String getString(Map<Object,Object> params,String key) throws LuanException {
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
54 Object val = params.remove(key);
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
55 if( val!=null && !(val instanceof String) )
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
56 throw new LuanException( "parameter '"+key+"' must be a string" );
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
57 return (String)val;
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
58 }
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
59
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
60 private static Message message(LuanTable mailTbl) throws LuanException {
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
61 Map<Object,Object> mailParams = mailTbl.asMap();
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
62 Object body = mailParams.remove("body");
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
63 if( body == null )
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
64 throw new LuanException( "parameter 'body' is required" );
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
65 Map<String,String> headers = new LinkedHashMap<String,String>();
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
66 boolean hasContentType = false;
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
67 for( Map.Entry<Object,Object> entry : mailParams.entrySet() ) {
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
68 Object key = entry.getKey();
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
69 Object value = entry.getValue();
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
70 if( !(key instanceof String) )
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
71 throw new LuanException( "keys must be strings" );
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
72 if( !(value instanceof String) )
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
73 throw new LuanException( "value for '"+key+"' must be string" );
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
74 String name = (String)key;
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
75 headers.put(name,(String)value);
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
76 if( name.equalsIgnoreCase("content-type") )
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
77 hasContentType = true;
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
78 }
1587
fa1a9aceac3e mail work
Franklin Schmidt <fschmidt@gmail.com>
parents: 1586
diff changeset
79 if( body instanceof String ) {
fa1a9aceac3e mail work
Franklin Schmidt <fschmidt@gmail.com>
parents: 1586
diff changeset
80 if( !hasContentType )
fa1a9aceac3e mail work
Franklin Schmidt <fschmidt@gmail.com>
parents: 1586
diff changeset
81 headers.put("Content-Type","text/plain; charset=utf-8");
fa1a9aceac3e mail work
Franklin Schmidt <fschmidt@gmail.com>
parents: 1586
diff changeset
82 return new Message(headers,(String)body);
fa1a9aceac3e mail work
Franklin Schmidt <fschmidt@gmail.com>
parents: 1586
diff changeset
83 }
fa1a9aceac3e mail work
Franklin Schmidt <fschmidt@gmail.com>
parents: 1586
diff changeset
84 if( body instanceof byte[] ) {
1589
0c46edec25dd mail work
Franklin Schmidt <fschmidt@gmail.com>
parents: 1587
diff changeset
85 if( !hasContentType )
0c46edec25dd mail work
Franklin Schmidt <fschmidt@gmail.com>
parents: 1587
diff changeset
86 throw new LuanException("Content-Type required for binary body");
1587
fa1a9aceac3e mail work
Franklin Schmidt <fschmidt@gmail.com>
parents: 1586
diff changeset
87 return new Message(headers,(byte[])body);
fa1a9aceac3e mail work
Franklin Schmidt <fschmidt@gmail.com>
parents: 1586
diff changeset
88 }
fa1a9aceac3e mail work
Franklin Schmidt <fschmidt@gmail.com>
parents: 1586
diff changeset
89 if( body instanceof LuanTable ) {
1589
0c46edec25dd mail work
Franklin Schmidt <fschmidt@gmail.com>
parents: 1587
diff changeset
90 if( !hasContentType )
0c46edec25dd mail work
Franklin Schmidt <fschmidt@gmail.com>
parents: 1587
diff changeset
91 headers.put("Content-Type","multipart/mixed");
1587
fa1a9aceac3e mail work
Franklin Schmidt <fschmidt@gmail.com>
parents: 1586
diff changeset
92 LuanTable tbl = (LuanTable)body;
fa1a9aceac3e mail work
Franklin Schmidt <fschmidt@gmail.com>
parents: 1586
diff changeset
93 if( !tbl.isList() )
fa1a9aceac3e mail work
Franklin Schmidt <fschmidt@gmail.com>
parents: 1586
diff changeset
94 throw new LuanException( "body table must be a list" );
fa1a9aceac3e mail work
Franklin Schmidt <fschmidt@gmail.com>
parents: 1586
diff changeset
95 List list = tbl.asList();
fa1a9aceac3e mail work
Franklin Schmidt <fschmidt@gmail.com>
parents: 1586
diff changeset
96 Message[] msgs = new Message[list.size()];
fa1a9aceac3e mail work
Franklin Schmidt <fschmidt@gmail.com>
parents: 1586
diff changeset
97 for( int i=0; i<msgs.length; i++ ) {
fa1a9aceac3e mail work
Franklin Schmidt <fschmidt@gmail.com>
parents: 1586
diff changeset
98 Object obj = list.get(i);
fa1a9aceac3e mail work
Franklin Schmidt <fschmidt@gmail.com>
parents: 1586
diff changeset
99 if( !(obj instanceof LuanTable) )
fa1a9aceac3e mail work
Franklin Schmidt <fschmidt@gmail.com>
parents: 1586
diff changeset
100 throw new LuanException( "body table must be a list of part tables" );
fa1a9aceac3e mail work
Franklin Schmidt <fschmidt@gmail.com>
parents: 1586
diff changeset
101 msgs[i] = message((LuanTable)obj);
fa1a9aceac3e mail work
Franklin Schmidt <fschmidt@gmail.com>
parents: 1586
diff changeset
102 }
fa1a9aceac3e mail work
Franklin Schmidt <fschmidt@gmail.com>
parents: 1586
diff changeset
103 return new Message(headers,msgs);
fa1a9aceac3e mail work
Franklin Schmidt <fschmidt@gmail.com>
parents: 1586
diff changeset
104 }
fa1a9aceac3e mail work
Franklin Schmidt <fschmidt@gmail.com>
parents: 1586
diff changeset
105 throw new LuanException("body must be a string, binary, or list of part tables");
1586
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
106 }
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
107
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
108 public void send(LuanTable mailTbl) throws LuanException, IOException, MailException {
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
109 Message msg = message(mailTbl);
1765
1ffe1e06ea55 SSL for port 465
Franklin Schmidt <fschmidt@gmail.com>
parents: 1589
diff changeset
110 Socket socket;
1ffe1e06ea55 SSL for port 465
Franklin Schmidt <fschmidt@gmail.com>
parents: 1589
diff changeset
111 if( port == 465 ) {
1ffe1e06ea55 SSL for port 465
Franklin Schmidt <fschmidt@gmail.com>
parents: 1589
diff changeset
112 SSLSocket sslSocket = (SSLSocket)IoUtils.getSSLSocketFactory().createSocket(host,port);
1ffe1e06ea55 SSL for port 465
Franklin Schmidt <fschmidt@gmail.com>
parents: 1589
diff changeset
113 sslSocket.startHandshake();
1ffe1e06ea55 SSL for port 465
Franklin Schmidt <fschmidt@gmail.com>
parents: 1589
diff changeset
114 socket = sslSocket;
1ffe1e06ea55 SSL for port 465
Franklin Schmidt <fschmidt@gmail.com>
parents: 1589
diff changeset
115 } else {
1ffe1e06ea55 SSL for port 465
Franklin Schmidt <fschmidt@gmail.com>
parents: 1589
diff changeset
116 socket = new Socket(host,port);
1ffe1e06ea55 SSL for port 465
Franklin Schmidt <fschmidt@gmail.com>
parents: 1589
diff changeset
117 }
1586
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
118 Smtp smtp = new Smtp(socket);
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
119 if( username != null )
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
120 smtp.authenticate(username,password);
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
121 smtp.send(msg);
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
122 smtp.close();
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
123 }
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
124
fcca0ddf5a4d luan uses goodjava.mail
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
125 }