View Javadoc
1   package com.randomnoun.common.security.impl;
2   
3   /* (c) 2013 randomnoun. All Rights Reserved. This work is licensed under a
4    * BSD Simplified License. (http://www.randomnoun.com/bsd-simplified.html)
5    */
6   
7   import java.io.IOException;
8   import java.util.*;
9   
10  import org.apache.log4j.Logger;
11  import org.springframework.jdbc.core.*;
12  
13  import com.randomnoun.common.Text;
14  import com.randomnoun.common.security.Permission;
15  import com.randomnoun.common.security.SecurityAuthenticator;
16  import com.randomnoun.common.security.User;
17  import com.randomnoun.common.security.impl.SpringSecurityAuthenticatorImpl;
18  
19  // ok. the USERID column in the table is actually a string. 
20  // presumably the actual User.userId is sourced from some other column.
21  
22  // this implementation appears to favour querying on the USERID String,
23  // so bear that in mind as well. It also doesn't populate the actual User.userId,
24  // so don't use that at all.
25  
26  /**
27   * See SpringSecurityLoaderImpl. Maybe.
28   *
29   * 
30   * @author knoxg
31   */
32  public class SpringSecurityAuthenticatorImpl
33  	implements SecurityAuthenticator
34  {
35  	
36  	/** Logger for this class */
37  	public static final Logger logger = Logger.getLogger(SpringSecurityAuthenticatorImpl.class);
38  
39  	/** Properties used in this loader */
40  	private Map<String, Object> properties = null;
41      
42  	public static String INIT_TABLENAME = "tableName";
43  	public static String INIT_USERNAME_COLUMN = "usernameColumn";
44  	public static String INIT_PASSWORD_COLUMN = "passwordColumn";
45  	
46  	/** Odd. */
47  	public static String INIT_JDBCTEMPLATE = "jdbcTemplate";
48  	
49  	String tableName;
50  	String usernameColumn;
51  	String passwordColumn;
52  	
53  	/** Initialise this loader.
54  	 *
55  	 * @see com.randomnoun.common.security.SecurityLoader#initialise(java.util.Map)
56  	 */
57  	public void initialise(Map<String, Object> properties)
58  	{
59  		this.properties = properties;
60  		if (properties.get(INIT_JDBCTEMPLATE)==null) { throw new NullPointerException("null INIT_JDBCTEMPLATE"); }
61          
62  		tableName = Text.strDefault((String) properties.get(INIT_TABLENAME), "users");
63  		usernameColumn = Text.strDefault((String) properties.get(INIT_USERNAME_COLUMN), "userId");
64  		passwordColumn = Text.strDefault((String) properties.get(INIT_PASSWORD_COLUMN), "password");
65  	}
66  
67  	/** Authenticates a user. 
68  	 * 
69  	 */
70  	public boolean authenticate(User user, String password)
71  	{
72  		// check that the password is not empty
73  		if (password == null || password.equals("")) {	
74  			return false;
75  		}
76  		JdbcTemplate jt = (JdbcTemplate)properties.get("jdbcTemplate");
77  		String sql = 
78  		  "SELECT " + passwordColumn  +
79  		  " FROM " + tableName +  
80  		  " WHERE " + usernameColumn + " = ?";
81  		List<Object> sqlParams = new ArrayList<Object>(2);
82  		sqlParams.add(user.getUsername());
83  		boolean authenticated = false;  
84  		try {           
85  			// TODO hash this, then perform the comparison in a stored procedure, 
86  			// then move it all to LDAP or OpenID
87  			String databasePassword = (String) jt.queryForObject(sql, sqlParams.toArray(), String.class);
88  			authenticated = password.equals(databasePassword);
89  		} catch (Exception ex) {
90  			logger.error("Error authenticating user", ex);
91  			authenticated = false;   
92  		}
93  		return authenticated;
94  	}
95  		
96  	
97  	/** Resets the security context. 
98  	 * 
99  	 * <p>This security context holds no state, so this method does nothing.
100 	 */
101 	public void resetSecurityContext() {
102 		// no action necessary
103 	}
104 
105 	public void saveUserRolesAndPermissions(User user, List<String> roles, List<Permission> userPermissions) throws IOException 
106 	{
107 		throw new UnsupportedOperationException("not implemented");
108 	}
109 
110 	public void saveRolePermissions(String role, List<Permission> rolePermissions)
111 		throws IOException 
112 	{
113 		throw new UnsupportedOperationException("not implemented");
114 	}
115 
116 }
117