Skip to content

Commit

Permalink
Add logging to the YoPass server
Browse files Browse the repository at this point in the history
This adds a logger, and it's usage to the YoPass server.
This should help with issue #1075
  • Loading branch information
boekkooi-lengoo committed Oct 2, 2021
1 parent 9634274 commit 1354745
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 13 deletions.
2 changes: 1 addition & 1 deletion cmd/yopass-server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func main() {
go func() {
addr := fmt.Sprintf("%s:%d", viper.GetString("address"), viper.GetInt("port"))
logger.Info("Starting yopass server", zap.String("address", addr))
y := server.New(db, viper.GetInt("max-length"), registry, viper.GetBool("force-onetime-secrets"))
y := server.New(db, viper.GetInt("max-length"), registry, viper.GetBool("force-onetime-secrets"), logger)
errc <- listenAndServe(addr, y.HTTPHandler(), cert, key)
}()

Expand Down
31 changes: 26 additions & 5 deletions pkg/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/gorilla/mux"
"github.com/jhaals/yopass/pkg/yopass"
"github.com/prometheus/client_golang/prometheus"
"go.uber.org/zap"
)

// Server struct holding database and settings.
Expand All @@ -22,15 +23,20 @@ type Server struct {
maxLength int
registry *prometheus.Registry
forceOneTimeSecrets bool
logger *zap.Logger
}

