diff --git a/formats/bitwarden.go b/formats/bitwarden.go new file mode 100644 index 0000000..2a41310 --- /dev/null +++ b/formats/bitwarden.go @@ -0,0 +1,69 @@ +package formats + +import "time" + +type BitwardenFile struct { + Folders []BitwardenFolder `json:"folders,omitempty"` + Items []BitwardenItem `json:"items"` +} + +type BitwardenFolder struct { + ID string `json:"id,omitempty"` + Name string `json:"name"` +} + +type BitwardenItemType uint8 + +const ( + BitwardenItemTypePassword = iota + 1 +) + +type BitwardenItem struct { + Type BitwardenItemType `json:"type"` + PasswordHistory []PasswordHistoryEntry `json:"password_history,omitempty"` + RevisionDate *time.Time `json:"revisionDate,omitempty"` + CreationDate *time.Time `json:"creationDate,omitempty"` + Name string `json:"name"` + Notes string `json:"notes"` + Login BitwardenLogin `json:"login"` + FolderID string `json:"folderId,omitempty"` +} + +type PasswordHistoryEntry struct { + LastUsedDate *time.Time `json:"lastUsedDate,omitempty"` +} + +type BitwardenLogin struct { + URIs []BitwardenLoginURI `json:"uris,omitempty"` + Username string `json:"username"` + Password string `json:"password"` + // TOPT +} + +type BitwardenLoginURI struct { + Match *string `json:"match"` + URI string `json:"uri"` +} + +func BitwardenFileFromNorton(entries []NortonEntry) (BitwardenFile, error) { + bf := BitwardenFile{} + + for _, entry := range entries { + bf.Items = append(bf.Items, BitwardenItem{ + Type: BitwardenItemTypePassword, + Name: entry.Title, + Notes: entry.Notes, + Login: BitwardenLogin{ + URIs: []BitwardenLoginURI{ + { + URI: entry.URL, + }, + }, + Username: entry.Username, + Password: entry.Password, + }, + }) + } + + return bf, nil +} diff --git a/formats/norton.go b/formats/norton.go new file mode 100644 index 0000000..42e05fc --- /dev/null +++ b/formats/norton.go @@ -0,0 +1,34 @@ +package formats + +import ( + "os" + + "github.com/gocarina/gocsv" +) + +// Username, Password, Title, Login, URL, Notes + +type NortonEntry struct { + Username string `csv:"Username"` + Password string `csv:"Password"` + Title string `csv:"Title"` + Login string `csv:"Login"` + URL string `csv:"URL"` + Notes string `csv:"Notes"` +} + +func DecodeNortonExport(filename string) ([]NortonEntry, error) { + f, err := os.Open(filename) + if err != nil { + return nil, err + } + defer f.Close() + + var out []NortonEntry + err = gocsv.UnmarshalFile(f, &out) + if err != nil { + return nil, err + } + + return out, nil +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..319c744 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module github.com/barrett370/norton2bitwarden + +go 1.21.0 + +require github.com/gocarina/gocsv v0.0.0-20231116093920-b87c2d0e983a diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..cf31734 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/gocarina/gocsv v0.0.0-20231116093920-b87c2d0e983a h1:RYfmiM0zluBJOiPDJseKLEN4BapJ42uSi9SZBQ2YyiA= +github.com/gocarina/gocsv v0.0.0-20231116093920-b87c2d0e983a/go.mod h1:5YoVOkjYAQumqlV356Hj3xeYh4BdZuLE0/nRkf2NKkI= diff --git a/main.go b/main.go new file mode 100644 index 0000000..cf9f6be --- /dev/null +++ b/main.go @@ -0,0 +1,34 @@ +package main + +import ( + "encoding/json" + "fmt" + "os" + + "github.com/barrett370/norton2bitwarden/formats" +) + +func main() { + passwords, err := formats.DecodeNortonExport("./test.csv") + if err != nil { + panic(err) + } + fmt.Printf("%+v\n", passwords) + + out, err := os.Create("out.json") + if err != nil { + panic(err) + } + defer out.Close() + + bf, err := formats.BitwardenFileFromNorton(passwords) + if err != nil { + panic(err) + } + + err = json.NewEncoder(out).Encode(bf) + + if err != nil { + panic(err) + } +} diff --git a/out.json b/out.json new file mode 100644 index 0000000..d1c20b1 --- /dev/null +++ b/out.json @@ -0,0 +1 @@ +{"items":[{"type":1,"name":"foo.com","notes":"","login":{"uris":[{"match":null,"uri":"foo.com"}],"username":"foo","password":"password"}},{"type":1,"name":" bar.com","notes":" some comment","login":{"uris":[{"match":null,"uri":" bar.com"}],"username":"bar","password":" password2"}}]} diff --git a/test.csv b/test.csv new file mode 100644 index 0000000..ea4aa14 --- /dev/null +++ b/test.csv @@ -0,0 +1,3 @@ +Username,Password,Title,Login,URL,Notes +foo,password,foo.com,foo.com,foo.com, +bar, password2, bar.com, bar.com, bar.com, some comment