Add Api-Logic
- THIS COMMIT IS ONLY FOR DATA SAFETY PURPOSES - Missing: corrent auth token generation - clean format/ "use" - will fix both in an upcoming commit
This commit is contained in:
27
examples/auth.rs
Normal file
27
examples/auth.rs
Normal file
@@ -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<dyn std::error::Error>> {
|
||||
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(())
|
||||
}
|
||||
@@ -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<HttpsConnector<HttpConnector>>,
|
||||
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<AuthResponse, ApiError> {
|
||||
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(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<bool>,
|
||||
conversations: Option<Vec<Conversation>>,
|
||||
has_more: Option<bool>,
|
||||
conversations: Option<Vec<Conversation>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Conversation {
|
||||
access: Option<Access>,
|
||||
creator: Option<String>,
|
||||
access_role: Option<String>,
|
||||
members: Option<ConversationMembers>,
|
||||
name: Option<String>,
|
||||
team: Option<String>,
|
||||
id: Option<String>,
|
||||
r#type: Option<u32>,
|
||||
receipt_mode: Option<u32>,
|
||||
last_event_time: String,
|
||||
message_timer: Option<u32>,
|
||||
last_event: Option<String>,
|
||||
access: Option<Access>,
|
||||
creator: Option<String>,
|
||||
access_role: Option<String>,
|
||||
members: Option<ConversationMembers>,
|
||||
name: Option<String>,
|
||||
team: Option<String>,
|
||||
id: Option<String>,
|
||||
r#type: Option<u32>,
|
||||
receipt_mode: Option<u32>,
|
||||
last_event_time: String,
|
||||
message_timer: Option<u32>,
|
||||
last_event: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Access {
|
||||
#[serde(rename = "0")]
|
||||
_0: Option<String>,
|
||||
#[serde(rename = "0")]
|
||||
_0: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct ConversationMembers {
|
||||
#[serde(rename = "self")]
|
||||
self_: Option<Member>,
|
||||
others: Option<Vec<OtherMember>>,
|
||||
#[serde(rename = "self")]
|
||||
self_: Option<Member>,
|
||||
others: Option<Vec<OtherMember>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Member {
|
||||
hidden_ref: Option<String>,
|
||||
stauts: Option<u32>,
|
||||
service: Option<ServiceRef>,
|
||||
otr_muted_ref: Option<String>,
|
||||
conversation_role: Option<String>,
|
||||
status_time: Option<String>,
|
||||
hidden: Option<bool>,
|
||||
status_ref: Option<String>,
|
||||
id: Option<String>,
|
||||
otr_archived: Option<bool>,
|
||||
otr_muted_status: Option<String>,
|
||||
otr_muted: Option<bool>,
|
||||
otr_archived_ref: Option<String>,
|
||||
hidden_ref: Option<String>,
|
||||
stauts: Option<u32>,
|
||||
service: Option<ServiceRef>,
|
||||
otr_muted_ref: Option<String>,
|
||||
conversation_role: Option<String>,
|
||||
status_time: Option<String>,
|
||||
hidden: Option<bool>,
|
||||
status_ref: Option<String>,
|
||||
id: Option<String>,
|
||||
otr_archived: Option<bool>,
|
||||
otr_muted_status: Option<String>,
|
||||
otr_muted: Option<bool>,
|
||||
otr_archived_ref: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct OtherMember {
|
||||
status: Option<u32>,
|
||||
conversation_role: Option<String>,
|
||||
id: Option<String>,
|
||||
status: Option<u32>,
|
||||
conversation_role: Option<String>,
|
||||
id: Option<String>,
|
||||
}
|
||||
|
||||
#[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<Conversations, ApiError> {
|
||||
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<Conversations, ApiError> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
19
src/net/wire_api/members.rs
Normal file
19
src/net/wire_api/members.rs
Normal file
@@ -0,0 +1,19 @@
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
use crate::net::wire_api::{error::ApiError};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Members {
|
||||
user: Option<String>,
|
||||
created_by: Option<String>,
|
||||
legalhold_status: Option<String>,
|
||||
created_at: Option<String>,
|
||||
permissions: Option<Permissions>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Permissions {
|
||||
copy: Option<u32>,
|
||||
#[serde(rename = "self")]
|
||||
self_: Option<u32>,
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
58
src/net/wire_api/self_info.rs
Normal file
58
src/net/wire_api/self_info.rs
Normal file
@@ -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<String>,
|
||||
handle: Option<String>,
|
||||
locale: Option<String>,
|
||||
managed_by: Option<String>,
|
||||
accent_id: Option<u32>,
|
||||
picture: Option<Vec<u32>>,
|
||||
name: Option<String>,
|
||||
pub team: Option<String>,
|
||||
id: Option<String>,
|
||||
assests: Option<Vec<UserAssets>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct UserAssets {
|
||||
size: Option<String>,
|
||||
key: Option<String>,
|
||||
r#type: Option<String>,
|
||||
}
|
||||
|
||||
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(())
|
||||
}
|
||||
}
|
||||
132
src/net/wire_api/wire_client.rs
Normal file
132
src/net/wire_api/wire_client.rs
Normal file
@@ -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<AuthResponse>,
|
||||
pub client: Client<HttpsConnector<HttpConnector>>,
|
||||
pub config: Config,
|
||||
pub self_info: Option<SelfInfo>,
|
||||
pub conversations: Option<Conversations>,
|
||||
pub members: Option<Members>
|
||||
}
|
||||
|
||||
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<T>(
|
||||
&mut self,
|
||||
endpoint: String,
|
||||
body_content: String) -> Result<T, ApiError>
|
||||
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<T>(
|
||||
&mut self,
|
||||
endpoint: String) -> Result<T, ApiError>
|
||||
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<AuthResponse, ApiError> {
|
||||
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)
|
||||
}
|
||||
*/
|
||||
}
|
||||
Reference in New Issue
Block a user