cli / oauth

A library for performing OAuth Device flow and Web application flow in Go client apps.
https://pkg.go.dev/github.com/cli/oauth
MIT License
460 stars 63 forks source link

Support third-party OAuth hosts #7

Closed jamierocks closed 2 years ago

jamierocks commented 3 years ago

This pull request should make some headway to supporting further OAuth providers than just GitHub. This pull request doesn't introduce specific support for anything, but provides an API to allow third-parties to their flavour endpoints.


Not all OAuth hosts use the same routes as GitHub, for example:

Similar differences are present for the authorise and access token routes too.

This commit introduces a concept of a Server, which is a container for the endpoints that the library uses. This is a replacement for Flow's Hostname and as such is a breaking change.

jamierocks commented 3 years ago

My original intention wasn't for this to be backwards-compatible, but looking back now its absolutely achievable - so I'll make an update to handle that.

Would just modifying the URLs allow this library to work with Microsoft without additional changes?

No. GitHub's server implementation is non-standard and responds with application/x-www-form-urlencoded responses which no other provider I'm aware of does. Never-the-less supporting Microsoft's endpoints is my end-goal here too, and it's not too dificult to support application/json responses.

I did make a start on this effort locally, with my original intent being to submit a second pr - those changes make sense under this pr, so I may just finish that up and push it here :)

jamierocks commented 3 years ago

I will look at the tests in a bit, but I've verified that the changes now support Microsoft's endpoints :)

Would you be interested in adding something like

// ServerAzure gets a Server for the given Azure Active Directory tenant. If tenant is
// empty, it will default to "common".
//
// See https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-device-code
func ServerAzure(tenant string) *Server {
    if tenant == "" {
        tenant = "common"
    }

    return &Server{
        DeviceCodeURL: fmt.Sprintf("https://login.microsoftonline.com/%s/oauth2/v2.0/devicecode", tenant),
        AuthorizeURL:  fmt.Sprintf("https://login.microsoftonline.com/%s/oauth2/v2.0/authorize", tenant),
        TokenURL:      fmt.Sprintf("https://login.microsoftonline.com/%s/oauth2/v2.0/token", tenant),
    }
}