0201e8ea6a448b2124e117c5909ced7ff4a253c8 hiram Tue May 19 13:43:53 2026 -0700 adding login verification to the liftRequest functions refs #31811 diff --git src/hg/hubApi/liftOver.c src/hg/hubApi/liftOver.c index a66498470b6..dfa3b03f982 100644 --- src/hg/hubApi/liftOver.c +++ src/hg/hubApi/liftOver.c @@ -1,27 +1,29 @@ /* liftOver functions */ #include "dataApi.h" #include "hgFind.h" #include "cartTrackDb.h" #include "cartJson.h" #include "genark.h" #include "asmAlias.h" #include "assemblyList.h" #include "liftOver.h" #include "liftOverChain.h" #include "net.h" +#include "wikiLink.h" +#include "userdata.h" /* do not need the mailViaPipe function here #include "mailViaPipe.h" */ /**** SHOULD BE IN LIBRARY - code from hgConvert.c ******/ static long chainTotalBlockSize(struct chain *chain) /* Return sum of sizes of all blocks in chain */ { struct cBlock *block; long total = 0; for (block = chain->blockList; block != NULL; block = block->next) total += block->tEnd - block->tStart; return total; } /**** SHOULD BE IN LIBRARY - code from hgConvert.c ******/ @@ -157,30 +159,102 @@ struct sqlResult *sr = sqlGetResult(conn, dyStringCannibalize(&pq)); if ((row = sqlNextRow(sr)) != NULL) { jsonWriteBoolean(jw, "pending", TRUE); jsonWriteNumber(jw, "pendingStatus", sqlSigned(row[1])); jsonWriteString(jw, "pendingRequestTime", row[2]); } sqlFreeResult(&sr); } } apiFinishOutput(0, NULL, jw); hDisconnectCentral(&conn); } +static void loginStatus() +/* output current user login status as JSON */ +{ +char *userName = (loginSystemEnabled() || wikiLinkEnabled()) ? wikiLinkUserName() : NULL; +struct jsonWrite *jw = apiStartOutput(); + +if (userName != NULL) + { + // Get both email and realName from gbMembers table + struct sqlConnection *sc = hConnectCentral(); + struct dyString *query = sqlDyStringCreate("select email, realName from gbMembers where userName = '%s'", userName); + struct sqlResult *sr = sqlGetResult(sc, dyStringCannibalize(&query)); + char **row = sqlNextRow(sr); + + char *email = NULL; + char *realName = NULL; + if (row != NULL) + { + email = cloneString(row[0] ? row[0] : ""); + realName = cloneString(row[1] ? row[1] : ""); + } + sqlFreeResult(&sr); + hDisconnectCentral(&sc); + + // Build logout URL with returnto parameter + char *returnTo = cgiOptionalString("returnTo"); + struct dyString *logoutUrl = dyStringNew(0); + if (isNotEmpty(returnTo)) + { + char *encodedReturnUrl = cgiEncodeFull(returnTo); + dyStringPrintf(logoutUrl, "/cgi-bin/hgLogin?hgLogin.do.displayLogout=1&returnto=%s", encodedReturnUrl); + freeMem(encodedReturnUrl); + } + else + { + dyStringPrintf(logoutUrl, "/cgi-bin/hgLogin?hgLogin.do.displayLogout=1"); + } + + jsonWriteString(jw, "userName", userName); + jsonWriteString(jw, "email", email ? email : ""); + jsonWriteString(jw, "realName", realName ? realName : ""); + jsonWriteString(jw, "logoutUrl", dyStringCannibalize(&logoutUrl)); + + if (email) + freeMem(email); + if (realName) + freeMem(realName); + } +else + { + jsonWriteString(jw, "userName", NULL); + // Use returnTo parameter passed by calling JavaScript + char *returnTo = cgiOptionalString("returnTo"); + if (isNotEmpty(returnTo)) + { + char *encodedReturnUrl = cgiEncodeFull(returnTo); + struct dyString *loginUrl = dyStringNew(0); + dyStringPrintf(loginUrl, "/cgi-bin/hgLogin?hgLogin.do.displayLoginPage=1&returnto=%s", encodedReturnUrl); + jsonWriteString(jw, "loginUrl", dyStringCannibalize(&loginUrl)); + freeMem(encodedReturnUrl); + } + else + { + // No returnTo provided, just give basic login URL + jsonWriteString(jw, "loginUrl", "/cgi-bin/hgLogin?hgLogin.do.displayLoginPage=1"); + } + jsonWriteString(jw, "signupUrl", "/cgi-bin/hgLogin?hgLogin.do.displaySignupPage=1"); + } + +apiFinishOutput(0, NULL, jw); +} + /**** SHOULD BE IN LIBRARY - code from hgConvert.c ******/ static char *skipWord(char *fw) /* skips over current word to start of next. * Error for this not to exist. */ { char *s; s = skipToSpaces(fw); if (s == NULL) errAbort("Expecting two words in .ra file line %s\n", fw); s = skipLeadingSpaces(s); if (s == NULL) errAbort("Expecting two words in .ra file line %s\n", fw); return s; } @@ -252,30 +326,35 @@ } /**** SHOULD BE IN LIBRARY - code from hgConvert.c ******/ void apiLiftOver(char *words[MAX_PATH_INFO]) /* 'liftOver' function words[1] is the subCommand */ { char *extraArgs = verifyLegalArgs(argLiftOver); if (extraArgs) apiErrAbort(err400, err400Msg, "extraneous arguments found for function /liftOver '%s'", extraArgs); if (sameWordOk("listExisting", words[1])) { listExisting(); return; } +else if (sameWordOk("loginStatus", words[1])) + { + loginStatus(); + return; + } char *fromGenome = cgiOptionalString(argFromGenome); char *toGenome = cgiOptionalString(argToGenome); char *chrom = cgiOptionalString(argChrom); char *start = cgiOptionalString(argStart); char *end = cgiOptionalString(argEnd); if (isEmpty(fromGenome) || isEmpty(toGenome) || isEmpty(chrom) || isEmpty(start) || isEmpty(end)) apiErrAbort(err400, err400Msg, "must have all arguments: %s, %s, %s, %s, %s for endpoint '/liftOver", argFromGenome, argToGenome, argChrom, argStart, argEnd); unsigned uStart = 0; unsigned uEnd = 0; uStart = sqlUnsigned(start); uEnd = sqlUnsigned(end); if (uEnd < uStart)