Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
Creative commons Attribution-NonCommercial license. http://creativecommons.org/licenses/by-nc/2.5/au/deed.en_GB NO WARRANTY IS GIVEN OR IMPLIED, USE AT YOUR OWN RISK.
  
  package base.jee.api.sql;
  
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 
 
 import base.Query;
 import base.json.Json;
 
 import static base.jee.api.sql.util.Log.log;

Request that an email be sent to an email address associated with a user of the system, that enables resetting of this users password. Password reset requests are also throttled, they considered to be an authentication request.
 
 public class RequestPasswordResetEmail extends Query<StringQueryResult> {
 
 	private SqlAPI api;
 	private Settings settings;
 	private String email;
 	private String ip;

Parameters:
api
templates A template manager with template files 'password_reset_email_html.txt' and 'password_reset_email_text.txt'
email Email address corresponding with the users account.
ip
 
 	public RequestPasswordResetEmail(SqlAPI apiTemplateManager templatesSettings settingsString emailString ip) {
 		if(api == null) {
 			throw new IllegalArgumentException("Invalid parameter: api");
 		}
 		if(ip == null) {
 			throw new IllegalArgumentException("Invalid parameter: ip");
 		}
 		if(templates == null) {
 			throw new IllegalArgumentException("Invalid parameter: templates");
 		}
 		if(settings == null) {
 			throw new IllegalArgumentException("Invalid parameter: settings");
 		}
 		if(email == null) {
 			throw new IllegalArgumentException("Invalid parameter: email");
 		}
 
 		if(email.trim().length() > .) {
 			throw new IllegalArgumentException("Please choose a shorter email address. Email should not have more than " + . + " characters.");
 		}
 
 		this. = api;
 		this. = templates;
 		this. = settings;
 		this. = email.trim().toLowerCase();
 	}
 
 	public List<StringQueryResultexecute() throws IOException {
 		List<StringQueryResultresults = new LinkedList<>();
 		Connection c = null;
 		PreparedStatement s = null;
 		ResultSet r = null;
 		User u = null;
 
 		try {
 			c.setAutoCommit(false);
 
 			if(isThrottled(c)) {
 				log(c"SEVERE", User.userWithIp(), "Blocked password reset request for throttled address: " + );
 				throw new IllegalStateException("This account is temporarily disabled due to repated sign in failures. Please try again shortly.");
 			}
 
 			String supportTeam = null;
 			String supportEmail = null;
			s = c.prepareStatement("select uuid, first_name, last_name, (select value from setting where name='support_team.name'), (select value from setting where name='support_team.email'), expiry from person where email=?");
			r = s.executeQuery();
			if(r.next()) {
				// Construct a user object for the purposes of making the user
				// info available in the email template.
				u = new User(
						null,
						null,
						null,
				supportTeam = r.getString(4);
				supportEmail = r.getString(5);
				//6
				if(r.getLong(6) > 0 && new Date(r.getLong(6)).getTime() < new Date().getTime()) {
					log(c"FINE"u"Password reset attempted from account that is expired.");
					throw new IllegalStateException("Password reset is not allowed for expired accounts.");
				}
			}
			r.close();
			r = null;
			s.close();
			s = null;
			if(u == null) {
				markForThrottling(c"password_reset_" + );
				log(c"FINE", User.userWithIp(), "Invalid email: " + );
				c.commit();
				c.close();
				c = null;
				return null;
			}
			String token = UUID.randomUUID().toString();
			log(c"DEBUG"u"Storing token " + token + " for person " + );
			s = c.prepareStatement("insert into request_token (token, person_uuid, type, ip, expiry) values(?,?,'password_reset',?,?)");
			s.setString(1, token);
			s.setString(3, );
			s.setLong(4, (new Date()).getTime()/1000);
			s.close();
			s = null;
			ST html = .getCurrentTemplate().getInstanceOf("password_reset_email_html");
			html.add("name"u.getDisplayName());
			html.add("email"this.);
			html.add("token"token);
			html.add("formurl".get("base.url"));
			ST text = .getCurrentTemplate().getInstanceOf("password_reset_email_text");
			text.add("name"u.getDisplayName());
			text.add("email"this.);
			text.add("token"token);
			text.add("formurl".get("base.url"));
			Email email = new Email();
			email.setTo(u.getDisplayName() + " <" + this. + ">");
			email.setFrom(supportTeam + " <" + supportEmail + ">");
			email.setText(text.render());
			email.setHtml(html.render());
			email.setSubject("Password reset request verification");
			s = c.prepareStatement("insert into email (uuid,to_address,email,retries,attempt_at,in_progress) values(?,?,?,0,?,0)");
			s.setString(1, new base.uuid.UUID().toString());
			s.setString(2, email.getTo());
			s.setString(3, email.toJson());
			s.setLong(4, new Date().getTime());
			s.close();
			s = null;
			log(c"INFO"u"Sending password reset request for " + this. + " with token " + token);
			c.commit();
			c.close();
			c = null;
			results.add(new StringQueryResult(token));
catch(SQLException e) {
			throw new IOException(e);
finally {
			if(r != null) { try { r.close(); } catch(Exception e) {} }
			if(s != null) { try { s.close(); } catch(Exception e) {} }
			if(c != null) {
				try { c.rollback(); } catch (SQLException e) { }
				try { c.close(); } catch (SQLException e) { }
			}
		}
		return results;
	}
		return "{" +
				"\"email\":\"" + Json.escape() + "\"," +
				"\"ip\":\"" + Json.escape() + "\"" +
				"}";
	}
	public boolean isThrottled(Connection cString keythrows SQLException {
		PreparedStatement q = null;
		PreparedStatement q2 = null;
		ResultSet r = null;
		try {
			q = c.prepareStatement("select updated + (select value from setting where name='throttle.auth.lockout') from throttle where key_value=? and attempts>=(select value from setting where name='throttle.auth.attempts')");
			q.setString(1, key);
			r = q.executeQuery();
			if(r.next()) {
				if((new Date().getTime()/1000) < r.getLong(1)) {
					return true;
else {
					q2 = c.prepareStatement("delete from throttle where key_value=?");
					q2.setString(1, key);
					q2.execute();
					return false;
				}
else {
				return false;
			}
finally {
			try { if(r != null) { r.close(); } } catch(Exception e) {}
			try { if(q != null) { q.close(); } } catch(Exception e) {}
			try { if(q2 != null) { q2.close(); } } catch(Exception e) {}
		}
	}
	public void markForThrottling(Connection cString keythrows SQLException {
		PreparedStatement q = null;
		PreparedStatement q2 = null;
		PreparedStatement q3 = null;
		ResultSet r = null;
		try {
			q = c.prepareStatement("select attempts,updated from throttle where key_value=?");
			q.setString(1, key);
			r = q.executeQuery();
			if(!r.next()) {
				// Insert new throttle
				q3 = c.prepareStatement("insert into throttle (key_value,attempts,updated) values(?,1,?)");
				q3.setString(1, key);
				q3.setLong(2, new Date().getTime()/1000);
				return;
else {
				long updated = r.getLong(2);
				r.close();
				r = null;
				q2 = c.prepareStatement("select value from setting where name = 'throttle.auth.window'");
				r = q2.executeQuery();
				if(!r.next()) {
					throw new IllegalStateException("System configuration setting 'throttle.auth.window' is missing.");
				}
				if(updated < (new Date().getTime()/1000)-r.getLong(1)) {
					// Marking outside the throttle window, reset the attempt counter
					q3 = c.prepareStatement("update throttle set attempts=1,updated=? where key_value=?");
					q3.setLong(1, new Date().getTime()/1000);
					q3.setString(2, key);
else {
					// Marking within the throttle window, just increment the attempts counter
					q3 = c.prepareStatement("update throttle set attempts=attempts+1 where key_value=?");
					q3.setString(1, key);
					return;
				}
			}
finally {
			try { if(r != null) { r.close(); } } catch(Exception e) {}
			try { if(q != null) { q.close(); } } catch(Exception e) {}
			try { if(q2 != null) { q2.close(); } } catch(Exception e) {}
			try { if(q3 != null) { q3.close(); } } catch(Exception e) {}
		}
	}
		throw new IllegalArgumentException("RequestPasswordResetEmail may not be instantiated using a parameter map");
	}
New to GrepCode? Check out our FAQ X