diff --git a/irc/database.go b/irc/database.go index e9de3f0e..da46e822 100644 --- a/irc/database.go +++ b/irc/database.go @@ -24,7 +24,7 @@ const ( // 'version' of the database schema keySchemaVersion = "db.version" // latest schema of the db - latestDbSchema = 17 + latestDbSchema = 18 keyCloakSecret = "crypto.cloak_secret" ) @@ -854,6 +854,55 @@ func schemaChangeV16ToV17(config *Config, tx *buntdb.Tx) error { return nil } +// #1274: we used to suspend accounts by deleting their "verified" key, +// now we save some metadata under a new key +func schemaChangeV17ToV18(config *Config, tx *buntdb.Tx) error { + now := time.Now().UTC() + + exists := "account.exists " + suspended := "account.suspended " + verif := "account.verified " + verifCode := "account.verificationcode " + + var accounts []string + + tx.AscendGreaterOrEqual("", exists, func(key, value string) bool { + if !strings.HasPrefix(key, exists) { + return false + } + account := strings.TrimPrefix(key, exists) + _, verifiedErr := tx.Get(verif + account) + _, verifCodeErr := tx.Get(verifCode + account) + if verifiedErr != nil && verifCodeErr != nil { + // verified key not present, but there's no code either, + // this is a suspension + accounts = append(accounts, account) + } + return true + }) + + type accountSuspensionV18 struct { + TimeCreated time.Time + Duration time.Duration + OperName string + Reason string + } + + for _, account := range accounts { + var sus accountSuspensionV18 + sus.TimeCreated = now + sus.OperName = "*" + sus.Reason = "[unknown]" + susBytes, err := json.Marshal(sus) + if err != nil { + return err + } + tx.Set(suspended+account, string(susBytes), nil) + } + + return nil +} + func getSchemaChange(initialVersion int) (result SchemaChange, ok bool) { for _, change := range allChanges { if initialVersion == change.InitialVersion { @@ -944,4 +993,9 @@ var allChanges = []SchemaChange{ TargetVersion: 17, Changer: schemaChangeV16ToV17, }, + { + InitialVersion: 17, + TargetVersion: 18, + Changer: schemaChangeV17ToV18, + }, } diff --git a/irc/import.go b/irc/import.go index 1499e15b..3f405eb2 100644 --- a/irc/import.go +++ b/irc/import.go @@ -15,6 +15,14 @@ import ( "github.com/oragono/oragono/irc/utils" ) +const ( + // produce a hardcoded version of the database schema + // XXX instead of referencing, e.g., keyAccountExists, we should write in the string literal + // (to ensure that no matter what code changes happen elsewhere, we're still producing a + // db of the hardcoded version) + importDBSchemaVersion = 18 +) + type userImport struct { Name string Hash string @@ -66,11 +74,7 @@ func doImportDBGeneric(config *Config, dbImport databaseImport, credsType Creden return fmt.Errorf("unsupported version of the db for import: version %d is required", requiredVersion) } - // produce a hardcoded version of the database schema - // XXX instead of referencing, e.g., keyAccountExists, we should write in the string literal - // (to ensure that no matter what code changes happen elsewhere, we're still producing a - // db of the hardcoded version) - tx.Set(keySchemaVersion, "17", nil) + tx.Set(keySchemaVersion, strconv.Itoa(importDBSchemaVersion), nil) tx.Set(keyCloakSecret, utils.GenerateSecretKey(), nil) for username, userInfo := range dbImport.Users {