use std::collections::{BTreeSet, HashMap};
use std::fmt::{Display, Formatter};
use std::str::FromStr;
use serde_json::Value;
#[cfg(feature = "interactive-auth")]
use graph_core::http::JsonHttpResponse;
#[cfg(feature = "interactive-auth")]
use crate::interactive::WindowCloseReason;
#[cfg(feature = "interactive-auth")]
use crate::identity::{DeviceCodeCredential, PublicClientApplication};
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct DeviceAuthorizationResponse {
pub device_code: String,
pub expires_in: u64,
#[serde(default = "default_interval")]
pub interval: u64,
pub message: String,
pub user_code: String,
pub verification_uri: String,
pub verification_uri_complete: Option<String>,
pub scopes: Option<BTreeSet<String>>,
#[serde(flatten)]
pub additional_fields: HashMap<String, Value>,
}
fn default_interval() -> u64 {
5
}
impl Display for DeviceAuthorizationResponse {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}, {}, {}, {}, {}, {}, {:#?}, {:#?}",
self.device_code,
self.expires_in,
self.interval,
self.message,
self.user_code,
self.verification_uri,
self.verification_uri_complete,
self.scopes
)
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub enum PollDeviceCodeEvent {
AuthorizationPending,
AuthorizationDeclined,
BadVerificationCode,
ExpiredToken,
AccessDenied,
SlowDown,
}
impl PollDeviceCodeEvent {
pub fn as_str(&self) -> &'static str {
match self {
PollDeviceCodeEvent::AuthorizationPending => "authorization_pending",
PollDeviceCodeEvent::AuthorizationDeclined => "authorization_declined",
PollDeviceCodeEvent::BadVerificationCode => "bad_verification_code",
PollDeviceCodeEvent::ExpiredToken => "expired_token",
PollDeviceCodeEvent::AccessDenied => "access_denied",
PollDeviceCodeEvent::SlowDown => "slow_down",
}
}
}
impl FromStr for PollDeviceCodeEvent {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"authorization_pending" => Ok(PollDeviceCodeEvent::AuthorizationPending),
"authorization_declined" => Ok(PollDeviceCodeEvent::AuthorizationDeclined),
"bad_verification_code" => Ok(PollDeviceCodeEvent::BadVerificationCode),
"expired_token" => Ok(PollDeviceCodeEvent::ExpiredToken),
"access_denied" => Ok(PollDeviceCodeEvent::AccessDenied),
"slow_down" => Ok(PollDeviceCodeEvent::SlowDown),
_ => Err(()),
}
}
}
impl AsRef<str> for PollDeviceCodeEvent {
fn as_ref(&self) -> &str {
self.as_str()
}
}
impl Display for PollDeviceCodeEvent {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.as_str())
}
}
#[cfg(feature = "interactive-auth")]
#[derive(Debug)]
pub enum InteractiveDeviceCodeEvent {
DeviceAuthorizationResponse {
response: JsonHttpResponse,
device_authorization_response: Option<DeviceAuthorizationResponse>,
},
PollDeviceCode {
poll_device_code_event: PollDeviceCodeEvent,
response: JsonHttpResponse,
},
WindowClosed(WindowCloseReason),
SuccessfulAuthEvent {
response: JsonHttpResponse,
public_application: PublicClientApplication<DeviceCodeCredential>,
},
}