Commit f4dec10e authored by ale's avatar ale

Use a response field instead of a 404 when no keys are found

This makes it easier to detect unexpected errors.
parent 9f1f2da0
......@@ -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
}
......
......@@ -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 {
......
......@@ -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) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment