Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add min interval between presence detections #2003

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion ee/localserver/presence-detection-middleware_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func TestPresenceDetectionHandler(t *testing.T) {
mockPresenceDetector := mocks.NewPresenceDetector(t)

if tt.expectDetectPresenceCall {
mockPresenceDetector.On("DetectPresence", mock.AnythingOfType("string"), mock.AnythingOfType("Duration")).Return(tt.durationSinceLastDetection, tt.presenceDetectionError)
mockPresenceDetector.On("DetectPresence", mock.AnythingOfType("string"), mock.AnythingOfType("Duration")).Return(tt.durationSinceLastDetection, tt.presenceDetectionError).Once()
}

server := &localServer{
Expand Down Expand Up @@ -112,6 +112,14 @@ func TestPresenceDetectionHandler(t *testing.T) {
require.NotEmpty(t, rr.Header().Get(kolideDurationSinceLastPresenceDetectionHeaderKey))
}
require.Equal(t, tt.expectedStatusCode, rr.Code)

// fire the request one more time, it should not call presence detector again
// because it's less than the minimum interval
mockPresenceDetector = mocks.NewPresenceDetector(t)
server.presenceDetector = mockPresenceDetector

handlerToTest.ServeHTTP(rr, req)
mockPresenceDetector.AssertNotCalled(t, "DetectPresence", mock.Anything, mock.Anything)
})
}
}
24 changes: 21 additions & 3 deletions ee/localserver/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,9 @@ type localServer struct {
serverKey *rsa.PublicKey
serverEcKey *ecdsa.PublicKey

presenceDetector presenceDetector
presenceDetectionMutex sync.Mutex
presenceDetector presenceDetector
presenceDetectionMutex sync.Mutex
lastPresenceDetectionAttempt time.Time
}

const (
Expand Down Expand Up @@ -422,6 +423,22 @@ func (ls *localServer) presenceDetectionHandler(next http.Handler) http.Handler
ls.presenceDetectionMutex.Lock()
defer ls.presenceDetectionMutex.Unlock()

// if the user fails or cancels the presence detection, we want to wait a bit before trying again
// so that if there are several queued up requests, we don't prompt the user multiple times in a row
// if they keep hitting cancel

const minTimeBetweenPresenceDetection = 3 * time.Second
if time.Since(ls.lastPresenceDetectionAttempt) < minTimeBetweenPresenceDetection {
ls.slogger.Log(r.Context(), slog.LevelInfo,
"presence detection attempted too soon",
"min_interval", minTimeBetweenPresenceDetection,
)

w.Header().Add(kolideDurationSinceLastPresenceDetectionHeaderKey, presencedetection.DetectionFailedDurationValue.String())
next.ServeHTTP(w, r)
return
}

// can test this by adding an unauthed endpoint to the mux and running, for example:
// curl -i -H "X-Kolide-Presence-Detection-Interval: 10s" -H "X-Kolide-Presence-Detection-Reason: my reason" localhost:12519/id
detectionIntervalStr := r.Header.Get(kolidePresenceDetectionIntervalHeaderKey)
Expand Down Expand Up @@ -461,7 +478,6 @@ func (ls *localServer) presenceDetectionHandler(next http.Handler) http.Handler
}

durationSinceLastDetection, err := ls.presenceDetector.DetectPresence(reason, detectionIntervalDuration)

if err != nil {
ls.slogger.Log(r.Context(), slog.LevelInfo,
"presence_detection",
Expand All @@ -472,6 +488,8 @@ func (ls *localServer) presenceDetectionHandler(next http.Handler) http.Handler
)
}

ls.lastPresenceDetectionAttempt = time.Now()

// if there was an error, we still want to return a 200 status code
// and send the request through
// allow the server to decide what to do based on last detection duration
Expand Down
Loading