diff --git a/PROTOCOL.md b/PROTOCOL.md index 4801196..9b61308 100644 --- a/PROTOCOL.md +++ b/PROTOCOL.md @@ -41,23 +41,23 @@ should be supplied as a `message` parameter. ## List of Error Codes -| Code | Description | Parameters | -| ---- | ----------------------------------------------------------------------- | -------------------------------------------------- | -| 10 | Unable to parse browser request length | message, error | -| 11 | Unable to parse browser request | message, error | -| 12 | Invalid request action | message, action | -| 13 | Inaccessible user-configured password store | message, action, error, storePath, storeName | -| 14 | Inaccessible default password store | message, action, error, storePath | -| 15 | Unable to determine the location of the default password store | message, action, error | -| 16 | Unable to read the default settings of a user-configured password store | message, action, error, storePath, storeName | -| 17 | Unable to read the default settings of the default password store | message, action, error, storePath | -| 18 | Unable to list files in a password store | message, action, error, storePath, storeName | -| 19 | Unable to determine a relative path for a file in a password store | message, action, error, storePath, storeName, file | -| 20 | Invalid password store name | message, action, storeName | -| 21 | Invalid gpg path | message, action, error, gpgPath | -| 22 | Unable to detect the location of the gpg binary | message, action, error | -| 23 | Invalid password file extension | message, action, file | -| 24 | Unable to decrypt the password file | message, action, error, storePath, storeName, file | +| Code | Description | Parameters | +| ---- | ----------------------------------------------------------------------- | ----------------------------------------------------------- | +| 10 | Unable to parse browser request length | message, error | +| 11 | Unable to parse browser request | message, error | +| 12 | Invalid request action | message, action | +| 13 | Inaccessible user-configured password store | message, action, error, storeId, storePath, storeName | +| 14 | Inaccessible default password store | message, action, error, storePath | +| 15 | Unable to determine the location of the default password store | message, action, error | +| 16 | Unable to read the default settings of a user-configured password store | message, action, error, storeId, storePath, storeName | +| 17 | Unable to read the default settings of the default password store | message, action, error, storePath | +| 18 | Unable to list files in a password store | message, action, error, storeId, storePath, storeName | +| 19 | Unable to determine a relative path for a file in a password store | message, action, error, storeId, storePath, storeName, file | +| 20 | Invalid password store ID | message, action, storeId | +| 21 | Invalid gpg path | message, action, error, gpgPath | +| 22 | Unable to detect the location of the gpg binary | message, action, error | +| 23 | Invalid password file extension | message, action, file | +| 24 | Unable to decrypt the password file | message, action, error, storeId, storePath, storeName, file | ## Settings @@ -86,10 +86,11 @@ Settings are applied using the following priority, highest first: ### Store-specific Settings -| Setting | Description | Default | -| ------- | ------------------------------------ | ------- | -| name | Store name (same as the store key) | | -| path | Path to the password store directory | `""` | +| Setting | Description | Default | +| ------- | --------------------------------------- | ------- | +| id | Unique store id (same as the store key) | `` | +| name | Store name (same as the store key) | `""` | +| path | Path to the password store directory | `""` | ## Actions @@ -121,7 +122,7 @@ is alive, determine the version at startup, and provide per-store defaults. "settings": "", }, “storeSettings”: { - “storeName”: "" + “storeId”: "" } } } @@ -130,7 +131,7 @@ is alive, determine the version at startup, and provide per-store defaults. ### List Get a list of all `*.gpg` files for each of a provided array of directory paths. The `storeN` -is the name of a password store, the key in `"settings.stores"` object. +is the ID of a password store, the key in `"settings.stores"` object. #### Request @@ -166,7 +167,7 @@ Get the decrypted contents of a specific file. { "settings": , "action": "fetch", - "store": "", + "storeId": "", "file": "relative/path/to/file.gpg" } ``` diff --git a/errors/errors.go b/errors/errors.go index a8ef633..a9ac3a7 100644 --- a/errors/errors.go +++ b/errors/errors.go @@ -40,7 +40,7 @@ const ( // CodeUnableToDetermineRelativeFilePathInPasswordStore error determining a relative path for a file in a password store CodeUnableToDetermineRelativeFilePathInPasswordStore Code = 19 - // CodeInvalidPasswordStore error looking for a password store with the given name + // CodeInvalidPasswordStore error looking for a password store with the given ID CodeInvalidPasswordStore Code = 20 // CodeInvalidGpgPath error looking for a gpg binary at the given path @@ -69,6 +69,9 @@ const ( // FieldError an error message returned from an external system FieldError Field = "error" + // FieldStoreID a password store id + FieldStoreID Field = "storeId" + // FieldStoreName a password store name FieldStoreName Field = "storeName" diff --git a/request/configure.go b/request/configure.go index 85c4684..bf29283 100644 --- a/request/configure.go +++ b/request/configure.go @@ -20,8 +20,8 @@ func configure(request *request) { normalizedStorePath, err := normalizePasswordStorePath(store.Path) if err != nil { log.Errorf( - "The password store '%v' is not accessible at the location '%v': %+v", - store.Name, store.Path, err, + "The password store '%+v' is not accessible at its location: %+v", + store, err, ) response.SendErrorAndExit( errors.CodeInaccessiblePasswordStore, @@ -29,6 +29,7 @@ func configure(request *request) { errors.FieldMessage: "The password store is not accessible", errors.FieldAction: "configure", errors.FieldError: err.Error(), + errors.FieldStoreID: store.ID, errors.FieldStoreName: store.Name, errors.FieldStorePath: store.Path, }, @@ -37,11 +38,11 @@ func configure(request *request) { store.Path = normalizedStorePath - responseData.StoreSettings[store.Name], err = readDefaultSettings(store.Path) + responseData.StoreSettings[store.ID], err = readDefaultSettings(store.Path) if err != nil { log.Errorf( - "Unable to read the default settings of the user-configured password store '%v' in '%v': %+v", - store.Name, store.Path, err, + "Unable to read the default settings of the user-configured password store '%+v' in its location: %+v", + store, err, ) response.SendErrorAndExit( errors.CodeUnreadablePasswordStoreDefaultSettings, @@ -49,6 +50,7 @@ func configure(request *request) { errors.FieldMessage: "Unable to read the default settings of the password store", errors.FieldAction: "configure", errors.FieldError: err.Error(), + errors.FieldStoreID: store.ID, errors.FieldStoreName: store.Name, errors.FieldStorePath: store.Path, }, diff --git a/request/fetch.go b/request/fetch.go index dce62d1..cc5053a 100644 --- a/request/fetch.go +++ b/request/fetch.go @@ -29,18 +29,18 @@ func fetchDecryptedContents(request *request) { ) } - store, ok := request.Settings.Stores[request.Store] + store, ok := request.Settings.Stores[request.StoreID] if !ok { log.Errorf( - "The password store '%v' is not present in the list of stores '%v'", - request.Store, request.Settings.Stores, + "The password store with ID '%v' is not present in the list of stores '%+v'", + request.StoreID, request.Settings.Stores, ) response.SendErrorAndExit( errors.CodeInvalidPasswordStore, &map[errors.Field]string{ - errors.FieldMessage: "The password store is not present in the list of stores", - errors.FieldAction: "fetch", - errors.FieldStoreName: request.Store, + errors.FieldMessage: "The password store is not present in the list of stores", + errors.FieldAction: "fetch", + errors.FieldStoreID: request.StoreID, }, ) } @@ -48,8 +48,8 @@ func fetchDecryptedContents(request *request) { normalizedStorePath, err := normalizePasswordStorePath(store.Path) if err != nil { log.Errorf( - "The password store '%v' is not accessible at the location '%v': %+v", - store.Name, store.Path, err, + "The password store '%+v' is not accessible at its location: %+v", + store, err, ) response.SendErrorAndExit( errors.CodeInaccessiblePasswordStore, @@ -57,6 +57,7 @@ func fetchDecryptedContents(request *request) { errors.FieldMessage: "The password store is not accessible", errors.FieldAction: "fetch", errors.FieldError: err.Error(), + errors.FieldStoreID: store.ID, errors.FieldStoreName: store.Name, errors.FieldStorePath: store.Path, }, @@ -100,8 +101,8 @@ func fetchDecryptedContents(request *request) { responseData.Contents, err = decryptFile(&store, request.File, gpgPath) if err != nil { log.Errorf( - "Unable to decrypt the password file '%v' in the password store '%v' located in '%v': %+v", - request.File, store.Name, store.Path, err, + "Unable to decrypt the password file '%v' in the password store '%+v': %+v", + request.File, store, err, ) response.SendErrorAndExit( errors.CodeUnableToDecryptPasswordFile, @@ -110,6 +111,7 @@ func fetchDecryptedContents(request *request) { errors.FieldAction: "fetch", errors.FieldError: err.Error(), errors.FieldFile: request.File, + errors.FieldStoreID: store.ID, errors.FieldStoreName: store.Name, errors.FieldStorePath: store.Path, }, diff --git a/request/list.go b/request/list.go index 5983f48..39a3f2d 100644 --- a/request/list.go +++ b/request/list.go @@ -17,8 +17,8 @@ func listFiles(request *request) { normalizedStorePath, err := normalizePasswordStorePath(store.Path) if err != nil { log.Errorf( - "The password store '%v' is not accessible at the location '%v': %+v", - store.Name, store.Path, err, + "The password store '%+v' is not accessible at its location: %+v", + store, err, ) response.SendErrorAndExit( errors.CodeInaccessiblePasswordStore, @@ -26,6 +26,7 @@ func listFiles(request *request) { errors.FieldMessage: "The password store is not accessible", errors.FieldAction: "list", errors.FieldError: err.Error(), + errors.FieldStoreID: store.ID, errors.FieldStoreName: store.Name, errors.FieldStorePath: store.Path, }, @@ -37,8 +38,8 @@ func listFiles(request *request) { files, err := zglob.GlobFollowSymlinks(filepath.Join(store.Path, "/**/*.gpg")) if err != nil { log.Errorf( - "Unable to list the files in the password store '%v' at the location '%v': %+v", - store.Name, store.Path, err, + "Unable to list the files in the password store '%+v' at its location: %+v", + store, err, ) response.SendErrorAndExit( errors.CodeUnableToListFilesInPasswordStore, @@ -46,6 +47,7 @@ func listFiles(request *request) { errors.FieldMessage: "Unable to list the files in the password store", errors.FieldAction: "list", errors.FieldError: err.Error(), + errors.FieldStoreID: store.ID, errors.FieldStoreName: store.Name, errors.FieldStorePath: store.Path, }, @@ -56,8 +58,8 @@ func listFiles(request *request) { relativePath, err := filepath.Rel(store.Path, file) if err != nil { log.Errorf( - "Unable to determine the relative path for a file '%v' in the password store '%v' at the location '%v': %+v", - file, store.Name, store.Path, err, + "Unable to determine the relative path for a file '%v' in the password store '%+v': %+v", + file, store, err, ) response.SendErrorAndExit( errors.CodeUnableToDetermineRelativeFilePathInPasswordStore, @@ -66,6 +68,7 @@ func listFiles(request *request) { errors.FieldAction: "list", errors.FieldError: err.Error(), errors.FieldFile: file, + errors.FieldStoreID: store.ID, errors.FieldStoreName: store.Name, errors.FieldStorePath: store.Path, }, @@ -75,7 +78,7 @@ func listFiles(request *request) { } sort.Strings(files) - responseData.Files[store.Name] = files + responseData.Files[store.ID] = files } response.SendOk(responseData) diff --git a/request/process.go b/request/process.go index 979749f..a729dd4 100644 --- a/request/process.go +++ b/request/process.go @@ -12,6 +12,7 @@ import ( ) type store struct { + ID string `json:"id"` Name string `json:"name"` Path string `json:"path"` } @@ -25,7 +26,7 @@ type request struct { Action string `json:"action"` Settings settings `json:"settings"` File string `json:"file"` - Store string `json:"store"` + StoreID string `json:"storeId"` EchoResponse interface{} `json:"echoResponse"` } diff --git a/request/process_test.go b/request/process_test.go index 8763079..dddac77 100644 --- a/request/process_test.go +++ b/request/process_test.go @@ -49,7 +49,8 @@ func Test_ParseRequest_CanParse(t *testing.T) { Action: "list", Settings: settings{ Stores: map[string]store{ - "default": store{ + "id1": store{ + ID: "id1", Name: "default", Path: "~/.password-store", },