From 0ea2f2cf827d16f4d87d7734790ccf011991941f Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Tue, 10 Jan 2023 17:03:25 +0100 Subject: [PATCH] db: Remove User without corresponding AuthUser --- storage/leveldb/database.go | 2 +- storage/leveldb/user.go | 49 +++++++++++++++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/storage/leveldb/database.go b/storage/leveldb/database.go index a173536..1588efd 100644 --- a/storage/leveldb/database.go +++ b/storage/leveldb/database.go @@ -71,7 +71,7 @@ func NewLevelDBStorage(path string) (s *LevelDBStorage, err error) { } func (s *LevelDBStorage) Tidy() error { - for _, tidy := range []func() error{s.TidySessions, s.TidyAuthUsers, s.TidyProviders, s.TidyDomains, s.TidyZones} { + for _, tidy := range []func() error{s.TidySessions, s.TidyAuthUsers, s.TidyUsers, s.TidyProviders, s.TidyDomains, s.TidyZones} { if err := tidy(); err != nil { return err } diff --git a/storage/leveldb/user.go b/storage/leveldb/user.go index 6c657a6..a0c1633 100644 --- a/storage/leveldb/user.go +++ b/storage/leveldb/user.go @@ -37,6 +37,7 @@ import ( "git.happydns.org/happydomain/model" + "github.com/syndtr/goleveldb/leveldb" "github.com/syndtr/goleveldb/leveldb/util" ) @@ -62,12 +63,16 @@ func (s *LevelDBStorage) GetUsers() (users happydns.Users, err error) { return } -func (s *LevelDBStorage) GetUser(id happydns.Identifier) (u *happydns.User, err error) { +func (s *LevelDBStorage) getUser(key string) (u *happydns.User, err error) { u = &happydns.User{} - err = s.get(fmt.Sprintf("user-%s", id.String()), &u) + err = s.get(key, &u) return } +func (s *LevelDBStorage) GetUser(id happydns.Identifier) (u *happydns.User, err error) { + return s.getUser(fmt.Sprintf("user-%s", id.String())) +} + func (s *LevelDBStorage) GetUserByEmail(email string) (u *happydns.User, err error) { var users happydns.Users @@ -148,3 +153,43 @@ func (s *LevelDBStorage) ClearUsers() error { return nil } + +func (s *LevelDBStorage) TidyUsers() error { + tx, err := s.db.OpenTransaction() + if err != nil { + return err + } + + iter := tx.NewIterator(util.BytesPrefix([]byte("user-")), nil) + defer iter.Release() + + for iter.Next() { + user, err := s.getUser(string(iter.Key())) + + if err != nil { + // Drop unreadable providers + log.Printf("Deleting unreadable user (%s): %v\n", err.Error(), user) + err = tx.Delete(iter.Key(), nil) + } else { + _, err = s.GetAuthUser(user.Id) + if err == leveldb.ErrNotFound { + // Drop providers of unexistant users + log.Printf("Deleting orphan user (authuser %s not found): %v\n", user.Id.String(), user) + err = tx.Delete(iter.Key(), nil) + } + } + + if err != nil { + tx.Discard() + return err + } + } + + err = tx.Commit() + if err != nil { + tx.Discard() + return err + } + + return nil +}