Skip to content

Commit d38277f

Browse files
committed
made smarter logging of authentication context
1 parent ccc32e4 commit d38277f

File tree

3 files changed

+50
-31
lines changed

3 files changed

+50
-31
lines changed

coderd/database/dbauthz/dbauthz.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ func As(ctx context.Context, actor rbac.Subject) context.Context {
476476

477477
func InjectActorToContext(ctx context.Context, actor rbac.Subject) context.Context {
478478
if rlogger := loggermw.RequestLoggerFromContext(ctx); rlogger != nil {
479-
rlogger.WithAuthContext(actor.ID, actor.FriendlyName, actor.Email)
479+
rlogger.WithAuthContext(actor.ID, actor.FriendlyName, actor.Email, actor.Type)
480480
}
481481
return context.WithValue(ctx, authContextKey{}, actor)
482482
}

coderd/httpmw/loggermw/logger.go

Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88

99
"cdr.dev/slog"
1010
"github.com/coder/coder/v2/coderd/httpapi"
11+
"github.com/coder/coder/v2/coderd/rbac"
1112
"github.com/coder/coder/v2/coderd/tracing"
1213
)
1314

@@ -62,48 +63,60 @@ func Logger(log slog.Logger) func(next http.Handler) http.Handler {
6263
type RequestLogger interface {
6364
WithFields(fields ...slog.Field)
6465
WriteLog(ctx context.Context, status int)
65-
WithAuthContext(id string, name string, email string)
66+
WithAuthContext(id string, name string, email string, subjectType rbac.SubjectType)
6667
}
6768

6869
type SlogRequestLogger struct {
69-
log slog.Logger
70-
written bool
71-
message string
72-
authCtxPresent bool
73-
start time.Time
70+
log slog.Logger
71+
written bool
72+
message string
73+
start time.Time
74+
authCtx map[rbac.SubjectType]authContext
75+
}
76+
77+
type authContext struct {
78+
id string
79+
name string
80+
email string
81+
subjectType rbac.SubjectType
7482
}
7583

7684
var _ RequestLogger = &SlogRequestLogger{}
7785

7886
func NewRequestLogger(log slog.Logger, message string, start time.Time) RequestLogger {
7987
return &SlogRequestLogger{
80-
log: log,
81-
written: false,
82-
message: message,
83-
start: start,
84-
authCtxPresent: false,
88+
log: log,
89+
written: false,
90+
message: message,
91+
start: start,
92+
authCtx: make(map[rbac.SubjectType]authContext),
8593
}
8694
}
8795

8896
func (c *SlogRequestLogger) WithFields(fields ...slog.Field) {
8997
c.log = c.log.With(fields...)
9098
}
9199

92-
func (c *SlogRequestLogger) WithAuthContext(id string, name string, email string) {
93-
// If the email is empty, we don't want to log the requestor context,
94-
// because it's an elevated privilege.
95-
if email == "" || id == "" {
96-
return
97-
}
98-
if c.authCtxPresent {
99-
return
100+
func (c *SlogRequestLogger) WithAuthContext(id string, name string, email string, subjectType rbac.SubjectType) {
101+
c.authCtx[subjectType] = authContext{id, name, email, subjectType}
102+
}
103+
104+
func (c *SlogRequestLogger) addAuthContextFields() {
105+
usr, ok := c.authCtx[rbac.SubjectTypeUser]
106+
if ok {
107+
c.log = c.log.With(
108+
slog.F("requestor_id", usr.id),
109+
slog.F("requestor_name", usr.name),
110+
slog.F("requestor_email", usr.email),
111+
)
112+
} else if len(c.authCtx) > 0 {
113+
for _, v := range c.authCtx {
114+
c.log = c.log.With(
115+
slog.F("requestor_name", v.name),
116+
)
117+
break
118+
}
100119
}
101-
c.authCtxPresent = true
102-
c.log = c.log.With(
103-
slog.F("requestor_id", id),
104-
slog.F("requestor_name", name),
105-
slog.F("requestor_email", email),
106-
)
107120
}
108121

109122
func (c *SlogRequestLogger) WriteLog(ctx context.Context, status int) {
@@ -113,11 +126,16 @@ func (c *SlogRequestLogger) WriteLog(ctx context.Context, status int) {
113126
c.written = true
114127
end := time.Now()
115128

129+
// Right before we write the log, we try to find the user in the authCtx
130+
// and add the fields to the log.
131+
c.addAuthContextFields()
132+
116133
logger := c.log.With(
117134
slog.F("took", end.Sub(c.start)),
118135
slog.F("status_code", status),
119136
slog.F("latency_ms", float64(end.Sub(c.start)/time.Millisecond)),
120137
)
138+
121139
// We already capture most of this information in the span (minus
122140
// the response body which we don't want to capture anyways).
123141
tracing.RunWithoutSpan(ctx, func(ctx context.Context) {

coderd/httpmw/loggermw/loggermock/loggermock.go

Lines changed: 6 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)