Skip to content

Commit dcf739c

Browse files
committed
Make sure to consume the device grant to avoid replays
1 parent 1dbed14 commit dcf739c

File tree

1 file changed

+18
-1
lines changed

1 file changed

+18
-1
lines changed

crates/handlers/src/oauth2/token.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -780,7 +780,11 @@ async fn device_code_grant(
780780
// Start the session
781781
let mut session = repo
782782
.oauth2_session()
783-
.add_from_browser_session(rng, clock, client, &browser_session, grant.scope)
783+
.add_from_browser_session(rng, clock, client, &browser_session, grant.scope.clone())
784+
.await?;
785+
786+
repo.oauth2_device_code_grant()
787+
.exchange(clock, grant, &session)
784788
.await?;
785789

786790
// XXX: should we get the user agent from the device code grant instead?
@@ -1605,6 +1609,19 @@ mod tests {
16051609
// We asked for the openid scope, so we should have an ID token
16061610
assert!(response.id_token.is_some());
16071611

1612+
// Calling it again should fail
1613+
let request =
1614+
Request::post(mas_router::OAuth2TokenEndpoint::PATH).form(serde_json::json!({
1615+
"grant_type": "urn:ietf:params:oauth:grant-type:device_code",
1616+
"device_code": grant.device_code,
1617+
"client_id": client_id,
1618+
}));
1619+
let response = state.request(request).await;
1620+
response.assert_status(StatusCode::BAD_REQUEST);
1621+
1622+
let ClientError { error, .. } = response.json();
1623+
assert_eq!(error, ClientErrorCode::InvalidGrant);
1624+
16081625
// Do another grant and make it expire
16091626
let request = Request::post(mas_router::OAuth2DeviceAuthorizationEndpoint::PATH).form(
16101627
serde_json::json!({

0 commit comments

Comments
 (0)