Implement list action (#12)

This commit is contained in:
Maxim Baz
2018-04-16 01:38:55 +02:00
committed by GitHub
parent 66850cfa4a
commit bd6ab67d3a
8 changed files with 120 additions and 18 deletions

11
Gopkg.lock generated
View File

@@ -1,6 +1,15 @@
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
[[projects]]
branch = "master"
name = "github.com/mattn/go-zglob"
packages = [
".",
"fastwalk"
]
revision = "4959821b481786922ac53e7ef25c61ae19fb7c36"
[[projects]]
name = "github.com/rifflock/lfshook"
packages = ["."]
@@ -34,6 +43,6 @@
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "f6199a143c790c5c1422bd35477ede08e5d2e3a0e5552d769e7c4de6ed8a14b1"
inputs-digest = "1f59ddaed2db7de2b34f8485550888fa1cb625342398af10acb68e5ee227f3f8"
solver-name = "gps-cdcl"
solver-version = 1

View File

@@ -27,3 +27,7 @@
[[constraint]]
name = "github.com/rifflock/lfshook"
version = "2.3.0"
[[constraint]]
branch = "master"
name = "github.com/mattn/go-zglob"

View File

@@ -41,16 +41,18 @@ should be supplied as a `message` parameter.
## List of Error Codes
| Code | Description | Parameters |
| ---- | ----------------------------------------------------------------------- | ----------------- |
| 10 | Unable to parse browser request length | error |
| 11 | Unable to parse browser request | error |
| 12 | Invalid request action | action |
| 13 | Inaccessible user-configured password store | error, name, path |
| 14 | Inaccessible default password store | error, path |
| 15 | Unable to determine the location of the default password store | error |
| 16 | Unable to read the default settings of a user-configured password store | error, name, path |
| 17 | Unable to read the default settings of the default password store | error, path |
| Code | Description | Parameters |
| ---- | ----------------------------------------------------------------------- | ----------------------- |
| 10 | Unable to parse browser request length | error |
| 11 | Unable to parse browser request | error |
| 12 | Invalid request action | action |
| 13 | Inaccessible user-configured password store | error, name, path |
| 14 | Inaccessible default password store | error, path |
| 15 | Unable to determine the location of the default password store | error |
| 16 | Unable to read the default settings of a user-configured password store | error, name, path |
| 17 | Unable to read the default settings of the default password store | error, path |
| 18 | Unable to list files in a password store | error, name, path |
| 19 | Unable to determine a relative path for a file in a password store | error, file, name, path |
## Settings
@@ -171,7 +173,7 @@ Get the decrypted contents of a specific file.
"status": "ok",
"version": <int>,
"data": {
"data": "<decrypted file contents>"
"contents": "<decrypted file contents>"
}
}
```

View File

@@ -33,6 +33,12 @@ const (
// CodeUnreadableDefaultPasswordStoreDefaultSettings error reading the default settings of the default password store
CodeUnreadableDefaultPasswordStoreDefaultSettings = 17
// CodeUnableToListFilesInPasswordStore error listing files in a password store
CodeUnableToListFilesInPasswordStore = 18
// CodeUnableToDetermineRelativeFilePathInPasswordStore error determining a relative path for a file in a password store
CodeUnableToDetermineRelativeFilePathInPasswordStore = 19
)
// ExitWithCode exit with error code

View File

@@ -16,7 +16,7 @@ function require()
if ! `command -v "$1" >/dev/null`; then
OUTPUT="{\n \"status\": \"error\"\n "version": $VERSION,\n \"params\": {\n \"message\": \"Required dependency '$1' is missing\"\n }, \"code\": 1\n}"
LANG=C LC_ALL=C LENGTH=${#OUTPUT}
echo -n
echo -n
exit 1
fi
}
@@ -94,11 +94,11 @@ function configure()
done
[ -n "$PASSWORD_STORE_DIR" ] || PASSWORD_STORE_DIR="~/.password-store"
OUTPUT="$(jq -n --arg defaultPath "$PASSWORD_STORE_DIR" '.defaultPath = $defaultPath')"
OUTPUT="$(jq -n --arg defaultPath "$PASSWORD_STORE_DIR" '.defaultStore.path = $defaultPath')"
STOREPATH=$(echo "$PASSWORD_STORE_DIR" | sed 's/^~/$HOME/' | envsubst)
if [ -f "$STOREPATH/.browserpass.json" ]; then
OUTPUT=$(jq --arg settings "$(cat "$STOREPATH/.browserpass.json")" '.defaultSettings = $settings' <<< "$OUTPUT")
OUTPUT=$(jq --arg settings "$(cat "$STOREPATH/.browserpass.json")" '.defaultStore.settings = $settings' <<< "$OUTPUT")
else
OUTPUT=$(jq '.defaultSettings = ""' <<< "$OUTPUT")
fi
@@ -153,9 +153,9 @@ function fetch()
# get file contents
[ -f "$FILEPATH" ] || fail "Requested file does not exist: $STORE:$FILE"
DATA="$(gpg -q --decrypt "$FILEPATH")"
# build output
echo "$(jq -n --arg data "$DATA" '.data = $data')"
echo "$(jq -n --arg data "$DATA" '.contents = $data')"
}
function run()

69
request/list.go Normal file
View File

@@ -0,0 +1,69 @@
package request
import (
"path/filepath"
"sort"
"github.com/browserpass/browserpass-native/errors"
"github.com/browserpass/browserpass-native/response"
"github.com/mattn/go-zglob"
log "github.com/sirupsen/logrus"
)
func listFiles(request request) {
responseData := response.MakeListResponse()
for _, store := range request.Settings.Stores {
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,
)
response.SendError(
errors.CodeInaccessiblePasswordStore,
"The password store is not accessible",
&map[string]string{"error": err.Error(), "name": store.Name, "path": store.Path},
)
errors.ExitWithCode(errors.CodeInaccessiblePasswordStore)
}
store.Path = normalizedStorePath
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,
)
response.SendError(
errors.CodeUnableToListFilesInPasswordStore,
"Unable to list the files in the password store",
&map[string]string{"error": err.Error(), "name": store.Name, "path": store.Path},
)
errors.ExitWithCode(errors.CodeUnableToListFilesInPasswordStore)
}
for i, file := range files {
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,
)
response.SendError(
errors.CodeUnableToDetermineRelativeFilePathInPasswordStore,
"Unable to determine the relative path for a file in the password store",
&map[string]string{"error": err.Error(), "file": file, "name": store.Name, "path": store.Path},
)
errors.ExitWithCode(errors.CodeUnableToDetermineRelativeFilePathInPasswordStore)
}
files[i] = relativePath
}
sort.Strings(files)
responseData.Files[store.Name] = files
}
response.SendOk(responseData)
}

View File

@@ -31,7 +31,7 @@ func Process() {
case "configure":
configure(request)
case "list":
break
listFiles(request)
case "fetch":
break
default:

View File

@@ -40,6 +40,18 @@ func MakeConfigureResponse() *ConfigureResponse {
}
}
// ListResponse a response format for the "list" request
type ListResponse struct {
Files map[string][]string `json:"files"`
}
// MakeListResponse initializes an empty list response
func MakeListResponse() *ListResponse {
return &ListResponse{
Files: make(map[string][]string),
}
}
// SendOk sends a success response to the browser extension in the predefined json format
func SendOk(data interface{}) {
send(&okResponse{