d0976c9d524ee428053266757aa17c7ef1b66a12
chmalee
  Wed Feb 18 12:20:45 2026 -0800
Libify the api key set/revoke methods, refs #36517

diff --git src/hg/lib/hubSpaceKeys.c src/hg/lib/hubSpaceKeys.c
index 8cc29daee3e..9815528dcdd 100644
--- src/hg/lib/hubSpaceKeys.c
+++ src/hg/lib/hubSpaceKeys.c
@@ -1,27 +1,27 @@
 /* hubSpaceKeys.c was originally generated by the autoSql program, which also 
  * generated hubSpaceKeys.h and hubSpaceKeys.sql.  This module links the database and
  * the RAM representation of objects. */
 
 #include "common.h"
 #include "linefile.h"
 #include "dystring.h"
 #include "jksql.h"
 #include "hubSpaceKeys.h"
 #include "hdb.h"
 #include "hgConfig.h"
-
+#include "htmshell.h"
 
 
 char *hubSpaceKeysCommaSepFieldNames = "userName,apiKey";
 
 void hubSpaceKeysStaticLoad(char **row, struct hubSpaceKeys *ret)
 /* Load a row from hubSpaceKeys table into ret.  The contents of ret will
  * be replaced at the next call to this function. */
 {
 
 ret->userName = row[0];
 ret->apiKey = row[1];
 }
 
 struct hubSpaceKeys *hubSpaceKeysLoad(char **row)
 /* Load a hubSpaceKeys from row fetched with select * from hubSpaceKeys
@@ -114,33 +114,76 @@
 void hubSpaceKeysOutput(struct hubSpaceKeys *el, FILE *f, char sep, char lastSep) 
 /* Print out hubSpaceKeys.  Separate fields with sep. Follow last field with lastSep. */
 {
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->userName);
 if (sep == ',') fputc('"',f);
 fputc(sep,f);
 if (sep == ',') fputc('"',f);
 fprintf(f, "%s", el->apiKey);
 if (sep == ',') fputc('"',f);
 fputc(lastSep,f);
 }
 
 /* -------------------------------- End autoSql Generated Code -------------------------------- */
 
-char *userNameForApiKey(struct sqlConnection *conn, char *apiKey)
+char *hubSpaceGetApiKey(char *userName)
+/* Grab the already created api key if it exists */
+{
+char *tableName = cfgOptionDefault("authTableName", AUTH_TABLE_DEFAULT);
+struct sqlConnection *conn = hConnectCentral();
+struct dyString *query = sqlDyStringCreate("select apiKey from %s where userName='%s'", tableName, userName);
+char *apiKey = sqlQuickString(conn, dyStringCannibalize(&query));
+hDisconnectCentral(&conn);
+return apiKey;
+}
+
+char *hubSpaceUserNameForApiKey(struct sqlConnection *conn, char *apiKey)
 /* Return userName associated with apiKey else NULL. If conn is NULL, will create a connection and free it. */
 {
 char *tableName = cfgOptionDefault("authTableName", AUTH_TABLE_DEFAULT);
 
 boolean doClose = FALSE;
 if (conn == NULL)
     {
     conn = hConnectCentral();
     doClose = TRUE;
     }
 
 struct dyString *query = sqlDyStringCreate("select userName from %s where apiKey = '%s'", tableName, apiKey);
 char *userName = sqlQuickString(conn, dyStringCannibalize(&query));
 if (doClose)
     hDisconnectCentral(&conn);
 return userName;
 }
+
+void hubSpaceRevokeApiKey(char *userName)
+/* Remove any api keys for userName. errAborts if userName is NULL.
+ * Run in an errCatch to handle errors. */
+{
+if (!userName)
+    errAbort("hubSpaceRevokeApiKey: no userName. You must be logged in to revoke your api key");
+
+char *tableName = cfgOptionDefault("authTableName", AUTH_TABLE_DEFAULT);
+struct sqlConnection *conn = hConnectCentral();
+struct dyString *query = sqlDyStringCreate("delete from %s where userName='%s'", tableName, userName);
+sqlUpdate(conn, dyStringCannibalize(&query));
+hDisconnectCentral(&conn);
+}
+
+char *hubSpaceGenerateApiKey(char *userName)
+/* Make a random (but not crypto-secure) api key for userName, for use of hubtools to upload
+ * to hubspace or for bypassing cloudflare. errAborts if userName is NULL.
+ * Run in an errCatch to handle errors. */
+{
+if (!userName)
+    errAbort("hubSpaceGenerateApiKey: no userName. You must be logged in to generate an api key");
+
+char *apiKey = makeRandomKey(256); // just needs some arbitrary length
+// save this key to the database for this user, the 'on duplicate' part automatically revokes old keys
+struct sqlConnection *conn = hConnectCentral();
+char *tableName = cfgOptionDefault("authTableName", AUTH_TABLE_DEFAULT);
+struct dyString *query = sqlDyStringCreate("insert into %s values ('%s', '%s') on duplicate key update apiKey='%s'", tableName, userName, apiKey, apiKey);
+sqlUpdate(conn, dyStringCannibalize(&query));
+hDisconnectCentral(&conn);
+return apiKey;
+}