mirror of
https://github.com/fleetdm/fleet
synced 2026-05-06 06:48:54 +00:00
Add logging to capture user email upon successful login (#7927)
* Log user email upon successful login * Add user email to logger context * Use logging.With Extras for login email
This commit is contained in:
parent
474fd8fab8
commit
749ff9ec2b
5 changed files with 59 additions and 4 deletions
1
changes/issue-7888-login-logs
Normal file
1
changes/issue-7888-login-logs
Normal file
|
|
@ -0,0 +1 @@
|
|||
* Added logging to capture user email upon successful login
|
||||
|
|
@ -132,7 +132,6 @@ func (l *LoggingContext) Log(ctx context.Context, logger kitlog.Logger) {
|
|||
}
|
||||
keyvals = append(keyvals, "user", loggedInUser)
|
||||
}
|
||||
|
||||
requestMethod, ok := ctx.Value(kithttp.ContextKeyRequestMethod).(string)
|
||||
if !ok {
|
||||
requestMethod = ""
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ func (s *integrationLoggerTestSuite) TestLogger() {
|
|||
assert.Equal(t, "GET", kv["method"])
|
||||
assert.Equal(t, "/api/latest/fleet/config", kv["uri"])
|
||||
assert.Equal(t, "admin1@example.com", kv["user"])
|
||||
case 2:
|
||||
case 3:
|
||||
assert.Equal(t, "debug", kv["level"])
|
||||
assert.Equal(t, "POST", kv["method"])
|
||||
assert.Equal(t, "/api/latest/fleet/queries", kv["uri"])
|
||||
|
|
@ -99,6 +99,61 @@ func (s *integrationLoggerTestSuite) TestLogger() {
|
|||
}
|
||||
}
|
||||
|
||||
func (s *integrationLoggerTestSuite) TestLoggerLogin() {
|
||||
t := s.T()
|
||||
|
||||
type logEntry struct {
|
||||
key string
|
||||
val string
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
loginRequest loginRequest
|
||||
expectedStatus int
|
||||
expectedLogs []logEntry
|
||||
}{
|
||||
{
|
||||
loginRequest: loginRequest{Email: testUsers["admin1"].Email, Password: testUsers["admin1"].PlaintextPassword},
|
||||
expectedStatus: http.StatusOK,
|
||||
expectedLogs: []logEntry{{"email", testUsers["admin1"].Email}},
|
||||
},
|
||||
{
|
||||
loginRequest: loginRequest{Email: testUsers["admin1"].Email, Password: "n074v411dp455w02d"},
|
||||
expectedStatus: http.StatusUnauthorized,
|
||||
expectedLogs: []logEntry{
|
||||
{"email", testUsers["admin1"].Email},
|
||||
{"level", "error"},
|
||||
{"internal", "invalid password"},
|
||||
},
|
||||
},
|
||||
{
|
||||
loginRequest: loginRequest{Email: "h4x0r@3x4mp13.c0m", Password: "n074v411dp455w02d"},
|
||||
expectedStatus: http.StatusUnauthorized,
|
||||
expectedLogs: []logEntry{
|
||||
{"email", "h4x0r@3x4mp13.c0m"},
|
||||
{"level", "error"},
|
||||
{"internal", "user not found"},
|
||||
},
|
||||
},
|
||||
}
|
||||
var resp loginResponse
|
||||
for _, tt := range testCases {
|
||||
s.DoJSON("POST", "/api/latest/fleet/login", tt.loginRequest, tt.expectedStatus, &resp)
|
||||
logString := s.buf.String()
|
||||
parts := strings.Split(strings.TrimSpace(logString), "\n")
|
||||
require.Len(t, parts, 1)
|
||||
logData := make(map[string]string)
|
||||
require.NoError(t, json.Unmarshal([]byte(parts[0]), &logData))
|
||||
|
||||
require.NotContains(t, logData, "user") // logger context is set to skip user
|
||||
|
||||
for _, e := range tt.expectedLogs {
|
||||
assert.Equal(t, logData[e.key], e.val)
|
||||
}
|
||||
s.buf.Reset()
|
||||
}
|
||||
}
|
||||
|
||||
func (s *integrationLoggerTestSuite) TestOsqueryEndpointsLogErrors() {
|
||||
t := s.T()
|
||||
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ func (svc *Service) Login(ctx context.Context, email, password string) (*fleet.U
|
|||
// skipauth: No user context available yet to authorize against.
|
||||
svc.authz.SkipAuthorization(ctx)
|
||||
|
||||
logging.WithLevel(logging.WithNoUser(ctx), level.Info)
|
||||
logging.WithLevel(logging.WithExtras(logging.WithNoUser(ctx), "email", email), level.Info)
|
||||
|
||||
// If there is an error, sleep until the request has taken at least 1
|
||||
// second. This means that generally a login failure for any reason will
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ func TestAuthenticate(t *testing.T) {
|
|||
svc := newTestService(t, ds, nil, nil)
|
||||
createTestUsers(t, ds)
|
||||
|
||||
var loginTests = []struct {
|
||||
loginTests := []struct {
|
||||
name string
|
||||
email string
|
||||
password string
|
||||
|
|
|
|||
Loading…
Reference in a new issue