Skip to content

Issue 30 tag #36

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jan 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 97 additions & 17 deletions actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"encoding/csv"
"errors"
"fmt"
"gorm.io/gorm"
"os"
"os/exec"
"os/signal"
Expand Down Expand Up @@ -175,14 +176,19 @@ func setActiveDatabasePath(dbPath string) error {
}

if newEncrypted {
// Decrypt new database if it is encrypted
fmt.Printf("Database %s is encrypted, decrypting it\n", fullPath)
err, _ = decryptDatabase(fullPath)
if err != nil {
fmt.Printf("Decryption Error - \"%s\", not switching databases\n", err.Error())
return err
if !settings.AutoEncrypt {
// Decrypt new database if it is encrypted
fmt.Printf("Database %s is encrypted, decrypting it\n", fullPath)
err, _ = decryptDatabase(fullPath)
if err != nil {
fmt.Printf("Decryption Error - \"%s\", not switching databases\n", err.Error())
return err
} else {
newEncrypted = false
}
} else {
newEncrypted = false
// New database is encrypted and autoencrypt is set - so keep it like that
// fmt.Printf("Database %s is already encrypted, nothing to do\n", fullPath)
}
}
}
Expand All @@ -193,7 +199,7 @@ func setActiveDatabasePath(dbPath string) error {
return nil
}

