Files
browserpass-native/request/process.go

103 lines
2.6 KiB
Go

package request
import (
"encoding/binary"
"encoding/json"
"io"
"os"
"github.com/browserpass/browserpass-native/errors"
"github.com/browserpass/browserpass-native/response"
log "github.com/sirupsen/logrus"
)
type StoreSettings struct {
GpgPath string `json:"gpgPath"`
}
type store struct {
ID string `json:"id"`
Name string `json:"name"`
Path string `json:"path"`
Settings StoreSettings `json:"settings"`
}
type settings struct {
GpgPath string `json:"gpgPath"`
Stores map[string]store `json:"stores"`
}
type request struct {
Action string `json:"action"`
Settings settings `json:"settings"`
File string `json:"file"`
StoreID string `json:"storeId"`
EchoResponse interface{} `json:"echoResponse"`
}
// Process handles browser request
func Process() {
requestLength, err := parseRequestLength(os.Stdin)
if err != nil {
log.Error("Unable to parse the length of the browser request: ", err)
response.SendErrorAndExit(
errors.CodeParseRequestLength,
&map[errors.Field]string{
errors.FieldMessage: "Unable to parse the length of the browser request",
errors.FieldError: err.Error(),
},
)
}
request, err := parseRequest(requestLength, os.Stdin)
if err != nil {
log.Error("Unable to parse the browser request: ", err)
response.SendErrorAndExit(
errors.CodeParseRequest,
&map[errors.Field]string{
errors.FieldMessage: "Unable to parse the browser request",
errors.FieldError: err.Error(),
},
)
}
switch request.Action {
case "configure":
configure(request)
case "list":
listFiles(request)
case "fetch":
fetchDecryptedContents(request)
case "echo":
response.SendRaw(request.EchoResponse)
default:
log.Errorf("Received a browser request with an unknown action: %+v", request)
response.SendErrorAndExit(
errors.CodeInvalidRequestAction,
&map[errors.Field]string{
errors.FieldMessage: "Invalid request action",
errors.FieldAction: request.Action,
},
)
}
}
// Request length is the first 4 bytes in LittleEndian encoding
func parseRequestLength(input io.Reader) (uint32, error) {
var length uint32
if err := binary.Read(input, binary.LittleEndian, &length); err != nil {
return 0, err
}
return length, nil
}
// Request is a json with a predefined structure
func parseRequest(messageLength uint32, input io.Reader) (*request, error) {
var parsed request
reader := &io.LimitedReader{R: input, N: int64(messageLength)}
if err := json.NewDecoder(reader).Decode(&parsed); err != nil {
return nil, err
}
return &parsed, nil
}