Class PasswordResetMail
The steps, in this order:
- Refuse a user without an e-mail address; nothing is changed.
- Address the mail: from the mail sender's default sender address, to the user's address only, no CC and no BCC, so a mis-configured or unparsable address is found before the password moves.
- Reset the password through the reset step, normally
BasicUserInfo.resetPassword(StringBuilder): a strong random password, "change password at next sign in" set, committed by that method. - Send the mail synchronously through the send step, normally
Mail.send().
The password is committed before the mail goes, because the reset step is the only owner of the users table and of the cached user, and it commits. So a send failure is not silent: the message returned to the administrator says that the password WAS changed and that the mail did not arrive, and the log carries the same. The password itself never appears in a returned message or in a log line.
The two steps are parameters so that the composition and the ordering can be proven with a fake mail send and a fake reset (PasswordResetMailTest); ServerAdmin passes the real ones.
resetAndMail(Connection,String,String,MailSender,IResetStep,ISendStep) is the same in ONE transaction on the caller's connection: the reset is written without a commit, the mail is sent, and only a sent mail commits the reset; a mail that cannot be sent rolls it back, so the old password keeps working and the administrator is told that nothing changed (CC-FIX-SERVERADMIN SA-4, the (a) of CC-FIX-NOTFOUND-AND-RESET's D-2). ServerAdmin uses it.
composeLink(MailSender, String, String, String) is the self-service reset of the SignIn module (CC-LOGIN-SERVER-CORE, D-6 of the SignIn survey): the mail carries a reset LINK (PasswordResetLink, sealed, 30 minutes, spent by the reset it makes) and no password at all, and nothing is changed until the user opens it. Same addressing, same class, so that there is one reset mail.
- Author:
- Christopher Mindus
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic interfaceThe reset step:BasicUserInfo::resetPassword.static interfaceThe send step:Mail::send.Field Summary
FieldsModifier and TypeFieldDescriptionstatic final intHow long the link ofcomposeLink(MailSender, String, String, String)is valid, for the text: 30 minutes.static final StringThe subject of the mail.Method Summary
Modifier and TypeMethodDescriptionstatic StringThe text of the mail.static Mailcompose(MailSender sender, String email) Addresses a reset mail: from the sender's default sender address, to the user's address only, subject set, no text yet.static MailcomposeLink(MailSender sender, String email, String userName, String link) Composes a reset link mail: addressed ascompose(MailSender, String), withlinkBody(String, String)as its text.static StringThe text of a reset link mail.static StringresetAndMail(String userName, String email, MailSender sender, PasswordResetMail.IResetStep reset, PasswordResetMail.ISendStep send) Resets the password and mails it to the user, in the order the class comment gives.static StringresetAndMail(Connection conn, String userName, String email, MailSender sender, PasswordResetMail.IResetStep reset, PasswordResetMail.ISendStep send) Resets the password and mails it in ONE transaction on the caller's connection.
Field Details
SUBJECT
LINK_MINUTES
public static final int LINK_MINUTESHow long the link ofcomposeLink(MailSender, String, String, String)is valid, for the text: 30 minutes.- See Also:
Method Details
compose
Addresses a reset mail: from the sender's default sender address, to the user's address only, subject set, no text yet.- Parameters:
sender- The mail sender.email- The user's registered e-mail address.- Returns:
- The addressed mail.
- Throws:
MessagingException- If the sender has no default sender address, or the user's address does not parse.
body
linkBody
composeLink
public static Mail composeLink(MailSender sender, String email, String userName, String link) throws MessagingException Composes a reset link mail: addressed ascompose(MailSender, String), withlinkBody(String, String)as its text. Nothing is sent and nothing is changed here.- Parameters:
sender- The mail sender.email- The user's registered e-mail address.userName- The user name.link- The reset link.- Returns:
- The mail, ready to send.
- Throws:
MessagingException- If the sender has no default sender address, or the user's address does not parse.
resetAndMail
public static String resetAndMail(String userName, String email, MailSender sender, PasswordResetMail.IResetStep reset, PasswordResetMail.ISendStep send) throws SQLException, NotFoundException Resets the password and mails it to the user, in the order the class comment gives.- Parameters:
userName- The user name, for the mail text and the messages.email- The user's registered e-mail address,nullor blank for none.sender- The mail sender to send through.reset- The reset step.send- The send step.- Returns:
nullif the password was reset and the mail sent, otherwise the reason to show the administrator. The reason never contains the password.- Throws:
SQLException- For SQL errors in the reset step; nothing has been sent.NotFoundException- If the user has been deleted since login; nothing has been sent.
resetAndMail
public static String resetAndMail(Connection conn, String userName, String email, MailSender sender, PasswordResetMail.IResetStep reset, PasswordResetMail.ISendStep send) throws SQLException, NotFoundException Resets the password and mails it in ONE transaction on the caller's connection. The checks before the reset are those ofresetAndMail(String,String,MailSender,IResetStep,ISendStep); then the reset step writes on the connection without committing, the mail is sent, and a sent mail commits the reset. A refused reset, a mail that is not accepted or a mail whose send throws roll the transaction back, and so does anything thrown by the reset step or the commit before it is rethrown.The caller's cached user is not updated by the reset step (see
BasicUserInfo.resetPassword(Connection,StringBuilder)): after anullreturn the caller refreshes it from the row.- Parameters:
conn- The connection, auto-commit "off"; committed or rolled back here.userName- The user name, for the mail text and the messages.email- The user's registered e-mail address,nullor blank for none.sender- The mail sender to send through.reset- The reset step, writing onconnwithout committing:(p)->user.resetPassword(conn,p).send- The send step.- Returns:
nullif the password was reset, mailed and committed, otherwise the reason to show the administrator: nothing was changed. The reason never contains the password.- Throws:
SQLException- For SQL errors in the reset step or the commit; rolled back. A commit that fails after the mail was sent leaves the user with a mailed password that does not work: reset again.NotFoundException- If the user has been deleted since login; rolled back.