6ec4a6f3965bca0696cfdaff18e70f19d69b2f37
chinhli
  Sun May 6 14:56:27 2012 -0700
Initial generate new password function.
diff --git src/hg/hgLogin/hgLogin.c src/hg/hgLogin/hgLogin.c
index 529ae8e..714aae9 100644
--- src/hg/hgLogin/hgLogin.c
+++ src/hg/hgLogin/hgLogin.c
@@ -153,30 +153,80 @@
 /* TODO: validate the email address is in right format */
 /* find all the user names assocaited with this email address */
 char user[256];
 safef(query,sizeof(query),"select * from gbMembers where email='%s'", email);
 sr = sqlGetResult(conn, query);
 while ((row = sqlNextRow(sr)) != NULL)
     {
     struct gbMembers *m = gbMembersLoad(row);
     safef(user, sizeof(user), m->userName);
     mailUsername(email, user);   
     }
 sqlFreeResult(&sr);
 }
 
 
+void generateNewPassword(struct sqlConnection *conn, char *username)
+/* Generate a new password */
+{
+char query[256];
+//char cmd[256];
+char *password = generateRandomPassword();
+char encPwd[45] = "";
+encryptNewPwd(password, encPwd, sizeof(encPwd));
+
+safef(query,sizeof(query), "update gbMembers set lastUse=NOW(),newPassword='%s', newPasswordExpire=DATE_ADD(NOW(), INTERVAL 7 DAY), passwordChangeRequired='Y' where userName='%s'",
+ sqlEscapeString(encPwd), sqlEscapeString(username));
+sqlUpdate(conn, query);
+/* quick return check table */
+sendNewPassword(conn, username, password);
+return;
+}
+
+void sendNewPassword(struct sqlConnection *conn, char *username, char *password)
+/* email user new password  */
+{
+struct sqlResult *sr;
+char query[256];
+
+/* find all the user names assocaited with this email address */
+safef(query,sizeof(query),"select email from gbMembers where userName='%s'", username);
+char *email = sqlQuickString(conn, query);
+if (!email || sameString(email,""))
+    {
+    freez(&errMsg);
+    errMsg = cloneString("Email address not found.");
+    displayAccHelpPage(conn);
+    return;
+    }
+mailNewPassword(username, email, password);
+sqlFreeResult(&sr);
+}
+
+void mailNewPassword(char *username, char *email, char *password)
+/* send user new password */
+{
+char subject[256];
+char msg[256];
+char signature[256]="\nUCSC Genome Browser \nhttp://www.genome.ucsc.edu ";
+safef(subject, sizeof(subject),"Greeting form UCSC Genome Browser");
+safef(msg, sizeof(msg), "New password for user %s:  \n\n  %s \n", username, password);
+safecat (msg, sizeof(msg), signature);
+sendMail(email, subject, msg);
+}
+
+
 /*************** to-do below *********************/
 void activateAccount(struct sqlConnection *conn)
 /* activate account */
 {
 // struct sqlResult *sr;
 // char **row;
 char query[256];
 char *token = cgiUsualString("hgLogin_activateAccount", "");
 safef(query,sizeof(query),"Token is %s ", token);
 if (!sameString(token,""))
     {
     freez(&errMsg);
     errMsg = cloneString(query);
     displayLoginPage(conn);
     return;
@@ -269,30 +319,31 @@
 const char *const seedchars =
 "0123456789ABCDEFGHIJKLMNOPQRST"
 "UVWXYZabcdefghijklmnopqrstuvwxyz";
 int i;
 /* Generate a (not very) random seed. */
 seed[0] = time(NULL);
 seed[1] = getpid() ^ (seed[0] >> 14 & 0x30000);
 /* Turn it into printable characters from `seedchars'. */
 for (i = 0; i < 8; i++)
     salt[i] = seedchars[(seed[i/5] >> (i%5)*6) & 0x3f];
 // /*DEBUG*/ printf("salt generated: %s\n", salt);
 encryptPWD(password, salt, buf, bufsize);
 }
 
 void findSalt(char *encPassword, char *salt, int saltSize)
+/* find the salt part from the password field */
 {
 // /*DEBUG*/ printf("encPassword from database is: %s\n",encPassword);
 char tempStr1[45];
 char tempStr2[45];
 
 int i;
 // Skip the ":B:" part
 for (i = 3; i <= strlen(encPassword); i++)
     tempStr1[i-3] = encPassword[i];
 // /*DEBUG*/ printf("encPassword is %s\n",encPassword);
 // /*DEBUG*/ printf("Trim out the :B: to become %s\n",tempStr1);
 i = strcspn(tempStr1,":");
 // /*DEBUG*/ printf(" : is at location %d\n", i);
 safencpy(tempStr2, sizeof(tempStr2), tempStr1, i);
 // /*DEBUG*/ printf("Trimmed salt is %s\n", tempStr2);
@@ -769,31 +820,32 @@
     freez(&errMsg);
     errMsg = cloneString("Passwords do not match.");
     signupPage(conn);
     return;
     }
 
 /* pass all the checks, OK to create the account now */
 char encPwd[45] = "";
 encryptNewPwd(password, encPwd, sizeof(encPwd));
 safef(query,sizeof(query), "insert into gbMembers set "
     "userName='%s',password='%s',email='%s', "
     "lastUse=NOW(),accountActivated='N'",
     sqlEscapeString(user),sqlEscapeString(encPwd),sqlEscapeString(email));
     sqlUpdate(conn, query);
 
-
+/* send out activate code mail, and display the main confirmation box */
+/* and comback here to contine back to URL */
 hPrintf(
 "<h2>UCSC Genome Browser</h2>\n"
 "<p align=\"left\">\n"
 "</p>\n"
 "<h3>User %s successfully added.</h3>\n"
 , user
 );
 /* TODO: cleanup the hgLogin_xxxx vars in the cart */
 backToHgSession(2);
 
 }
 
 void displayAccHelpPage(struct sqlConnection *conn)
 /* draw the account help page */
 {
@@ -859,69 +911,75 @@
 "     &nbsp;<a href=\"javascript:history.go(-1)\">Cancel</a>"
 "</div>"
 "</form>"
 "</div><!-- END - accountHelpBox -->"
 , username
 , email
 );
 cartSaveSession(cart);
 }
 
 void accountHelp(struct sqlConnection *conn)
 /* email user username(s) or new password */
 {
 // struct sqlResult *sr;
 // char **row;
-// char query[256];
+char query[256];
 char *email = cartUsualString(cart, "hgLogin_email", "");
 char *username = cartUsualString(cart, "hgLogin_userName", "");
 char *helpWith = cartUsualString(cart, "hgLogin_helpWith", "");
 
 /* Forgot username */
 if (sameString(helpWith,"username"))
 {
     if (sameString(email,""))
     {
     freez(&errMsg);
     errMsg = cloneString("Email address cannot be blank.");
     displayAccHelpPage(conn);
     return;
     } else {
     sendUsername(conn, email);
     return;
     }
 }
 /* Forgot password */
 if (sameString(helpWith,"password"))
 {
+    /* validate username first */
     if (sameString(username,""))
     {
     freez(&errMsg);
     errMsg = cloneString("Username cannot be blank.");
     displayAccHelpPage(conn);
     return;
     } else {
-/**** temp code before mail password function is done ****/
-/**** sendNewPassword(conn, username) *******************/
+    safef(query,sizeof(query), 
+        "select password from gbMembers where userName='%s'", username);
+    char *password = sqlQuickString(conn, query);
+    if (!password)
+        {
     freez(&errMsg);
-    errMsg = cloneString("Will send a new password to you soon ...");
+        errMsg = cloneString("Username not found.");
     displayAccHelpPage(conn);
     return;
     }
 }
+    generateNewPassword(conn, username);
+    return;
+}
 cartRemove(cart, "hgLogin_helpWith");
-
 cartRemove(cart, "hgLogin_email");
 // cartRemove(cart, "hgLogin_userName");
 displayAccHelpPage(conn);
 return;
 }
 
 /* ----- account login/display functions ---- */
 
 
 void displayLoginPage(struct sqlConnection *conn)
 /* draw the account login page */
 {
 char *username = cartUsualString(cart, "hgLogin_userName", "");
 /* for password security, use cgi hash instead of cart */
 // char *password = cgiUsualString("hgLogin_password", "");
@@ -963,33 +1021,32 @@
 "Need an account? <a href=\"hgLogin?hgLogin.do.signupPage=1\">Sign up</a>.<br>"
 "To change password, click <a href=\"hgLogin?hgLogin.do.changePasswordPage=1\">here</a>."
 "</div><!-- END - helpBox -->"
 "</div><!-- END - loginBox -->"
 "\n"
 "\n"
 "</body>"
 "</html>"
 , username
 );
 
 cartSaveSession(cart);
 }
 
 
