Skip to content

Commit

Permalink
Merge pull request #68 from abhisek/main
Browse files Browse the repository at this point in the history
feat: Add support for audience in authorization request
  • Loading branch information
jtmcg authored Oct 14, 2024
2 parents 96b35bb + 9aec06b commit 6c44f68
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 5 deletions.
25 changes: 22 additions & 3 deletions device/device_flow.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,31 @@ type CodeResponse struct {
Interval int
}

// AuthRequestEditorFn defines the function signature for setting additional form values.
type AuthRequestEditorFn func(*url.Values)

// WithAudience sets the audience parameter in the request.
func WithAudience(audience string) AuthRequestEditorFn {
return func(values *url.Values) {
if audience != "" {
values.Add("audience", audience)
}
}
}

// RequestCode initiates the authorization flow by requesting a code from uri.
func RequestCode(c httpClient, uri string, clientID string, scopes []string) (*CodeResponse, error) {
resp, err := api.PostForm(c, uri, url.Values{
func RequestCode(c httpClient, uri string, clientID string, scopes []string,
optionalRequestParams ...AuthRequestEditorFn) (*CodeResponse, error) {
values := url.Values{
"client_id": {clientID},
"scope": {strings.Join(scopes, " ")},
})
}

for _, fn := range optionalRequestParams {
fn(&values)
}

resp, err := api.PostForm(c, uri, values)
if err != nil {
return nil, err
}
Expand Down
40 changes: 39 additions & 1 deletion device/device_flow_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ func TestRequestCode(t *testing.T) {
url string
clientID string
scopes []string
audience string
}
tests := []struct {
name string
Expand Down Expand Up @@ -126,6 +127,42 @@ func TestRequestCode(t *testing.T) {
},
},
},
{
name: "with audience",
args: args{
http: apiClient{
stubs: []apiStub{
{
body: "verification_uri=http://verify.me&interval=5&expires_in=99&device_code=DEVIC&user_code=123-abc&verification_uri_complete=http://verify.me/?code=123-abc",
status: 200,
contentType: "application/x-www-form-urlencoded; charset=utf-8",
},
},
},
url: "https://github.com/oauth",
clientID: "CLIENT-ID",
scopes: []string{"repo", "gist"},
audience: "https://api.github.com",
},
want: &CodeResponse{
DeviceCode: "DEVIC",
UserCode: "123-abc",
VerificationURI: "http://verify.me",
VerificationURIComplete: "http://verify.me/?code=123-abc",
ExpiresIn: 99,
Interval: 5,
},
posts: []postArgs{
{
url: "https://github.com/oauth",
params: url.Values{
"client_id": {"CLIENT-ID"},
"scope": {"repo gist"},
"audience": {"https://api.github.com"},
},
},
},
},
{
name: "unsupported",
args: args{
Expand Down Expand Up @@ -237,7 +274,8 @@ func TestRequestCode(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := RequestCode(&tt.args.http, tt.args.url, tt.args.clientID, tt.args.scopes)
got, err := RequestCode(&tt.args.http, tt.args.url,
tt.args.clientID, tt.args.scopes, WithAudience(tt.args.audience))
if (err != nil) != (tt.wantErr != "") {
t.Errorf("RequestCode() error = %v, wantErr %v", err, tt.wantErr)
return
Expand Down
2 changes: 2 additions & 0 deletions oauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ type Flow struct {
Host *Host
// OAuth scopes to request from the user.
Scopes []string
// OAuth audience to request from the user.
Audience string
// OAuth application ID.
ClientID string
// OAuth application secret. Only applicable in web application flow.
Expand Down
3 changes: 2 additions & 1 deletion oauth_device.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ func (oa *Flow) DeviceFlow() (*api.AccessToken, error) {
host = parsedHost
}

code, err := device.RequestCode(httpClient, host.DeviceCodeURL, oa.ClientID, oa.Scopes)
code, err := device.RequestCode(httpClient, host.DeviceCodeURL,
oa.ClientID, oa.Scopes, device.WithAudience(oa.Audience))
if err != nil {
return nil, err
}
Expand Down
1 change: 1 addition & 0 deletions oauth_webapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ func (oa *Flow) WebAppFlow() (*api.AccessToken, error) {
ClientID: oa.ClientID,
RedirectURI: oa.CallbackURI,
Scopes: oa.Scopes,
Audience: oa.Audience,
AllowSignup: true,
}
browserURL, err := flow.BrowserURL(host.AuthorizeURL, params)
Expand Down
5 changes: 5 additions & 0 deletions webapp/webapp_flow.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ type BrowserParams struct {
ClientID string
RedirectURI string
Scopes []string
Audience string
LoginHandle string
AllowSignup bool
}
Expand All @@ -68,6 +69,10 @@ func (flow *Flow) BrowserURL(baseURL string, params BrowserParams) (string, erro
q.Set("redirect_uri", ru.String())
q.Set("scope", strings.Join(params.Scopes, " "))
q.Set("state", flow.state)

if params.Audience != "" {
q.Set("audience", params.Audience)
}
if params.LoginHandle != "" {
q.Set("login", params.LoginHandle)
}
Expand Down
18 changes: 18 additions & 0 deletions webapp/webapp_flow_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,24 @@ func TestFlow_BrowserURL(t *testing.T) {
want: "https://github.com/authorize?client_id=CLIENT-ID&redirect_uri=http%3A%2F%2F127.0.0.1%3A12345%2Fhello&scope=repo+read%3Aorg&state=xy%2Fz",
wantErr: false,
},
{
name: "happy path with audience",
fields: fields{
server: server,
state: "xy/z",
},
args: args{
baseURL: "https://github.com/authorize",
params: BrowserParams{
ClientID: "CLIENT-ID",
RedirectURI: "http://127.0.0.1/hello",
Scopes: []string{"repo", "read:org"},
AllowSignup: true,
Audience: "https://api.github.com",
},
},
want: "https://github.com/authorize?audience=https%3A%2F%2Fapi.github.com&client_id=CLIENT-ID&redirect_uri=http%3A%2F%2F127.0.0.1%3A12345%2Fhello&scope=repo+read%3Aorg&state=xy%2Fz",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down

0 comments on commit 6c44f68

Please sign in to comment.