use http::header::LOCATION;
use serde::Serialize;
use crate::auth::X_AUTH_TOKEN;
use crate::types::{Collection, OdataId, Session};
use crate::{Error, Result, SessionToken};
#[cfg(feature = "_blocking")]
use crate::BlockingClient;
#[cfg(feature = "_async")]
use crate::Client;
#[derive(Debug, Clone)]
pub struct SessionLogin {
pub token: SessionToken,
pub location: String,
pub session: Option<Session>,
}
#[derive(Debug, Clone, Copy)]
pub struct SessionsService<'a, C> {
client: &'a C,
}
impl<'a, C> SessionsService<'a, C> {
pub(crate) fn new(client: &'a C) -> Self {
Self { client }
}
}
#[derive(Debug, Serialize)]
struct SessionCreateRequest<'a> {
#[serde(rename = "UserName")]
user_name: &'a str,
#[serde(rename = "Password")]
password: &'a str,
}
#[cfg(feature = "_async")]
impl<'a> SessionsService<'a, Client> {
pub async fn list(&self) -> Result<Collection<OdataId>> {
let url = self.client.redfish_url(&["SessionService", "Sessions"])?;
self.client.get_json(url).await
}
pub async fn get(&self, session_id: &str) -> Result<Session> {
let url = self
.client
.redfish_url(&["SessionService", "Sessions", session_id])?;
self.client.get_json(url).await
}
pub async fn create(&self, username: &str, password: &str) -> Result<SessionLogin> {
let url = self.client.redfish_url(&["SessionService", "Sessions"])?;
let req = SessionCreateRequest {
user_name: username,
password,
};
let response = self.client.post_json_raw(url, &req).await?;
let token = response
.headers
.get(X_AUTH_TOKEN.clone())
.and_then(|v| v.to_str().ok())
.map(SessionToken::new)
.ok_or_else(|| Error::auth("Missing X-Auth-Token in session response"))?;
let location = response
.headers
.get(LOCATION)
.and_then(|v| v.to_str().ok())
.map(str::to_string)
.ok_or_else(|| Error::auth("Missing Location in session response"))?;
let session = if response.body.is_empty() {
None
} else {
serde_json::from_slice::<Session>(&response.body).ok()
};
Ok(SessionLogin {
token,
location,
session,
})
}
pub async fn delete(&self, location: &str) -> Result<()> {
let url = self.client.resolve_uri(location)?;
self.client.delete_raw(url).await?;
Ok(())
}
}
#[cfg(feature = "_blocking")]
impl<'a> SessionsService<'a, BlockingClient> {
pub fn list(&self) -> Result<Collection<OdataId>> {
let url = self.client.redfish_url(&["SessionService", "Sessions"])?;
self.client.get_json(url)
}
pub fn get(&self, session_id: &str) -> Result<Session> {
let url = self
.client
.redfish_url(&["SessionService", "Sessions", session_id])?;
self.client.get_json(url)
}
pub fn create(&self, username: &str, password: &str) -> Result<SessionLogin> {
let url = self.client.redfish_url(&["SessionService", "Sessions"])?;
let req = SessionCreateRequest {
user_name: username,
password,
};
let response = self.client.post_json_raw(url, &req)?;
let token = response
.headers
.get(X_AUTH_TOKEN.clone())
.and_then(|v| v.to_str().ok())
.map(SessionToken::new)
.ok_or_else(|| Error::auth("Missing X-Auth-Token in session response"))?;
let location = response
.headers
.get(LOCATION)
.and_then(|v| v.to_str().ok())
.map(str::to_string)
.ok_or_else(|| Error::auth("Missing Location in session response"))?;
let session = if response.body.is_empty() {
None
} else {
serde_json::from_slice::<Session>(&response.body).ok()
};
Ok(SessionLogin {
token,
location,
session,
})
}
pub fn delete(&self, location: &str) -> Result<()> {
let url = self.client.resolve_uri(location)?;
self.client.delete_raw(url)?;
Ok(())
}
}