From 53c40f694e761f63c93c031107b546089df0d152 Mon Sep 17 00:00:00 2001 From: Brad Rydzewski Date: Thu, 24 Jan 2019 13:01:23 -0800 Subject: [PATCH] add oauth2 logger --- login/internal/oauth2/config.go | 6 +++++ login/internal/oauth2/handler.go | 14 +++++++++- login/logger/logger.go | 45 ++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 login/logger/logger.go diff --git a/login/internal/oauth2/config.go b/login/internal/oauth2/config.go index c6c1ac3..fab40a0 100644 --- a/login/internal/oauth2/config.go +++ b/login/internal/oauth2/config.go @@ -9,6 +9,8 @@ import ( "net/http" "net/url" "strings" + + "github.com/drone/go-login/login/logger" ) // token stores the authorization credentials used to @@ -53,6 +55,10 @@ type Config struct { // the authorization header and provide the client_id // and client_secret in the formdata. BasicAuthOff bool + + // Logger is used to log errors. If nil the provider + // use the default noop logger. + Logger logger.Logger } // authorizeRedirect returns a client authorization diff --git a/login/internal/oauth2/handler.go b/login/internal/oauth2/handler.go index 75ee8ba..f420f84 100644 --- a/login/internal/oauth2/handler.go +++ b/login/internal/oauth2/handler.go @@ -10,17 +10,19 @@ import ( "time" "github.com/drone/go-login/login" + "github.com/drone/go-login/login/logger" ) // Handler returns a Handler that runs h at the completion // of the oauth2 authorization flow. func Handler(h http.Handler, c *Config) http.Handler { - return &handler{next: h, conf: c} + return &handler{next: h, conf: c, logs: c.Logger} } type handler struct { conf *Config next http.Handler + logs logger.Logger } func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { @@ -30,6 +32,7 @@ func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // If non-empty, write to the context and proceed with // the next http.Handler in the chain. if erro := r.FormValue("error"); erro != "" { + h.logger().Errorf("oauth: authorization error: %s", erro) ctx = login.WithError(ctx, errors.New(erro)) h.next.ServeHTTP(w, r.WithContext(ctx)) return @@ -50,6 +53,7 @@ func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { state := r.FormValue("state") deleteState(w) if err := validateState(r, state); err != nil { + h.logger().Errorln("oauth: invalid or missing state") ctx = login.WithError(ctx, err) h.next.ServeHTTP(w, r.WithContext(ctx)) return @@ -61,6 +65,7 @@ func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // next http.Handler in the chain. source, err := h.conf.exchange(code, state) if err != nil { + h.logger().Errorf("oauth: cannot exchange code: %s: %s", code, err) ctx = login.WithError(ctx, err) h.next.ServeHTTP(w, r.WithContext(ctx)) return @@ -78,3 +83,10 @@ func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { h.next.ServeHTTP(w, r.WithContext(ctx)) } + +func (h *handler) logger() logger.Logger { + if h.logs == nil { + return logger.Discard() + } + return h.logs +} diff --git a/login/logger/logger.go b/login/logger/logger.go new file mode 100644 index 0000000..00fe175 --- /dev/null +++ b/login/logger/logger.go @@ -0,0 +1,45 @@ +// Copyright 2017 Drone.IO Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package logger + +// A Logger represents an active logging object that generates +// lines of output to an io.Writer. +type Logger interface { + Debug(args ...interface{}) + Debugf(format string, args ...interface{}) + Debugln(args ...interface{}) + + Error(args ...interface{}) + Errorf(format string, args ...interface{}) + Errorln(args ...interface{}) + + Info(args ...interface{}) + Infof(format string, args ...interface{}) + Infoln(args ...interface{}) + + Warn(args ...interface{}) + Warnf(format string, args ...interface{}) + Warnln(args ...interface{}) +} + +// Discard returns a no-op logger +func Discard() Logger { + return &discard{} +} + +type discard struct{} + +func (*discard) Debug(args ...interface{}) {} +func (*discard) Debugf(format string, args ...interface{}) {} +func (*discard) Debugln(args ...interface{}) {} +func (*discard) Error(args ...interface{}) {} +func (*discard) Errorf(format string, args ...interface{}) {} +func (*discard) Errorln(args ...interface{}) {} +func (*discard) Info(args ...interface{}) {} +func (*discard) Infof(format string, args ...interface{}) {} +func (*discard) Infoln(args ...interface{}) {} +func (*discard) Warn(args ...interface{}) {} +func (*discard) Warnf(format string, args ...interface{}) {} +func (*discard) Warnln(args ...interface{}) {}