src/hg/instinct/hgHeatmap2/hgUsers.c 1.4
1.4 2009/06/04 03:50:37 jsanborn
added copyright notices, removed cluster library
Index: src/hg/instinct/hgHeatmap2/hgUsers.c
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/hg/instinct/hgHeatmap2/hgUsers.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -b -B -U 1000000 -r1.3 -r1.4
--- src/hg/instinct/hgHeatmap2/hgUsers.c 24 Nov 2008 23:38:44 -0000 1.3
+++ src/hg/instinct/hgHeatmap2/hgUsers.c 4 Jun 2009 03:50:37 -0000 1.4
@@ -1,354 +1,358 @@
+/********************************************************************************/
+/* Copyright 2007-2009 -- The Regents of the University of California */
+/********************************************************************************/
+
/* hgUsers.c
* These routines are the beginning of a simple user authentication scheme to handle
* multiple semi-private datasets on a public server. Only somewhat secure.
*/
#include "common.h"
#include "cart.h"
#include "hCommon.h"
#include "hdb.h"
#include "hgUsers.h"
#include "hgHeatmap2.h"
static char const rcsid[] = "$Id$";
static char *heatMapDbProfile = "localDb"; // database profile to use
void createTokenTable(struct sqlConnection *conn)
{
struct dyString *dy = newDyString(1024);
dyStringPrintf(dy, "CREATE TABLE %s (\n", TOKENS_TABLE);
dyStringPrintf(dy, "tokenId int not null,\n");
dyStringPrintf(dy, "token varchar(255) not null,\n");
dyStringPrintf(dy, "userId int,\n");
dyStringPrintf(dy, "cartId int not null,\n");
dyStringPrintf(dy, "PRIMARY KEY(tokenId)\n");
dyStringPrintf(dy, ")\n");
sqlUpdate(conn,dy->string);
dyStringFree(&dy);
}
boolean getUniqueToken(struct sqlConnection *conn, int *tokenId, char **token)
{
int stime;
long ltime;
// get current time to seed random
ltime = time(NULL);
stime = (unsigned) ltime/2;
srand(stime);
char timeStr[128];
safef(timeStr, sizeof(timeStr), "%u", stime);
char *tmpToken = md5HashString(timeStr);
char query[256];
struct sqlResult *sr = NULL;
char **row = NULL;
int tmpTokenId = random();
safef(query, sizeof(query), "SELECT * FROM %s WHERE tokenId=%d",
TOKENS_TABLE, tmpTokenId);
sr = sqlGetResult(conn,query);
row = sqlNextRow(sr);
int count = 0;
while (row && count < 100)
{
sqlFreeResult(&sr);
tmpTokenId = random();
safef(query, sizeof(query), "SELECT * FROM %s WHERE tokenId=%d",
TOKENS_TABLE, tmpTokenId);
sr = sqlGetResult(conn,query);
row = sqlNextRow(sr);
count++;
}
if (row)
errAbort("Couldn't find unique token after 100 tries.");
*tokenId = tmpTokenId;
*token = cloneString(tmpToken);
return TRUE;
}
boolean checkTokenId(struct sqlConnection *conn, struct cart *cart, int tokenId)
{
if (!sqlTableExists(conn, TOKENS_TABLE))
errAbort("checkTokenId: TOKENS_TABLE doesn't exist!");
unsigned int cartId = cartUserId(cart);
char query[256];
safef(query, sizeof(query), "select * from %s where cartId=%u and tokenId=%d",
TOKENS_TABLE, cartId, tokenId);
return sqlExists(conn, query);
}
char *getToken(struct sqlConnection *conn, struct cart *cart, int tokenId)
{
if (!checkTokenId(conn, cart, tokenId))
return NULL;
unsigned int cartId = cartUserId(cart);
char query[256];
safef(query, sizeof(query), "select token from %s where cartId=%u and tokenId=%d",
TOKENS_TABLE, cartId, tokenId);
return sqlQuickString(conn, query);
}
boolean updateTokenWithUserId(struct sqlConnection *conn, struct cart *cart,
int tokenId, int userId)
{
char query[256];
struct sqlResult *sr = NULL;
char **row = NULL;
unsigned int cartId = cartUserId(cart);
safef(query, sizeof(query), "SELECT * FROM %s WHERE cartId=%u and tokenId=%d",
TOKENS_TABLE, cartId, tokenId);
sr = sqlGetResult(conn, query);
row = sqlNextRow(sr);
struct dyString *dy = newDyString(256);
if (row)
dyStringPrintf(dy, "UPDATE %s SET userId=%d WHERE cartId=%u and tokenId=%d",
TOKENS_TABLE, userId, cartId, tokenId);
else
return FALSE;
sqlFreeResult(&sr);
sqlUpdate(conn, dy->string);
return TRUE;
}
struct json *hgUsersGetToken(struct cart *cart)
{
if (!cart)
errAbort("Cart does not exist.");
struct sqlConnection *conn = hAllocConnProfile(heatMapDbProfile, HGUSERS_DB);
if (!conn)
errAbort("Couldn't connect to user database");
if (!sqlTableExists(conn, TOKENS_TABLE))
createTokenTable(conn);
int tokenId;
char *token = NULL;
if (!getUniqueToken(conn, &tokenId, &token))
errAbort("Failed to get token");
char query[256];
struct sqlResult *sr = NULL;
char **row = NULL;
unsigned int cartId = cartUserId(cart);
safef(query, sizeof(query), "SELECT * FROM %s WHERE cartId=%u",
TOKENS_TABLE, cartId);
sr = sqlGetResult(conn, query);
row = sqlNextRow(sr);
struct dyString *dy = newDyString(256);
if (row)
dyStringPrintf(dy, "UPDATE %s SET tokenId=%d,token=\"%s\",userId=NULL WHERE cartId=%u",
TOKENS_TABLE, tokenId, token, cartId);
else
dyStringPrintf(dy, "INSERT %s VALUES(%d,\"%s\",NULL,%u)",
TOKENS_TABLE, tokenId, token, cartId);
sqlFreeResult(&sr);
sqlUpdate(conn, dy->string);
hFreeConn(&conn);
struct json *js = newJson();
jsonAddInt(js, "token_id", tokenId);
jsonAddString(js, "token", token);
return js;
}
void createUsersTable(struct sqlConnection *conn)
{
struct dyString *dy = newDyString(1024);
dyStringPrintf(dy, "CREATE TABLE %s (\n", USERS_TABLE);
dyStringPrintf(dy, "userId int not null,\n");
dyStringPrintf(dy, "login varchar(255) not null,\n");
dyStringPrintf(dy, "dbPass varchar(255),\n");
dyStringPrintf(dy, "lastLoggedIn datetime,\n");
dyStringPrintf(dy, "PRIMARY KEY(userId)\n");
dyStringPrintf(dy, ")\n");
sqlUpdate(conn,dy->string);
dyStringFree(&dy);
}
char *getUserDbPass(struct sqlConnection *conn, char *login)
{
char query[128];
safef(query, sizeof(query), "SELECT dbPass FROM %s WHERE login=\"%s\"",
USERS_TABLE, login);
return sqlQuickString(conn, query);
}
int getUserId(struct sqlConnection *conn, char *login)
{
char query[128];
safef(query, sizeof(query), "SELECT userId FROM %s WHERE login=\"%s\"",
USERS_TABLE, login);
return sqlQuickNum(conn, query);
}
char *getUserLogin(struct sqlConnection *conn, int userId)
{
char query[128];
safef(query, sizeof(query), "SELECT login FROM %s WHERE userId=%d",
USERS_TABLE, userId);
return sqlQuickString(conn, query);
}
boolean validateUserAndToken(struct sqlConnection *conn,
struct cart *cart, int tokenId, int userId)
{
unsigned int cartId = cartUserId(cart);
char query[128];
safef(query, sizeof(query), "SELECT * FROM %s WHERE tokenId=%d and userId=%d and cartId=%u",
TOKENS_TABLE, tokenId, userId, cartId);
return sqlExists(conn, query);
}
int validateUser(struct sqlConnection *conn, struct cart *cart,
char *login, char *pass, int tokenId)
{
char *token = getToken(conn, cart, tokenId);
char *dbPass = getUserDbPass(conn, login);
if (!dbPass || !token)
return -1;
char str[512];
safef(str, sizeof(str), "%s%s", dbPass, token);
char *md5Str = md5HashString(str);
if (!sameString(md5Str, pass))
return -1;
int userId = getUserId(conn, login);
return userId;
}
boolean updateUserLoggedIn(struct sqlConnection *conn, char *login)
{
char query[256];
struct sqlResult *sr = NULL;
char **row = NULL;
safef(query, sizeof(query), "SELECT * FROM %s WHERE login=\"%s\"",
USERS_TABLE, login);
sr = sqlGetResult(conn, query);
row = sqlNextRow(sr);
struct dyString *dy = newDyString(256);
if (row)
dyStringPrintf(dy, "UPDATE %s SET lastLoggedIn=now() WHERE login=\"%s\"",
USERS_TABLE, login);
else
return FALSE;
sqlFreeResult(&sr);
sqlUpdate(conn, dy->string);
return TRUE;
}
struct json *hgUsersLogin(struct cart *cart, char *login, char *pass, int tokenId)
{
if (!cart)
errAbort("Cart does not exist");
struct sqlConnection *conn = hAllocConnProfile(heatMapDbProfile, HGUSERS_DB);
if (!conn)
errAbort("Couldn't connect to user database");
if (!sqlTableExists(conn, USERS_TABLE))
createUsersTable(conn);
int userId = validateUser(conn, cart, login, pass, tokenId);
if (userId == -1)
errAbort("User or password is incorrect");
updateTokenWithUserId(conn, cart, tokenId, userId);
updateUserLoggedIn(conn, login);
struct json *js = newJson();
jsonAddString(js, "login", "success");
jsonAddInt(js, "user_id", userId);
hFreeConn(&conn);
return js;
}
void createUserDatasetsTable(struct sqlConnection *conn)
{
struct dyString *dy = newDyString(1024);
dyStringPrintf(dy, "CREATE TABLE %s (\n", USERDATASETS_TABLE);
dyStringPrintf(dy, "login varchar(255) not null,\n");
dyStringPrintf(dy, "dataset varchar(255) not null,\n");
dyStringPrintf(dy, "INDEX (login)\n");
dyStringPrintf(dy, ")\n");
sqlUpdate(conn,dy->string);
dyStringFree(&dy);
}
struct slName *getUserDatasets(struct cart *cart, int tokenId, int userId)
{
if (!cart)
errAbort("Cart does not exist.");
struct sqlConnection *conn = hAllocConnProfile(heatMapDbProfile, HGUSERS_DB);
if (!conn)
return NULL;
if (!validateUserAndToken(conn, cart, tokenId, userId))
return NULL;
if (!sqlTableExists(conn, USERDATASETS_TABLE))
createUserDatasetsTable(conn);
struct slName *datasets = NULL;
char query[128];
struct sqlResult *sr = NULL;
char **row = NULL;
char *login = getUserLogin(conn, userId);
if (!login)
return NULL;
safef(query, sizeof(query), "SELECT dataset FROM %s WHERE login=\"%s\"",
USERDATASETS_TABLE, login);
sr = sqlGetResult(conn, query);
while ((row = sqlNextRow(sr)) != NULL)
slNameAddHead(&datasets, row[0]);
slReverse(&datasets);
sqlFreeResult(&sr);
hFreeConn(&conn);
return datasets;
}