Skip to content

Commit 66a94d4

Browse files
authored
Merge pull request #148 from janhoon/master
2 parents 4a74dcc + a020d51 commit 66a94d4

File tree

3 files changed

+127
-21
lines changed

3 files changed

+127
-21
lines changed

ginoauth2.go

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ import (
6464
"time"
6565

6666
"github.com/gin-gonic/gin"
67-
"github.com/golang/glog"
6867
"golang.org/x/oauth2"
6968
)
7069

@@ -102,26 +101,6 @@ func maskAccessToken(a interface{}) string {
102101
return s
103102
}
104103

105-
func logf(l func(string, ...interface{}), f string, args ...interface{}) {
106-
for i := range args {
107-
args[i] = maskAccessToken(args[i])
108-
}
109-
110-
l(f, args...)
111-
}
112-
113-
func errorf(f string, args ...interface{}) {
114-
logf(glog.Errorf, f, args...)
115-
}
116-
117-
func infof(f string, args ...interface{}) {
118-
logf(glog.Infof, f, args...)
119-
}
120-
121-
func infofv2(f string, args ...interface{}) {
122-
logf(glog.V(2).Infof, f, args...)
123-
}
124-
125104
func extractToken(r *http.Request) (*oauth2.Token, error) {
126105
hdr := r.Header.Get("Authorization")
127106
if hdr == "" {

logging.go

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package ginoauth2
2+
3+
import (
4+
"fmt"
5+
"io"
6+
"os"
7+
8+
"github.com/golang/glog"
9+
)
10+
11+
// Logger is the interface used by GinOAuth2 to log messages.
12+
type Logger interface {
13+
Errorf(format string, args ...interface{})
14+
Infof(format string, args ...interface{})
15+
Debugf(format string, args ...interface{})
16+
}
17+
18+
type glogLogger struct {
19+
output io.Writer
20+
}
21+
22+
// DefaultLogger is the default logger used by GinOAuth2 if no other logger is provided.
23+
// To use a different logger, set the DefaultLogger variable to a logger of your choice.
24+
// Replacement loggers must implement the Logger interface.
25+
//
26+
// Example:
27+
//
28+
// import "github.com/zalando/gin-oauth2"
29+
//
30+
// ginoauth2.DefaultLogger = &logrusLogger{} // use logrus
31+
var DefaultLogger Logger = &glogLogger{output: os.Stderr}
32+
33+
func maskLogArgs(args ...interface{}) []interface{} {
34+
for i := range args {
35+
args[i] = maskAccessToken(args[i])
36+
}
37+
38+
return args
39+
}
40+
41+
// SetOutput sets the output destination for the logger
42+
func (gl *glogLogger) setOutput(w io.Writer) {
43+
gl.output = w
44+
}
45+
46+
// Errorf is a logging function using glog.Errorf
47+
func (gl *glogLogger) Errorf(f string, args ...interface{}) {
48+
glog.ErrorDepth(1, fmt.Sprintf(f, args...))
49+
if gl.output != nil {
50+
fmt.Fprintf(gl.output, f+"\n", args...)
51+
}
52+
}
53+
54+
// Infof is a logging function using glog.Infof
55+
func (gl *glogLogger) Infof(f string, args ...interface{}) {
56+
glog.InfoDepth(1, fmt.Sprintf(f, args...))
57+
if gl.output != nil {
58+
fmt.Fprintf(gl.output, f+"\n", args...)
59+
}
60+
}
61+
62+
// Debugf is a verbose logging function using glog.V(2)
63+
func (gl *glogLogger) Debugf(f string, args ...interface{}) {
64+
if glog.V(2) {
65+
glog.InfoDepth(1, fmt.Sprintf(f, args...))
66+
}
67+
if gl.output != nil {
68+
fmt.Fprintf(gl.output, f+"\n", args...)
69+
}
70+
}
71+
72+
func errorf(f string, args ...interface{}) {
73+
DefaultLogger.Errorf(f, maskLogArgs(args...)...)
74+
}
75+
76+
func infof(f string, args ...interface{}) {
77+
DefaultLogger.Infof(f, maskLogArgs(args...)...)
78+
}
79+
80+
func infofv2(f string, args ...interface{}) {
81+
DefaultLogger.Debugf(f, maskLogArgs(args...)...)
82+
}

logging_test.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package ginoauth2
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
"strings"
7+
"testing"
8+
)
9+
10+
type mockLogger struct{ buffer bytes.Buffer }
11+
12+
func (m *mockLogger) Errorf(format string, args ...interface{}) {
13+
m.buffer.WriteString(fmt.Sprintf("ERROR: "+format, args...))
14+
}
15+
func (m *mockLogger) Infof(format string, args ...interface{}) {
16+
m.buffer.WriteString(fmt.Sprintf("INFO: "+format, args...))
17+
}
18+
func (m *mockLogger) Debugf(format string, args ...interface{}) {
19+
m.buffer.WriteString(fmt.Sprintf("DEBUG: "+format, args...))
20+
}
21+
22+
func TestLogWithMaskedAccessToken(t *testing.T) {
23+
mockLog := &mockLogger{}
24+
DefaultLogger = mockLog
25+
tests := []struct{ name, input, expected string }{
26+
{"With access token", "&access_token=abcdefghijklmnop&", "INFO: <MASK>&"},
27+
{"Without access token", "no_token_here", "INFO: no_token_here"},
28+
{"Empty string", "", "INFO: "},
29+
}
30+
for _, tt := range tests {
31+
t.Run(tt.name, func(t *testing.T) {
32+
mockLog.buffer.Reset()
33+
34+
infof("%s", tt.input)
35+
36+
logOutput := mockLog.buffer.String()
37+
if logOutput != tt.expected {
38+
t.Errorf("Expected log to contain %q, got %q", tt.expected, logOutput)
39+
}
40+
if strings.Contains(logOutput, "abcdefghijklmnop") {
41+
t.Errorf("Log should not contain the original token")
42+
}
43+
})
44+
}
45+
}

0 commit comments

Comments
 (0)