-
Notifications
You must be signed in to change notification settings - Fork 0
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
oauthdevice: Rename to auth
; simplify interface
#28
Conversation
e3607a3
to
6398213
Compare
note to reviewers: Don't feel especially strong about this - I just have a sneaking suspicion that the original interface is too narrow to be futureproof, and thought that the best time to change it was sooner rather than later edit: Without this change, swapping code paths based on server version may be less clean |
internal/auth/authenticator.go
Outdated
if oauthErr := (*oauth2.RetrieveError)(nil); errors.As(err, &oauthErr) { | ||
return nil, err | ||
} | ||
// BUG(CUS-320): Clusters that are not oauth-aware will return HTML with |
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.
btw, is this bug addressed now?
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.
Dunno - do we have any non-oauth-aware backends running, or have we enabled the feature everywhere?
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.
It got merged in https://github.com/EngFlow/engflow/pull/22227.
Will have to see if what version coral has deployed, but I think it's enabled for them.
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.
The check should stay until no backends exist that can return this kind of response IMO
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.
We could rephrase to say that older versions of EngFlow redirected unknown API requests to a login page that eventually responded with 200 and HTML. That shouldn't happen anymore, but we can still guard against it. The new behavior is to return 404 instead when OAuth2 device flow is disabled.
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.
Ok, rephrased
Seems fine to me though it moves the control flow for opening browser into the interface. @jayconrod should comment about Golang hygeines. |
internal/auth/authenticator.go
Outdated
if oauthErr := (*oauth2.RetrieveError)(nil); errors.As(err, &oauthErr) { | ||
return nil, err | ||
} | ||
// BUG(CUS-320): Clusters that are not oauth-aware will return HTML with |
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.
We could rephrase to say that older versions of EngFlow redirected unknown API requests to a login page that eventually responded with 200 and HTML. That shouldn't happen anymore, but we can still guard against it. The new behavior is to return 404 instead when OAuth2 device flow is disabled.
|
||
var errUnexpectedHTML = errors.New("request to JSON API returned HTML unexpectedly") | ||
|
||
type Backend 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.
Exported definitions should have doc comments if their purpose isn't entirely clear from their names. Doubly so for types.
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.
Added comments for Backend
and DeviceCode
; I think NewDeviceCode
and DeviceCode.Authenticate
are fairly obvious from these docs; WDYT?
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.
Looks good. Types are the biggest thing.
browserOpener browser.Opener | ||
clientID string | ||
scopes []string | ||
httpTransport http.RoundTripper |
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.
It doesn't seem like this can be initialized by the constructor. What's it for?
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.
Added a comment here, and explicitly set it to nil in the constructor so that it looks more intentional.
} | ||
|
||
func (d *DeviceCode) Authenticate(ctx context.Context, host *url.URL) (*oauth2.Token, error) { | ||
if d.httpTransport != nil { |
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.
What's happening here?
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.
Added a comment
internal/auth/authenticator_test.go
Outdated
"golang.org/x/oauth2" | ||
) | ||
|
||
func AssertErrorContains(t *testing.T, got error, want string) { |
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.
Unexport: this can't be used by other packages.
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.
Done!
@@ -20,6 +20,7 @@ require ( | |||
github.com/godbus/dbus/v5 v5.1.0 // indirect | |||
github.com/pmezard/go-difflib v1.0.0 // indirect | |||
github.com/russross/blackfriday/v2 v2.1.0 // indirect | |||
github.com/stretchr/objx v0.5.2 // indirect |
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.
Is this covered by security review already?
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.
Just checked - it's not :/
I created https://docs.google.com/spreadsheets/d/1uTKuur4qbow2tRw7qvRfmReSJWjzhfpKtUM3Zlh7Ppg/edit?gid=0#gid=0; will update the PR desc and add security
This change simplifies the `oauthdevice.Authenticator` interface from the two-step `FetchCode` + `FetchToken` to a combined single method `Authenticate` that essentially chains the two code paths. The former interface may over-fit the device code auth flow, whereas the new interface may allow for non-device-code-flows to be implemented in the future. Since this change causes the interface to no longer be device-code-specific, the former package name no longer makes sense. This change results in the following renames: `package oauthdevice` -> `package auth` `oauthdevice.Authenticator` -> `auth.Backend` `oauthdevice.Auth` -> `auth.DeviceCode` `oauthdevice.NewAuth` -> `auth.NewDeviceCode` This change moves the browser-opening step from `main` into `auth.DeviceCode` as a consequence (which more accurately reflects the reality that not all auth flows involve opening a browser). Tests for main are simpler but tests for `auth.DeviceCode` are more complex as a result. Tests for `auth.DeviceCode` mock the underlying transport to perform validation on the HTTP requests and responses, bringing some of the `oauth2` package logic into the test. This results in slight over-testing, but may allow us to more easily validate `engflow_auth` against actual HTTP responses from our oauth endpoint in the future.
6398213
to
10d8b09
Compare
(LGTM by me, but still needs security approval for the new dependency). |
This change modifies the HTTP client used by the `DeviceCode` Authenticator implementation to send version information in each request. The version info is sent in the `User-Agent` header, using the format: engflow_auth/vX.Y.Z The version string is generated by the `buildstamp` library and is a semver string in a release binary, or a "pseudoversion" in a dev binary, similar go Go module pseudoversions. Tested: * Added unit tests * `bazel run //cmd/engflow_auth` against dev cluster fails (no buildstamp info) * `bazel run --stamp //cmd/engflow_auth` against dev cluster succeeds Bug: linear/CUS-387
This change simplifies the
oauthdevice.Authenticator
interface fromthe two-step
FetchCode
+FetchToken
to a combined single methodAuthenticate
that essentially chains the two code paths. The formerinterface may over-fit the device code auth flow, whereas the new
interface may allow for non-device-code-flows to be implemented in the
future.
Since this change causes the interface to no longer be
device-code-specific, the former package name no longer makes sense.
This change results in the following renames:
package oauthdevice
->package auth
oauthdevice.Authenticator
->auth.Backend
oauthdevice.Auth
->auth.DeviceCode
oauthdevice.NewAuth
->auth.NewDeviceCode
This change moves the browser-opening step from
main
intoauth.DeviceCode
as a consequence (which more accurately reflectsthe reality that not all auth flows involve opening a browser). Tests
for main are simpler but tests for
auth.DeviceCode
are more complex asa result.
Tests for
auth.DeviceCode
mock the underlying transport to performvalidation on the HTTP requests and responses, bringing some of the
oauth2
package logic into the test. This results in slightover-testing, but may allow us to more easily validate
engflow_auth
against actual HTTP responses from our oauth endpoint in the future.
The first dependency on
github.com/stretchr/testify/mock
requires us to addgithub.com/stretchr/objx
as a dependency, which requires a security approval