src-cli
src-cli copied to clipboard
feat(oauth): use oauth device flow to authenticate with predefined src-cli OAuth client
This adds the flag --device-flow to login command which then starts the OAuth device authentication flow. gh does the same flow when you authenticate from the cli with gh auth login.
- add package
internal/oauthdevice - discover oauth configuration via path
.well-known/openid-configuration - add client to handle flow, in particular to discover the endpoints it should use and ultimately poll for the token once the user as authorized the application.
I wanted to add --client-id in case people wanted to override the default client that is used which can also be used for testing, but when I tried creating a client on S2 it doesn't have the correct configuration as set from the UI to be able to do this.
[!IMPORTANT] Seems like a lot of code but it's the tests that make up most of it
Test plan
- Unit tests
go test -v ./internal/oauthdevice/...
=== RUN TestDiscover_Success
--- PASS: TestDiscover_Success (0.00s)
=== RUN TestDiscover_Caching
--- PASS: TestDiscover_Caching (0.00s)
=== RUN TestDiscover_Error
--- PASS: TestDiscover_Error (0.00s)
=== RUN TestStart_Success
--- PASS: TestStart_Success (0.00s)
=== RUN TestStart_WithScopes
--- PASS: TestStart_WithScopes (0.00s)
=== RUN TestStart_Error
--- PASS: TestStart_Error (0.00s)
=== RUN TestStart_NoDeviceEndpoint
--- PASS: TestStart_NoDeviceEndpoint (0.00s)
=== RUN TestPoll_Success
--- PASS: TestPoll_Success (0.00s)
=== RUN TestPoll_AuthorizationPending
--- PASS: TestPoll_AuthorizationPending (0.00s)
=== RUN TestPoll_SlowDown
--- PASS: TestPoll_SlowDown (0.00s)
=== RUN TestPoll_ExpiredToken
--- PASS: TestPoll_ExpiredToken (0.00s)
=== RUN TestPoll_AccessDenied
--- PASS: TestPoll_AccessDenied (0.00s)
=== RUN TestPoll_Timeout
--- PASS: TestPoll_Timeout (0.00s)
=== RUN TestPoll_ContextCancellation
--- PASS: TestPoll_ContextCancellation (0.00s)
PASS
ok github.com/sourcegraph/src-cli/internal/oauthdevice 0.625s
- Tested manually against my local SG