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.KeyValue;
 import base.Query;
 import base.json.Json;
 
 import static base.jee.api.sql.util.AddPerson.addPerson;
 import static base.jee.api.sql.util.CreateSession.createSession;
 import static base.jee.api.sql.util.IpLocation.ipLocation;
 import static base.jee.api.sql.util.Log.log;
 import static base.jee.api.sql.util.UpdatePersonFromLdap.updatePersonFromLdap;

 
 public class Authenticate extends Query<KeyValue> {
 
 	private DataSource ds;
 	private String currentToken;
 	private String username;
 	private String password;
 	private String ip;
 
 	public Authenticate() {
 	}
 
 	public Authenticate(DataSource dsString currentTokenString usernameString passwordString ip) {
 
 		if(ds == null) {
 			throw new IllegalArgumentException("Invalid parameter: ds");
 		}
 		if(username == null) {
 			throw new IllegalArgumentException("Invalid parameter: username");
 		}
 		if(password == null) {
 			throw new IllegalArgumentException("Invalid parameter: password");
 		}
 
 		if(currentToken != null && currentToken.trim().length() > .) {
 			throw new IllegalArgumentException("Invalid token.");
 		}
 		if(username.trim().length() > .) {
 			throw new IllegalArgumentException("Invalid username. Usernames should not have more than " + . + " characters.");
 		}
 		if(password.trim().length() > .) {
 			throw new IllegalArgumentException("Invalid password. Passwords should not have more than " + . + " characters.");
 		}
 		if(ip != null && ip.trim().length() > .) {
 			throw new IllegalArgumentException("Invalid IP address. IP address should not have more than " + . + " characters.");
 		}
 
 		this. = ds;
 		this. = currentToken;
 		this. = username.trim().toLowerCase();
 		this. = password.trim();
 		this. = ip == null?null:ip.trim();
 	}
 
 		return new Authenticate(
 				((SqlAPI)parameters.get("api")).getDataSource(),
 				(String)parameters.get("current_token"),
 				(String)parameters.get("username"),
 				(String)parameters.get("password"),
 				((User)parameters.get("user")).getIp());
 	}
 
 	public List<KeyValueexecute() throws IOException {
 		List<KeyValueresults = new LinkedList<>();
		String token = null;
		Connection c = null;
		PreparedStatement s = null;
		ResultSet r = null;
		try {
			c.setAutoCommit(false);
			if(isThrottled(c"ip")) {
				log(c"SEVERE"null"Blocked authentication for throttled IP address: " + );
				c.commit();
				c.close();
				c = null;
				results.add(new KeyValue("error""Sign-in from this IP address is temporarily disabled due to repated sign in failures. Please try again shortly."));
				return results;
			}
			if(isThrottled(c"auth")) {
				markForThrottling(c"ip");
				log(c"SEVERE"null"Blocked authentication for throttled username: " + );
				c.commit();
				c.close();
				c = null;
				results.add(new KeyValue("error""Sign-in using this account is temporarily disabled due to repated sign in failures. Please try again shortly."));
				return results;
			}
				c.commit();
				c.close();
				c = null;
				results.add(new KeyValue("error""Invalid password."));
				return results;
			}
			UUID personUuid = null;
			s = c.prepareStatement("select uuid, password, expiry from person where " + (.contains("@")?"email":"username") + "=?");
			r = s.executeQuery();
			if(r.next() && r.getString(2) != null && r.getString(2).length() > 0) {
				personUuid = UUID.fromString(r.getString(1));
				// Expiry check before password check, ensuring there is no fall through
				// to LDAP authentication in this case.
				if(r.getLong(3) > 0 && new Date(r.getLong(3)).getTime() < new Date().getTime()) {
					log(c"FINE", User.userWithUuidAndIp(personUuid), "Sign-in attempted from account that is expired.");
					return null;
				}
				// If password hash does not match password, we forget this search result,
				// this enables a lookup on LDAP (below).
				if(!Password.verifyPassword(r.getString(2), )) {
					personUuid = null;
				}
				// Internal authentication success
			}
			r.close();
			r = null;
			s.close();
			s = null;
			// Internal password check failed. Do LDAP lookup if this feature is configured to be enabled.
			if(personUuid == null) {
				boolean ldapEnabled = false;
				String ldapUrl = null;
				String ldapUserDn = null;
				if(!.contains("@")) {
					s = c.prepareStatement("select (select value from setting where name='ldap.enabled'),(select value from setting where name='ldap.url'),(select value from setting where name='ldap.userdn')");
					r = s.executeQuery();
					if(r.next()) {
						ldapEnabled = r.getString(1).equalsIgnoreCase("true") || r.getString(1).equalsIgnoreCase("y") || r.getString(1).equalsIgnoreCase("yes");
						ldapUrl = r.getString(2);
						ldapUserDn = r.getString(3);
					}
					r.close();
					r = null;
					s.close();
					s = null;
				}
				if(ldapEnabled) {
					String user = ldapUserDn.replace("{u}", LdapHelper.ldapEscape());
					Map<StringStringattributes;
					try {
						ldap = new LdapHelper(ldapUrlusertrue);
						attributes = ldap.getAttributes(user);
catch (AuthenticationException e) {
						log(c"FINE", User.userWithIp(), "Invalid internal and/or ldap username or password. Username: " + );
						c.commit();
						c.close();
						c = null;
						results.add(new KeyValue("error""Invalid username or password."));
						return results;
catch (NamingException | IOException e) {
						log(c"SEVERE", User.userWithIp(), "Problem communicating with LDAP server. user: " + user + " - " + StringHelper.exceptionToString(e"\n    "));
						c.commit();
						c.close();
						c = null;
						results.add(new KeyValue("error""Authentication temporarily unavailable."));
						return results;
					}
					personUuid = createOrUpdatePersonUsingLdapAttributes(cattributes);
				}
				if(personUuid == null) {
					log(c"FINE", User.userWithIp(), "Invalid username or password. Username: " + );
					c.commit();
					c.close();
					c = null;
					results.add(new KeyValue("error""Invalid username or password."));
					return results;
				}
			}
			if(.length() == 0) {
				log(c"SEVERE", User.userWithUuidAndIp(personUuid), "Blocked authentication for account with no password: Username: " + );
				c.commit();
				c.close();
				c = null;
				results.add(new KeyValue("error""This user account has no password."));
				return results;
			}
			s = c.prepareStatement("update person set last_auth=?,last_auth_ip=? where uuid=?");
			s.setLong(1, new Date().getTime());
			s.setString(2, );
			s.setString(3, personUuid.toString());
			s.close();
			s = null;
			token = createSession(cpersonUuid);
			Location l = ipLocation(c);
			log(c"INFO", User.userWithUuidAndIp(personUuid), "Authentication success. Location: " + (l == null?"unknown":l.toString()));
			c.commit();
			c.close();
			c = null;
			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) { }
			}
		}
		results.add(new KeyValue("token"token));
		return results;
	}
	private UUID createOrUpdatePersonUsingLdapAttributes(Connection cString usernameMap<StringStringattributesthrows IOException {
		UUID personUuid = null;
		PreparedStatement s = null;
		ResultSet r = null;
		String firstName = attributes.get("givenName");
		String lastName = attributes.get("sn");
		String email = attributes.get("mail");
		try {
			s = c.prepareStatement("select uuid, first_name, last_name, email from person where username=?");
			s.setString(1, username);
			r = s.executeQuery();
			if(r.next()) {
				personUuid = UUID.fromString(r.getString(1));
				if((email != null && !email.equals(r.getString(4)))
					|| (firstName != null && !firstName.equals(r.getString(2)))
					|| (lastName != null && !lastName.equals(r.getString(3)))
					) {
					if(email.equals(r.getString(4))) {
						email = null;
					}
					if(firstName.equals(r.getString(2))) {
						firstName = null;
					}
					if(lastName.equals(r.getString(3))) {
						lastName = null;
					}
					updatePersonFromLdap(c, User.userWithUuidAndIp(personUuid), firstNamelastNameemail);
				}
				return personUuid;
			}
			personUuid = addPerson(cfirstNamelastNameemailusernamenullnull);
			log(c"INFO", User.userWithUuidAndIp(personUuid), "Auto created user account using LDAP date for username=" + username);
			throw new IOException(e);
finally {
			if(r != null) { try { r.close(); } catch(Exception e) {} }
			if(s != null) { try { s.close(); } catch(Exception e) {} }
		}
		return personUuid;
	}
		return "{" +
				"\"current_token\":\"" + Json.escape() + "\"," +
				( == null?"":("\"ip\":\"" + Json.escape() + "\",")) +
				"\"username\":\"" + Json.escape() + "\"" +
				"}";
	}
	public boolean isThrottled(Connection cString keyString typethrows SQLException {
		PreparedStatement q = null;
		PreparedStatement q2 = null;
		ResultSet r = null;
		try {
			q = c.prepareStatement("select updated + (select value from setting where name='throttle." + type + ".lockout') from throttle where key_value=? and attempts>=(select value from setting where name='throttle." + type + ".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 keyString typethrows 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." + type + ".window'");
				r = q2.executeQuery();
				if(!r.next()) {
					throw new IllegalStateException("System configuration setting 'throttle." + type + ".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) {}
		}
	}
	private void badUser(Connection cString usernameString ipthrows SQLException {
		if(username.contains("=") || username.contains("&")
			|| username.contains("%") || username.contains("..")
			|| username.contains("/") || username.contains("\\")
			|| username.contains("(") || username.contains(")")
			|| username.contains("!") || username.contains("--")
			|| username.contains(";") || username.contains("$")) {
			markForThrottling(cip"ip");
			markForThrottling(cip"ip");
			markForThrottling(cip"ip");
		}
		if(username.contains("cn=") || username.contains("file://")
			|| username.contains("http://") || username.contains("sleep(")
			|| username.contains("<script") || username.contains("win.ini")
			|| username.contains("..\\") || username.contains("../")
			|| username.contains("<script") || username.contains("boot.ini")
			|| username.contains("/etc/") || username.contains("web.xml")) {
			markForThrottling(cip"ip");
			markForThrottling(cip"ip");
			markForThrottling(cip"ip");
			markForThrottling(cip"ip");
			markForThrottling(cip"ip");
			markForThrottling(cip"ip");
			markForThrottling(cip"ip");
			markForThrottling(cip"ip");
			markForThrottling(cip"ip");
			markForThrottling(cip"ip");
			markForThrottling(cip"ip");
			markForThrottling(cip"ip");
		}
		markForThrottling(cip"ip");
		markForThrottling(cusername"auth");
	}
New to GrepCode? Check out our FAQ X