func NewGitLabClient(ctx context.Context, token string) (*gitlab.Client, error) {
// GitLab has various token types and they're authenticated differently.
// e.g. `JOB-TOKEN: $CI_JOB_TOKEN` vs `PRIVATE-TOKEN: <user/group access token>`
// References:
// - https://docs.gitlab.com/ee/security/token_overview.html#token-prefixes
// - https://docs.gitlab.com/ee/api/rest/#authentication
var newClientFunc func(token string, opts ...gitlab.ClientOptionFunc) (*gitlab.Client, error)
prefix, _, ok := strings.Cut(token, "-")
if !ok {
// NOTE: do NOT write out the value here, as it might be a secret!
return nil, errors.New("invalid token: no prefix")
} else if !strings.HasPrefix(prefix, "gl") {
// all known token prefixes themselves start with `gl`, so this is an extra
// check so that we can safely log out unsupported prefixes below.
return nil, errors.New("invalid token: prefix does not start with `gl`")
}
switch prefix {
case "glcbt":
newClientFunc = gitlab.NewJobClient
case "gloas":
newClientFunc = gitlab.NewOAuthClient
case "glpat":
// N.B. the default "NewClient" ctor is for PATs
newClientFunc = gitlab.NewClient
default:
return nil, fmt.Errorf("invalid token: unsupported type (%s)", prefix)
}
gitlabCli, err := newClientFunc(
token,
gitlab.WithRequestOptions(
gitlab.WithContext(ctx),
),
)
if err != nil {
return nil, fmt.Errorf("creating gitlab client: %w", err)
}
return gitlabCli, nil
}
Is this functionality you'd be interested in? I'm happy to open a PR if so, but I also understand if this is outside the scope of this library!
GitLab uses known token prefixes: https://docs.gitlab.com/ee/security/token_overview.html#token-prefixes
I wrote this wrapper:
Is this functionality you'd be interested in? I'm happy to open a PR if so, but I also understand if this is outside the scope of this library!