Device flow token code exchange (#2)

* Added /device/token handler with associated business logic and storage tests.

Perform user code exchange, flag the device code as complete.

Moved device handler code into its own file for cleanliness.  Cleanup

* Removed PKCE code

* Rate limiting for /device/token endpoint based on ietf standards

* Configurable Device expiry

Signed-off-by: justin-slowik <justin.slowik@thermofisher.com>
This commit is contained in:
Justin Slowik
2020-01-28 14:14:30 -05:00
committed by justin-slowik
parent 0d1a0e4129
commit 9bbdc721d5
20 changed files with 777 additions and 274 deletions

View File

@@ -843,12 +843,11 @@ func testGC(t *testing.T, s storage.Storage) {
}
d := storage.DeviceRequest{
UserCode: userCode,
DeviceCode: storage.NewID(),
ClientID: "client1",
Scopes: []string{"openid", "email"},
PkceVerifier: storage.NewID(),
Expiry: expiry,
UserCode: userCode,
DeviceCode: storage.NewID(),
ClientID: "client1",
Scopes: []string{"openid", "email"},
Expiry: expiry,
}
if err := s.CreateDeviceRequest(d); err != nil {
@@ -970,12 +969,11 @@ func testDeviceRequestCRUD(t *testing.T, s storage.Storage) {
panic(err)
}
d1 := storage.DeviceRequest{
UserCode: userCode,
DeviceCode: storage.NewID(),
ClientID: "client1",
Scopes: []string{"openid", "email"},
PkceVerifier: storage.NewID(),
Expiry: neverExpire,
UserCode: userCode,
DeviceCode: storage.NewID(),
ClientID: "client1",
Scopes: []string{"openid", "email"},
Expiry: neverExpire,
}
if err := s.CreateDeviceRequest(d1); err != nil {
@@ -991,20 +989,44 @@ func testDeviceRequestCRUD(t *testing.T, s storage.Storage) {
}
func testDeviceTokenCRUD(t *testing.T, s storage.Storage) {
//Create a Token
d1 := storage.DeviceToken{
DeviceCode: storage.NewID(),
Status: "pending",
Token: storage.NewID(),
Expiry: neverExpire,
DeviceCode: storage.NewID(),
Status: "pending",
Token: storage.NewID(),
Expiry: neverExpire,
LastRequestTime: time.Now(),
PollIntervalSeconds: 0,
}
if err := s.CreateDeviceToken(d1); err != nil {
t.Fatalf("failed creating device token: %v", err)
}
// Attempt to create same DeviceRequest twice.
// Attempt to create same Device Token twice.
err := s.CreateDeviceToken(d1)
mustBeErrAlreadyExists(t, "device token", err)
//TODO Add update / delete tests as functionality is put into main code
//Update the device token, simulate a redemption
if err := s.UpdateDeviceToken(d1.DeviceCode, func(old storage.DeviceToken) (storage.DeviceToken, error) {
old.Token = "token data"
old.Status = "complete"
return old, nil
}); err != nil {
t.Fatalf("failed to update device token: %v", err)
}
//Retrieve the device token
got, err := s.GetDeviceToken(d1.DeviceCode)
if err != nil {
t.Fatalf("failed to get device token: %v", err)
}
//Validate expected result set
if got.Status != "complete" {
t.Fatalf("update failed, wanted token status=%#v got %#v", "complete", got.Status)
}
if got.Token != "token data" {
t.Fatalf("update failed, wanted token =%#v got %#v", "token data", got.Token)
}
}