From f4dec10e8f097e79b4bba3187431ecf3c4899083 Mon Sep 17 00:00:00 2001 From: ale <ale@incal.net> Date: Fri, 6 Dec 2019 10:49:33 +0000 Subject: [PATCH] Use a response field instead of a 404 when no keys are found This makes it easier to detect unexpected errors. --- client/client.go | 15 ++++++++++++--- protocol.go | 3 ++- server/server.go | 14 +++++++++----- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/client/client.go b/client/client.go index 307f3eeb..5ffa3951 100644 --- a/client/client.go +++ b/client/client.go @@ -2,12 +2,16 @@ package client import ( "context" + "errors" "git.autistici.org/ai3/go-common/clientutil" "git.autistici.org/id/keystore" ) +// ErrNoKeys indicates that the user has no encryption keys. +var ErrNoKeys = errors.New("no keys available") + // Client for the keystore API. type Client interface { Open(context.Context, string, string, string, int) error @@ -19,9 +23,8 @@ type ksClient struct { be clientutil.Backend } -// New returns a new Client with the given Config. Use this when the -// keystore service runs on a single global instance. -func New(config *clientutil.BackendConfig) (*ksClient, error) { +// New returns a new Client with the given backend Config. +func New(config *clientutil.BackendConfig) (Client, error) { be, err := clientutil.NewBackend(config) if err != nil { return nil, err @@ -46,6 +49,12 @@ func (c *ksClient) Get(ctx context.Context, shard, username, ssoTicket string) ( } var resp keystore.GetResponse err := c.be.Call(ctx, shard, "/api/get_key", &req, &resp) + if err != nil { + return nil, err + } + if !resp.HasKey { + return nil, ErrNoKeys + } return resp.Key, err } diff --git a/protocol.go b/protocol.go index 0e65499f..fc6113e3 100644 --- a/protocol.go +++ b/protocol.go @@ -14,7 +14,8 @@ type GetRequest struct { } type GetResponse struct { - Key []byte `json:"key"` + HasKey bool `json:"has_key"` + Key []byte `json:"key"` } type CloseRequest struct { diff --git a/server/server.go b/server/server.go index ba17efd1..71a3eb22 100644 --- a/server/server.go +++ b/server/server.go @@ -41,22 +41,26 @@ func (s *keyStoreServer) handleGet(w http.ResponseWriter, r *http.Request) { return } + var resp keystore.GetResponse key, err := s.KeyStore.Get(req.Username, req.SSOTicket) - if err != nil { - log.Printf("Get(%s) error: %v", req.Username, err) + if err == errNoKeys { + log.Printf("no keys for %s", req.Username) + } else if err != nil { // Return an appropriate error code. switch err { case errUnauthorized, errBadUser: http.Error(w, err.Error(), http.StatusForbidden) - case errNoKeys: - http.NotFound(w, r) default: + log.Printf("Get(%s) error: %v", req.Username, err) http.Error(w, err.Error(), http.StatusInternalServerError) } return + } else { + resp.HasKey = true + resp.Key = key } - serverutil.EncodeJSONResponse(w, &keystore.GetResponse{Key: key}) + serverutil.EncodeJSONResponse(w, &resp) } func (s *keyStoreServer) handleClose(w http.ResponseWriter, r *http.Request) { -- GitLab