Skip to content
This repository was archived by the owner on Feb 16, 2023. It is now read-only.

Commit d9dbccf

Browse files
Merge pull request #379 from secrethub/feature/repeatable-migrate-apply
Repeatable migrate apply
2 parents c17010f + fac9436 commit d9dbccf

2 files changed

Lines changed: 271 additions & 55 deletions

File tree

internals/onepassword/onepassword.go

Lines changed: 75 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,37 @@ func CreateItem(vault string, template *ItemTemplate, title string) error {
3434
return err
3535
}
3636

37+
func SetField(vault, item, field, value string) error {
38+
_, err := execOP("edit", "item", item, fmt.Sprintf(`%s=%s`, field, value), "--vault="+vault)
39+
if err != nil {
40+
return fmt.Errorf("could not set field '%s'.'%s'.'%s'", vault, item, field)
41+
}
42+
return nil
43+
}
44+
45+
// GetFields returns a title-to-value map of the fields from the first section of the given 1Password item.
46+
// The rest of the fields are ignored as the migration tool only stores information in the first
47+
// section of each item.
48+
func GetFields(vault, item string) (map[string]string, error) {
49+
opItem := struct {
50+
Details ItemTemplate `json:"details"`
51+
}{}
52+
opItemJSON, err := execOP("get", "item", item, "--vault="+vault)
53+
if err != nil {
54+
return nil, fmt.Errorf("could not get item '%s'.'%s' from 1Password: %s", vault, item, err)
55+
}
56+
err = json.Unmarshal(opItemJSON, &opItem)
57+
if err != nil {
58+
return nil, fmt.Errorf("unexpected format of 1Password item in `op get item` command output: %s", err)
59+
}
60+
61+
fields := make(map[string]string, len(opItem.Details.Sections[0].Fields))
62+
for _, field := range opItem.Details.Sections[0].Fields {
63+
fields[field.Title] = field.Value
64+
}
65+
return fields, nil
66+
}
67+
3768
func NewItemTemplate() *ItemTemplate {
3869
return &ItemTemplate{
3970
Sections: []sectionTemplate{
@@ -64,15 +95,15 @@ func (tpl *ItemTemplate) AddField(name, value string, concealed bool) {
6495
tpl.Sections[0].Fields = append(tpl.Sections[0].Fields, itemFieldTemplate{
6596
Designation: designation,
6697
Name: name,
67-
Type: name,
98+
Title: name,
6899
Value: value,
69100
})
70101
}
71102

72103
type itemFieldTemplate struct {
73104
Designation string `json:"k"`
74105
Name string `json:"n"`
75-
Type string `json:"t"`
106+
Title string `json:"t"`
76107
Value string `json:"v"`
77108
}
78109

@@ -100,14 +131,52 @@ func EnsureSignedIn() error {
100131
return fmt.Errorf("OP_SESSION environment variable not found, run `eval $(op signin)` to set one")
101132
}
102133

134+
func opConfigDirPath() (string, error) {
135+
xdgConfigHome, _ := os.LookupEnv("XDG_CONFIG_HOME")
136+
home, _ := homedir.Dir()
137+
138+
// Inspect possible config directories in reverse order of priority.
139+
// This code has been taken from the op cli's source code.
140+
configDirPaths := []string{}
141+
if home != "" {
142+
// Legacy home
143+
configDirPaths = append(configDirPaths, filepath.Join(home, ".op"))
144+
}
145+
if xdgConfigHome != "" {
146+
// Legacy xdg
147+
configDirPaths = append(configDirPaths, filepath.Join(xdgConfigHome, ".op"))
148+
}
149+
if home != "" {
150+
// New home
151+
configDirPaths = append(configDirPaths, filepath.Join(home, ".config", "op"))
152+
}
153+
if xdgConfigHome != "" {
154+
// New xdg
155+
configDirPaths = append(configDirPaths, filepath.Join(xdgConfigHome, "op"))
156+
}
157+
158+
for _, configDir := range configDirPaths {
159+
fileInfo, err := os.Stat(configDir)
160+
if err == nil && fileInfo.IsDir() {
161+
return configDir, nil
162+
}
163+
}
164+
165+
// If we reach this point then none of those directories exist (op is executed
166+
// for the first time). Default to the last entry in the list.
167+
if len(configDirPaths) > 0 {
168+
return configDirPaths[len(configDirPaths)-1], nil
169+
}
170+
171+
return "", fmt.Errorf("unable to determine location of config directory")
172+
}
173+
103174
func GetSignInAddress() (string, error) {
104-
home, err := homedir.Dir()
175+
path, err := opConfigDirPath()
105176
if err != nil {
106177
return "", err
107178
}
108-
109-
path := filepath.Join(home, ".op", "config")
110-
bytes, err := ioutil.ReadFile(path)
179+
bytes, err := ioutil.ReadFile(filepath.Join(path, "config"))
111180
if err != nil {
112181
return "", fmt.Errorf("could not read 1password config file at %s", path)
113182
}

0 commit comments

Comments
 (0)