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
Fix Assume Start Time Validation #39008
Conversation
my changelog is lame... i'm still thinking on making it clearer, or should I even add one? i highly doubt anyone's using this feature yet |
b3d57f8
to
14faaba
Compare
api/types/access_request_test.go
Outdated
) | ||
|
||
func TestAssertAccessRequestImplementsResourceWithLabels(t *testing.T) { | ||
ar, err := NewAccessRequest("test", "test", "test") | ||
require.NoError(t, err) | ||
require.Implements(t, (*ResourceWithLabels)(nil), ar) | ||
} | ||
|
||
func TestValidateAssumeStartTime(t *testing.T) { | ||
clock := clockwork.NewFakeClock() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think you really need a fake clock here, as the test is really about working with arbitrary time.Time
values.
lib/auth/access_request_test.go
Outdated
|
||
t.Cleanup(func() { require.NoError(t, requesterClient.Close()) }) | ||
|
||
clock := clockwork.NewFakeClock() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you need this clock? The clock that your fake server is using is going to be a different clock anyway.
4d04132
to
9852ae8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few nits. Overall LGTM
api/types/access_request_test.go
Outdated
|
||
func TestValidateAssumeStartTime(t *testing.T) { | ||
creation := time.Now().UTC() | ||
day := 24 * time.Hour |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
day := 24 * time.Hour | |
const day = 24 * time.Hour |
api/types/access_request_test.go
Outdated
{ | ||
name: "start time too far in the future", | ||
startTime: creation.Add(constants.MaxAssumeStartDuration + (1 * day)), | ||
errCheck: func(tt require.TestingT, err error, i ...interface{}) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
errCheck: func(tt require.TestingT, err error, i ...interface{}) { | |
errCheck: func(tt require.TestingT, err error, i ...any) { |
api/types/access_request_test.go
Outdated
}{ | ||
{ | ||
name: "start time too far in the future", | ||
startTime: creation.Add(constants.MaxAssumeStartDuration + (1 * day)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
startTime: creation.Add(constants.MaxAssumeStartDuration + (1 * day)), | |
startTime: creation.Add(constants.MaxAssumeStartDuration + day), |
createdRequest types.AccessRequest | ||
} | ||
|
||
func createAccessRequestWithStartTime(t *testing.T) accessRequestWithStartTime { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: You can add t.Helper()
to mark this as a helper function.
lib/services/access_request_test.go
Outdated
@@ -644,7 +644,7 @@ func TestReviewThresholds(t *testing.T) { | |||
propose: approve, | |||
assumeStartTime: clock.Now().UTC().Add(10000 * time.Hour), | |||
errCheck: func(tt require.TestingT, err error, i ...interface{}) { | |||
require.ErrorIs(tt, err, trace.BadParameter("request start time is after expiry"), i...) | |||
require.Contains(tt, err.Error(), "assume start time must be prior to access expiry time", i...) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use require.ErrorContains(t, err, "Error message...")
as nil passed here will panic at e.Error()
without any sensible error message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approved with suggestions.
api/types/access_request.go
Outdated
func ValidateAssumeStartTime(assumeStartTime time.Time, accessExpiry time.Time, creationTime time.Time) error { | ||
// Guard against requesting a start time before the request creation time. | ||
if assumeStartTime.Before(creationTime) { | ||
return trace.BadParameter("assume start time has to be after: %q", creationTime.Format(time.RFC3339)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return trace.BadParameter("assume start time has to be after: %q", creationTime.Format(time.RFC3339)) | |
return trace.BadParameter("assume start time has to be after %v", creationTime.Format(time.RFC3339)) |
I don't know that quoting the creation time is necessary. The quote helps if we want to be able to identify an empty string, but formatting a time will always product a non-empty string.
I also don't think :
is necessary - just make it read like a normal sentence.
(don't forget to update your tests if you decide to accept these suggestions)
api/types/access_request.go
Outdated
} | ||
// Guard against requesting a start time after access expiry. | ||
if assumeStartTime.After(accessExpiry) || assumeStartTime.Equal(accessExpiry) { | ||
return trace.BadParameter("assume start time must be prior to access expiry time at: %q", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return trace.BadParameter("assume start time must be prior to access expiry time at: %q", | |
return trace.BadParameter("assume start time must be prior to access expiry time at %v", |
api/types/access_request.go
Outdated
// should be on or before constants.MaxAssumeStartDuration. | ||
maxAssumableStartTime := creationTime.Add(constants.MaxAssumeStartDuration) | ||
if maxAssumableStartTime.Before(accessExpiry) && assumeStartTime.After(maxAssumableStartTime) { | ||
return trace.BadParameter("assume start time is too far in the future, latest time allowed %q", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return trace.BadParameter("assume start time is too far in the future, latest time allowed %q", | |
return trace.BadParameter("assume start time is too far in the future, latest time allowed is %v", |
api/types/access_request_test.go
Outdated
name: "start time too far in the future", | ||
startTime: creation.Add(constants.MaxAssumeStartDuration + day), | ||
errCheck: func(tt require.TestingT, err error, i ...any) { | ||
require.True(tt, trace.IsBadParameter(err), "expected bad parameter, got %v", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
require.True(tt, trace.IsBadParameter(err), "expected bad parameter, got %v", err) |
The test still holds if you remove this line, right? (same below)
lib/auth/access_request_test.go
Outdated
}, | ||
} | ||
for _, tc := range testCases { | ||
review.Review.AssumeStartTime = &tc.startTime |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you use t.Run()
here to run proper subtests? Otherwise if this test fails we will just see that there was an error on line 1603 and won't be obvious which of the test cases actually failed.
(same goes for below)
The following allows modifying the start time and is where validation is placed: - CreateAccessRequestV2 - SubmitAccessReview - SetAccessRequestState (used with tctl)
63f53fa
to
0e0c0d1
Compare
* Fix Assume Start Time Validation (#39008) * Remove checking for max assume start time test (same as max duration)
part of #35436
While testing i ran into some issues. Fixes the following:
tctl requests approve
(we allowed modifying in client, but was not being set in the backend)maxest start time
allowed in the error message when user goes too farconstants.MaxAssumeStartTimeDuration
FROM the creation date (eg: if the const was 1 week max, then the start time cannot exceed one week from creation time, even if access expiry is set for 2 weeks)Extra context, we allow modifying assume start time in the following places and is where the validations are placed:
Manual Testing:
changelog: Fixes allowing invalid access request start time date to be set