if newEncrypted {
if newEncrypted && !settings.AutoEncrypt {
// Use should manually decrypt before switching
fmt.Println("Auto-encrypt disabled, decrypt new database manually before switching.")
return nil
Expand Down Expand Up @@ -223,6 +229,7 @@ func addNewEntry() error {
var url string
var notes string
var passwd string
var tags string
var err error
var customEntries []CustomEntry

Expand Down Expand Up @@ -250,7 +257,8 @@ func addNewEntry() error {
}
// fmt.Printf("Password => %s\n", passwd)

notes = readInput(reader, "\nNotes")
tags = readInput(reader, "\nTags (separated by space): ")
notes = readInput(reader, "Notes")

// Title and username/password are mandatory
if len(title) == 0 {
Expand All @@ -269,7 +277,7 @@ func addNewEntry() error {
customEntries = addCustomFields(reader)

// Trim spaces
err = addNewDatabaseEntry(title, userName, url, passwd, notes, customEntries)
err = addNewDatabaseEntry(title, userName, url, passwd, tags, notes, customEntries)

if err != nil {
fmt.Printf("Error adding entry - \"%s\"\n", err.Error())
Expand Down Expand Up @@ -299,7 +307,7 @@ func addOrUpdateCustomFields(reader *bufio.Reader, entry *Entry) ([]CustomEntry,
fmt.Println("Field Name: " + customEntry.FieldName)
fieldName = readInput(reader, "\tNew Field Name (Enter to keep, \"x\" to delete)")
if strings.ToLower(strings.TrimSpace(fieldName)) == "x" {
fmt.Println("Deleting field " + fieldName)
fmt.Println("Deleting field: " + customEntry.FieldName)
} else {
if strings.TrimSpace(fieldName) == "" {
fieldName = customEntry.FieldName
Expand Down Expand Up @@ -365,6 +373,7 @@ func editCurrentEntry(idString string) error {
var title string
var url string
var notes string
var tags string
var passwd string
var err error
var entry *Entry
Expand Down Expand Up @@ -407,13 +416,16 @@ func editCurrentEntry(idString string) error {
}
// fmt.Printf("Password => %s\n", passwd)

fmt.Printf("\nCurrent Tags: %s\n", entry.Tags)
tags = readInput(reader, "New Tags")

fmt.Printf("\nCurrent Notes: %s\n", entry.Notes)
notes = readInput(reader, "New Notes")

customEntries, flag := addOrUpdateCustomFields(reader, entry)

// Update
err = updateDatabaseEntry(entry, title, userName, url, passwd, notes, customEntries, flag)
err = updateDatabaseEntry(entry, title, userName, url, passwd, tags, notes, customEntries, flag)
if err != nil {
fmt.Printf("Error updating entry - \"%s\"\n", err.Error())
}
Expand Down Expand Up @@ -629,6 +641,9 @@ func copyCurrentEntry(idString string) error {

var err error
var entry *Entry
var entryNew *Entry
var exEntries []ExtendedEntry

var id int

if err = checkActiveDatabase(); err != nil {
Expand All @@ -643,12 +658,24 @@ func copyCurrentEntry(idString string) error {
return err
}

err, _ = cloneEntry(entry)
err, entryNew = cloneEntry(entry)
if err != nil {
fmt.Printf("Error cloning entry: \"%s\"\n", err.Error())
return err
}

exEntries = getExtendedEntries(entry)

if len(exEntries) > 0 {
fmt.Printf("%d extended entries found\n", len(exEntries))

err = cloneExtendedEntries(entryNew, exEntries)
if err != nil {
fmt.Printf("Error cloning extended entries: \"%s\"\n", err.Error())
return err
}
}

return err
}

Expand Down Expand Up @@ -684,11 +711,11 @@ func encryptDatabase(dbPath string, givenPasswd *string) error {
}

if len(passwd) == 0 {
fmt.Printf("Password: ")
fmt.Printf("Encryption Password: ")
err, passwd = readPassword()

if err == nil {
fmt.Printf("\nPassword again: ")
fmt.Printf("\nEncryption Password again: ")
err, passwd2 = readPassword()
if err == nil {
if passwd != passwd2 {
Expand Down Expand Up @@ -736,7 +763,7 @@ func decryptDatabase(dbPath string) (error, string) {
return err, ""
}

fmt.Printf("Password: ")
fmt.Printf("Decryption Password: ")
err, passwd = readPassword()

if err != nil {
Expand All @@ -757,12 +784,65 @@ func decryptDatabase(dbPath string) (error, string) {
}

if err == nil {
fmt.Println("\nDecryption complete.")
fmt.Println("...decryption complete.")
}

return err, passwd
}

// Migrate an existing database to the new schema
func migrateDatabase(dbPath string) error {

var err error
var flag bool
var passwd string
var db *gorm.DB

if _, err = os.Stat(dbPath); os.IsNotExist(err) {
fmt.Printf("Error - path %s does not exist\n", dbPath)
return err
}

if err, flag = isFileEncrypted(dbPath); flag {
err, passwd = decryptDatabase(dbPath)
}

if err != nil {
return err
}

err, db = openDatabase(dbPath)

if err != nil {
fmt.Printf("Error opening database path - %s: %s\n", dbPath, err.Error())
return err
}

fmt.Println("Migrating tables ...")
err = db.AutoMigrate(&Entry{})

if err != nil {
fmt.Printf("Error migrating table \"entries\" - %s: %s\n", dbPath, err.Error())
return err
}

err = db.AutoMigrate(&ExtendedEntry{})

if err != nil {
fmt.Printf("Error migrating table \"exentries\" - %s: %s\n", dbPath, err.Error())
return err
}

if flag {
// File was encrypted - encrypt it again
encryptDatabase(dbPath, &passwd)
}

fmt.Println("Migration successful.")

return nil
}

// Export data to a varity of file types
func exportToFile(fileName string) error {

Expand Down
6 changes: 3 additions & 3 deletions crypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ func decryptFileAES(encDbPath string, password string) error {
return err
}

err, origFile = rewriteBaseFile(encDbPath, plainText, 0600)
err, origFile = rewriteFile(encDbPath, plainText, 0600)

if err != nil {
fmt.Printf("Error writing decrypted data to %s - \"%s\"\n", origFile, err.Error())
Expand Down Expand Up @@ -425,8 +425,8 @@ func decryptFileXChachaPoly(encDbPath string, password string) error {
return err
}

// err = os.WriteFile("test.sqlite3", plainText, 0600)
err, origFile = rewriteBaseFile(encDbPath, plainText, 0600)
// err = os.WriteFile("test.sqlite3", oplainText, 0600)
err, origFile = rewriteFile(encDbPath, plainText, 0600)

if err != nil {
fmt.Printf("Error writing decrypted data to %s - \"%s\"\n", origFile, err.Error())
Expand Down
64 changes: 60 additions & 4 deletions db.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type Entry struct {
Url string `gorm:"column:url"`
Password string `gorm:"column:password"`
Notes string `gorm:"column:notes"`
Tags string `gorm:"column:tags"`
Timestamp time.Time `gorm:"type:timestamp;default:(datetime('now','localtime'))"` // sqlite3
}

Expand Down Expand Up @@ -56,6 +57,16 @@ func (e1 *Entry) Copy(e2 *Entry) {
}
}

// Clone an entry
func (e1 *ExtendedEntry) Copy(e2 *ExtendedEntry) {

if e2 != nil {
e1.FieldName = e2.FieldName
e1.FieldValue = e2.FieldValue
e1.EntryID = e2.EntryID
}
}

// Create a new database
func openDatabase(filePath string) (error, *gorm.DB) {

Expand Down Expand Up @@ -219,13 +230,15 @@ func replaceCustomEntries(db *gorm.DB, entry *Entry, updatedEntries []CustomEntr
}

// Add a new entry to current database
func addNewDatabaseEntry(title, userName, url, passwd, notes string, customEntries []CustomEntry) error {
func addNewDatabaseEntry(title, userName, url, passwd, tags string,
notes string, customEntries []CustomEntry) error {

var entry Entry
var err error
var db *gorm.DB

entry = Entry{Title: title, User: userName, Url: url, Password: passwd, Notes: notes}
entry = Entry{Title: title, User: userName, Url: url, Password: passwd, Tags: strings.TrimSpace(tags),
Notes: notes}

err, db = openActiveDatabase()
if err == nil && db != nil {
Expand All @@ -247,13 +260,20 @@ func addNewDatabaseEntry(title, userName, url, passwd, notes string, customEntri
}

// Update current database entry with new values
func updateDatabaseEntry(entry *Entry, title, userName, url, passwd, notes string, customEntries []CustomEntry, flag bool) error {
func updateDatabaseEntry(entry *Entry, title, userName, url, passwd, tags string,
notes string, customEntries []CustomEntry, flag bool) error {

var updateMap map[string]interface{}

updateMap = make(map[string]interface{})

keyValMap := map[string]string{"title": title, "user": userName, "url": url, "password": passwd, "notes": notes}
keyValMap := map[string]string{
"title": title,
"user": userName,
"url": url,
"password": passwd,
"notes": notes,
"tags": tags}

for key, val := range keyValMap {
if len(val) > 0 {
Expand Down Expand Up @@ -416,11 +436,22 @@ func removeDatabaseEntry(entry *Entry) error {

err, db = openActiveDatabase()
if err == nil && db != nil {
var exEntries []ExtendedEntry

res := db.Delete(entry)
if res.Error != nil {
return res.Error
}

// Delete extended entries if any
exEntries = getExtendedEntries(entry)
if len(exEntries) > 0 {
res = db.Delete(exEntries)
if res.Error != nil {
return res.Error
}
}

return nil
}

Expand Down Expand Up @@ -450,6 +481,31 @@ func cloneEntry(entry *Entry) (error, *Entry) {
return err, nil
}

// Clone extended entries for an entry and return error code
func cloneExtendedEntries(entry *Entry, exEntries []ExtendedEntry) error {

var err error
var db *gorm.DB

err, db = openActiveDatabase()
if err == nil && db != nil {
for _, exEntry := range exEntries {
var exEntryNew ExtendedEntry

exEntryNew.Copy(&exEntry)
// Update the ID!
exEntryNew.EntryID = entry.ID

result := db.Create(&exEntryNew)
if result.Error != nil {
return result.Error
}
}
}

return err
}

// Return an iterator over all entries using the given order query keys
func iterateEntries(orderKey string, order string) (error, []Entry) {

Expand Down
4 changes: 3 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"strings"
)

const VERSION = 0.3
const VERSION = 0.4
const APP = "varuh"

const AUTHOR_INFO = `
Expand Down Expand Up @@ -91,6 +91,7 @@ func performAction(optMap map[string]interface{}) {
"clone": WrapperMaxKryptStringFunc(copyCurrentEntry),
"use-db": setActiveDatabasePath,
"export": exportToFile,
"migrate": migrateDatabase,
}

stringListActionsMap := map[string]actionFunc{
Expand Down Expand Up @@ -190,6 +191,7 @@ func initializeCmdLine(parser *argparse.Parser) map[string]interface{} {
{"E", "edit", "Edit entry by <id>", "<id>", ""},
{"l", "list-entry", "List entry by <id>", "<id>", ""},
{"x", "export", "Export all entries to <filename>", "<filename>", ""},
{"m", "migrate", "Migrate a database to latest schema", "<path>", ""},
}

for _, opt := range stringOptions {
Expand Down
Loading