diff --git a/examples/auth.rs b/examples/auth.rs new file mode 100644 index 0000000..ec52ca3 --- /dev/null +++ b/examples/auth.rs @@ -0,0 +1,27 @@ +use std::env; + +use irssi_wire::net::wire_api::{ + wire_client::WireClient, + auth::Config, + conversations::Conversations, + members::Members, + self_info::SelfInfo, +}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let mut client = WireClient::new( + env::var("EMAIL").unwrap(), + env::var("PW").unwrap(), + Config::Default, + ); + + let auth_response = client + .authentification() + .await + .unwrap(); + + dbg!(client); + + Ok(()) +} diff --git a/src/net/wire_api/auth.rs b/src/net/wire_api/auth.rs index 619208f..7fc5662 100644 --- a/src/net/wire_api/auth.rs +++ b/src/net/wire_api/auth.rs @@ -4,11 +4,9 @@ use hyper::{header, Body, Client, Method, Request}; use hyper_tls::HttpsConnector; use serde::{Deserialize, Serialize}; +use crate::net::wire_api::wire_client::{WireClient}; use crate::net::wire_api::error::ApiError; -const USER_AGENT: &str = "irssi"; -const CONTENT_TYPE: &str = "application/json"; - #[derive(Debug, Clone)] pub struct ConnectionUrls { pub websocket: String, @@ -35,8 +33,8 @@ impl Config { #[derive(Serialize, Deserialize, Debug)] pub struct LoginInfo { - email: String, - password: String, + pub email: String, + pub password: String, } #[derive(Serialize, Deserialize, Debug)] @@ -53,51 +51,39 @@ impl AuthResponse { } } -pub struct WireClient { - login_info: LoginInfo, - pub client: Client>, - pub config: Config, -} - +// TODO move auth here impl WireClient { - pub fn new(email: String, password: String, config: Config) -> WireClient { - let https_client = Client::builder().build::<_, hyper::Body>(HttpsConnector::new()); - WireClient { - login_info: LoginInfo { email, password }, - client: https_client, - config: config, - } - } - - pub async fn authentification(&mut self) -> Result { + pub async fn authentification(&mut self) -> Result<(), ApiError> { let endpoint = [ self.config.fetch().rest_url, - "/login?persist=true".to_string(), - ] - .concat(); - let json = serde_json::to_string(&self.login_info).unwrap(); + String::from("/login?persist=true") + ].concat(); + + let json = serde_json::to_string(&self.login_info) + .unwrap(); let auth_request = Request::builder() .method(Method::POST) .uri(endpoint) - .header(header::CONTENT_TYPE, CONTENT_TYPE) - .header(header::USER_AGENT, USER_AGENT) + .header(header::CONTENT_TYPE, "application/json") + .header(header::USER_AGENT, &self.user_agent) .body(Body::from(json)) .unwrap(); - let auth_result = self - .client + let auth_response = self.client .request(auth_request) .await .map_err(|e| ApiError::HttpError(e))?; - let auth_body = hyper::body::aggregate(auth_result) + let body = hyper::body::aggregate(auth_response) .await .map_err(|e| ApiError::HttpError(e))?; - let auth_response = serde_json::from_reader(auth_body.bytes()) + let parsed_json = serde_json::from_reader(body.bytes()) .map_err(|e| ApiError::JsonParseError(Box::new(e)))?; - Ok(auth_response) + self.auth_token = Some(parsed_json); + + Ok(()) } } diff --git a/src/net/wire_api/conversations.rs b/src/net/wire_api/conversations.rs index 28123a6..a74a5c9 100644 --- a/src/net/wire_api/conversations.rs +++ b/src/net/wire_api/conversations.rs @@ -4,94 +4,95 @@ use hyper::{header, Body, Client, Method, Request}; use hyper_tls::HttpsConnector; use serde::{Deserialize, Serialize}; -use crate::net::wire_api::auth::{AuthResponse, Config, WireClient}; -use crate::net::wire_api::error::ApiError; - -const CONTENT_TYPE: &str = "application/json"; -const USER_AGENT: &str = "irssi"; +use crate::net::wire_api::{ + wire_client::WireClient, + auth::AuthResponse, + error::ApiError}; #[derive(Serialize, Deserialize, Debug)] pub struct Conversations { - has_more: Option, - conversations: Option>, +has_more: Option, +conversations: Option>, } #[derive(Serialize, Deserialize, Debug)] pub struct Conversation { - access: Option, - creator: Option, - access_role: Option, - members: Option, - name: Option, - team: Option, - id: Option, - r#type: Option, - receipt_mode: Option, - last_event_time: String, - message_timer: Option, - last_event: Option, +access: Option, +creator: Option, +access_role: Option, +members: Option, +name: Option, +team: Option, +id: Option, +r#type: Option, +receipt_mode: Option, +last_event_time: String, +message_timer: Option, +last_event: Option, } #[derive(Serialize, Deserialize, Debug)] pub struct Access { - #[serde(rename = "0")] - _0: Option, +#[serde(rename = "0")] +_0: Option, } #[derive(Serialize, Deserialize, Debug)] pub struct ConversationMembers { - #[serde(rename = "self")] - self_: Option, - others: Option>, +#[serde(rename = "self")] +self_: Option, +others: Option>, } #[derive(Serialize, Deserialize, Debug)] pub struct Member { - hidden_ref: Option, - stauts: Option, - service: Option, - otr_muted_ref: Option, - conversation_role: Option, - status_time: Option, - hidden: Option, - status_ref: Option, - id: Option, - otr_archived: Option, - otr_muted_status: Option, - otr_muted: Option, - otr_archived_ref: Option, +hidden_ref: Option, +stauts: Option, +service: Option, +otr_muted_ref: Option, +conversation_role: Option, +status_time: Option, +hidden: Option, +status_ref: Option, +id: Option, +otr_archived: Option, +otr_muted_status: Option, +otr_muted: Option, +otr_archived_ref: Option, } #[derive(Serialize, Deserialize, Debug)] pub struct OtherMember { - status: Option, - conversation_role: Option, - id: Option, +status: Option, +conversation_role: Option, +id: Option, } #[derive(Serialize, Deserialize, Debug)] pub struct ServiceRef { - id: String, - provider: String, +id: String, +provider: String, } +// TODO delete this +/* impl WireClient { - pub async fn fetch_conversations( - &mut self, - auth_response: &AuthResponse, - ) -> Result { - let endpoint = [ - self.config.fetch().rest_url, - String::from("/conversations?size=500"), - ] - .concat(); - let auth_token = auth_response.token_string(); + pub async fn fetch_conversations( + &mut self, + auth_response: &AuthResponse, +) -> Result { + let endpoint = [ + self.config.fetch().rest_url, + String::from("/conversations?size=500"), + ] + .concat(); + let auth_token = auth_response.token_string(); - let fetch_request = Request::builder() - .method(Method::GET) - .uri(endpoint) - .header(header::CONTENT_TYPE, CONTENT_TYPE) - .header(header::USER_AGENT, USER_AGENT) + let fetch_request = Request::builder() + .method(Method::GET) + .uri(endpoint) + .header(header::CONTENT_TYPE, "application/json") + .header(header::USER_AGENT, self.user_agent) .header(header::AUTHORIZATION, auth_token) .body(Body::empty()) .unwrap(); @@ -112,3 +113,4 @@ impl WireClient { Ok(fetch_response) } } +*/ diff --git a/src/net/wire_api/members.rs b/src/net/wire_api/members.rs new file mode 100644 index 0000000..d1c734b --- /dev/null +++ b/src/net/wire_api/members.rs @@ -0,0 +1,19 @@ +use serde::{Serialize, Deserialize}; + +use crate::net::wire_api::{error::ApiError}; + +#[derive(Serialize, Deserialize, Debug)] +pub struct Members { + user: Option, + created_by: Option, + legalhold_status: Option, + created_at: Option, + permissions: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct Permissions { + copy: Option, + #[serde(rename = "self")] + self_: Option, +} diff --git a/src/net/wire_api/mod.rs b/src/net/wire_api/mod.rs index 9db02b3..e3db7ca 100644 --- a/src/net/wire_api/mod.rs +++ b/src/net/wire_api/mod.rs @@ -1,3 +1,7 @@ -pub mod auth; -pub mod conversations; pub mod error; + +pub mod wire_client; +pub mod auth; +pub mod self_info; +pub mod conversations; +pub mod members; diff --git a/src/net/wire_api/self_info.rs b/src/net/wire_api/self_info.rs new file mode 100644 index 0000000..354d65c --- /dev/null +++ b/src/net/wire_api/self_info.rs @@ -0,0 +1,58 @@ +use serde::{Serialize, Deserialize}; + +use crate::net::wire_api::wire_client::WireClient; +use crate::net::wire_api::error::ApiError; + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct SelfInfo { + email: Option, + handle: Option, + locale: Option, + managed_by: Option, + accent_id: Option, + picture: Option>, + name: Option, + pub team: Option, + id: Option, + assests: Option>, +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct UserAssets { + size: Option, + key: Option, + r#type: Option, +} + +impl WireClient { + pub async fn fetch_self(&mut self) -> Result<(), ApiError> { + self.self_info = Some(self + .api_get(String::from("/self")) + .await + .unwrap()); + + Ok(()) + } + + pub async fn fetch_conversations(&mut self) -> Result<(), ApiError> { + self.conversations = Some(self + .api_get(String::from("/conversations?size=500")) + .await + .unwrap()); + + Ok(()) + } + + pub async fn fetch_members(&mut self) -> Result<(), ApiError>{ + self.members = Some(self + .api_get(String::from( + [String::from("/teams/"), + self.self_info.clone().unwrap().team.unwrap(), + String::from("/members"),].concat() + )) + .await + .unwrap()); + + Ok(()) + } +} diff --git a/src/net/wire_api/wire_client.rs b/src/net/wire_api/wire_client.rs new file mode 100644 index 0000000..e16933b --- /dev/null +++ b/src/net/wire_api/wire_client.rs @@ -0,0 +1,132 @@ +use hyper::body::Buf; +use hyper::{ + client::connect::HttpConnector, + {header, Body, Client, Method, Request}}; +use hyper_tls::HttpsConnector; + +use crate::net::wire_api::error::ApiError; +use crate::net::wire_api::auth::{LoginInfo, AuthResponse, Config}; +use crate::net::wire_api::{ + self_info::SelfInfo, + conversations::Conversations, + members::Members, +}; + +#[derive(Debug)] +pub struct WireClient { + pub user_agent: String, + pub login_info: LoginInfo, + pub auth_token: Option, + pub client: Client>, + pub config: Config, + pub self_info: Option, + pub conversations: Option, + pub members: Option +} + +impl WireClient { + pub fn new(email: String, password: String, config: Config) -> WireClient { + let https_client = Client::builder().build::<_, hyper::Body>(HttpsConnector::new()); + WireClient { + user_agent: String::from("irssi"), + login_info: LoginInfo { email, password }, + auth_token: None, + client: https_client, + config: config, + self_info: None, + conversations: None, + members: None, + } + } + + pub async fn api_post( + &mut self, + endpoint: String, + body_content: String) -> Result + where T: serde::de::DeserializeOwned { + let api_request = Request::builder() + .method(Method::POST) + .uri(endpoint) + .header(header::CONTENT_TYPE, "application/json") + .header(header::USER_AGENT, &self.user_agent) + .header(header::AUTHORIZATION, self.auth_token.as_ref().unwrap().token_string()) + .body(Body::from(body_content)) + .unwrap(); + + let api_response = self.client + .request(api_request) + .await + .map_err(|e| ApiError::HttpError(e))?; + + let body = hyper::body::aggregate(api_response) + .await + .map_err(|e| ApiError::HttpError(e))?; + + let parsed_json = serde_json::from_reader(body.bytes()) + .map_err(|e| ApiError::JsonParseError(Box::new(e)))?; + + Ok(parsed_json) + } + + pub async fn api_get( + &mut self, + endpoint: String) -> Result + where T: serde::de::DeserializeOwned { + let api_request = Request::builder() + .method(Method::GET) + .uri([self.config.fetch().rest_url, endpoint].concat()) + .header(header::CONTENT_TYPE, "application/json") + .header(header::USER_AGENT, &self.user_agent) + .header(header::AUTHORIZATION, self.auth_token.as_ref().unwrap().token_string()) + .body(Body::empty()) + .unwrap(); + + let api_response = self.client + .request(api_request) + .await + .map_err(|e| ApiError::HttpError(e))?; + + let body = hyper::body::aggregate(api_response) + .await.map_err(|e| ApiError::HttpError(e))?; + + let parsed_json = serde_json::from_reader(body.bytes()) + .map_err(|e| ApiError::JsonParseError(Box::new(e)))?; + + Ok(parsed_json) + } + + /* + // TODO delete this + pub async fn authentification(&mut self) -> Result { + let endpoint = [ + self.config.fetch().rest_url, + "/login?persist=true".to_string(), + ] + .concat(); + let json = serde_json::to_string(&self.login_info).unwrap(); + + let auth_request = Request::builder() + .method(Method::POST) + .uri(endpoint) + .header(header::CONTENT_TYPE, "application/json") + .header(header::USER_AGENT, self.user_agent) + .body(Body::from(json)) + .unwrap(); + + let auth_result = self + .client + .request(auth_request) + .await + .map_err(|e| ApiError::HttpError(e))?; + + let auth_body = hyper::body::aggregate(auth_result) + .await + .map_err(|e| ApiError::HttpError(e))?; + + let auth_response = serde_json::from_reader(auth_body.bytes()) + .map_err(|e| ApiError::JsonParseError(Box::new(e)))?; + + Ok(auth_response) + } + */ +}