Better offline handling, implemented the local portion of delete, and maybe fixed the bug when running tests on github actions

This commit is contained in:
David Dworken 2022-09-18 09:42:24 -07:00
parent 6c6acc5473
commit 1bf510ff8a
5 changed files with 59 additions and 7 deletions

View File

@ -16,7 +16,6 @@ import (
func TestESubmitThenQuery(t *testing.T) { func TestESubmitThenQuery(t *testing.T) {
// Set up // Set up
defer shared.BackupAndRestore(t)()
InitDB() InitDB()
// Register a few devices // Register a few devices
@ -114,7 +113,6 @@ func TestESubmitThenQuery(t *testing.T) {
func TestDumpRequestAndResponse(t *testing.T) { func TestDumpRequestAndResponse(t *testing.T) {
// Set up // Set up
defer shared.BackupAndRestore(t)()
InitDB() InitDB()
// Register a first device for two different users // Register a first device for two different users
@ -285,7 +283,6 @@ func TestUpdateReleaseVersion(t *testing.T) {
} }
// Set up // Set up
defer shared.BackupAndRestore(t)()
InitDB() InitDB()
// Check that ReleaseVersion hasn't been set yet // Check that ReleaseVersion hasn't been set yet

View File

@ -1,6 +1,7 @@
package data package data
import ( import (
"bufio"
"crypto/aes" "crypto/aes"
"crypto/cipher" "crypto/cipher"
"crypto/hmac" "crypto/hmac"
@ -10,6 +11,7 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
"os"
"strings" "strings"
"time" "time"
@ -133,12 +135,12 @@ func parseTimeGenerously(input string) (time.Time, error) {
return dateparse.ParseLocal(input) return dateparse.ParseLocal(input)
} }
func Search(db *gorm.DB, query string, limit int) ([]*HistoryEntry, error) { func makeWhereQueryFromSearch(db *gorm.DB, query string) (*gorm.DB, error) {
tokens, err := tokenize(query) tokens, err := tokenize(query)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to tokenize query: %v", err) return nil, fmt.Errorf("failed to tokenize query: %v", err)
} }
tx := db.Where("true") tx := db.Model(&HistoryEntry{}).Where("true")
for _, token := range tokens { for _, token := range tokens {
if strings.HasPrefix(token, "-") { if strings.HasPrefix(token, "-") {
if strings.Contains(token, ":") { if strings.Contains(token, ":") {
@ -168,6 +170,45 @@ func Search(db *gorm.DB, query string, limit int) ([]*HistoryEntry, error) {
tx = tx.Where(query, v1, v2, v3) tx = tx.Where(query, v1, v2, v3)
} }
} }
return tx, nil
}
func Redact(db *gorm.DB, query string) error {
tx, err := makeWhereQueryFromSearch(db, query)
if err != nil {
return err
}
var count int64
res := tx.Count(&count)
if res.Error != nil {
return res.Error
}
fmt.Printf("This will permanently delete %d entries, are you sure? [y/N]", count)
reader := bufio.NewReader(os.Stdin)
resp, err := reader.ReadString('\n')
if err != nil {
return fmt.Errorf("failed to read response: %v", err)
}
if strings.TrimSpace(resp) != "y" {
fmt.Printf("Aborting delete per user response of %#v\n", strings.TrimSpace(resp))
return nil
}
tx, err = makeWhereQueryFromSearch(db, query)
if err != nil {
return err
}
res = tx.Delete(&HistoryEntry{})
if res.Error != nil {
return res.Error
}
return nil
}
func Search(db *gorm.DB, query string, limit int) ([]*HistoryEntry, error) {
tx, err := makeWhereQueryFromSearch(db, query)
if err != nil {
return nil, err
}
tx = tx.Order("end_time DESC") tx = tx.Order("end_time DESC")
if limit > 0 { if limit > 0 {
tx = tx.Limit(limit) tx = tx.Limit(limit)

View File

@ -1055,6 +1055,9 @@ func ApiPost(path, contentType string, data []byte) ([]byte, error) {
} }
func IsOfflineError(err error) bool { func IsOfflineError(err error) bool {
if err == nil {
return false
}
return strings.Contains(err.Error(), "dial tcp: lookup api.hishtory.dev") || strings.Contains(err.Error(), "read: connection reset by peer") || strings.Contains(err.Error(), ": EOF") return strings.Contains(err.Error(), "dial tcp: lookup api.hishtory.dev") || strings.Contains(err.Error(), "read: connection reset by peer") || strings.Contains(err.Error(), ": EOF")
} }

View File

@ -33,7 +33,9 @@ func main() {
case "redact": case "redact":
fallthrough fallthrough
case "delete": case "delete":
panic("TODO: not yet implemented") db, err := lib.OpenLocalSqliteDb()
lib.CheckFatalError(err)
lib.CheckFatalError(data.Redact(db, strings.Join(os.Args[2:], " ")))
case "init": case "init":
lib.CheckFatalError(lib.Setup(os.Args)) lib.CheckFatalError(lib.Setup(os.Args))
case "install": case "install":
@ -115,6 +117,9 @@ func printDumpStatus(config lib.ClientConfig) {
func getDumpRequests(config lib.ClientConfig) ([]*shared.DumpRequest, error) { func getDumpRequests(config lib.ClientConfig) ([]*shared.DumpRequest, error) {
resp, err := lib.ApiGet("/api/v1/get-dump-requests?user_id=" + data.UserId(config.UserSecret) + "&device_id=" + config.DeviceId) resp, err := lib.ApiGet("/api/v1/get-dump-requests?user_id=" + data.UserId(config.UserSecret) + "&device_id=" + config.DeviceId)
if lib.IsOfflineError(err) {
return []*shared.DumpRequest{}, nil
}
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -129,6 +134,9 @@ func retrieveAdditionalEntriesFromRemote(db *gorm.DB) error {
return err return err
} }
respBody, err := lib.ApiGet("/api/v1/query?device_id=" + config.DeviceId + "&user_id=" + data.UserId(config.UserSecret)) respBody, err := lib.ApiGet("/api/v1/query?device_id=" + config.DeviceId + "&user_id=" + data.UserId(config.UserSecret))
if lib.IsOfflineError(err) {
return nil
}
if err != nil { if err != nil {
return err return err
} }
@ -171,6 +179,9 @@ func displayBannerIfSet() error {
} }
url := "/api/v1/banner?commit_hash=" + GitCommit + "&user_id=" + data.UserId(config.UserSecret) + "&device_id=" + config.DeviceId + "&version=" + lib.Version + "&forced_banner=" + os.Getenv("FORCED_BANNER") url := "/api/v1/banner?commit_hash=" + GitCommit + "&user_id=" + data.UserId(config.UserSecret) + "&device_id=" + config.DeviceId + "&version=" + lib.Version + "&forced_banner=" + os.Getenv("FORCED_BANNER")
respBody, err := lib.ApiGet(url) respBody, err := lib.ApiGet(url)
if lib.IsOfflineError(err) {
return nil
}
if err != nil { if err != nil {
return err return err
} }

View File

@ -72,7 +72,7 @@ func BackupAndRestoreWithId(t *testing.T, id string) func() {
touchFile(path.Join(homedir, ".zsh_history")) touchFile(path.Join(homedir, ".zsh_history"))
return func() { return func() {
for _, file := range renameFiles { for _, file := range renameFiles {
_ = os.Rename(file+id+".bak", file) checkError(os.Rename(file+id+".bak", file))
} }
for _, file := range copyFiles { for _, file := range copyFiles {
checkError(copy(file+id+".bak", file)) checkError(copy(file+id+".bak", file))