Skip to content

Commit 7e2ce41

Browse files
committed
PasswordCredentialsToken with AuthCodeOption
Signed-off-by: Jmnote <[email protected]>
1 parent 39adbb7 commit 7e2ce41

File tree

2 files changed

+94
-2
lines changed

2 files changed

+94
-2
lines changed

oauth2.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ func (c *Config) AuthCodeURL(state string, opts ...AuthCodeOption) string {
195195
// See https://tools.ietf.org/html/rfc6749#section-4.3 for more info.
196196
//
197197
// The provided context optionally controls which HTTP client is used. See the HTTPClient variable.
198-
func (c *Config) PasswordCredentialsToken(ctx context.Context, username, password string) (*Token, error) {
198+
func (c *Config) PasswordCredentialsToken(ctx context.Context, username, password string, opts ...AuthCodeOption) (*Token, error) {
199199
v := url.Values{
200200
"grant_type": {"password"},
201201
"username": {username},
@@ -204,6 +204,9 @@ func (c *Config) PasswordCredentialsToken(ctx context.Context, username, passwor
204204
if len(c.Scopes) > 0 {
205205
v.Set("scope", strings.Join(c.Scopes, " "))
206206
}
207+
for _, opt := range opts {
208+
opt.setValue(v)
209+
}
207210
return retrieveToken(ctx, c, v)
208211
}
209212

oauth2_test.go

+90-1
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ func TestPasswordCredentialsTokenRequest(t *testing.T) {
393393
if headerContentType != expected {
394394
t.Errorf("Content-Type header = %q; want %q", headerContentType, expected)
395395
}
396-
body, err := ioutil.ReadAll(r.Body)
396+
body, err := io.ReadAll(r.Body)
397397
if err != nil {
398398
t.Errorf("Failed reading request body: %s.", err)
399399
}
@@ -423,6 +423,95 @@ func TestPasswordCredentialsTokenRequest(t *testing.T) {
423423
}
424424
}
425425

426+
func TestPasswordCredentialsTokenRequest_AuthCodeOption(t *testing.T) {
427+
testCases := []struct {
428+
ctx context.Context
429+
username string
430+
password string
431+
authCodeOption AuthCodeOption
432+
wantURLString string
433+
wantHeaderAuth string
434+
wantHeaderContentType string
435+
wantBody string
436+
}{
437+
{
438+
username: "user1",
439+
password: "password1",
440+
authCodeOption: nil,
441+
wantURLString: "/token",
442+
wantHeaderAuth: "Basic Q0xJRU5UX0lEOkNMSUVOVF9TRUNSRVQ=",
443+
wantHeaderContentType: "application/x-www-form-urlencoded",
444+
wantBody: "grant_type=password&password=password1&scope=scope1+scope2&username=user1",
445+
},
446+
{
447+
username: "user1",
448+
password: "password1",
449+
authCodeOption: SetAuthURLParam("foo", "bar"),
450+
wantURLString: "/token",
451+
wantHeaderAuth: "Basic Q0xJRU5UX0lEOkNMSUVOVF9TRUNSRVQ=",
452+
wantHeaderContentType: "application/x-www-form-urlencoded",
453+
wantBody: "foo=bar&grant_type=password&password=password1&scope=scope1+scope2&username=user1",
454+
},
455+
{
456+
username: "user1",
457+
password: "password1",
458+
authCodeOption: SetAuthURLParam("zoo", "world"),
459+
wantURLString: "/token",
460+
wantHeaderAuth: "Basic Q0xJRU5UX0lEOkNMSUVOVF9TRUNSRVQ=",
461+
wantHeaderContentType: "application/x-www-form-urlencoded",
462+
wantBody: "grant_type=password&password=password1&scope=scope1+scope2&username=user1&zoo=world",
463+
},
464+
}
465+
for _, tc := range testCases {
466+
t.Run("", func(t *testing.T) {
467+
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
468+
defer r.Body.Close()
469+
if r.URL.String() != tc.wantURLString {
470+
t.Errorf("URL = %q; want %q", r.URL, tc.wantURLString)
471+
}
472+
if r.Header.Get("Authorization") != tc.wantHeaderAuth {
473+
t.Errorf("Authorization header = %q; want %q", r.Header.Get("Authorization"), tc.wantHeaderAuth)
474+
}
475+
if r.Header.Get("Content-Type") != tc.wantHeaderContentType {
476+
t.Errorf("Content-Type header = %q; want %q", r.Header.Get("Content-Type"), tc.wantHeaderContentType)
477+
}
478+
body, err := io.ReadAll(r.Body)
479+
if err != nil {
480+
t.Errorf("Failed reading request body: %s.", err)
481+
}
482+
if string(body) != tc.wantBody {
483+
t.Errorf("res.Body = %q; want %q", string(body), tc.wantBody)
484+
}
485+
w.Header().Set("Content-Type", "application/x-www-form-urlencoded")
486+
w.Write([]byte("access_token=90d64460d14870c08c81352a05dedd3465940a7c&scope=user&token_type=bearer"))
487+
}))
488+
defer ts.Close()
489+
conf := newConf(ts.URL)
490+
var tok *Token
491+
var err error
492+
if tc.authCodeOption == nil {
493+
tok, err = conf.PasswordCredentialsToken(context.Background(), "user1", "password1")
494+
} else {
495+
tok, err = conf.PasswordCredentialsToken(context.Background(), "user1", "password1", tc.authCodeOption)
496+
}
497+
if err != nil {
498+
t.Error(err)
499+
}
500+
if !tok.Valid() {
501+
t.Fatalf("Token invalid. Got: %#v", tok)
502+
}
503+
expected := "90d64460d14870c08c81352a05dedd3465940a7c"
504+
if tok.AccessToken != expected {
505+
t.Errorf("AccessToken = %q; want %q", tok.AccessToken, expected)
506+
}
507+
expected = "bearer"
508+
if tok.TokenType != expected {
509+
t.Errorf("TokenType = %q; want %q", tok.TokenType, expected)
510+
}
511+
})
512+
}
513+
}
514+
426515
func TestTokenRefreshRequest(t *testing.T) {
427516
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
428517
if r.URL.String() == "/somethingelse" {

0 commit comments

Comments
 (0)