upgraded the internal Emailer class into the new MailSend class that can

do pretty much anything; emailer and stock messages are now managed through
the GlobalSite; security-releated generation is now handled through the
Generator class instead of several different ones
This commit is contained in:
Eric J. Bowersox 2002-05-22 07:38:29 +00:00
parent ffc862426a
commit 3ee3e4abeb
21 changed files with 835 additions and 644 deletions

View File

@ -331,6 +331,13 @@
Venice - community services, conferencing and more. <http://venice.sourceforge.net> Venice - community services, conferencing and more. <http://venice.sourceforge.net>
]]></signature> ]]></signature>
<!-- Message which is added to e-mail headers -->
<header-disclaimer><![CDATA[
Message sent via Venice Web Communities System - <http://venice.sourceforge.net>
The Venice Project is not responsible for the contents of this message
Report abuses to: <abuse@example.com>
]]></header-disclaimer>
<!-- This is the message sent out with the email confirmation number. --> <!-- This is the message sent out with the email confirmation number. -->
<!-- Parameters: username - account user name, confnum - confirmation number --> <!-- Parameters: username - account user name, confnum - confirmation number -->
<email-confirm><![CDATA[ <email-confirm><![CDATA[

View File

@ -464,9 +464,9 @@ class AdminUserContextImpl implements AdminUserContext
{ // retrieve a connection from the data pool { // retrieve a connection from the data pool
conn = env.getConnection(); conn = env.getConnection();
stmt = conn.createStatement(); stmt = conn.createStatement();
PasswordHash phash = new PasswordHash(password); String hash_value = Generator.hashPassword(password);
StringBuffer sql = new StringBuffer("UPDATE users SET passhash = '"); StringBuffer sql = new StringBuffer("UPDATE users SET passhash = '");
sql.append(phash.toString()).append("', passreminder = '").append(SQLUtil.encodeString(reminder)); sql.append(hash_value).append("', passreminder = '").append(SQLUtil.encodeString(reminder));
sql.append("', access_tries = 0 WHERE uid = ").append(uid).append(';'); sql.append("', access_tries = 0 WHERE uid = ").append(uid).append(';');
stmt.executeUpdate(sql.toString()); stmt.executeUpdate(sql.toString());

View File

@ -28,6 +28,7 @@ import com.silverwrist.venice.except.*;
import com.silverwrist.venice.security.AuditRecord; import com.silverwrist.venice.security.AuditRecord;
import com.silverwrist.venice.security.Role; import com.silverwrist.venice.security.Role;
import com.silverwrist.venice.svc.*; import com.silverwrist.venice.svc.*;
import com.silverwrist.venice.util.MailSend;
class CommunityUserContextImpl implements CommunityContext, CommunityBackend class CommunityUserContextImpl implements CommunityContext, CommunityBackend
{ {
@ -1225,7 +1226,7 @@ class CommunityUserContextImpl implements CommunityContext, CommunityBackend
my_comm.testMembership(level,is_member); my_comm.testMembership(level,is_member);
// Prepare the subject line to be sent to the user. // Prepare the subject line to be sent to the user.
String subject = env.getEngine().getStockMessage("subj-invite"); String subject = env.getStockMessage("subj-invite");
HashMap vars = new HashMap(5); HashMap vars = new HashMap(5);
vars.put("community.name",my_comm.getName()); vars.put("community.name",my_comm.getName());
subject = StringUtil.replaceAllVariables(subject,vars); subject = StringUtil.replaceAllVariables(subject,vars);
@ -1233,10 +1234,10 @@ class CommunityUserContextImpl implements CommunityContext, CommunityBackend
// Prepare the message text to be sent to the user. // Prepare the message text to be sent to the user.
String msg; String msg;
if (my_comm.isPublicCommunity()) if (my_comm.isPublicCommunity())
msg = env.getEngine().getStockMessage("invite-public"); msg = env.getStockMessage("invite-public");
else else
{ // get the private invite message and set the join key variable { // get the private invite message and set the join key variable
msg = env.getEngine().getStockMessage("invite-private"); msg = env.getStockMessage("invite-private");
vars.put("joinkey",my_comm.getJoinKey()); vars.put("joinkey",my_comm.getJoinKey());
} // end else } // end else
@ -1248,16 +1249,13 @@ class CommunityUserContextImpl implements CommunityContext, CommunityBackend
String uname = env.getUser().realUserName(); String uname = env.getUser().realUserName();
vars.put("username",uname); vars.put("username",uname);
msg = StringUtil.replaceAllVariables(msg,vars); msg = StringUtil.replaceAllVariables(msg,vars);
StringBuffer msg_buf = new StringBuffer(msg);
msg_buf.append("\n\n--\n").append(env.getEngine().getStockMessage("signature"));
// Get a Emailer object, set it up, and send it. // Get a MailSend object, set it up, and send it.
Emailer em = env.getEngine().createEmailer(); MailSend msend = new PersonalMailSend(env.getMailSender(),env.getGlobalSite(),env.getUser());
em.setFrom(uname,env.getUser().realEmailAddress()); msend.addRecipient(MailSend.RECIP_TO,address);
em.setTo(address); msend.setSubject(subject);
em.setSubject(subject); msend.setText(msg + "\n");
em.setText(msg_buf.toString()); msend.send();
em.send();
} // end sendInvitation } // end sendInvitation
@ -1406,8 +1404,10 @@ class CommunityUserContextImpl implements CommunityContext, CommunityBackend
buf.append("\n\n").append(StringUtil.replaceAllVariables(disklaimer,vars)); buf.append("\n\n").append(StringUtil.replaceAllVariables(disklaimer,vars));
// send the mail in the background! // send the mail in the background!
MailerAgent agent = new MailerAgent(env,env.getUser().realUserName(),env.getUser().realEmailAddress(), MailSend msend = new PersonalMailSend(env.getMailSender(),env.getGlobalSite(),env.getUser());
mail_list,subject,buf.toString()); msend.setSubject(subject);
msend.setText(buf.toString());
MailerAgent agent = new MailerAgent(msend,mail_list);
agent.start(); agent.start();
} // end if } // end if

View File

@ -27,6 +27,7 @@ import com.silverwrist.venice.db.*;
import com.silverwrist.venice.except.*; import com.silverwrist.venice.except.*;
import com.silverwrist.venice.htmlcheck.*; import com.silverwrist.venice.htmlcheck.*;
import com.silverwrist.venice.security.Role; import com.silverwrist.venice.security.Role;
import com.silverwrist.venice.util.MailSend;
class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
{ {
@ -1513,7 +1514,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
HashMap vars = new HashMap(); HashMap vars = new HashMap();
vars.put("community.name",env.getCommunityName()); vars.put("community.name",env.getCommunityName());
vars.put("conference.name",getName()); vars.put("conference.name",getName());
String extra_msg = env.getEngine().getStockMessage("add-conf-invite"); String extra_msg = env.getStockMessage("add-conf-invite");
String msg = StringUtil.replaceAllVariables(extra_msg,vars); String msg = StringUtil.replaceAllVariables(extra_msg,vars);
if (!StringUtil.isStringEmpty(personal_message)) if (!StringUtil.isStringEmpty(personal_message))
msg += ("\n\n" + personal_message); msg += ("\n\n" + personal_message);
@ -1619,8 +1620,10 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
buf.append("\n\n").append(StringUtil.replaceAllVariables(disklaimer,vars)); buf.append("\n\n").append(StringUtil.replaceAllVariables(disklaimer,vars));
// send the actual E-mail messages in the background // send the actual E-mail messages in the background
MailerAgent agent = new MailerAgent(env,env.getUser().realUserName(),env.getUser().realEmailAddress(), MailSend msend = new PersonalMailSend(env.getMailSender(),env.getGlobalSite(),env.getUser());
rc,subject,buf.toString()); msend.setSubject(subject);
msend.setText(buf.toString());
MailerAgent agent = new MailerAgent(msend,rc);
agent.start(); agent.start();
} // end if } // end if

View File

@ -11,7 +11,7 @@
* *
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>, * The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. * Copyright (C) 2001-02 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
* *
* Contributor(s): * Contributor(s):
*/ */
@ -23,6 +23,7 @@ import com.silverwrist.util.StringUtil;
import com.silverwrist.venice.core.internals.*; import com.silverwrist.venice.core.internals.*;
import com.silverwrist.venice.except.*; import com.silverwrist.venice.except.*;
import com.silverwrist.venice.htmlcheck.*; import com.silverwrist.venice.htmlcheck.*;
import com.silverwrist.venice.util.MailSend;
class MailerAgent extends Thread class MailerAgent extends Thread
{ {
@ -38,29 +39,21 @@ class MailerAgent extends Thread
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------
*/ */
private EnvUser env; // the environment private MailSend msend; // the mail sender
private String from_name; // the "from" name
private String from_addr; // the "from" address
private List recipients; // who gets the message private List recipients; // who gets the message
private String subject; // message subject
private String text; // message text
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
* Constructor * Constructor
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------
*/ */
MailerAgent(EnvUser env, String from_name, String from_addr, List recipients, String subject, String text) MailerAgent(MailSend msend, List recipients)
{ {
super(); super();
setDaemon(false); setDaemon(false);
this.env = env; this.msend = msend;
this.from_name = from_name;
this.from_addr = from_addr;
this.recipients = recipients; this.recipients = recipients;
this.subject = subject;
this.text = text;
} // end constructor } // end constructor
@ -74,16 +67,7 @@ class MailerAgent extends Thread
NDC.push("MailerAgent"); NDC.push("MailerAgent");
try try
{ // attach the signature to the message { // Deliver the mail to each of the target addresses in turn.
StringBuffer buf = new StringBuffer(text);
buf.append("\n--\n").append(env.getStockMessage("signature"));
// Create the emailer object and load it up with most of the data.
Emailer em = env.getEngine().createEmailer();
em.setSubject(subject);
em.setText(buf.toString());
// Deliver the mail to each of the target addresses in turn.
Iterator it = recipients.iterator(); Iterator it = recipients.iterator();
while (it.hasNext()) while (it.hasNext())
{ // get ready to deliver the mail... { // get ready to deliver the mail...
@ -93,9 +77,9 @@ class MailerAgent extends Thread
try try
{ // set the recipient and send it out { // set the recipient and send it out
em.setFrom(from_name,from_addr); msend.clearRecipients(MailSend.RECIP_TO);
em.setTo(addr); msend.addRecipient(MailSend.RECIP_TO,addr);
em.send(); msend.send();
} // end try } // end try
catch (EmailException e) catch (EmailException e)

View File

@ -0,0 +1,159 @@
/*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
*
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.venice.core.impl;
import com.silverwrist.util.*;
import com.silverwrist.venice.core.internals.UserBackend;
import com.silverwrist.venice.except.*;
import com.silverwrist.venice.svc.internal.GlobalSite;
import com.silverwrist.venice.util.MailSend;
class PersonalMailSend implements MailSend
{
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private MailSend inner; // inner object that we pass through calls to
private GlobalSite site; // for getting stock messages
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
PersonalMailSend(MailSend inner, GlobalSite site, UserBackend user) throws DataException
{
this.inner = inner;
this.site = site;
try
{ // set the "From" address in advance
inner.setFrom(user.realFullName(),user.realEmailAddress());
} // end try
catch (EmailException ee)
{ // this shouldn't happen
throw new InternalStateError("shouldn\'t be an EmailException here!",ee);
} // end catch
StringBuffer buf = new StringBuffer("uid ");
buf.append(user.realUID()).append("; username \"").append(user.realUserName()).append("\"; ip [");
buf.append(user.userRemoteAddress()).append("]");
inner.addHeader("X-Venice-Sender-Info",buf.toString());
String[] headers = StringUtil.splitArray(site.getStockMessage("header-disclaimer"),"\r\n");
for (int i=0; i<headers.length; i++)
inner.addHeader("X-Disclaimer-" + String.valueOf(i+1),headers[i]);
} // end constructor
/*--------------------------------------------------------------------------------
* Internal operations
*--------------------------------------------------------------------------------
*/
private static final void checkHeaderName(String name)
{
name = name.toLowerCase();
if (name.equals("x-venice-sender-info") || name.startsWith("x-disclaimer-"))
throw new UnsupportedOperationException("cannot modify this header");
} // end checkHeaderName
/*--------------------------------------------------------------------------------
* Implementations from interface MailSend
*--------------------------------------------------------------------------------
*/
public void addRecipient(int type, String addr) throws EmailException
{
inner.addRecipient(type,addr);
} // end addRecipient
public void removeRecipient(int type, String addr) throws EmailException
{
inner.removeRecipient(type,addr);
} // end removeRecipient
public void clearRecipients(int type)
{
inner.clearRecipients(type);
} // end clearRecipients
public void setFrom(String from_name, String from_addr)
{
throw new UnsupportedOperationException("cannot modify sender address");
} // end setFrom
public void setSubject(String subject)
{
inner.setSubject(subject);
} // end setSubject
public void setStockSubject(String identifier)
{
inner.setStockSubject(identifier);
} // end setStockSubject
public void setText(String text)
{
inner.setText(text + "\n--\n" + site.getStockMessage("signature"));
} // end setText
public void setStockText(String identifier)
{
this.setText(site.getStockMessage(identifier));
} // end setStockText
public void setVariable(String name, String value)
{
inner.setVariable(name,value);
} // end setVariable
public void addHeader(String name, String value)
{
checkHeaderName(name);
inner.addHeader(name,value);
} // end addHeader
public void removeHeader(String name)
{
checkHeaderName(name);
inner.removeHeader(name);
} // end removeHeader
public void send() throws EmailException
{
inner.send();
} // end send
} // end class PersonalMailSend

View File

@ -23,6 +23,7 @@ import com.silverwrist.util.StringUtil;
import com.silverwrist.venice.core.internals.*; import com.silverwrist.venice.core.internals.*;
import com.silverwrist.venice.except.*; import com.silverwrist.venice.except.*;
import com.silverwrist.venice.htmlcheck.*; import com.silverwrist.venice.htmlcheck.*;
import com.silverwrist.venice.util.MailSend;
class PostDeliveryAgent extends Thread class PostDeliveryAgent extends Thread
{ {
@ -61,13 +62,12 @@ class PostDeliveryAgent extends Thread
this.delivery_addresses = addrs; this.delivery_addresses = addrs;
// Now build the substitution table used to format the templates. // Now build the substitution table used to format the templates.
HashMap xvars = new HashMap(); vars = new HashMap();
xvars.put("message.poster",env.getUserName()); vars.put("message.poster",env.getUserName());
xvars.put("topic.name",topicname); vars.put("topic.name",topicname);
xvars.put("topic.locator",env.getCommunityAlias() + "!" + env.getConferenceAlias() + "." + topicnum); vars.put("topic.locator",env.getCommunityAlias() + "!" + env.getConferenceAlias() + "." + topicnum);
xvars.put("conference.name",env.getConferenceName()); vars.put("conference.name",env.getConferenceName());
xvars.put("community.name",env.getCommunityName()); vars.put("community.name",env.getCommunityName());
vars = Collections.unmodifiableMap(xvars);
} // end constructor } // end constructor
@ -118,10 +118,10 @@ class PostDeliveryAgent extends Thread
body.append("\n\n").append(real_pseud).append("\n\n").append(real_text).append("\n\n"); body.append("\n\n").append(real_pseud).append("\n\n").append(real_text).append("\n\n");
body.append(msg_bot).append("\n--\n").append(env.getStockMessage("signature")); body.append(msg_bot).append("\n--\n").append(env.getStockMessage("signature"));
// Create the emailer object and load it up with most of the data. // Create the MailSend object and load it up with most of the data.
Emailer em = env.getEngine().createEmailer(); MailSend msend = env.getMailSender();
em.setSubject(msg_subj); msend.setSubject(msg_subj);
em.setText(body.toString()); msend.setText(body.toString());
// Deliver the mail to each of the target addresses in turn. // Deliver the mail to each of the target addresses in turn.
Iterator it = delivery_addresses.iterator(); Iterator it = delivery_addresses.iterator();
@ -133,8 +133,9 @@ class PostDeliveryAgent extends Thread
try try
{ // set the recipient and send it out { // set the recipient and send it out
em.setTo(addr); msend.clearRecipients(MailSend.RECIP_TO);
em.send(); msend.addRecipient(MailSend.RECIP_TO,addr);
msend.send();
} // end try } // end try
catch (EmailException e) catch (EmailException e)

View File

@ -1,176 +0,0 @@
/*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
*
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.venice.core.impl;
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
import com.silverwrist.venice.core.internals.Emailer;
import com.silverwrist.venice.except.EmailException;
import com.silverwrist.venice.except.InternalStateError;
class SimpleEmailer implements Emailer
{
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private Session session; // the email session
private MimeMessage msg; // the message being composed
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
SimpleEmailer(Properties props, javax.mail.Session session)
{
this.session = session;
msg = new MimeMessage(session);
try
{ // set the X-Mailer header
msg.setHeader("X-Mailer",(String)(props.get("com.silverwrist.venice.email.mailer")));
} // end try
catch (Exception e)
{ // do nothing - we don't really care about this too much
} // end catch
try
{ // set the From address on the message
msg.setFrom(InternetAddress.getLocalAddress(session));
} // end try
catch (MessagingException me)
{ // this should be impossible
throw new InternalStateError("condition should not apply to message here",me);
} // end catch
} // end constructor
/*--------------------------------------------------------------------------------
* Implementations from interface Emailer
*--------------------------------------------------------------------------------
*/
public void setTo(String to) throws EmailException
{
try
{ // create an Internet address and set the recipient to it
InternetAddress[] address = { new InternetAddress(to) };
msg.setRecipients(Message.RecipientType.TO,address);
} // end try
catch (AddressException e1)
{ // the address was somehow invalid
throw new EmailException("invalid email recipient address",e1);
} // end catch
catch (MessagingException e2)
{ // msg.setRecipients should NOT be throwing a MessageException here!
throw new InternalStateError("condition should not apply to message here",e2);
} // end catch
} // end setTo
public void setFrom(String from_name, String from_addr) throws EmailException
{
try
{ // set the "from" address
InternetAddress addr = new InternetAddress(from_addr);
addr.setPersonal(from_name);
msg.setFrom(addr);
// make sure the "Sender" address reflects our email address
InternetAddress sender = InternetAddress.getLocalAddress(session);
msg.setHeader("Sender",sender.toString());
} // end try
catch (AddressException e1)
{ // the address was somehow invalid
throw new EmailException("invalid email sender address",e1);
} // end catch
catch (MessagingException e2)
{ // msg.setRecipients should NOT be throwing a MessageException here!
throw new InternalStateError("condition should not apply to message here",e2);
} // end catch
catch (java.io.UnsupportedEncodingException e3)
{ // we can't really have that happen here, either!
throw new InternalStateError("condition should not apply to message here",e3);
} // end catch
} // end setFrom
public void setSubject(String subject)
{
try
{ // set the mail message subject
msg.setSubject(subject);
} // end try
catch (MessagingException e2)
{ // msg.setSubject should NOT be throwing a MessageException here!
throw new InternalStateError("condition should not apply to message here",e2);
} // end catch
} // end setSubject
public void setText(String text)
{
try
{ // set the mail message subject
msg.setText(text);
} // end try
catch (MessagingException e2)
{ // msg.setText should NOT be throwing a MessageException here!
throw new InternalStateError("condition should not apply to message here",e2);
} // end catch
} // end setText
public void send() throws EmailException
{
try
{ // attempt to send the transport message
Transport.send(msg);
} // end try
catch (SendFailedException e1)
{ // convert this exception into an EmailException
throw new EmailException("send of the email message failed: " + e1.getMessage(),e1);
} // end catch
catch (MessagingException e2)
{ // msg.setText should NOT be throwing a MessageException here!
throw new InternalStateError("condition should not apply to message here",e2);
} // end catch
} // end send
} // end class SimpleEmailer

View File

@ -28,6 +28,7 @@ import com.silverwrist.venice.db.*;
import com.silverwrist.venice.except.*; import com.silverwrist.venice.except.*;
import com.silverwrist.venice.htmlcheck.*; import com.silverwrist.venice.htmlcheck.*;
import com.silverwrist.venice.security.AuditRecord; import com.silverwrist.venice.security.AuditRecord;
import com.silverwrist.venice.util.MailSend;
class TopicUserContextImpl implements TopicContext class TopicUserContextImpl implements TopicContext
{ {
@ -1370,7 +1371,7 @@ class TopicUserContextImpl implements TopicContext
vars.put("community.name",env.getCommunityName()); vars.put("community.name",env.getCommunityName());
vars.put("conference.name",env.getConferenceName()); vars.put("conference.name",env.getConferenceName());
vars.put("topic.name",name); vars.put("topic.name",name);
String extra_msg = env.getEngine().getStockMessage("add-topic-invite"); String extra_msg = env.getStockMessage("add-topic-invite");
String msg = StringUtil.replaceAllVariables(extra_msg,vars); String msg = StringUtil.replaceAllVariables(extra_msg,vars);
if (!StringUtil.isStringEmpty(personal_message)) if (!StringUtil.isStringEmpty(personal_message))
msg += ("\n\n" + personal_message); msg += ("\n\n" + personal_message);
@ -1477,8 +1478,10 @@ class TopicUserContextImpl implements TopicContext
buf.append("\n\n").append(StringUtil.replaceAllVariables(disklaimer,vars)); buf.append("\n\n").append(StringUtil.replaceAllVariables(disklaimer,vars));
// send the actual E-mail messages in the background // send the actual E-mail messages in the background
MailerAgent agent = new MailerAgent(env,env.getUser().realUserName(),env.getUser().realEmailAddress(), MailSend msend = new PersonalMailSend(env.getMailSender(),env.getGlobalSite(),env.getUser());
rc,subject,buf.toString()); msend.setSubject(subject);
msend.setText(buf.toString());
MailerAgent agent = new MailerAgent(msend,rc);
agent.start(); agent.start();
} // end if } // end if

View File

@ -28,6 +28,7 @@ import com.silverwrist.venice.db.*;
import com.silverwrist.venice.except.*; import com.silverwrist.venice.except.*;
import com.silverwrist.venice.security.*; import com.silverwrist.venice.security.*;
import com.silverwrist.venice.svc.ServiceControl; import com.silverwrist.venice.svc.ServiceControl;
import com.silverwrist.venice.util.MailSend;
class UserContextImpl implements UserContext, UserBackend class UserContextImpl implements UserContext, UserBackend
{ {
@ -184,7 +185,7 @@ class UserContextImpl implements UserContext, UserBackend
logger.debug("sendEmailConfirmation(): sending to \"" + my_email + "\""); logger.debug("sendEmailConfirmation(): sending to \"" + my_email + "\"");
// Create the message to be sent. // Create the message to be sent.
String message = env.getEngine().getStockMessage("email-confirm"); String message = env.getStockMessage("email-confirm");
if (message==null) if (message==null)
{ // no message defined? oy! { // no message defined? oy!
logger.error("internal error condition: email-confirm stock message not defined"); logger.error("internal error condition: email-confirm stock message not defined");
@ -198,16 +199,16 @@ class UserContextImpl implements UserContext, UserBackend
vars.put("confnum",String.valueOf(confirm_num)); vars.put("confnum",String.valueOf(confirm_num));
message = StringUtil.replaceAllVariables(message,vars); message = StringUtil.replaceAllVariables(message,vars);
String subject = env.getEngine().getStockMessage("email-confirm-subject"); String subject = env.getStockMessage("email-confirm-subject");
if (subject==null) if (subject==null)
subject = "Venice Email Confirmation"; subject = "Venice Email Confirmation";
// Create the emailer and send the message. // Create the emailer and send the message.
Emailer emailer = env.getEngine().createEmailer(); MailSend msend = env.getMailSender();
emailer.setTo(my_email); msend.addRecipient(MailSend.RECIP_TO,my_email);
emailer.setSubject(subject); msend.setSubject(subject);
emailer.setText(message); msend.setText(message);
emailer.send(); msend.send();
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("...email sent!"); logger.debug("...email sent!");
@ -440,8 +441,8 @@ class UserContextImpl implements UserContext, UserBackend
} // end if } // end if
// hash the password and compare it to the stored password hash // hash the password and compare it to the stored password hash
PasswordHash phash = new PasswordHash(password); String hash_value = Generator.hashPassword(password);
if (!(phash.equals(rs.getString("passhash")))) if (!(hash_value.equals(rs.getString("passhash"))))
{ // they specified an incorrect password { // they specified an incorrect password
// TODO: advance an "invalid" counter and lock the account out if more than X tries // TODO: advance an "invalid" counter and lock the account out if more than X tries
logger.warn("...invalid password"); logger.warn("...invalid password");
@ -572,7 +573,7 @@ class UserContextImpl implements UserContext, UserBackend
stmt = conn.createStatement(); stmt = conn.createStatement();
// generate new confirmation number // generate new confirmation number
int new_confirm_num = env.getEngine().getNewConfirmationNumber(); int new_confirm_num = Generator.get().getNewConfirmationNumber();
// create an SQL statement to reset the user account information, and execute it // create an SQL statement to reset the user account information, and execute it
StringBuffer sql = new StringBuffer("UPDATE users SET email_confnum = "); StringBuffer sql = new StringBuffer("UPDATE users SET email_confnum = ");
@ -684,7 +685,7 @@ class UserContextImpl implements UserContext, UserBackend
logger.debug("email address changed, need to reconfirm"); logger.debug("email address changed, need to reconfirm");
// generate new confirmation number // generate new confirmation number
int new_confirm_num = env.getEngine().getNewConfirmationNumber(); int new_confirm_num = Generator.get().getNewConfirmationNumber();
Role new_role = env.getDefaultRole("Global.Unverified"); Role new_role = env.getDefaultRole("Global.Unverified");
Statement stmt = null; Statement stmt = null;
@ -816,9 +817,9 @@ class UserContextImpl implements UserContext, UserBackend
{ // retrieve a connection from the data pool { // retrieve a connection from the data pool
conn = env.getConnection(); conn = env.getConnection();
stmt = conn.createStatement(); stmt = conn.createStatement();
PasswordHash phash = new PasswordHash(password); String hash_value = Generator.hashPassword(password);
StringBuffer sql = new StringBuffer("UPDATE users SET passhash = '"); StringBuffer sql = new StringBuffer("UPDATE users SET passhash = '");
sql.append(phash.toString()).append("', passreminder = '").append(SQLUtil.encodeString(reminder)); sql.append(hash_value).append("', passreminder = '").append(SQLUtil.encodeString(reminder));
sql.append("' WHERE uid = ").append(uid).append(';'); sql.append("' WHERE uid = ").append(uid).append(';');
stmt.executeUpdate(sql.toString()); stmt.executeUpdate(sql.toString());
@ -1227,7 +1228,7 @@ class UserContextImpl implements UserContext, UserBackend
} // end if } // end if
// Generate a random authentication string and poke it into the database for this user. // Generate a random authentication string and poke it into the database for this user.
String tokenauth = env.getEngine().generateRandomAuthString(); String tokenauth = Generator.get().generateRandomAuthString();
Connection conn = null; Connection conn = null;
Statement stmt = null; Statement stmt = null;
@ -1314,7 +1315,7 @@ class UserContextImpl implements UserContext, UserBackend
} // end if } // end if
String pending_auth = token.substring(xstart,xend); String pending_auth = token.substring(xstart,xend);
if (!(env.getEngine().isValidRandomAuthString(pending_auth))) if (!(Generator.isValidRandomAuthString(pending_auth)))
{ // the auth string is not valid by the rules under which it was generated { // the auth string is not valid by the rules under which it was generated
logger.error("Token parse error: invalid auth string value"); logger.error("Token parse error: invalid auth string value");
return false; return false;
@ -1800,11 +1801,11 @@ class UserContextImpl implements UserContext, UserBackend
SQLUtil.shutdown(rs); SQLUtil.shutdown(rs);
// Insert a new record for this user // Insert a new record for this user
PasswordHash phash = new PasswordHash(password); String hash_value = Generator.hashPassword(password);
StringBuffer sql = StringBuffer sql =
new StringBuffer("INSERT INTO users (username, passhash, verify_email, lockout, email_confnum, " new StringBuffer("INSERT INTO users (username, passhash, verify_email, lockout, email_confnum, "
+ "base_lvl, created, lastaccess, passreminder, description) VALUES ('"); + "base_lvl, created, lastaccess, passreminder, description) VALUES ('");
sql.append(encode_username).append("', '").append(phash.toString()).append("', "); sql.append(encode_username).append("', '").append(hash_value).append("', ");
sql.append(verify_email ? '1' : '0').append(", ").append(lockout ? '1' : '0').append(", "); sql.append(verify_email ? '1' : '0').append(", ").append(lockout ? '1' : '0').append(", ");
sql.append(confirm_num).append(", ").append(base_role.getLevel()).append(", '"); sql.append(confirm_num).append(", ").append(base_role.getLevel()).append(", '");
created = new java.util.Date(); created = new java.util.Date();

View File

@ -25,6 +25,7 @@ import com.silverwrist.venice.core.*;
import com.silverwrist.venice.core.internals.*; import com.silverwrist.venice.core.internals.*;
import com.silverwrist.venice.db.*; import com.silverwrist.venice.db.*;
import com.silverwrist.venice.except.*; import com.silverwrist.venice.except.*;
import com.silverwrist.venice.util.MailSend;
class UserProfileImpl implements UserProfile class UserProfileImpl implements UserProfile
{ {
@ -455,21 +456,16 @@ class UserProfileImpl implements UserProfile
if (is_anon) if (is_anon)
{ // we can't send quick emails to the anonymous user { // we can't send quick emails to the anonymous user
logger.error("target user is the anonymous user"); logger.error("target user is the anonymous user");
throw new AccessError("You cannot send email to the anonymous user."); throw new AccessError("You cannot send E-mail to the anonymous user.");
} // end if } // end if
// assemble the full text
StringBuffer text_buf = new StringBuffer(text);
text_buf.append("\n\n--\n").append(env.getEngine().getStockMessage("signature"));
// create the emailer object, fill it in, and send it // create the emailer object, fill it in, and send it
Emailer em = env.getEngine().createEmailer(); MailSend msend = new PersonalMailSend(env.getMailSender(),env.getGlobalSite(),env.getUser());
em.setFrom(env.getUser().realUserName(),env.getUser().realEmailAddress()); msend.addRecipient(MailSend.RECIP_TO,real_email);
em.setTo(real_email); msend.setSubject(subject);
em.setSubject(subject); msend.setText(text + "\n");
em.setText(text_buf.toString()); msend.send();
em.send();
} // end sendQuickEmail } // end sendQuickEmail

View File

@ -34,6 +34,7 @@ import com.silverwrist.venice.htmlcheck.filters.*;
import com.silverwrist.venice.security.*; import com.silverwrist.venice.security.*;
import com.silverwrist.venice.svc.*; import com.silverwrist.venice.svc.*;
import com.silverwrist.venice.svc.internal.GlobalSite; import com.silverwrist.venice.svc.internal.GlobalSite;
import com.silverwrist.venice.util.MailSend;
import com.silverwrist.venice.util.XMLLoader; import com.silverwrist.venice.util.XMLLoader;
public class VeniceEngineImpl implements VeniceEngine, EngineBackend public class VeniceEngineImpl implements VeniceEngine, EngineBackend
@ -189,7 +190,7 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
this.uid = uid; this.uid = uid;
this.username = username; this.username = username;
this.email = email; this.email = email;
this.authentication = rng.nextInt(Integer.MAX_VALUE); this.authentication = Generator.get().getAuthorizationNumber();
this.timestamp = System.currentTimeMillis(); this.timestamp = System.currentTimeMillis();
} // end constructor } // end constructor
@ -242,10 +243,6 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
private static Category logger = Category.getInstance(VeniceEngineImpl.class); private static Category logger = Category.getInstance(VeniceEngineImpl.class);
private static final String AUTH_ALPHABET =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./";
private static final int AUTH_STRING_LEN = 32;
private static final Dimension DEFAULT_DIM_USERPHOTO = new Dimension(100,100); private static final Dimension DEFAULT_DIM_USERPHOTO = new Dimension(100,100);
private static final Dimension DEFAULT_DIM_COMMUNITYLOGO = new Dimension(110,65); private static final Dimension DEFAULT_DIM_COMMUNITYLOGO = new Dimension(110,65);
@ -256,10 +253,6 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
private GlobalSiteImpl globalsite = null; // my global site private GlobalSiteImpl globalsite = null; // my global site
private EnvEngine env = null; // my environment private EnvEngine env = null; // my environment
private Random rng; // random number generator
private Properties email_props = null; // email properties
private javax.mail.Session mailsession = null; // email session object
private StockMessages stock_messages = null; // stock messages holder
private ObjectCache comm_objcache = new ObjectCache(new CommunityCoreDataCreator()); private ObjectCache comm_objcache = new ObjectCache(new CommunityCoreDataCreator());
private ObjectCache conf_objcache = new ObjectCache(new ConferenceCoreDataCreator()); private ObjectCache conf_objcache = new ObjectCache(new ConferenceCoreDataCreator());
private HTMLCheckerConfig[] html_configs; // holder for HTML checker configurations private HTMLCheckerConfig[] html_configs; // holder for HTML checker configurations
@ -282,11 +275,7 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
*/ */
public VeniceEngineImpl() public VeniceEngineImpl()
{ { // do nothing
// Initialize the random number generator.
java.util.Date seed_date = new java.util.Date();
rng = new Random(seed_date.getTime());
} // end constructor } // end constructor
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
@ -595,18 +584,6 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
} // end for } // end for
// Get the <email/> section.
sect = loader.configGetSubSection(root_h,"email");
sect_h = new DOMElementHelper(sect);
// initialize the email properties and get a mail session object
email_props = new Properties();
email_props.put("mail.transport.protocol","smtp");
email_props.put("mail.smtp.host",sect_h.getSubElementText("smtp-host"));
email_props.put("mail.from",sect_h.getSubElementText("mail-from-addr"));
email_props.put("com.silverwrist.venice.email.mailer",sect_h.getSubElementText("mailer"));
mailsession = javax.mail.Session.getInstance(email_props,null);
// Get the <dictionary/> section. // Get the <dictionary/> section.
sect = loader.configGetSubSection(root_h,"dictionary"); sect = loader.configGetSubSection(root_h,"dictionary");
@ -639,12 +616,6 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
} // end if } // end if
// else no list, just proceed // else no list, just proceed
// Get the <messages/> section.
sect = loader.configGetSubSection(root_h,"messages");
// Initialize the stock messages list.
stock_messages = new StockMessages(sect);
// Now done with the master config... // Now done with the master config...
// Load the sidebox configuration file. // Load the sidebox configuration file.
Document subdoc = loader.loadConfigDocument(sidebox_config); Document subdoc = loader.loadConfigDocument(sidebox_config);
@ -927,7 +898,7 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
password_changes.put(new Integer(pcr.getUID()),pcr); password_changes.put(new Integer(pcr.getUID()),pcr);
// Create the message to be sent. // Create the message to be sent.
String message = getStockMessage("reminder"); String message = globalsite.getStockMessage("reminder");
if (message==null) if (message==null)
{ // what? the message does not exist? { // what? the message does not exist?
logger.error("\"reminder\" message does not exist in config file!"); logger.error("\"reminder\" message does not exist in config file!");
@ -944,16 +915,16 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
message = StringUtil.replaceAllVariables(message,vars); message = StringUtil.replaceAllVariables(message,vars);
// Find the message subject. // Find the message subject.
String subject = getStockMessage("reminder-subject"); String subject = globalsite.getStockMessage("reminder-subject");
if (subject==null) if (subject==null)
subject = "Venice Password Reminder Message"; subject = "Venice Password Reminder Message";
// Create the emailer and send the message. // Create the mail sender and send the message.
Emailer emailer = createEmailer(); MailSend msend = (MailSend)(globalsite.queryService(MailSend.class));
emailer.setTo(email_addr); msend.addRecipient(MailSend.RECIP_TO,email_addr);
emailer.setSubject(subject); msend.setSubject(subject);
emailer.setText(message); msend.setText(message);
emailer.send(); msend.send();
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("...email sent"); logger.debug("...email sent");
@ -997,8 +968,8 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
logger.debug("completePasswordChange for user \"" + pcr.getUserName() + "\""); logger.debug("completePasswordChange for user \"" + pcr.getUserName() + "\"");
// Request is valid; synthesize a new password // Request is valid; synthesize a new password
PasswordGenerator pgen = new PasswordGenerator(); String new_password = Generator.get().generateRandomPassword();
PasswordHash phash = new PasswordHash(pgen.toString()); String hash_value = Generator.hashPassword(new_password);
Connection conn = null; Connection conn = null;
Statement stmt = null; Statement stmt = null;
try try
@ -1006,7 +977,7 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
conn = env.getConnection(); conn = env.getConnection();
stmt = conn.createStatement(); stmt = conn.createStatement();
StringBuffer sql = new StringBuffer("UPDATE users SET passhash = '"); StringBuffer sql = new StringBuffer("UPDATE users SET passhash = '");
sql.append(phash.toString()).append("' WHERE uid = ").append(uid).append(';'); sql.append(hash_value).append("' WHERE uid = ").append(uid).append(';');
stmt.executeUpdate(sql.toString()); stmt.executeUpdate(sql.toString());
} // end try } // end try
@ -1024,7 +995,7 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
} // end finally } // end finally
// Create the message to be sent. // Create the message to be sent.
String message = getStockMessage("password-change"); String message = globalsite.getStockMessage("password-change");
if (message==null) if (message==null)
{ // what? the message does not exist? { // what? the message does not exist?
logger.error("\"password-change\" message does not exist in config file!"); logger.error("\"password-change\" message does not exist in config file!");
@ -1035,20 +1006,20 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
// Replace the message variables. // Replace the message variables.
HashMap vars = new HashMap(2); HashMap vars = new HashMap(2);
vars.put("username",pcr.getUserName()); vars.put("username",pcr.getUserName());
vars.put("password",pgen.toString()); vars.put("password",new_password);
message = StringUtil.replaceAllVariables(message,vars); message = StringUtil.replaceAllVariables(message,vars);
// Find the message subject. // Find the message subject.
String subject = getStockMessage("password-change-subject"); String subject = globalsite.getStockMessage("password-change-subject");
if (subject==null) if (subject==null)
subject = "Venice Password Changed"; subject = "Venice Password Changed";
// Create the emailer and send the message. // Create the mail sender and send the message.
Emailer emailer = createEmailer(); MailSend msend = (MailSend)(globalsite.queryService(MailSend.class));
emailer.setTo(pcr.getEmail()); msend.addRecipient(MailSend.RECIP_TO,pcr.getEmail());
emailer.setSubject(subject); msend.setSubject(subject);
emailer.setText(message); msend.setText(message);
emailer.send(); msend.send();
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("...email sent"); logger.debug("...email sent");
@ -1060,7 +1031,7 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
checkInitialized(); checkInitialized();
Role new_role = global_security.getDefaultRole("Global.NewUser"); Role new_role = global_security.getDefaultRole("Global.NewUser");
// email confirmation # is between 1000000 and 9999999 // email confirmation # is between 1000000 and 9999999
int confirm_num = getNewConfirmationNumber(); int confirm_num = Generator.get().getNewConfirmationNumber();
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("createNewAccount(\"" + username + "\",<password>,<reminder>)..."); logger.debug("createNewAccount(\"" + username + "\",<password>,<reminder>)...");
@ -1541,27 +1512,6 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
} // end getSelf } // end getSelf
public Emailer createEmailer()
{
checkInitialized();
return new SimpleEmailer(email_props,mailsession);
} // end createEmailer
public String getStockMessage(String key)
{
checkInitialized();
return (String)(stock_messages.get(key));
} // end getStockMessage
public int getNewConfirmationNumber()
{
checkInitialized();
return rng.nextInt(9000000) + 1000000;
} // end getNewConfirmationNumber
public CommunityData getCommunityDataObject(int cid) throws DataException public CommunityData getCommunityDataObject(int cid) throws DataException
{ {
checkInitialized(); checkInitialized();
@ -1749,30 +1699,6 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
} // end unpublish } // end unpublish
public String generateRandomAuthString()
{
StringBuffer buf = new StringBuffer(AUTH_STRING_LEN);
for (int i=0; i<AUTH_STRING_LEN; i++)
buf.append(AUTH_ALPHABET.charAt(rng.nextInt(AUTH_ALPHABET.length())));
return buf.toString();
} // end generateRandomAuthString
public boolean isValidRandomAuthString(String s)
{
if (s.length()!=AUTH_STRING_LEN)
return false;
for (int i=0; i<AUTH_STRING_LEN; i++)
{ // verify each authentication character in turn
if (AUTH_ALPHABET.indexOf(s.charAt(i))<0)
return false;
} // end for
return true; // all tests passed - ship it!
} // end isValidRandomAuthString
public boolean isNoCompressMimeType(String type) public boolean isNoCompressMimeType(String type)
{ {
if (no_compress_types.isEmpty()) if (no_compress_types.isEmpty())

View File

@ -0,0 +1,293 @@
/*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
*
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.venice.core.internals;
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
import com.silverwrist.util.*;
import com.silverwrist.venice.except.*;
import com.silverwrist.venice.svc.internal.GlobalSite;
import com.silverwrist.venice.util.MailSend;
class BaseMailSend implements MailSend
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
private static final InternetAddress[] ADDR_TEMPLATE = new InternetAddress[0];
private static final Message.RecipientType[] TYPE_VALS =
{ Message.RecipientType.TO, Message.RecipientType.CC, Message.RecipientType.BCC };
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private GlobalSite site; // the global site
private Session session; // the email session
private MimeMessage msg; // the message being composed
private ArrayList[] recips; // lists of recipients
private String subject = null; // subject string
private String text = null; // text string
private HashMap variables = null; // substitution variables for subject and text
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
BaseMailSend(GlobalSite site, Properties props, javax.mail.Session session)
{
this.site = site;
this.session = session;
msg = new MimeMessage(session);
try
{ // set the X-Mailer header
msg.setHeader("X-Mailer",(String)(props.get("com.silverwrist.venice.email.mailer")));
} // end try
catch (Exception e)
{ // do nothing - we don't really care about this too much
} // end catch
try
{ // set the From address on the message
msg.setFrom(InternetAddress.getLocalAddress(session));
} // end try
catch (MessagingException me)
{ // this should be impossible
throw new InternalStateError("condition should not apply to message here",me);
} // end catch
recips = new ArrayList[3];
recips[0] = recips[1] = recips[2] = null;
} // end constructor
/*--------------------------------------------------------------------------------
* Implementations from interface MailSend
*--------------------------------------------------------------------------------
*/
public void addRecipient(int type, String addr) throws EmailException
{
if ((type<0) || (type>=recips.length))
throw new IndexOutOfBoundsException("invalid recipient type");
try
{ // create an Internet address and set the recipient to it
InternetAddress address = new InternetAddress(addr);
if (recips[type]==null)
recips[type] = new ArrayList();
recips[type].add(address);
} // end try
catch (AddressException e1)
{ // the address was somehow invalid
throw new EmailException("invalid email recipient address",e1);
} // end catch
} // end addRecipient
public void removeRecipient(int type, String addr) throws EmailException
{
if ((type<0) || (type>=recips.length))
throw new IndexOutOfBoundsException("invalid recipient type");
if (recips[type]==null)
return; // nothing there
for (int i=0; i<recips[type].size(); i++)
{ // check out each address
InternetAddress a = (InternetAddress)(recips[type].get(i));
if (addr.equalsIgnoreCase(a.getAddress()))
{ // remove the address!
recips[type].remove(i);
break;
} // end if
} // end for
} // end removeRecipient
public void clearRecipients(int type)
{
if ((type<0) || (type>=recips.length))
throw new IndexOutOfBoundsException("invalid recipient type");
if (recips[type]!=null)
recips[type].clear();
} // end clearRecipients
public void setFrom(String from_name, String from_addr) throws EmailException
{
try
{ // set the "from" address
InternetAddress addr = new InternetAddress(from_addr);
addr.setPersonal(from_name);
msg.setFrom(addr);
// make sure the "Sender" address reflects our email address
InternetAddress sender = InternetAddress.getLocalAddress(session);
msg.setHeader("Sender",sender.toString());
} // end try
catch (AddressException e1)
{ // the address was somehow invalid
throw new EmailException("invalid email sender address",e1);
} // end catch
catch (MessagingException e2)
{ // msg.setRecipients should NOT be throwing a MessageException here!
throw new InternalStateError("condition should not apply to message here",e2);
} // end catch
catch (java.io.UnsupportedEncodingException e3)
{ // we can't really have that happen here, either!
throw new InternalStateError("condition should not apply to message here",e3);
} // end catch
} // end setFrom
public void setSubject(String subject)
{
this.subject = subject;
} // end setSubject
public void setStockSubject(String identifier)
{
this.subject = site.getStockMessage(identifier);
} // end setStockSubject
public void setText(String text)
{
this.text = text;
} // end setStockText
public void setStockText(String identifier)
{
this.text = site.getStockMessage(identifier);
} // end setStockText
public void setVariable(String name, String value)
{
if (variables==null)
variables = new HashMap();
if (value==null)
variables.remove(name);
else
variables.put(name,value);
} // end setVariable
public void addHeader(String name, String value)
{
try
{ // pass through
msg.addHeader(name,value);
} // end try
catch (MessagingException me)
{ // this should be impossible
throw new InternalStateError("condition should not apply to message here",me);
} // end catch
} // end addHeader
public void removeHeader(String name)
{
try
{ // pass through
msg.removeHeader(name);
} // end try
catch (MessagingException me)
{ // this should be impossible
throw new InternalStateError("condition should not apply to message here",me);
} // end catch
} // end removeHeader
public void send() throws EmailException
{
try
{ // set the recipient addresses
for (int i=0; i<recips.length; i++)
{ // load each set of addresses into the message
if ((recips[i]!=null) && !(recips[i].isEmpty()))
{ // retrieve the address list and save it off
InternetAddress[] addrlist = (InternetAddress[])(recips[i].toArray(ADDR_TEMPLATE));
msg.setRecipients(TYPE_VALS[i],addrlist);
} // end if
else // null out these addresses
msg.setRecipients(TYPE_VALS[i],ADDR_TEMPLATE);
} // end for
if (subject!=null)
{ // set the message subject
if (variables==null)
msg.setSubject(subject);
else
msg.setSubject(StringUtil.replaceAllVariables(subject,variables));
} // end if
if (text!=null)
{ // set the message subject
if (variables==null)
msg.setText(text);
else
msg.setText(StringUtil.replaceAllVariables(text,variables));
} // end if
// attempt to send the message!
Transport.send(msg);
} // end try
catch (SendFailedException e1)
{ // convert this exception into an EmailException
throw new EmailException("send of the email message failed: " + e1.getMessage(),e1);
} // end catch
catch (MessagingException e2)
{ // msg.setText should NOT be throwing a MessageException here!
throw new InternalStateError("condition should not apply to message here",e2);
} // end catch
} // end send
} // end class BaseMailSend

View File

@ -64,12 +64,6 @@ public interface EngineBackend
public abstract VeniceEngine getSelf(); public abstract VeniceEngine getSelf();
public abstract Emailer createEmailer();
public abstract String getStockMessage(String key);
public abstract int getNewConfirmationNumber();
public abstract CommunityData getCommunityDataObject(int cid) throws DataException; public abstract CommunityData getCommunityDataObject(int cid) throws DataException;
public abstract void detachCommunityDataObject(int cid); public abstract void detachCommunityDataObject(int cid);
@ -100,10 +94,6 @@ public interface EngineBackend
public abstract void unpublish(long postid); public abstract void unpublish(long postid);
public abstract String generateRandomAuthString();
public abstract boolean isValidRandomAuthString(String s);
public abstract boolean isNoCompressMimeType(String type); public abstract boolean isNoCompressMimeType(String type);
public abstract GlobalProperties getProperties(); public abstract GlobalProperties getProperties();

View File

@ -27,6 +27,7 @@ import com.silverwrist.venice.except.AccessError;
import com.silverwrist.venice.security.*; import com.silverwrist.venice.security.*;
import com.silverwrist.venice.svc.ServiceControl; import com.silverwrist.venice.svc.ServiceControl;
import com.silverwrist.venice.svc.internal.GlobalSite; import com.silverwrist.venice.svc.internal.GlobalSite;
import com.silverwrist.venice.util.MailSend;
public class EnvEngine public class EnvEngine
{ {
@ -171,8 +172,14 @@ public class EnvEngine
public final String getStockMessage(String key) public final String getStockMessage(String key)
{ {
return engine.getStockMessage(key); return globalsite.getStockMessage(key);
} // end getStockMessage } // end getStockMessage
public final MailSend getMailSender()
{
return (MailSend)(globalsite.queryService(MailSend.class));
} // end getMailSender
} // end class EnvEngine } // end class EnvEngine

View File

@ -18,6 +18,7 @@
package com.silverwrist.venice.core.internals; package com.silverwrist.venice.core.internals;
import java.sql.*; import java.sql.*;
import java.util.*;
import org.apache.log4j.*; import org.apache.log4j.*;
import org.w3c.dom.*; import org.w3c.dom.*;
import com.silverwrist.util.*; import com.silverwrist.util.*;
@ -25,6 +26,7 @@ import com.silverwrist.venice.db.*;
import com.silverwrist.venice.except.*; import com.silverwrist.venice.except.*;
import com.silverwrist.venice.svc.internal.GlobalSite; import com.silverwrist.venice.svc.internal.GlobalSite;
import com.silverwrist.venice.util.ServiceProvider; import com.silverwrist.venice.util.ServiceProvider;
import com.silverwrist.venice.util.MailSend;
import com.silverwrist.venice.util.XMLLoader; import com.silverwrist.venice.util.XMLLoader;
public class GlobalSiteImpl implements GlobalSite public class GlobalSiteImpl implements GlobalSite
@ -41,8 +43,11 @@ public class GlobalSiteImpl implements GlobalSite
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------
*/ */
private EngineBackend engine; // the engine back end private EngineBackend engine = null; // the engine back end
private DataPool datapool; // the database pool private DataPool datapool = null; // the database pool
private Properties email_props = null; // email properties
private javax.mail.Session mailsession = null; // email session object
private StockMessages stock_messages = null; // stock messages holder
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
* Constructor * Constructor
@ -70,6 +75,24 @@ public class GlobalSiteImpl implements GlobalSite
} // end catch } // end catch
// Get the <email/> section.
sect = loader.configGetSubSection(config_h,"email");
DOMElementHelper sect_h = new DOMElementHelper(sect);
// initialize the email properties and get a mail session object
email_props = new Properties();
email_props.put("mail.transport.protocol","smtp");
email_props.put("mail.smtp.host",sect_h.getSubElementText("smtp-host"));
email_props.put("mail.from",sect_h.getSubElementText("mail-from-addr"));
email_props.put("com.silverwrist.venice.email.mailer",sect_h.getSubElementText("mailer"));
mailsession = javax.mail.Session.getInstance(email_props,null);
// Get the <messages/> section.
sect = loader.configGetSubSection(config_h,"messages");
// Initialize the stock messages list.
stock_messages = new StockMessages(sect);
} // end class GlobalSiteImpl } // end class GlobalSiteImpl
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
@ -81,6 +104,8 @@ public class GlobalSiteImpl implements GlobalSite
{ {
if (klass==DataPool.class) if (klass==DataPool.class)
return datapool; return datapool;
if (klass==MailSend.class)
return new BaseMailSend(this,email_props,mailsession);
throw new NoSuchServiceException("GlobalSite",klass); throw new NoSuchServiceException("GlobalSite",klass);
} // end queryService } // end queryService
@ -103,6 +128,12 @@ public class GlobalSiteImpl implements GlobalSite
} // end getConnection } // end getConnection
public String getStockMessage(String key)
{
return stock_messages.get(key);
} // end getStockMessage
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
* External operations * External operations
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------

View File

@ -0,0 +1,210 @@
/*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
*
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.venice.security;
import java.security.MessageDigest;
import java.util.*;
public class Generator
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
public static final int CONFIRM_MIN = 1000000;
public static final int CONFIRM_MAX = 9999999;
private static final String AUTH_ALPHABET =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./";
private static final int AUTH_STRING_LEN = 32;
private static final String[] syllabary = {
"ba", "be", "bi", "bo", "bu",
"da", "de", "di", "do", "du",
"cha", "chi", "cho", "chu",
"fa", "fe", "fi", "fo", "fu",
"ga", "ge", "gi", "go", "gu",
"ha", "he", "hi", "ho", "hu",
"ja", "je", "ji", "jo", "ju",
"ka", "ke", "ki", "ko", "ku",
"la", "le", "li", "lo", "lu",
"ma", "me", "mi", "mo", "mu",
"na", "ne", "ni", "no", "nu",
"pa", "pe", "pi", "po", "pu",
"ra", "re", "ri", "ro", "ru",
"sa", "se", "si", "so", "su",
"sha", "she", "sho", "shu",
"ta", "te", "ti", "to", "tu",
"va", "ve", "vi", "vo", "vu",
"wa", "we", "wi", "wo", "wu",
"ya", "ye", "yi", "yo", "yu",
"za", "ze", "zi", "zo", "zu"
}; // 98 syllables
private static final char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
private static Generator self = null; // my own personal instance
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private Random rng; // my random number generator
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
private Generator()
{
// Initialize the random number generator.
java.util.Date seed_date = new java.util.Date();
rng = new Random(seed_date.getTime());
} // end constructor
/*--------------------------------------------------------------------------------
* External operations
*--------------------------------------------------------------------------------
*/
public final String generateRandomAuthString()
{
StringBuffer buf = new StringBuffer(AUTH_STRING_LEN);
for (int i=0; i<AUTH_STRING_LEN; i++)
buf.append(AUTH_ALPHABET.charAt(rng.nextInt(AUTH_ALPHABET.length())));
return buf.toString();
} // end generateRandomAuthString
public final int getNewConfirmationNumber()
{
return rng.nextInt(CONFIRM_MAX - CONFIRM_MIN + 1) + CONFIRM_MIN;
} // end getNewConfirmationNumber
public final int getAuthorizationNumber()
{
return rng.nextInt(Integer.MAX_VALUE);
} // end getAuthorizationNumber
public final String generateRandomPassword()
{
StringBuffer buf = new StringBuffer();
int i;
for (i=0; i<4; i++) // 4 random syllables
buf.append(syllabary[rng.nextInt(syllabary.length)]);
for (i=0; i<3; i++) // 3 random digits
buf.append(digits[rng.nextInt(digits.length)]);
return buf.toString();
// total possible number of passwords = 92,236,816,000
} // end generateRandomPassword
/*--------------------------------------------------------------------------------
* External static operations
*--------------------------------------------------------------------------------
*/
public static final boolean isValidRandomAuthString(String s)
{
if (s.length()!=AUTH_STRING_LEN)
return false;
for (int i=0; i<AUTH_STRING_LEN; i++)
{ // verify each authentication character in turn
if (AUTH_ALPHABET.indexOf(s.charAt(i))<0)
return false;
} // end for
return true; // all tests passed - ship it!
} // end isValidRandomAuthString
public static final String hashPassword(String password)
{
if ((password!=null) && (password.length()>0))
{ // hash the password and save the hash value
MessageDigest hasher;
try
{ // get a hasher implementing the Secure Hashing Algorithm
hasher = MessageDigest.getInstance("SHA");
} // end try
catch (java.security.NoSuchAlgorithmException e)
{ // SHA should be a standard algorithm...if it isn't, we're h0sed
throw new RuntimeException("HOSED JRE - SHA should be a standard algorithm");
} // end catch
try
{ // update the hasher with the UTF-8 bytes of the password
hasher.update(password.getBytes("UTF8"));
} // end try
catch (java.io.UnsupportedEncodingException e)
{ // WTF? How can the JRE NOT know about UTF-8? HOW?!?
throw new RuntimeException("HOSED JRE - UTF-8 encoding should be supported");
} // end catch
// Retrieve the raw hash value (should be 160 bits, or 20 bytes)
byte[] raw_hash = hasher.digest();
// Convert the hash value to a hexadecimal string (40 chars in length)
StringBuffer hash_buf = new StringBuffer(raw_hash.length * 2);
StringBuffer tmp_buf = new StringBuffer();
String tmp;
for (int i=0; i<raw_hash.length; i++)
{ // N.B.: Integer.toHexString does not zero-pad on the left, so that's why this is
// a little complex
tmp_buf.setLength(0);
tmp_buf.append("00").append(Integer.toHexString(raw_hash[i]).trim());
tmp = tmp_buf.toString();
hash_buf.append(tmp.substring(tmp.length()-2));
} // end for
// finally, save off the password hash value
return hash_buf.toString().toUpperCase();
} // end if
else // no password
return "";
} // end hashPassword
public static final Generator get()
{
synchronized (Generator.class)
{ // create me if I don't exist
if (self==null)
self = new Generator();
} // end synchronized block
return self;
} // end get
} // end class Generator

View File

@ -1,114 +0,0 @@
/*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
*
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.venice.security;
import java.util.Random;
public class PasswordGenerator
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
private static final String[] syllabary = {
"ba", "be", "bi", "bo", "bu",
"da", "de", "di", "do", "du",
"cha", "chi", "cho", "chu",
"fa", "fe", "fi", "fo", "fu",
"ga", "ge", "gi", "go", "gu",
"ha", "he", "hi", "ho", "hu",
"ja", "je", "ji", "jo", "ju",
"ka", "ke", "ki", "ko", "ku",
"la", "le", "li", "lo", "lu",
"ma", "me", "mi", "mo", "mu",
"na", "ne", "ni", "no", "nu",
"pa", "pe", "pi", "po", "pu",
"ra", "re", "ri", "ro", "ru",
"sa", "se", "si", "so", "su",
"sha", "she", "sho", "shu",
"ta", "te", "ti", "to", "tu",
"va", "ve", "vi", "vo", "vu",
"wa", "we", "wi", "wo", "wu",
"ya", "ye", "yi", "yo", "yu",
"za", "ze", "zi", "zo", "zu"
}; // 98 syllables
private static final char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private String value; // the password value
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
public PasswordGenerator()
{
Random rng = new Random();
StringBuffer buf = new StringBuffer();
int i;
for (i=0; i<4; i++) // 4 random syllables
buf.append(syllabary[rng.nextInt(syllabary.length)]);
for (i=0; i<3; i++) // 3 random digits
buf.append(digits[rng.nextInt(digits.length)]);
value = buf.toString();
// total possible number of passwords = 92,236,816,000
} // end constructor
/*--------------------------------------------------------------------------------
* Overrides from class Object
*--------------------------------------------------------------------------------
*/
public String toString()
{
return value;
} // end toString
public boolean equals(Object obj)
{
if (obj==null)
return false; // trivial case
else if (obj==(Object)this)
return true; // trivial case
if (obj instanceof PasswordGenerator)
{ // compare value of PasswordHash argument to value
PasswordGenerator other = (PasswordGenerator)obj;
return value.equals(other.value);
} // end if
else
return value.equals(obj.toString());
} // end equals
public int hashCode()
{
return value.hashCode();
} // end hashCode
} // end class PasswordGenerator

View File

@ -1,150 +0,0 @@
/*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
*
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.venice.security;
import java.security.MessageDigest;
public class PasswordHash
{
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private String value; // the hashed password value
/*--------------------------------------------------------------------------------
* Constructors
*--------------------------------------------------------------------------------
*/
public PasswordHash()
{
value = "";
} // end constructor
public PasswordHash(String password)
{
if ((password!=null) && (password.length()>0))
{ // hash the password and save the hash value
MessageDigest hasher;
try
{ // get a hasher implementing the Secure Hashing Algorithm
hasher = MessageDigest.getInstance("SHA");
} // end try
catch (java.security.NoSuchAlgorithmException e)
{ // SHA should be a standard algorithm...if it isn't, we're h0sed
throw new RuntimeException("HOSED JRE - SHA should be a standard algorithm");
} // end catch
try
{ // update the hasher with the UTF-8 bytes of the password
hasher.update(password.getBytes("UTF8"));
} // end try
catch (java.io.UnsupportedEncodingException e)
{ // WTF? How can the JRE NOT know about UTF-8? HOW?!?
throw new RuntimeException("HOSED JRE - UTF-8 encoding should be supported");
} // end catch
// Retrieve the raw hash value (should be 160 bits, or 20 bytes)
byte[] raw_hash = hasher.digest();
// Convert the hash value to a hexadecimal string (40 chars in length)
StringBuffer hash_buf = new StringBuffer(raw_hash.length * 2);
StringBuffer tmp_buf = new StringBuffer();
String tmp;
for (int i=0; i<raw_hash.length; i++)
{ // N.B.: Integer.toHexString does not zero-pad on the left, so that's why this is
// a little complex
tmp_buf.setLength(0);
tmp_buf.append("00").append(Integer.toHexString(raw_hash[i]).trim());
tmp = tmp_buf.toString();
hash_buf.append(tmp.substring(tmp.length()-2));
} // end for
// finally, save off the password hash value
value = hash_buf.toString().toUpperCase();
} // end if
else // no password
value = "";
} // end constructor
/*--------------------------------------------------------------------------------
* Overrides from class Object
*--------------------------------------------------------------------------------
*/
public String toString()
{
return value;
} // end toString
public boolean equals(Object obj)
{
if (obj==null)
return false; // trivial case
else if (obj==(Object)this)
return true; // trivial case
if (obj instanceof PasswordHash)
{ // compare value of PasswordHash argument to value
PasswordHash other = (PasswordHash)obj;
return value.equals(other.value);
} // end if
else
return value.equals(obj.toString());
} // end equals
public int hashCode()
{
return value.hashCode();
} // end hashCode
/*--------------------------------------------------------------------------------
* Test program
*--------------------------------------------------------------------------------
*/
public static void main(String[] args)
{
if (args.length<1)
{ // no password specified
System.err.println("usage: PasswordHash password");
System.exit(1);
} // end if
PasswordHash foo = new PasswordHash(args[0]);
System.out.println(foo.toString());
System.exit(0);
} // end main
} // end class PasswordHash

View File

@ -25,4 +25,6 @@ public interface GlobalSite extends ServiceProvider
{ {
public abstract Connection getConnection(String db_selector) throws SQLException; public abstract Connection getConnection(String db_selector) throws SQLException;
public abstract String getStockMessage(String key);
} // end interface GlobalSite } // end interface GlobalSite

View File

@ -11,24 +11,42 @@
* *
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>, * The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
* *
* Contributor(s): * Contributor(s):
*/ */
package com.silverwrist.venice.core.internals; package com.silverwrist.venice.util;
import com.silverwrist.venice.except.EmailException; import com.silverwrist.venice.except.EmailException;
public interface Emailer public interface MailSend
{ {
public abstract void setTo(String to) throws EmailException; public static final int RECIP_TO = 0;
public static final int RECIP_CC = 1;
public static final int RECIP_BCC = 2;
public abstract void addRecipient(int type, String addr) throws EmailException;
public abstract void removeRecipient(int type, String addr) throws EmailException;
public abstract void clearRecipients(int type);
public abstract void setFrom(String from_name, String from_addr) throws EmailException; public abstract void setFrom(String from_name, String from_addr) throws EmailException;
public abstract void setSubject(String subject); public abstract void setSubject(String subject);
public abstract void setStockSubject(String identifier);
public abstract void setText(String text); public abstract void setText(String text);
public abstract void setStockText(String identifier);
public abstract void setVariable(String name, String value);
public abstract void addHeader(String name, String value);
public abstract void removeHeader(String name);
public abstract void send() throws EmailException; public abstract void send() throws EmailException;
} // end interface Emailer } // end interface MailSend