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 ...@@ -2,12 +2,16 @@ package client
import ( import (
"context" "context"
"errors"
"git.autistici.org/ai3/go-common/clientutil" "git.autistici.org/ai3/go-common/clientutil"
"git.autistici.org/id/keystore" "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. // Client for the keystore API.
type Client interface { type Client interface {
Open(context.Context, string, string, string, int) error Open(context.Context, string, string, string, int) error
...@@ -19,9 +23,8 @@ type ksClient struct { ...@@ -19,9 +23,8 @@ type ksClient struct {
be clientutil.Backend be clientutil.Backend
} }
// New returns a new Client with the given Config. Use this when the // New returns a new Client with the given backend Config.
// keystore service runs on a single global instance. func New(config *clientutil.BackendConfig) (Client, error) {
func New(config *clientutil.BackendConfig) (*ksClient, error) {
be, err := clientutil.NewBackend(config) be, err := clientutil.NewBackend(config)
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -46,6 +49,12 @@ func (c *ksClient) Get(ctx context.Context, shard, username, ssoTicket string) ( ...@@ -46,6 +49,12 @@ func (c *ksClient) Get(ctx context.Context, shard, username, ssoTicket string) (
} }
var resp keystore.GetResponse var resp keystore.GetResponse
err := c.be.Call(ctx, shard, "/api/get_key", &req, &resp) 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 return resp.Key, err
} }
......
...@@ -14,7 +14,8 @@ type GetRequest struct { ...@@ -14,7 +14,8 @@ type GetRequest struct {
} }
type GetResponse struct { type GetResponse struct {
Key []byte `json:"key"` HasKey bool `json:"has_key"`
Key []byte `json:"key"`
} }
type CloseRequest struct { type CloseRequest struct {
......
...@@ -41,22 +41,26 @@ func (s *keyStoreServer) handleGet(w http.ResponseWriter, r *http.Request) { ...@@ -41,22 +41,26 @@ func (s *keyStoreServer) handleGet(w http.ResponseWriter, r *http.Request) {
return return
} }
var resp keystore.GetResponse
key, err := s.KeyStore.Get(req.Username, req.SSOTicket) key, err := s.KeyStore.Get(req.Username, req.SSOTicket)
if err != nil { if err == errNoKeys {
log.Printf("Get(%s) error: %v", req.Username, err) log.Printf("no keys for %s", req.Username)
} else if err != nil {
// Return an appropriate error code. // Return an appropriate error code.
switch err { switch err {
case errUnauthorized, errBadUser: case errUnauthorized, errBadUser:
http.Error(w, err.Error(), http.StatusForbidden) http.Error(w, err.Error(), http.StatusForbidden)
case errNoKeys:
http.NotFound(w, r)
default: default:
log.Printf("Get(%s) error: %v", req.Username, err)
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
} }
return 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) { 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