Files
Oxicloud/src/application/dtos/device_auth_dto.rs
T

97 lines
3.2 KiB
Rust
Raw Normal View History

//! DTOs for OAuth 2.0 Device Authorization Grant (RFC 8628).
use serde::{Deserialize, Serialize};
// ============================================================================
// Request DTOs
// ============================================================================
/// POST /api/auth/device/authorize — request body
#[derive(Debug, Deserialize)]
pub struct DeviceAuthorizeRequestDto {
/// Human-readable name of the client (e.g. "rclone", "DAVx⁵")
#[serde(default = "default_client_name")]
pub client_name: String,
/// Comma-separated scopes (e.g. "webdav,caldav,carddav")
#[serde(default = "default_scopes")]
pub scope: String,
}
fn default_client_name() -> String {
"Unknown Client".to_string()
}
fn default_scopes() -> String {
"webdav,caldav,carddav".to_string()
}
/// POST /api/auth/device/verify — user submits the code from the browser
#[derive(Debug, Deserialize)]
pub struct DeviceVerifyRequestDto {
/// The user_code displayed on the client device
pub user_code: String,
/// Whether the user approves ("approve") or denies ("deny")
pub action: String,
}
/// POST /api/auth/device/token — client polls for tokens
#[derive(Debug, Deserialize)]
pub struct DeviceTokenRequestDto {
/// The device_code received from the initial authorize call
pub device_code: String,
/// Must be "urn:ietf:params:oauth:grant-type:device_code"
#[serde(default)]
pub grant_type: String,
}
// ============================================================================
// Response DTOs
// ============================================================================
/// Response to POST /api/auth/device/authorize (RFC 8628 §3.2)
#[derive(Debug, Serialize)]
pub struct DeviceAuthorizeResponseDto {
/// The device verification code
pub device_code: String,
/// The end-user verification code (short, human-readable)
pub user_code: String,
/// The end-user verification URI
pub verification_uri: String,
/// Optional: verification URI with user_code pre-filled
#[serde(skip_serializing_if = "Option::is_none")]
pub verification_uri_complete: Option<String>,
/// Lifetime in seconds of the device_code and user_code
pub expires_in: i64,
/// Minimum polling interval in seconds
pub interval: i32,
}
/// Response to POST /api/auth/device/token when authorization is still pending
#[derive(Debug, Serialize)]
pub struct DeviceTokenPendingDto {
pub error: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub error_description: Option<String>,
}
/// Response to POST /api/auth/device/token when authorization is complete
#[derive(Debug, Serialize)]
pub struct DeviceTokenSuccessDto {
pub access_token: String,
pub token_type: String,
pub refresh_token: String,
pub expires_in: i64,
pub scope: String,
}
/// GET /api/auth/device/verify — info about the pending device code
#[derive(Debug, Serialize)]
pub struct DeviceVerifyInfoDto {
/// The client name requesting access
pub client_name: String,
/// Scopes being requested
pub scopes: String,
/// Whether the user_code is valid and pending
pub valid: bool,
}