diff --git a/management/server/activity/cmd/main.go b/management/server/activity/cmd/main.go new file mode 100644 index 000000000..9b5901e3b --- /dev/null +++ b/management/server/activity/cmd/main.go @@ -0,0 +1,23 @@ +package main + +import ( + "context" + + _ "github.com/mattn/go-sqlite3" + "github.com/netbirdio/netbird/management/server/activity/sqlite" + log "github.com/sirupsen/logrus" +) + +func main() { + encryptionKey := "" + eventsDBBase := "management/server/activity/cmd/events.db" + + store, err := sqlite.NewSQLiteStore(context.Background(), eventsDBBase, encryptionKey) + if err != nil { + log.Fatalf("failed to create sqlite store: %v", err) + } + + if err = store.GetLegacyEvents(); err != nil { + log.Fatalf("failed to get legacy events: %v", err) + } +} diff --git a/management/server/activity/sqlite/legacy_events.go b/management/server/activity/sqlite/legacy_events.go new file mode 100644 index 000000000..6d8405f4e --- /dev/null +++ b/management/server/activity/sqlite/legacy_events.go @@ -0,0 +1,78 @@ +package sqlite + +import ( + "database/sql" + "fmt" + + log "github.com/sirupsen/logrus" +) + +func (store *Store) GetLegacyEvents() error { + rows, err := store.db.Query(`SELECT id, email, name FROM deleted_users`) + if err != nil { + return fmt.Errorf("failed to execute select query: %v", err) + } + defer rows.Close() + + if err = processLegacyEvents(store.fieldEncrypt, rows); err != nil { + return err + } + + return nil +} + +// processUserRows processes database rows of user data, decrypts legacy encryption fields, and re-encrypts them using GCM. +func processLegacyEvents(crypt *FieldEncrypt, rows *sql.Rows) error { + var ( + successCount int + failureCount int + ) + + for rows.Next() { + var ( + id string + email, name *string + ) + + err := rows.Scan(&id, &email, &name) + if err != nil { + return err + } + + if email != nil { + _, err = crypt.LegacyDecrypt(*email) + if err != nil { + log.Warnf("failed to decrypt email for user %s: %v", + id, + fmt.Errorf("failed to decrypt email: %w", err), + ) + failureCount++ + continue + } + } + + if name != nil { + _, err = crypt.LegacyDecrypt(*name) + if err != nil { + log.Warnf("failed to decrypt name for user %s: %v", + id, + fmt.Errorf("failed to decrypt name: %w", err), + ) + failureCount++ + continue + } + } + + successCount++ + + } + + if err := rows.Err(); err != nil { + return err + } + + log.Infof("Successfully decoded entries: %d", successCount) + log.Infof("Failed decoded entries: %d", failureCount) + + return nil +} diff --git a/management/server/activity/sqlite/sqlite.go b/management/server/activity/sqlite/sqlite.go index 823e0b4ac..c73cbb021 100644 --- a/management/server/activity/sqlite/sqlite.go +++ b/management/server/activity/sqlite/sqlite.go @@ -5,7 +5,7 @@ import ( "database/sql" "encoding/json" "fmt" - "path/filepath" + "os" "time" _ "github.com/mattn/go-sqlite3" @@ -26,7 +26,7 @@ const ( "meta TEXT," + " target_id TEXT);" - creatTableDeletedUsersQuery = `CREATE TABLE IF NOT EXISTS deleted_users (id TEXT NOT NULL, email TEXT NOT NULL, name TEXT, enc_algo TEXT NOT NULL);` + creatTableDeletedUsersQuery = `CREATE TABLE IF NOT EXISTS deleted_users (id TEXT NOT NULL, email TEXT NOT NULL, name TEXT);` selectDescQuery = `SELECT events.id, activity, timestamp, initiator_id, i.name as "initiator_name", i.email as "initiator_email", target_id, t.name as "target_name", t.email as "target_email", account_id, meta FROM events @@ -69,7 +69,7 @@ const ( and some selfhosted deployments might have duplicates already so we need to clean the table first. */ - insertDeleteUserQuery = `INSERT INTO deleted_users(id, email, name, enc_algo) VALUES(?, ?, ?, ?)` + insertDeleteUserQuery = `INSERT INTO deleted_users(id, email, name) VALUES(?, ?, ?)` fallbackName = "unknown" fallbackEmail = "unknown@unknown.com" @@ -89,9 +89,15 @@ type Store struct { } // NewSQLiteStore creates a new Store with an event table if not exists. -func NewSQLiteStore(ctx context.Context, dataDir string, encryptionKey string) (*Store, error) { - dbFile := filepath.Join(dataDir, eventSinkDB) - db, err := sql.Open("sqlite3", dbFile) +func NewSQLiteStore(ctx context.Context, dbPath string, encryptionKey string) (*Store, error) { + //dbFile := filepath.Join(dataDir, eventSinkDB) + stats, err := os.Stat(dbPath) + if err != nil { + return nil, err + } + _ = stats + + db, err := sql.Open("sqlite3", dbPath) if err != nil { return nil, err } @@ -102,10 +108,10 @@ func NewSQLiteStore(ctx context.Context, dataDir string, encryptionKey string) ( return nil, err } - if err = migrate(ctx, crypt, db); err != nil { - _ = db.Close() - return nil, fmt.Errorf("events database migration: %w", err) - } + //if err = migrate(ctx, crypt, db); err != nil { + // _ = db.Close() + // return nil, fmt.Errorf("events database migration: %w", err) + //} return createStore(crypt, db) }