// New is the main way of creating the server.
func New(db Database, maxLength int, r *prometheus.Registry, forceOneTimeSecrets bool) Server {
func New(db Database, maxLength int, r *prometheus.Registry, forceOneTimeSecrets bool, logger *zap.Logger) Server {
if logger == nil {
logger = zap.NewNop()
}
return Server{
db: db,
maxLength: maxLength,
registry: r,
forceOneTimeSecrets: forceOneTimeSecrets,
logger: logger,
}
}

Expand All @@ -41,6 +47,7 @@ func (y *Server) createSecret(w http.ResponseWriter, request *http.Request) {
decoder := json.NewDecoder(request.Body)
var s yopass.Secret
if err := decoder.Decode(&s); err != nil {
y.logger.Debug("Unable to decode request", zap.Error(err))
http.Error(w, `{"message": "Unable to parse json"}`, http.StatusBadRequest)
return
}
Expand All @@ -63,38 +70,52 @@ func (y *Server) createSecret(w http.ResponseWriter, request *http.Request) {
// Generate new UUID
uuidVal, err := uuid.NewV4()
if err != nil {
y.logger.Error("Unable to generate UUID", zap.Error(err))
http.Error(w, `{"message": "Unable to generate UUID"}`, http.StatusInternalServerError)
return
}
key := uuidVal.String()

// store secret in memcache with specified expiration.
if err := y.db.Put(key, s); err != nil {
y.logger.Error("Unable to store secret", zap.Error(err))
http.Error(w, `{"message": "Failed to store secret in database"}`, http.StatusInternalServerError)
return
}

resp := map[string]string{"message": key}
jsonData, _ := json.Marshal(resp)
w.Write(jsonData)
jsonData, err := json.Marshal(resp)
if err != nil {
y.logger.Error("Failed to marshal create secret response", zap.Error(err), zap.String("key", key))
}

if _, err = w.Write(jsonData); err != nil {
y.logger.Error("Failed to write response", zap.Error(err), zap.String("key", key))
}
}

// getSecret from database
func (y *Server) getSecret(w http.ResponseWriter, request *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")

secret, err := y.db.Get(mux.Vars(request)["key"])
secretKey := mux.Vars(request)["key"]
secret, err := y.db.Get(secretKey)
if err != nil {
y.logger.Debug("Secret not found", zap.Error(err), zap.String("key", secretKey))
http.Error(w, `{"message": "Secret not found"}`, http.StatusNotFound)
return
}

data, err := secret.ToJSON()
if err != nil {
y.logger.Error("Failed to encode request", zap.Error(err), zap.String("key", secretKey))
http.Error(w, `{"message": "Failed to encode secret"}`, http.StatusInternalServerError)
return
}
w.Write(data)

if _, err := w.Write(data); err != nil {
y.logger.Error("Failed to write response", zap.Error(err), zap.String("key", secretKey))
}
}

// HTTPHandler containing all routes
Expand Down
11 changes: 6 additions & 5 deletions pkg/server/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/jhaals/yopass/pkg/yopass"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/testutil"
"go.uber.org/zap/zaptest"
)

type mockDB struct{}
Expand Down Expand Up @@ -103,7 +104,7 @@ func TestCreateSecret(t *testing.T) {
t.Run(fmt.Sprintf(tc.name), func(t *testing.T) {
req, _ := http.NewRequest("POST", "/secret", tc.body)
rr := httptest.NewRecorder()
y := New(tc.db, tc.maxLength, prometheus.NewRegistry(), false)
y := New(tc.db, tc.maxLength, prometheus.NewRegistry(), false, zaptest.NewLogger(t))
y.createSecret(rr, req)
var s yopass.Secret
json.Unmarshal(rr.Body.Bytes(), &s)
Expand Down Expand Up @@ -160,7 +161,7 @@ func TestOneTimeEnforcement(t *testing.T) {
t.Run(fmt.Sprintf(tc.name), func(t *testing.T) {
req, _ := http.NewRequest("POST", "/secret", tc.body)
rr := httptest.NewRecorder()
y := New(&mockDB{}, 100, prometheus.NewRegistry(), tc.requireOneTime)
y := New(&mockDB{}, 100, prometheus.NewRegistry(), tc.requireOneTime, zaptest.NewLogger(t))
y.createSecret(rr, req)
var s yopass.Secret
json.Unmarshal(rr.Body.Bytes(), &s)
Expand Down Expand Up @@ -204,7 +205,7 @@ func TestGetSecret(t *testing.T) {
t.Fatal(err)
}
rr := httptest.NewRecorder()
y := New(tc.db, 1, prometheus.NewRegistry(), false)
y := New(tc.db, 1, prometheus.NewRegistry(), false, zaptest.NewLogger(t))
y.getSecret(rr, req)
var s yopass.Secret
json.Unmarshal(rr.Body.Bytes(), &s)
Expand Down Expand Up @@ -232,7 +233,7 @@ func TestMetrics(t *testing.T) {
path: "/secret/invalid-key-format",
},
}
y := New(&mockDB{}, 1, prometheus.NewRegistry(), false)
y := New(&mockDB{}, 1, prometheus.NewRegistry(), false, zaptest.NewLogger(t))
h := y.HTTPHandler()

for _, r := range requests {
Expand Down Expand Up @@ -305,7 +306,7 @@ func TestSecurityHeaders(t *testing.T) {
},
}

y := New(&mockDB{}, 1, prometheus.NewRegistry(), false)
y := New(&mockDB{}, 1, prometheus.NewRegistry(), false, zaptest.NewLogger(t))
h := y.HTTPHandler()

t.Parallel()
Expand Down
5 changes: 3 additions & 2 deletions pkg/yopass/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package yopass_test
import (
"errors"
"fmt"
"go.uber.org/zap/zaptest"
"net/http/httptest"
"testing"

Expand All @@ -13,7 +14,7 @@ import (

func TestFetch(t *testing.T) {
db := testDB(map[string]string{})
y := server.New(&db, 1024, prometheus.NewRegistry(), false)
y := server.New(&db, 1024, prometheus.NewRegistry(), false, zaptest.NewLogger(t))
ts := httptest.NewServer(y.HTTPHandler())
defer ts.Close()

Expand Down Expand Up @@ -45,7 +46,7 @@ func TestFetchInvalidServer(t *testing.T) {
}
func TestStore(t *testing.T) {
db := testDB(map[string]string{})
y := server.New(&db, 1024, prometheus.NewRegistry(), false)
y := server.New(&db, 1024, prometheus.NewRegistry(), false, zaptest.NewLogger(t))
ts := httptest.NewServer(y.HTTPHandler())
defer ts.Close()

Expand Down

0 comments on commit 1354745

Please sign in to comment.