From c4a0d85e05931df1affd4f2fd7466d2e61d90da3 Mon Sep 17 00:00:00 2001 From: luke Date: Wed, 12 Oct 2022 18:01:16 -0500 Subject: [PATCH] user/mysql: Fix session delete bug. This fixes a bug that was preventing sessions from being deleted from the user database. The delete statement arguments were not being passed to the driver properly. This bug was introduced by 0b1982a48. --- politeiawww/legacy/user/mysql/mysql.go | 56 ++++++++++++++++++++------ 1 file changed, 44 insertions(+), 12 deletions(-) diff --git a/politeiawww/legacy/user/mysql/mysql.go b/politeiawww/legacy/user/mysql/mysql.go index 9db43ea7b..e3c9b5ee4 100644 --- a/politeiawww/legacy/user/mysql/mysql.go +++ b/politeiawww/legacy/user/mysql/mysql.go @@ -964,24 +964,35 @@ func (m *mysql) SessionsDeleteByUserID(uid uuid.UUID, exemptSessionIDs []string) ctx, cancel := ctxWithTimeout() defer cancel() - // Session primary key is a SHA256 hash of the session ID. - exempt := make([]string, 0, len(exemptSessionIDs)) + // Build the sql query. Using an empty NOT IN() set + // results in no records being deleted, so the queries + // will differ when exempt session IDs are present. + var q string + if len(exemptSessionIDs) == 0 { + q = "DELETE FROM sessions WHERE user_id = ?" + } else { + q = fmt.Sprintf("DELETE FROM sessions WHERE user_id = ? AND k NOT IN %v", + buildPlaceholders(len(exemptSessionIDs))) + } + + // Prepare the query arguments + args := []interface{}{ + uid.String(), + } for _, v := range exemptSessionIDs { - exempt = append(exempt, hex.EncodeToString(util.Digest([]byte(v)))) + // Convert the exemptSessionIDs to hex encoded + // SHA256 hashes. These hashes are the primary + // keys for the sessions in the database. + h := hex.EncodeToString(util.Digest([]byte(v))) + args = append(args, h) } - // Using an empty NOT IN() set will result in no records being - // deleted. - if len(exempt) == 0 { - _, err := m.userDB. - ExecContext(ctx, "DELETE FROM sessions WHERE user_id = ?", uid.String()) + _, err := m.userDB.ExecContext(ctx, q, args...) + if err != nil { return err } - _, err := m.userDB. - ExecContext(ctx, "DELETE FROM sessions WHERE user_id = ? AND k NOT IN (?)", - uid.String(), exempt) - return err + return nil } // SetPaywallAddressIndex updates the paywall address index. @@ -1413,3 +1424,24 @@ func New(host, password, network, encryptionKey string) (*mysql, error) { encryptionKey: key, }, nil } + +// buildPlaceholders builds and returns a parameter placeholder string with the +// specified number of placeholders. +// +// Input: 1 Output: "(?)" +// Input: 3 Output: "(?,?,?)" +func buildPlaceholders(placeholders int) string { + var b strings.Builder + + b.WriteString("(") + for i := 0; i < placeholders; i++ { + b.WriteString("?") + // Don't add a comma on the last one + if i < placeholders-1 { + b.WriteString(",") + } + } + b.WriteString(")") + + return b.String() +}