feat(auth): allow a custom OAuth client_id on gitlab.com
Description
On gitlab.com, glab always used its built-in OAuth application and ignored client_id and GITLAB_CLIENT_ID. Now glab auth login on gitlab.com (web and device) can use your own OAuth application.
For gitlab.com, glab picks the application ID in this order:
- Login:
GITLAB_CLIENT_ID, thenclient_idunderhosts.gitlab.com, then the built-in application. - Token refresh:
client_idunderhosts.gitlab.com, then the built-in application.
A top-level or local repository client_id is ignored for gitlab.com. After a successful login with GITLAB_CLIENT_ID, glab saves the ID as client_id for gitlab.com, so the next refresh uses the same application.
Refresh does not read GITLAB_CLIENT_ID, because people often set it machine-wide for a self-managed instance. This way existing gitlab.com sessions keep working. Self-managed and GitLab Dedicated hosts work the same as before.
For the docs, I updated the client_id description and regenerated the config docs. I also added a "Use your own OAuth application" section to the authentication page and updated the GITLAB_CLIENT_ID row in its environment variables table.
Two choices you may want to change:
- After a
gitlab.comlogin withGITLAB_CLIENT_ID, I always save the ID, even when it equals the built-in one. This way an old custom ID does not stay. Or do you prefer to save it only when it differs from the built-in one? - A machine-wide
GITLAB_CLIENT_IDfor a self-managed instance also applies to a newgitlab.comlogin, as the issue asks. The docs showGITLAB_CLIENT_ID= glab auth login --hostname gitlab.comto use the built-in application. Or shouldgitlab.comlogin use onlyclient_idunderhosts.gitlab.com?
Related Issues
Closes #8616
How has this been tested?
I added tests for gitlab.com that check the client ID the OAuth endpoints receive:
- Device login uses
GITLAB_CLIENT_IDand saves it underhosts.gitlab.com. - A top-level
client_idis ignored. - Refresh ignores
GITLAB_CLIENT_IDand uses the savedclient_id.
Three of them fail on the first version of this MR: the shell ID and the top-level ID were used, and nothing was saved.
$ GOFLAGS=-p=2 go test -count=1 ./internal/oauth2/ ./internal/config/
ok gitlab.com/gitlab-org/cli/internal/oauth2 1.742s
ok gitlab.com/gitlab-org/cli/internal/config 1.808sI also ran the oauth2 tests with GITLAB_CLIENT_ID set in the shell, to check they do not depend on it:
$ GITLAB_CLIENT_ID=from-shell GOFLAGS=-p=2 go test -count=1 ./internal/oauth2/
ok gitlab.com/gitlab-org/cli/internal/oauth2 1.690sThe rest runs in the pipeline.
Implemented with AI assistance; I reviewed and tested the changes.