3d7f8e49ea48a5c6e101ad257731b22cba96288f chinhli Mon May 7 15:43:28 2012 -0700 Fixed the activation code. diff --git src/hg/hgLogin/hgLogin.c src/hg/hgLogin/hgLogin.c index e4862ec..93df91f 100644 --- src/hg/hgLogin/hgLogin.c +++ src/hg/hgLogin/hgLogin.c @@ -1,1367 +1,1378 @@ /* hgLogin - Administer UCSC Genome Browser membership - signup, lost password, etc. */ #include "common.h" #include "hash.h" #include "obscure.h" #include "hgConfig.h" #include "cheapcgi.h" #include "memalloc.h" #include "jksql.h" #include "htmshell.h" #include "cart.h" #include "hPrint.h" #include "hdb.h" #include "hui.h" #include "web.h" #include "ra.h" #include "hgColors.h" #include #include #include "net.h" #include "wikiLink.h" #include "hgLogin.h" #include "gbMembers.h" #include "versionInfo.h" char msg[2048] = ""; char *excludeVars[] = { "submit", "Submit", "debug", "fixMembers", "update", "hgLogin_password", "hgLogin_password2", "hgLogin_newPassword1", "hgLogin_newPassword2", NULL }; /* The excludeVars are not saved to the cart. (We also exclude * any variables that start "near.do.") */ /* ---- Global variables. ---- */ struct cart *cart; /* This holds cgi and other variables between clicks. */ char *database; /* Name of genome database - hg15, mm3, or the like. */ struct hash *oldCart; /* Old cart hash. */ char *errMsg; /* Error message to show user when form data rejected */ /* -------- utilities functions --- */ +boolean tokenExpired(char *dateTime) +/* Is token expired? */ +{ + return FALSE; +} + void returnToURL(int nSec) -/* delay for N micro seconds then go back to hgSession page */ +/* delay for N micro seconds then return to the URL */ { char *returnURL = cartUsualString(cart, "returnto", ""); char *hgLoginHost = wikiLinkHost(); char returnTo[512]; if (!returnURL || sameString(returnURL,"")) safef(returnTo, sizeof(returnTo), "http://%s/cgi-bin/hgSession?hgS_doMainPage=1", hgLoginHost); else safef(returnTo, sizeof(returnTo), returnURL); int delay=nSec*1000; hPrintf( "" ,delay ,returnTo); } void displayMailSuccess() /* display mail success confirmation box */ { char *email = cartUsualString(cart, "hgLogin_email", ""); char *obj=cartUsualString(cart, "hgLogin_helpWith", ""); // safecpy(obj, sizeof(obj),object); hPrintf( "
" "\n" "

UCSC Genome Browser

" "

An email has been sent to " " %s containing %s...

" "\n" "

Return to Login

