Skip to content

Commit

Permalink
test json marshal and unmarshal
Browse files Browse the repository at this point in the history
  • Loading branch information
hickford committed Mar 5, 2023
1 parent 2a9d404 commit 8b213fb
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 11 deletions.
46 changes: 37 additions & 9 deletions deviceauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"net/http"
"net/url"
"strings"
"time"

"golang.org/x/net/context/ctxhttp"
)
Expand All @@ -20,17 +21,44 @@ const (
errExpiredToken = "expired_token"
)

type DeviceAuth struct {
DeviceCode string `json:"device_code"`
UserCode string `json:"user_code"`
VerificationURI string `json:"verification_uri,verification_url"`
VerificationURIComplete string `json:"verification_uri_complete,omitempty"`
ExpiresIn int `json:"expires_in"`
Interval int `json:"interval,omitempty"`
type DeviceAuthResponse struct {
DeviceCode string `json:"device_code"`
UserCode string `json:"user_code"`
VerificationURI string `json:"verification_uri"`
VerificationURIComplete string `json:"verification_uri_complete,omitempty"`
Expiry time.Time `json:"expires_in"`
Interval int `json:"interval,omitempty"`
raw map[string]interface{}
}

func retrieveDeviceAuth(ctx context.Context, c *Config, v url.Values) (*DeviceAuth, error) {
func (d DeviceAuthResponse) MarshalJSON() ([]byte, error) {
type Alias DeviceAuthResponse
return json.Marshal(&struct {
ExpiresIn int64 `json:"expires_in"`
*Alias
}{
ExpiresIn: int64(time.Until(d.Expiry).Seconds()),
Alias: (*Alias)(&d),
})

}

func (c *DeviceAuthResponse) UnmarshalJSON(data []byte) error {
type Alias DeviceAuthResponse
aux := &struct {
ExpiresIn int64 `json:"expires_in"`
*Alias
}{
Alias: (*Alias)(c),
}
if err := json.Unmarshal(data, &aux); err != nil {
return err
}
c.Expiry = time.Now().UTC().Add(time.Second * time.Duration(aux.ExpiresIn))
return nil
}

func retrieveDeviceAuth(ctx context.Context, c *Config, v url.Values) (*DeviceAuthResponse, error) {
req, err := http.NewRequest("POST", c.Endpoint.DeviceAuthURL, strings.NewReader(v.Encode()))
if err != nil {
return nil, err
Expand All @@ -54,7 +82,7 @@ func retrieveDeviceAuth(ctx context.Context, c *Config, v url.Values) (*DeviceAu
}
}

da := &DeviceAuth{}
da := &DeviceAuthResponse{}
err = json.Unmarshal(body, &da)
if err != nil {
return nil, fmt.Errorf("unmarshal %s", err)
Expand Down
36 changes: 36 additions & 0 deletions deviceauth_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package oauth2

import (
"encoding/json"
"testing"
"time"

"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
)

func TestDeviceAuthResponseMarshalJson(t *testing.T) {
d := DeviceAuthResponse{Expiry: time.Now().Add(100 * time.Second)}
gotBytes, err := json.Marshal(d)
if err != nil {
t.Fatal(err)
}
got := string(gotBytes)
want := `{"expires_in":99,"device_code":"","user_code":"","verification_uri":""}`
if got != want {
t.Errorf("want=%s, got=%s", want, got)
}
}

func TestDeviceAuthResponseUnmarshalJson(t *testing.T) {
data := []byte(`{"expires_in":100}`)
want := DeviceAuthResponse{Expiry: time.Now().UTC().Add(100 * time.Second)}
got := DeviceAuthResponse{}
err := json.Unmarshal(data, &got)
if err != nil {
t.Fatal(err)
}
if !cmp.Equal(got, want, cmpopts.IgnoreUnexported(DeviceAuthResponse{}), cmpopts.EquateApproxTime(time.Second)) {
t.Errorf("want=%#v, got=%#v", want, got)
}
}
4 changes: 2 additions & 2 deletions oauth2.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ func (c *Config) Exchange(ctx context.Context, code string, opts ...AuthCodeOpti

// AuthDevice returns a device auth struct which contains a device code
// and authorization information provided for users to enter on another device.
func (c *Config) AuthDevice(ctx context.Context, opts ...AuthCodeOption) (*DeviceAuth, error) {
func (c *Config) AuthDevice(ctx context.Context, opts ...AuthCodeOption) (*DeviceAuthResponse, error) {
v := url.Values{
"client_id": {c.ClientID},
}
Expand All @@ -242,7 +242,7 @@ func (c *Config) AuthDevice(ctx context.Context, opts ...AuthCodeOption) (*Devic
}

// Poll does a polling to exchange an device code for a token.
func (c *Config) Poll(ctx context.Context, da *DeviceAuth, opts ...AuthCodeOption) (*Token, error) {
func (c *Config) Poll(ctx context.Context, da *DeviceAuthResponse, opts ...AuthCodeOption) (*Token, error) {
v := url.Values{
"client_id": {c.ClientID},
"grant_type": {"urn:ietf:params:oauth:grant-type:device_code"},
Expand Down

0 comments on commit 8b213fb

Please sign in to comment.