From 32e393cdb0c863eb7dd32d611471f09caed3fafa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zoran=20Plesiv=C4=8Dak?= <z@plesiv.com>
Date: Fri, 12 Jul 2019 22:10:34 +0100
Subject: [PATCH 1/2] Enable passing of additional Querystring params when
 requesting token

Some JWT Authentication APIs require the ability to pass additional
querystring parameters. For example Box.com API requires "client_id" and
"client_secret" parameters to be set ([ref][1]).

[1]: https://developer.box.com/docs/construct-jwt-claim-manually#section-4-request-access-token
---
 jwt/jwt.go      | 11 +++++++++++
 jwt/jwt_test.go | 23 +++++++++++++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/jwt/jwt.go b/jwt/jwt.go
index b2bf18298..f49c3369c 100644
--- a/jwt/jwt.go
+++ b/jwt/jwt.go
@@ -71,6 +71,11 @@ type Config struct {
 	// See http://tools.ietf.org/html/draft-jones-json-web-token-10#section-4.3
 	PrivateClaims map[string]interface{}
 
+	// Query-string parameters in addition to ones already set ("grant_type"
+	// and "assertion"). "grant_type" and "assertion" should not be set through
+	// this parameter.
+	Querystring url.Values
+
 	// UseIDToken optionally specifies whether ID token should be used instead
 	// of access token when the server returns both.
 	UseIDToken bool
@@ -131,6 +136,12 @@ func (js jwtSource) Token() (*oauth2.Token, error) {
 	v := url.Values{}
 	v.Set("grant_type", defaultGrantType)
 	v.Set("assertion", payload)
+	for qn, qv := range js.conf.Querystring {
+		if qn == "grant_type" || qn == "assertion" {
+			return nil, fmt.Errorf("oauth2: supplying param \"%v\" in Querystring is illegal", qn)
+		}
+		v[qn] = qv
+	}
 	resp, err := hc.PostForm(js.conf.TokenURL, v)
 	if err != nil {
 		return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err)
diff --git a/jwt/jwt_test.go b/jwt/jwt_test.go
index 9772dc520..d14203558 100644
--- a/jwt/jwt_test.go
+++ b/jwt/jwt_test.go
@@ -11,6 +11,7 @@ import (
 	"fmt"
 	"net/http"
 	"net/http/httptest"
+	"net/url"
 	"reflect"
 	"strings"
 	"testing"
@@ -142,9 +143,12 @@ func TestJWTFetch_BadResponseType(t *testing.T) {
 
 func TestJWTFetch_Assertion(t *testing.T) {
 	var assertion string
+	var extra_querystring_param string
+
 	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 		r.ParseForm()
 		assertion = r.Form.Get("assertion")
+		extra_querystring_param = r.Form.Get("extra_querystring_param")
 
 		w.Header().Set("Content-Type", "application/json")
 		w.Write([]byte(`{
@@ -161,6 +165,7 @@ func TestJWTFetch_Assertion(t *testing.T) {
 		PrivateKey:   dummyPrivateKey,
 		PrivateKeyID: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
 		TokenURL:     ts.URL,
+		Querystring:  url.Values{"extra_querystring_param": []string{"example_value"}},
 	}
 
 	_, err := conf.TokenSource(context.Background()).Token()
@@ -168,6 +173,10 @@ func TestJWTFetch_Assertion(t *testing.T) {
 		t.Fatalf("Failed to fetch token: %v", err)
 	}
 
+	if extra_querystring_param != "example_value" {
+		t.Fatalf("extra_querystring_param = %v; should be \"example_value\"", extra_querystring_param)
+	}
+
 	parts := strings.Split(assertion, ".")
 	if len(parts) != 3 {
 		t.Fatalf("assertion = %q; want 3 parts", assertion)
@@ -316,3 +325,17 @@ func TestTokenRetrieveError(t *testing.T) {
 		t.Fatalf("got %#v, expected %#v", errStr, expected)
 	}
 }
+
+func TestInvalidConfigArgument(t *testing.T) {
+	conf := &Config{
+		Email:       "aaa@xxx.com",
+		PrivateKey:  dummyPrivateKey,
+		Audience:    "https://example.com",
+		Querystring: url.Values{"assertion": []string{"Trying to override assertion"}},
+	}
+
+	_, err := conf.TokenSource(context.Background()).Token()
+	if err == nil {
+		t.Fatalf("got no error, expected one")
+	}
+}

From f444c3dcc43b0f512566834d52e29e368e86d115 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zoran=20Plesiv=C4=8Dak?= <z@plesiv.com>
Date: Fri, 12 Jul 2019 22:43:17 +0100
Subject: [PATCH 2/2] box: add box.com OAuth endpoint

More info [here][1].

[1]: https://box-content.readme.io/docs/oauth-20
---
 box/box.go | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
 create mode 100644 box/box.go

diff --git a/box/box.go b/box/box.go
new file mode 100644
index 000000000..142b7e1ec
--- /dev/null
+++ b/box/box.go
@@ -0,0 +1,16 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package box provides constants for using OAuth2 to access box.com.
+package box // import "golang.org/x/oauth2/box"
+
+import (
+	"golang.org/x/oauth2"
+)
+
+// Endpoint is box.com's OAuth 2.0 endpoint.
+var Endpoint = oauth2.Endpoint{
+	AuthURL:  "https://account.box.com/api/oauth2/authorize",
+	TokenURL: "https://api.box.com/oauth2/token",
+}