" , email , obj ); } void sendMail(char *email, char *subject, char *msg) { char *hgLoginHost = wikiLinkHost(); char *obj = cartUsualString(cart, "hgLogin_helpWith", ""); char cmd[1024]; safef(cmd,sizeof(cmd), "echo '%s' | mail -s \"%s\" %s" , msg, subject, email); int result = system(cmd); if (result == -1) { hPrintf( "

UCSC Genome Browser

" "

" "

" "

Error emailing %s to: %s

" "Click here to return.
" , obj , email ); } else { hPrintf( "" , hgLoginHost ); } // cartRemove(cart, "hgLogin_helpWith"); } void mailUsername(char *email, char *users) /* send user name list to the email address */ { 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), "User name(s) associated with this email address at UCSC Genome Browser: \n\n %s \n", users); safecat (msg, sizeof(msg), signature); sendMail(email, subject, msg); } void sendUsername(struct sqlConnection *conn, char *email) /* email user username(s) */ { struct sqlResult *sr; char **row; char query[256]; /* 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 lostPassword(struct sqlConnection *conn, char *username) /* Generate and mail new password to user */ { 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); 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 email address assocaited with this username */ 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 setupNewAccount(struct sqlConnection *conn, char *email, char *username) /* Send an activation mail to user */ { char query[256]; char *token = generateRandomPassword(); // char encToken[45] = ""; // encryptNewPwd(token, encToken, sizeof(encToken)); int i; unsigned char result[MD5_DIGEST_LENGTH]; char tokenMD5[MD5_DIGEST_LENGTH*2 + 1]; i = MD5_DIGEST_LENGTH; // /*DEBUG*/ printf("MD5_DIGEST_LENGT is -- %d\n",i); MD5((unsigned char *) token, strlen(token), result); // output /****************************************************** DEBUG printf("result array:\n"); for(i = 0; i < MD5_DIGEST_LENGTH; i++) printf("%02x", result[i]); printf("\n"); ************************************************************/ // Convert the tokenMD5 value to string // /* DEBUG */ printf("Convert result to tokenMD5 .......\n"); for(i = 0; i < MD5_DIGEST_LENGTH; i++) { sprintf(&tokenMD5[i*2], "%02x", result[i]); } safef(query,sizeof(query), "update gbMembers set lastUse=NOW(),emailToken='%s', emailTokenExpires=DATE_ADD(NOW(), INTERVAL 7 DAY), accountActivated='N' where userName='%s'" // , sqlEscapeString(encToken) , sqlEscapeString(tokenMD5) , sqlEscapeString(username) ); sqlUpdate(conn, query); // sendActivateMail(email, username, encToken); sendActivateMail(email, username, tokenMD5); return; } void sendActivateMail(char *email, char *username, char *encToken) /* Send activation mail with token to user*/ { char subject[256]; char msg[4064]; char activateURL[256]; char *hgLoginHost = wikiLinkHost(); safef(activateURL, sizeof(activateURL), - "http://%s/cgi-bin/hgLogin?do.activateAccount=1&user=%s&token=%s\n" + "http://%s/cgi-bin/hgLogin?hgLogin.do.activateAccount=1&user=%s&token=%s\n" , sqlEscapeString(hgLoginHost) , sqlEscapeString(username) , sqlEscapeString(encToken) ); char signature[256]="\nUCSC Genome Browser \nhttp://www.genome.ucsc.edu "; safef(subject, sizeof(subject),"Greeting form UCSC Genome Browser"); safef(msg, sizeof(msg), "You have sign up an account at UCSC Genome Browser with username \"%s\". \n Please click the following link to activate the account -- \n\n%s\n\n" , username , activateURL ); safecat (msg, sizeof(msg), signature); sendMail(email, subject, msg); } void activateAccount(struct sqlConnection *conn) /* activate account */ { // struct sqlResult *sr; // char **row; char query[256]; char *token = cgiUsualString("token", ""); char *username = cgiUsualString("user",""); safef(query,sizeof(query), "select emailToken from gbMembers where userName='%s'", username); char *emailToken = sqlQuickString(conn, query); -hPrintf("

emailToken in DB: %s token: %s

", emailToken, token); if (sameString(emailToken, token)) { safef(query,sizeof(query), "update gbMembers set lastUse=NOW(), dateActivated=NOW(), emailToken='', emailTokenExpires='', accountActivated='Y' where userName='%s'" , username ); sqlUpdate(conn, query); } else { freez(&errMsg); errMsg = cloneString("Token does not match."); } displayLoginPage(conn); return; } /* -------- password functions ---- */ void cryptWikiWay(char *password, char *salt, char* result) // encrypt password as mediawiki does: ':B:'.$salt.':'. md5($salt.'-'.md5($password ) { int i; unsigned char result1[MD5_DIGEST_LENGTH]; unsigned char result2[MD5_DIGEST_LENGTH]; char firstMD5[MD5_DIGEST_LENGTH*2 + 1]; char secondMD5[MD5_DIGEST_LENGTH*2 + 1]; i = MD5_DIGEST_LENGTH; // /*DEBUG*/ printf("MD5_DIGEST_LENGT is -- %d\n",i); MD5((unsigned char *) password, strlen(password), result1); // output /****************************************************** DEBUG printf("result1 array:\n"); for(i = 0; i < MD5_DIGEST_LENGTH; i++) printf("%02x", result1[i]); printf("\n"); ************************************************************/ // Convert the first MD5 value to string // /* DEBUG */ printf("Convert result1 to firstMD5 .......\n"); for(i = 0; i < MD5_DIGEST_LENGTH; i++) { sprintf(&firstMD5[i*2], "%02x", result1[i]); } /****************************************************** DEBUG printf("\n"); printf("firstMD5 string\n"); printf("firstMD5 is: %s \n",firstMD5); printf("\n"); ***************************************************************/ // add the salt with "-" char saltDashMD5[256]; strcpy(saltDashMD5,salt); // /*DEBUG*/ printf("String3 is: %s \n",saltDashMD5); strcat(saltDashMD5,"-"); // /*DEBUG*/ printf("String3 is: %s \n",saltDashMD5); strcat(saltDashMD5,firstMD5); // /*DEBUG*/ printf("firstMD5 is: %s \n",firstMD5); // /*DEBUG*/ printf("saltDashMD5 is: %s \n",saltDashMD5); MD5((unsigned char *) saltDashMD5, strlen(saltDashMD5), result2); // output /****************************************************** DEBUG for(i = 0; i < MD5_DIGEST_LENGTH; i++) printf("%02x", result2[i]); printf("\n"); printf("Convert result2 to secondMD5 .......\n"); ***************************************************************/ for(i = 0; i < MD5_DIGEST_LENGTH; i++) { sprintf(&secondMD5[i*2], "%02x", result2[i]); } /*************************************************************** DEBUG printf("\n"); i = MD5_DIGEST_LENGTH; printf("MD5_DIGEST_LENGTH is %d\nLength of secondMD5 is %d\n",i,strlen(secondMD5)); printf("secondMD5 before return is: \n%s\n", secondMD5); ************************************************************************/ strcpy(result, secondMD5); } void encryptPWD(char *password, char *salt, char *buf, int bufsize) /* encrypt a password */ { /* encrypt user's password. */ // safef(buf,bufsize,crypt(password, salt)); char md5Returned[100]; cryptWikiWay(password, salt, md5Returned); safecat(buf,bufsize,":B:"); safecat(buf,bufsize,salt); safecat(buf,bufsize,":"); safecat(buf,bufsize,md5Returned); // /*DEBUG*/ printf("After encrypt, buf is \n%s\n bufsize is %d\n", buf, bufsize); } void encryptNewPwd(char *password, char *buf, int bufsize) /* encrypt a new password */ /* XXXX TODO: use MD5 in linked SSL */ { unsigned long seed[2]; char salt[] = "........"; 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); safef(salt, saltSize,tempStr2); // /*DEBUG*/ printf("Final salt is %s\n", salt); } bool checkPwd(char *password, char *encPassword) /* check an encrypted password */ { // /*DEBUG*/ printf("password type in is: %s\n",password); char salt[14]; int saltSize; saltSize = sizeof(salt); findSalt(encPassword, salt, saltSize); char encPwd[45] = ""; // encryptPWD(password, encPassword, encPwd, sizeof(encPwd)); encryptPWD(password, salt, encPwd, sizeof(encPwd)); if (sameString(encPassword,encPwd)) { return TRUE; } else { return FALSE; } } unsigned int randInt(unsigned int n) /* little randome number helper returns 0 to n-1 */ { return (unsigned int) n * (rand() / (RAND_MAX + 1.0)); } char *generateRandomPassword() /* Generate valid random password for users who have lost their old one. * Free the returned value.*/ { char boundary[256]; char punc[] = "!@#$%^&*()"; /* choose a new string for the boundary */ /* Set initial seed */ int i = 0; int r = 0; char c = ' '; boundary[0]=0; srand( (unsigned)time( NULL ) ); for(i=0;i<8;++i) { r = randInt(4); switch (r) { case 0 : c = 'A' + randInt(26); break; case 1 : c = 'a' + randInt(26); break; case 2 : c = '0' + randInt(10); break; default: c = punc[randInt(10)]; break; } boundary[i] = c; } boundary[i]=0; return cloneString(boundary); } /* --- update passwords file ----- */ void updatePasswordsFile(struct sqlConnection *conn) /* update the passwords file containing email:encryptedPassword */ { struct sqlResult *sr; char **row; FILE *out = mustOpen("../conf/passwords", "w"); sr = sqlGetResult(conn, "select email,password from gbMembers where activated='Y'" " and (expireDate='' or (current_date() < expireDate))"); while ((row = sqlNextRow(sr)) != NULL) { fprintf(out,"%s:%s\n",row[0],row[1]); } sqlFreeResult(&sr); carefulClose(&out); } /* -------- functions ---- */ void debugShowAllMembers(struct sqlConnection *conn) /* display all gbMembers */ { struct sqlResult *sr; char **row; hPrintf("

Members

"); hPrintf(""); hPrintf(""); sr = sqlGetResult(conn, "select * from members"); while ((row = sqlNextRow(sr)) != NULL) { hPrintf("",row[0],row[1]); } sqlFreeResult(&sr); hPrintf("
emailpassword
%s%s
"); } void changePasswordPage(struct sqlConnection *conn) /* change password page */ { hPrintf( "
" "\n" "

UCSC Genome Browser

" "\n" "

Change Password

" "\n" "

%s

" "\n" "
" "\n" "
" "" "" "
" "\n" , errMsg ? errMsg : "" , cartUsualString(cart, "hgLogin_userName", "") ); hPrintf( "
" "\n" "" "" "
" "\n" "
" "" "" "
" "\n" "
" "" "" "
" "\n" "
" "   " " Cancel" "\n" "
" "
" "\n" "
" "\n" ); cartSaveSession(cart); } void changePassword(struct sqlConnection *conn) /* process the change password form */ { char query[256]; char *user = cartUsualString(cart, "hgLogin_userName", ""); char *currentPassword = cartUsualString(cart, "hgLogin_password", ""); char *newPassword1 = cartUsualString(cart, "hgLogin_newPassword1", ""); char *newPassword2 = cartUsualString(cart, "hgLogin_newPassword2", ""); char *changeRequired = cartUsualString(cart, "hgLogin_changeRequired", ""); if (!user || sameString(user,"")) { freez(&errMsg); errMsg = cloneString("Username cannot be blank."); changePasswordPage(conn); return; } if (!currentPassword || sameString(currentPassword,"")) { freez(&errMsg); errMsg = cloneString("Current password cannot be blank."); changePasswordPage(conn); return; } if (!newPassword1 || sameString(newPassword1,"") || (strlen(newPassword1)<5)) { freez(&errMsg); errMsg = cloneString("New Password must be at least 5 characters long."); changePasswordPage(conn); return; } if (!newPassword2 || sameString(newPassword2,"") ) { freez(&errMsg); errMsg = cloneString("Re-enter New Password field cannot be blank."); changePasswordPage(conn); return; } if (newPassword1 && newPassword2 && !sameString(newPassword1, newPassword2)) { freez(&errMsg); errMsg = cloneString("New passwords do not match."); changePasswordPage(conn); return; } /* check username existence and is user using a new password */ char *password; if (changeRequired && sameString(changeRequired, "YES")) { safef(query,sizeof(query), "select newPassword from gbMembers where userName='%s'", user); password = sqlQuickString(conn, query); } else { safef(query,sizeof(query), "select password from gbMembers where userName='%s'", user); password = sqlQuickString(conn, query); } if (!password) { freez(&errMsg); errMsg = cloneString("User not found."); changePasswordPage(conn); return; } if (!checkPwd(currentPassword, password)) { freez(&errMsg); errMsg = cloneString("Invalid current password."); changePasswordPage(conn); return; } char encPwd[45] = ""; encryptNewPwd(newPassword1, encPwd, sizeof(encPwd)); safef(query,sizeof(query), "update gbMembers set password='%s' where userName='%s'", sqlEscapeString(encPwd), sqlEscapeString(user)); sqlUpdate(conn, query); clearNewPasswordFields(conn, user); hPrintf ( "

UCSC Genome Browser

" "

" "

" "

Password has been changed.

" ); backToDoLoginPage(2); cartRemove(cart, "hgLogin_password"); cartRemove(cart, "hgLogin_newPassword1"); cartRemove(cart, "hgLogin_newPassword2"); } void signupPage(struct sqlConnection *conn) /* draw the signup page */ -/* XXXX TODO: +/* TODO: cornfirm password, password help like Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only. optional real name */ { hPrintf( "
" "

UCSC Genome Browser

" "\n" "

Signing up enables you to save multiple sessions and to share your sessions with others.

" "Already have an account? Login.
" "\n" ); hPrintf( "

Sign Up

" "
" //"
" //" %s" //"
" "%s" "\n" , errMsg ? errMsg : "" ); hPrintf( "
" "" "" "
" "\n" "
" "" "" "
" "\n" "
" "" "" "
" "\n" , cartUsualString(cart, "hgLogin_userName", "") , cartUsualString(cart, "hgLogin_email", "") , cartUsualString(cart, "hgLogin_email2", "") ); hPrintf( "
" "" "" "
" "\n" "
" "" "" "\n" "
" "\n" "
" "   " " Cancel" "
" "
" "
" "\n" , cartUsualString(cart, "hgLogin_password", "") , cartUsualString(cart, "hgLogin_password2", "") ); // TODO: group them to one remove function // , cartUsualString(cart, "hgLogin_userName", "") // , cartUsualString(cart, "hgLogin_email", "") // , cartUsualString(cart, "hgLogin_email2", "") // , cartUsualString(cart, "hgLogin_password", "") // , cartUsualString(cart, "hgLogin_password2", "") // ); // cartSaveSession(cart); hPrintf(""); } void signup(struct sqlConnection *conn) /* process the signup form */ { char query[256]; char *user = cartUsualString(cart, "hgLogin_userName", ""); if (!user || sameString(user,"")) { freez(&errMsg); errMsg = cloneString("User name cannot be blank."); signupPage(conn); return; } safef(query,sizeof(query), "select password from gbMembers where userName='%s'", user); char *password = sqlQuickString(conn, query); if (password) { freez(&errMsg); errMsg = cloneString("A user with this name already exists."); signupPage(conn); freez(&user); return; } char *email = cartUsualString(cart, "hgLogin_email", ""); if (!email || sameString(email,"")) { freez(&errMsg); errMsg = cloneString("Email cannot be blank."); signupPage(conn); return; } char *email2 = cartUsualString(cart, "hgLogin_email2", ""); if (!email2 || sameString(email2,"")) { freez(&errMsg); errMsg = cloneString("Email cannot be blank."); signupPage(conn); return; } if (email && email2 && !sameString(email, email2)) { freez(&errMsg); errMsg = cloneString("Email addresses do not match."); signupPage(conn); return; } password = cartUsualString(cart, "hgLogin_password", ""); if (!password || sameString(password,"") || (strlen(password)<5)) { freez(&errMsg); errMsg = cloneString("Password must be at least 5 characters long."); signupPage(conn); return; } char *password2 = cartUsualString(cart, "hgLogin_password2", ""); if (!password2 || sameString(password2,"") ) { freez(&errMsg); errMsg = cloneString("Password field cannot be blank."); signupPage(conn); return; } if (password && password2 && !sameString(password, password2)) { 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); setupNewAccount(conn, email, user); /* send out activate code mail, and display the main confirmation box */ /* and comback here to contine back to URL */ hPrintf( "

UCSC Genome Browser

\n" "

\n" "

\n" "

User %s successfully added.

\n" , user ); /* TODO: cleanup the hgLogin_xxxx vars in the cart */ backToHgSession(2); } void displayAccHelpPage(struct sqlConnection *conn) /* draw the account help page */ { char *email = cartUsualString(cart, "hgLogin_email", ""); char *username = cartUsualString(cart, "hgLogin_userName", ""); //cartRemove(cart, "hgLogin_helpWith"); //cartRemove(cart, "hgLogin_email"); hPrintf( "" "\n" ); hPrintf( "
" "\n" "

UCSC Genome Browser

" "\n" "

Having trouble signing in?

" "\n" "
" "\n" "

%s

" "\n" , errMsg ? errMsg : "" ); hPrintf( "

" "
" "
" "
" "
" "\n" "
" "\n" ); hPrintf( "
" "" "" "
" "\n" "
" "" "" "
" "\n" "
" " " "  Cancel" "
" "
" "
" , 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 *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 { safef(query,sizeof(query), "select password from gbMembers where userName='%s'", username); char *password = sqlQuickString(conn, query); if (!password) { freez(&errMsg); errMsg = cloneString("Username not found."); displayAccHelpPage(conn); return; } } lostPassword(conn, username); return; } // cartRemove(cart, "hgLogin_helpWith"); // cartRemove(cart, "hgLogin_email"); // cartRemove(cart, "hgLogin_userName"); displayAccHelpPage(conn); return; } void clearNewPasswordFields(struct sqlConnection *conn, char *username) /* clear the newPassword fields */ { char query[256]; safef(query,sizeof(query), "update gbMembers set lastUse=NOW(),newPassword='', newPasswordExpire='', passwordChangeRequired='N' where userName='%s'", sqlEscapeString(username)); sqlUpdate(conn, query); cartRemove(cart, "hgLogin_changeRequired"); return; } /* ----- account login/display functions ---- */ boolean usingNewPassword(struct sqlConnection *conn, char *userName) /* The user is using requested new password */ { char query[256]; safef(query,sizeof(query), "select passwordChangeRequired from gbMembers where userName='%s'", userName); char *change = sqlQuickString(conn, query); if (change && sameString(change, "Y")) return TRUE; else return FALSE; } 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", ""); hPrintf( "
" "\n" "

UCSC Genome Browser

" "\n" "

Login

" "\n" "%s" "\n" , errMsg ? errMsg : "" ); hPrintf( "
" "\n" "
" "" "" "
" "\n" "
" "" "" "
" "\n" "
" " " "  Cancel" "
" "
" "\n" "\n" "
" "Can't access your account?
" "Need an account? Sign up.
" "To change password, click here." "
" "
" "\n" "\n" "" "" , username ); cartSaveSession(cart); } void displayLogin(struct sqlConnection *conn) /* 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,"")) { freez(&errMsg); errMsg = cloneString("Password cannot be blank."); displayLoginPage(conn); return; } safef(query,sizeof(query),"select * from gbMembers where userName='%s'", userName); sr = sqlGetResult(conn, query); if ((row = sqlNextRow(sr)) == NULL) { freez(&errMsg); char temp[256]; safef(temp,sizeof(temp),"User name %s not found.",userName); errMsg = cloneString(temp); displayLoginPage(conn); return; } struct gbMembers *m = gbMembersLoad(row); sqlFreeResult(&sr); -/* TODO: check user name exist and activated */ +/* Check user name exist and account activated */ /* ..... */ - +if (!sameString(m->accountActivated,"Y")) +{ + freez(&errMsg); + errMsg = cloneString("Account is not activated."); + displayLoginPage(conn); + return; +} if (checkPwd(password,m->password)) { unsigned int userID=m->idx; hPrintf("

Login successful for user %s with id %d.\n

\n" ,userName,userID); clearNewPasswordFields(conn, userName); displayLoginSuccess(userName,userID); return; } else if (usingNewPassword(conn, userName)) { cartSetString(cart, "hgLogin_changeRequired", "YES"); changePasswordPage(conn); } else { - errMsg = cloneString("Invalid user name or password. (login)"); + errMsg = cloneString("Invalid user name or password."); displayLoginPage(conn); return; } gbMembersFree(&m); } /******* END dispalyLogin *************************/ void displayLoginSuccess(char *userName, int userID) /* display login success msg, and set cookie */ { // char *hgLoginHost = wikiLinkHost(); hPrintf( "

UCSC Genome Browser

" "

" "

" "" "\n" ); /* Set cookies */ /* TODO: use htmlSetCookie() to set cookies */ hPrintf( "\n" "" "\n", userName,userID); //backToHgSession(2); returnToURL(2); } void displayLogoutSuccess() /* display logout success msg, and reset cookie */ { // char *hgLoginHost = wikiLinkHost(); hPrintf( "

UCSC Genome Browser Sign Out

" "

" "

" "" "\n" ); hPrintf( "\n" ); /* TODO: cleanup the hgLogin_xxxx vars in the cart */ /* return to session */ // backToHgSession(2); returnToURL(2); } void backToHgSession(int nSec) /* delay for N micro seconds then go back to hgSession page */ /* TODO: afterDelayBackTo("http....") */ { char *hgLoginHost = wikiLinkHost(); int delay=nSec*1000; hPrintf( "" ,delay ,hgLoginHost); } void backToDoLoginPage(int nSec) /* delay for N micro seconds then go back to Login page */ /* TODO: afterDelayBackTo("http....") */ { char *hgLoginHost = wikiLinkHost(); int delay=nSec*1000; hPrintf( "" ,delay ,hgLoginHost); } void displayUserInfo(struct sqlConnection *conn) /* display user account info */ { struct sqlResult *sr; char **row; char query[256]; char *user = cartUsualString(cart, "hgLogin_userName", ""); if (sameString(user,"")) { freez(&errMsg); errMsg = cloneString("User name cannot be blank."); displayUserInfo(conn); return; } /* for password security, use cgi hash instead of cart */ char *password = cgiUsualString("hgLogin_password", ""); if (sameString(password,"")) { freez(&errMsg); errMsg = cloneString("Password cannot be blank."); displayUserInfo(conn); return; } safef(query,sizeof(query),"select * from gbMembers where username='%s'", user); sr = sqlGetResult(conn, query); if ((row = sqlNextRow(sr)) == NULL) { freez(&errMsg); char temp[256]; safef(temp,sizeof(temp),"User %s not found.",user); errMsg = cloneString(temp); displayUserInfo(conn); return; } struct gbMembers *m = gbMembersLoad(row); sqlFreeResult(&sr); if (checkPwd(password,m->password)) { hPrintf("

UCSC Genome Browser User Information:

\n"); hPrintf("\n"); hPrintf("\n",m->userName); hPrintf("\n",m->realName); hPrintf("\n",m->email); hPrintf("
User name:%s
Real name:%s
E-mail:%s
\n"); hPrintf("
\n"); hPrintf("Return to signup.
\n"); hPrintf("Go to UCSC Genome Browser.
\n"); } else { hPrintf("

Invalid User/Password

\n"); hPrintf("Return to signup.
\n"); } gbMembersFree(&m); } 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); 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")) displayUserInfo(conn); else if (cartVarExists(cart, "hgLogin.do.displayAccHelpPage")) displayAccHelpPage(conn); else if (cartVarExists(cart, "hgLogin.do.accountHelp")) accountHelp(conn); else if (cartVarExists(cart, "hgLogin.do.activateAccount")) activateAccount(conn); else if (cartVarExists(cart, "hgLogin.do.displayMailSuccess")) displayMailSuccess(); else if (cartVarExists(cart, "hgLogin.do.displayLoginPage")) displayLoginPage(conn); else if (cartVarExists(cart, "hgLogin.do.displayLogin")) displayLogin(conn); else if (cartVarExists(cart, "hgLogin.do.displayLogout")) displayLogoutSuccess(); else if (cartVarExists(cart, "hgLogin.do.signup")) signup(conn); else signupPage(conn); + hDisconnectCentral(&conn); cartRemovePrefix(cart, "hgLogin.do."); } void usage() /* Explain usage and exit. */ { errAbort( "hgLogin - administer gsid hiv membership functions - a cgi script\n" "usage:\n" " hgLogin\n" ); } int main(int argc, char *argv[]) /* Process command line. */ { pushCarefulMemHandler(100000000); cgiSpoof(&argc, argv); htmlSetStyleSheet("/style/userAccounts.css"); htmlSetStyle(htmlStyleUndecoratedLink); htmlSetBgColor(HG_CL_OUTSIDE); htmlSetFormClass("accountScreen"); oldCart = hashNew(10); cartHtmlShell("Login - UCSC Genome Browser", doMiddle, hUserCookie(), excludeVars, oldCart); return 0; }