-/******* BEGIN dispalyLogin *************************/
 void displayLogin(struct sqlConnection *conn)
-/* display user account info */
+/* display and process login info */
 {
 struct sqlResult *sr;
 char **row;
 char query[256];
 char *userName = cartUsualString(cart, "hgLogin_userName", "");
 if (sameString(userName,""))
     {
     freez(&errMsg);
     errMsg = cloneString("User name cannot be blank.");
     displayLoginPage(conn);
     return;
     }
 /* for password security, use cgi hash instead of cart */
 char *password = cgiUsualString("hgLogin_password", "");
 if (sameString(password,""))
@@ -1202,55 +1259,30 @@
 
 }
 
 
 void doMiddle(struct cart *theCart)
 /* Write the middle parts of the HTML page.
  * This routine sets up some globals and then
  * dispatches to the appropriate page-maker. */
 {
 struct sqlConnection *conn = hConnectCentral();
 cart = theCart;
 
 
 if (cartVarExists(cart, "debug"))
     debugShowAllMembers(conn);
-/* remove after a while when it is no longer needed
-else if (cartVarExists(cart, "fixMembers"))
-    {
-    upgradeMembersTable(conn);
-    updatePasswordsFile(conn);
-    hPrintf(
-    "<h2>UCSC Genome Browser</h2>"
-    "<p align=\"left\">"
-    "</p>"
-    "<h3>Successfully updated the gbMembers table to store hashed passwords.</h3>"
-    "Click <a href=hgLogin?hgLogin.do.signupPage=1>here</a> to return.<br>"
-    );
-    }
-*/
-else if (cartVarExists(cart, "update"))
-    {
-    updatePasswordsFile(conn);
-    hPrintf(
-    "<h2>UCSC Genome Browser</h2>"
-    "<p align=\"left\">"
-    "</p>"
-    "<h3>Successfully updated the authentication file.</h3>"
-    "Click <a href=hgLogin?hgLogin.do.signupPage=1>here</a> to return.<br>"
-    );
-    }
 /*******************************************************************
 else if (cartVarExists(cart, "hgLogin.do.lostUserNamePage"))
     lostUserNamedPage(conn);
 else if (cartVarExists(cart, "hgLogin.do.lostUserName"))
     lostUserName(conn);
 ********************************************************************/
 // else if (cartVarExists(cart, "hgLogin.do.lostPasswordPage"))
 //    lostPasswordPage(conn);
 else if (cartVarExists(cart, "hgLogin.do.lostPassword"))
     lostPassword(conn);
 else if (cartVarExists(cart, "hgLogin.do.changePasswordPage"))
     changePasswordPage(conn);
 else if (cartVarExists(cart, "hgLogin.do.changePassword"))
     changePassword(conn);
 else if (cartVarExists(cart, "hgLogin.do.displayUserInfo"))