Skip to content

Commit

Permalink
test(auth): add test case for device flow error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
ymgyt committed Jun 13, 2024
1 parent d1034f6 commit 708cbf4
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 20 deletions.
4 changes: 2 additions & 2 deletions crates/synd_auth/src/device_flow/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ pub struct DeviceAccessTokenResponse {
}

/// <https://datatracker.ietf.org/doc/html/rfc6749#section-5.2>
#[derive(Deserialize, Debug)]
#[derive(Serialize, Deserialize, Debug)]
pub struct DeviceAccessTokenErrorResponse {
pub error: DeviceAccessTokenErrorCode,
#[allow(unused)]
Expand All @@ -215,7 +215,7 @@ pub struct DeviceAccessTokenErrorResponse {
pub error_uri: Option<Uri>,
}

#[derive(PartialEq, Eq, Debug, Deserialize)]
#[derive(PartialEq, Eq, Debug, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum DeviceAccessTokenErrorCode {
AuthorizationPending,
Expand Down
61 changes: 43 additions & 18 deletions crates/synd_test/src/mock/mod.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
use std::{collections::HashMap, time::Duration};
use std::{collections::HashMap, sync::atomic::AtomicUsize, time::Duration};

use axum::{
http::{HeaderMap, StatusCode},
response::{IntoResponse, Response},
routing::{get, post},
Form, Json, Router,
};
use headers::{authorization::Bearer, Authorization, Header};
use serde::Serialize;
use synd_auth::device_flow::{
provider::google::DeviceAccessTokenRequest as GoogleDeviceAccessTokenRequest,
DeviceAccessTokenRequest, DeviceAccessTokenResponse, DeviceAuthorizationRequest,
DeviceAuthorizationResponse,
DeviceAccessTokenErrorResponse, DeviceAccessTokenRequest, DeviceAccessTokenResponse,
DeviceAuthorizationRequest, DeviceAuthorizationResponse,
};
use tokio::net::TcpListener;

Expand All @@ -33,7 +34,7 @@ async fn github_device_authorization(
verification_url: None,
verification_uri_complete: None,
expires_in: 3600,
interval: None,
interval: Some(1), // for test speed
};

Ok(Json(res))
Expand All @@ -54,32 +55,56 @@ async fn google_device_authorization(
verification_url: None,
verification_uri_complete: None,
expires_in: 3600,
interval: None,
interval: Some(1), // for test speed
};

Ok(Json(res))
}

async fn github_device_access_token(
Form(DeviceAccessTokenRequest { device_code, .. }): Form<DeviceAccessTokenRequest<'static>>,
) -> Result<Json<DeviceAccessTokenResponse>, StatusCode> {
) -> Response {
// Check error handling
static TRY: AtomicUsize = AtomicUsize::new(0);
let count = TRY.fetch_add(1, std::sync::atomic::Ordering::Relaxed);

tracing::debug!("Handle device access token request");

if device_code != "DC001" {
return Err(StatusCode::BAD_REQUEST);
return StatusCode::BAD_REQUEST.into_response();
}
// mock user input duration
tokio::time::sleep(Duration::from_secs(1)).await;

let res = DeviceAccessTokenResponse {
access_token: "gh_dummy_access_token".into(),
token_type: String::new(),
expires_in: None,
refresh_token: None,
id_token: None,
};

Ok(Json(res))
match count {
0 => (
StatusCode::BAD_REQUEST,
Json(DeviceAccessTokenErrorResponse {
error: synd_auth::device_flow::DeviceAccessTokenErrorCode::AuthorizationPending,
error_description: None,
error_uri: None,
}),
)
.into_response(),
1 => (
StatusCode::PRECONDITION_REQUIRED,
Json(DeviceAccessTokenErrorResponse {
error: synd_auth::device_flow::DeviceAccessTokenErrorCode::SlowDown,
error_description: None,
error_uri: None,
}),
)
.into_response(),
_ => {
let res = DeviceAccessTokenResponse {
access_token: "gh_dummy_access_token".into(),
token_type: String::new(),
expires_in: None,
refresh_token: None,
id_token: None,
};

Json(res).into_response()
}
}
}

async fn google_device_access_token(
Expand Down

0 comments on commit 708cbf4

Please sign in to comment.