IDEMPIERE-358 Login- how to make unique and safe - implement email login for monitor

This commit is contained in:
Juliana Corredor 2012-08-16 15:34:37 -05:00
parent e0b518164e
commit ca94ad6670
1 changed files with 52 additions and 69 deletions

View File

@ -36,6 +36,7 @@ import org.compiere.util.CCache;
import org.compiere.util.CLogger; import org.compiere.util.CLogger;
import org.compiere.util.DB; import org.compiere.util.DB;
import org.compiere.util.Env; import org.compiere.util.Env;
import org.compiere.util.KeyNamePair;
import org.compiere.util.Msg; import org.compiere.util.Msg;
import org.compiere.util.Secure; import org.compiere.util.Secure;
import org.compiere.util.SecureEngine; import org.compiere.util.SecureEngine;
@ -173,80 +174,62 @@ public class MUser extends X_AD_User
return null; return null;
} }
boolean hash_password = MSysConfig.getBooleanValue(MSysConfig.USER_PASSWORD_HASH, false); boolean hash_password = MSysConfig.getBooleanValue(MSysConfig.USER_PASSWORD_HASH, false);
boolean email_login = MSysConfig.getBooleanValue(MSysConfig.USE_EMAIL_FOR_LOGIN, false);
ArrayList<KeyNamePair> clientList = new ArrayList<KeyNamePair>();
ArrayList<Integer> clientsValidated = new ArrayList<Integer>();
MUser retValue = null; MUser retValue = null;
if (!hash_password)
{ StringBuffer where = new StringBuffer("Password IS NOT NULL AND ");
int AD_Client_ID = Env.getAD_Client_ID(ctx); if (email_login)
where.append("EMail=?");
else
String sql = "SELECT * FROM AD_User " where.append("COALESCE(LDAPUser,Name)=?");
+ "WHERE COALESCE(LDAPUser, Name)=? " // #1 where.append(" AND")
+ " AND ((Password=? AND (SELECT IsEncrypted FROM AD_Column WHERE AD_Column_ID=417)='N') " // #2 .append(" EXISTS (SELECT * FROM AD_User_Roles ur")
+ "OR (Password=? AND (SELECT IsEncrypted FROM AD_Column WHERE AD_Column_ID=417)='Y'))" // #3 .append(" INNER JOIN AD_Role r ON (ur.AD_Role_ID=r.AD_Role_ID)")
+ " AND IsActive='Y' AND AD_Client_ID=?" // #4 .append(" WHERE ur.AD_User_ID=AD_User.AD_User_ID AND ur.IsActive='Y' AND r.IsActive='Y') AND ")
; .append(" EXISTS (SELECT * FROM AD_Client c")
PreparedStatement pstmt = null; .append(" WHERE c.AD_Client_ID=AD_User.AD_Client_ID")
ResultSet rs = null; .append(" AND c.IsActive='Y') AND ")
try .append(" AD_User.IsActive='Y'");
{
pstmt = DB.prepareStatement (sql, null); List<MUser> users = new Query(ctx, MUser.Table_Name, where.toString(), null)
pstmt.setString (1, name); .setParameters(name)
pstmt.setString (2, password); .setOrderBy(MUser.COLUMNNAME_AD_User_ID)
pstmt.setString (3, SecureEngine.encrypt(password)); .list();
pstmt.setInt(4, AD_Client_ID);
rs = pstmt.executeQuery (); if (users.size() == 0) {
if (rs.next ()) s_log.saveError("UserPwdError", name, false);
{ return null;
retValue = new MUser (ctx, rs, null); }
if (rs.next())
s_log.warning ("More then one user with Name/Password = " + name); for (MUser user : users) {
} if (clientsValidated.contains(user.getAD_Client_ID())) {
else s_log.severe("Two users with password with the same name/email combination on same tenant: " + name);
s_log.fine("No record"); return null;
} }
catch (Exception e)
{ clientsValidated.add(user.getAD_Client_ID());
s_log.log(Level.SEVERE, sql, e); boolean valid = false;
if (hash_password) {
String hash = user.getPassword();
String salt = user.getSalt();
// always do calculation to confuse timing based attacks
if ( hash == null )
hash = "0000000000000000";
if ( salt == null )
salt = "0000000000000000";
valid = user.authenticateHash(password);
} else {
// password not hashed
valid = user.getPassword().equals(password);
} }
finally
{ if (valid){
DB.close(rs, pstmt);
rs = null; pstmt = null;
}
} else {
String where = " COALESCE(LDAPUser,Name) = ? AND" +
" EXISTS (SELECT * FROM AD_User_Roles ur" +
" INNER JOIN AD_Role r ON (ur.AD_Role_ID=r.AD_Role_ID)" +
" WHERE ur.AD_User_ID=AD_User.AD_User_ID AND ur.IsActive='Y' AND r.IsActive='Y') AND " +
" EXISTS (SELECT * FROM AD_Client c" +
" WHERE c.AD_Client_ID=AD_User.AD_Client_ID" +
" AND c.IsActive='Y') AND " +
" AD_User.IsActive='Y'";
MUser user = MTable.get(ctx, MUser.Table_ID).createQuery( where, null).setParameters(name).firstOnly(); // throws error if username collision occurs
String hash = null;
String salt = null;
if (user != null )
{
hash = user.getPassword();
salt = user.getSalt();
}
// always do calculation to confuse timing based attacks
if ( user == null )
user = MUser.get(ctx, 0);
if ( hash == null )
hash = "0000000000000000";
if ( salt == null )
salt = "0000000000000000";
if ( user.authenticateHash(password) )
{
retValue=user; retValue=user;
} }
} }
return retValue; return retValue;
} // get } // get