mirror of
https://github.com/golang/oauth2.git
synced 2025-07-21 00:00:09 +08:00
Device Authorization Grant following RFC 8628 https://datatracker.ietf.org/doc/html/rfc8628 Tested with GitHub Fixes #418 Fixes golang/go#58126 Co-authored-by: cmP <centimitr@gmail.com> Change-Id: Id588867110c6a5289bf1026da5d7ead88f9c7d14 GitHub-Last-Rev: 9a126d7b534532c7d18fb8d6796ad673b95fc09f GitHub-Pull-Request: golang/oauth2#609 Reviewed-on: https://go-review.googlesource.com/c/oauth2/+/450155 Commit-Queue: Bryan Mills <bcmills@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Than McIntosh <thanm@google.com> Auto-Submit: Bryan Mills <bcmills@google.com> Run-TryBot: Matt Hickford <matt.hickford@gmail.com> Reviewed-by: Bryan Mills <bcmills@google.com> Run-TryBot: Bryan Mills <bcmills@google.com>
98 lines
2.2 KiB
Go
98 lines
2.2 KiB
Go
package oauth2
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
"github.com/google/go-cmp/cmp/cmpopts"
|
|
)
|
|
|
|
func TestDeviceAuthResponseMarshalJson(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
response DeviceAuthResponse
|
|
want string
|
|
}{
|
|
{
|
|
name: "empty",
|
|
response: DeviceAuthResponse{},
|
|
want: `{"device_code":"","user_code":"","verification_uri":""}`,
|
|
},
|
|
{
|
|
name: "soon",
|
|
response: DeviceAuthResponse{
|
|
Expiry: time.Now().Add(100*time.Second + 999*time.Millisecond),
|
|
},
|
|
want: `{"expires_in":100,"device_code":"","user_code":"","verification_uri":""}`,
|
|
},
|
|
}
|
|
for _, tc := range tests {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
begin := time.Now()
|
|
gotBytes, err := json.Marshal(tc.response)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if strings.Contains(tc.want, "expires_in") && time.Since(begin) > 999*time.Millisecond {
|
|
t.Skip("test ran too slowly to compare `expires_in`")
|
|
}
|
|
got := string(gotBytes)
|
|
if got != tc.want {
|
|
t.Errorf("want=%s, got=%s", tc.want, got)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDeviceAuthResponseUnmarshalJson(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
data string
|
|
want DeviceAuthResponse
|
|
}{
|
|
{
|
|
name: "empty",
|
|
data: `{}`,
|
|
want: DeviceAuthResponse{},
|
|
},
|
|
{
|
|
name: "soon",
|
|
data: `{"expires_in":100}`,
|
|
want: DeviceAuthResponse{Expiry: time.Now().UTC().Add(100 * time.Second)},
|
|
},
|
|
}
|
|
for _, tc := range tests {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
begin := time.Now()
|
|
got := DeviceAuthResponse{}
|
|
err := json.Unmarshal([]byte(tc.data), &got)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !cmp.Equal(got, tc.want, cmpopts.IgnoreUnexported(DeviceAuthResponse{}), cmpopts.EquateApproxTime(time.Second+time.Since(begin))) {
|
|
t.Errorf("want=%#v, got=%#v", tc.want, got)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func ExampleConfig_DeviceAuth() {
|
|
var config Config
|
|
ctx := context.Background()
|
|
response, err := config.DeviceAuth(ctx)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
fmt.Printf("please enter code %s at %s\n", response.UserCode, response.VerificationURI)
|
|
token, err := config.DeviceAccessToken(ctx, response)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
fmt.Println(token)
|
|
}
|