Add API calls and their infrastructure
- Add dependencies - Add authentification (email, password) - Add token request - Fetch /self - Fetch /conversations - Add infrastructure for above - Add auth example
This commit is contained in:
13
Cargo.toml
13
Cargo.toml
@@ -10,15 +10,18 @@ bindgen = "0.50"
|
|||||||
protoc-rust = "2.8.1"
|
protoc-rust = "2.8.1"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["dylib"]
|
crate-type = ["rlib","dylib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
diesel = { version = "1.4.2", features=["sqlite"] }
|
|
||||||
cryptobox = { git = "https://github.com/wireapp/cryptobox.git", branch = "develop" }
|
cryptobox = { git = "https://github.com/wireapp/cryptobox.git", branch = "develop" }
|
||||||
proteus = { git = "https://github.com/wireapp/proteus", branch = "develop" }
|
proteus = { git = "https://github.com/wireapp/proteus", branch = "develop" }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
|
||||||
serde_json = "1.0"
|
|
||||||
protobuf = "2.8.1"
|
protobuf = "2.8.1"
|
||||||
chrono = { version = "0.4", features = ["serde"] }
|
|
||||||
uuid = { version = "0.7", features = ["serde", "v4"] }
|
uuid = { version = "0.7", features = ["serde", "v4"] }
|
||||||
base64 = "0.10.1"
|
base64 = "0.10.1"
|
||||||
|
tungstenite = "0.9.2"
|
||||||
|
hyper = "0.13.1"
|
||||||
|
hyper-tls = "0.4.0"
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
serde_json = "1.0"
|
||||||
|
tokio = { version = "0.2.6", features = ["full"] }
|
||||||
|
|
||||||
|
|||||||
16
build.rs
16
build.rs
@@ -1,7 +1,7 @@
|
|||||||
use std::path::PathBuf;
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::io::prelude::*;
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
|
use std::io::prelude::*;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use protoc_rust::Customize;
|
use protoc_rust::Customize;
|
||||||
|
|
||||||
@@ -14,7 +14,8 @@ typedef struct _WireServerRec {
|
|||||||
int x;
|
int x;
|
||||||
} WireServerRec;
|
} WireServerRec;
|
||||||
|
|
||||||
#define STRUCT_SERVER_REC WireServerRec".to_string();
|
#define STRUCT_SERVER_REC WireServerRec"
|
||||||
|
.to_string();
|
||||||
|
|
||||||
let mut recs = File::create("recs.h").unwrap();
|
let mut recs = File::create("recs.h").unwrap();
|
||||||
recs.write_all(server_rec.as_bytes()).unwrap();
|
recs.write_all(server_rec.as_bytes()).unwrap();
|
||||||
@@ -33,8 +34,7 @@ typedef struct _WireServerRec {
|
|||||||
bindings
|
bindings
|
||||||
.write_to_file("src/irssi/bindgen_output.rs")
|
.write_to_file("src/irssi/bindgen_output.rs")
|
||||||
.expect("Couldn't write bindings!");
|
.expect("Couldn't write bindings!");
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
eprintln!("Skipping C binding generation");
|
eprintln!("Skipping C binding generation");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,9 +48,9 @@ typedef struct _WireServerRec {
|
|||||||
customize: Customize {
|
customize: Customize {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
}).expect("Couln't generate code from protobuffers for wire api");
|
})
|
||||||
}
|
.expect("Couln't generate code from protobuffers for wire api");
|
||||||
else {
|
} else {
|
||||||
eprintln!("Skipping protobuf generation");
|
eprintln!("Skipping protobuf generation");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
17
examples/auth.rs
Normal file
17
examples/auth.rs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
use irssi_wire::net::wire_api::auth::*;
|
||||||
|
use irssi_wire::net::wire_api::conversations::*;
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let mut client = WireClient::new(
|
||||||
|
String::from("marco_thomas@genua.de"),
|
||||||
|
String::from("MarcMK1337#"),
|
||||||
|
Config::Default,
|
||||||
|
);
|
||||||
|
|
||||||
|
let auth_response = client.authentification().await.unwrap();
|
||||||
|
|
||||||
|
let conversations = client.fetch_conversations(&auth_response).await.unwrap();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
19
src/lib.rs
19
src/lib.rs
@@ -1,28 +1,31 @@
|
|||||||
use std::os::raw::c_int;
|
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
|
use std::os::raw::c_int;
|
||||||
|
|
||||||
mod irssi;
|
mod irssi;
|
||||||
mod net;
|
pub mod net;
|
||||||
|
|
||||||
use irssi::bindings::*;
|
use irssi::bindings::*;
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern fn wire_core_abicheck(version: *mut c_int) {
|
pub extern "C" fn wire_core_abicheck(version: *mut c_int) {
|
||||||
unsafe {
|
unsafe {
|
||||||
*version = 23;
|
*version = 24;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern fn wire_core_init() {
|
pub extern "C" fn wire_core_init() {
|
||||||
println!("HEY");
|
println!("HEY");
|
||||||
unsafe {
|
unsafe {
|
||||||
module_register_full(CString::new("wire").unwrap().as_ptr(), CString::new("core").unwrap().as_ptr(), CString::new("wire/core").unwrap().as_ptr());
|
module_register_full(
|
||||||
|
CString::new("wire").unwrap().as_ptr(),
|
||||||
|
CString::new("core").unwrap().as_ptr(),
|
||||||
|
CString::new("wire/core").unwrap().as_ptr(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern fn wire_core_deinit() {
|
pub extern "C" fn wire_core_deinit() {
|
||||||
println!("BYE");
|
println!("BYE");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
pub mod protos;
|
pub mod protos;
|
||||||
|
pub mod wire_api;
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
pub mod wire_api;
|
pub mod wire_websocket;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// This file is generated by rust-protobuf 2.8.1. Do not edit
|
// This file is generated by rust-protobuf 2.10.0. Do not edit
|
||||||
// @generated
|
// @generated
|
||||||
|
|
||||||
// https://github.com/Manishearth/rust-clippy/issues/702
|
// https://github.com/Manishearth/rust-clippy/issues/702
|
||||||
@@ -17,14 +17,14 @@
|
|||||||
#![allow(unsafe_code)]
|
#![allow(unsafe_code)]
|
||||||
#![allow(unused_imports)]
|
#![allow(unused_imports)]
|
||||||
#![allow(unused_results)]
|
#![allow(unused_results)]
|
||||||
//! Generated file from `wire-api.proto`
|
//! Generated file from `wire_websocket.proto`
|
||||||
|
|
||||||
use protobuf::Message as Message_imported_for_functions;
|
use protobuf::Message as Message_imported_for_functions;
|
||||||
use protobuf::ProtobufEnum as ProtobufEnum_imported_for_functions;
|
use protobuf::ProtobufEnum as ProtobufEnum_imported_for_functions;
|
||||||
|
|
||||||
/// Generated files are compatible only with the same version
|
/// Generated files are compatible only with the same version
|
||||||
/// of protobuf runtime.
|
/// of protobuf runtime.
|
||||||
const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_8_1;
|
const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_10_0;
|
||||||
|
|
||||||
#[derive(PartialEq,Clone,Default)]
|
#[derive(PartialEq,Clone,Default)]
|
||||||
pub struct GenericMessage {
|
pub struct GenericMessage {
|
||||||
@@ -10612,89 +10612,89 @@ impl ::protobuf::reflect::ProtobufValue for LegalHoldStatus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static file_descriptor_proto_data: &'static [u8] = b"\
|
static file_descriptor_proto_data: &'static [u8] = b"\
|
||||||
\n\x0ewire-api.proto\"\xf3\x05\n\x0eGenericMessage\x12\x1d\n\nmessage_id\
|
\n\x14wire_websocket.proto\"\xf3\x05\n\x0eGenericMessage\x12\x1d\n\nmess\
|
||||||
\x18\x01\x20\x02(\tR\tmessageId\x12\x1b\n\x04text\x18\x02\x20\x01(\x0b2\
|
age_id\x18\x01\x20\x02(\tR\tmessageId\x12\x1b\n\x04text\x18\x02\x20\x01(\
|
||||||
|
\x0b2\x05.TextH\0R\x04text\x12#\n\x05image\x18\x03\x20\x01(\x0b2\x0b.Ima\
|
||||||
|
geAssetH\0R\x05image\x12\x1e\n\x05knock\x18\x04\x20\x01(\x0b2\x06.KnockH\
|
||||||
|
\0R\x05knock\x12'\n\x08lastRead\x18\x06\x20\x01(\x0b2\t.LastReadH\0R\x08\
|
||||||
|
lastRead\x12$\n\x07cleared\x18\x07\x20\x01(\x0b2\x08.ClearedH\0R\x07clea\
|
||||||
|
red\x12'\n\x08external\x18\x08\x20\x01(\x0b2\t.ExternalH\0R\x08external\
|
||||||
|
\x123\n\x0cclientAction\x18\t\x20\x01(\x0e2\r.ClientActionH\0R\x0cclient\
|
||||||
|
Action\x12$\n\x07calling\x18\n\x20\x01(\x0b2\x08.CallingH\0R\x07calling\
|
||||||
|
\x12\x1e\n\x05asset\x18\x0b\x20\x01(\x0b2\x06.AssetH\0R\x05asset\x12&\n\
|
||||||
|
\x06hidden\x18\x0c\x20\x01(\x0b2\x0c.MessageHideH\0R\x06hidden\x12'\n\
|
||||||
|
\x08location\x18\r\x20\x01(\x0b2\t.LocationH\0R\x08location\x12*\n\x07de\
|
||||||
|
leted\x18\x0e\x20\x01(\x0b2\x0e.MessageDeleteH\0R\x07deleted\x12&\n\x06e\
|
||||||
|
dited\x18\x0f\x20\x01(\x0b2\x0c.MessageEditH\0R\x06edited\x123\n\x0cconf\
|
||||||
|
irmation\x18\x10\x20\x01(\x0b2\r.ConfirmationH\0R\x0cconfirmation\x12'\n\
|
||||||
|
\x08reaction\x18\x11\x20\x01(\x0b2\t.ReactionH\0R\x08reaction\x12*\n\tep\
|
||||||
|
hemeral\x18\x12\x20\x01(\x0b2\n.EphemeralH\0R\tephemeral\x123\n\x0cavail\
|
||||||
|
ability\x18\x13\x20\x01(\x0b2\r.AvailabilityH\0R\x0cavailabilityB\t\n\
|
||||||
|
\x07content\"k\n\x0cAvailability\x12&\n\x04type\x18\x01\x20\x02(\x0e2\
|
||||||
|
\x12.Availability.TypeR\x04type\"3\n\x04Type\x12\x08\n\x04NONE\x10\0\x12\
|
||||||
|
\r\n\tAVAILABLE\x10\x01\x12\x08\n\x04AWAY\x10\x02\x12\x08\n\x04BUSY\x10\
|
||||||
|
\x03\"\xf1\x01\n\tEphemeral\x12.\n\x13expire_after_millis\x18\x01\x20\
|
||||||
|
\x02(\x03R\x11expireAfterMillis\x12\x1b\n\x04text\x18\x02\x20\x01(\x0b2\
|
||||||
\x05.TextH\0R\x04text\x12#\n\x05image\x18\x03\x20\x01(\x0b2\x0b.ImageAss\
|
\x05.TextH\0R\x04text\x12#\n\x05image\x18\x03\x20\x01(\x0b2\x0b.ImageAss\
|
||||||
etH\0R\x05image\x12\x1e\n\x05knock\x18\x04\x20\x01(\x0b2\x06.KnockH\0R\
|
etH\0R\x05image\x12\x1e\n\x05knock\x18\x04\x20\x01(\x0b2\x06.KnockH\0R\
|
||||||
\x05knock\x12'\n\x08lastRead\x18\x06\x20\x01(\x0b2\t.LastReadH\0R\x08las\
|
\x05knock\x12\x1e\n\x05asset\x18\x05\x20\x01(\x0b2\x06.AssetH\0R\x05asse\
|
||||||
tRead\x12$\n\x07cleared\x18\x07\x20\x01(\x0b2\x08.ClearedH\0R\x07cleared\
|
t\x12'\n\x08location\x18\x06\x20\x01(\x0b2\t.LocationH\0R\x08locationB\t\
|
||||||
\x12'\n\x08external\x18\x08\x20\x01(\x0b2\t.ExternalH\0R\x08external\x12\
|
\n\x07content\"\x9f\x02\n\x04Text\x12\x18\n\x07content\x18\x01\x20\x02(\
|
||||||
3\n\x0cclientAction\x18\t\x20\x01(\x0e2\r.ClientActionH\0R\x0cclientActi\
|
\tR\x07content\x12/\n\x0clink_preview\x18\x03\x20\x03(\x0b2\x0c.LinkPrev\
|
||||||
on\x12$\n\x07calling\x18\n\x20\x01(\x0b2\x08.CallingH\0R\x07calling\x12\
|
iewR\x0blinkPreview\x12$\n\x08mentions\x18\x04\x20\x03(\x0b2\x08.Mention\
|
||||||
\x1e\n\x05asset\x18\x0b\x20\x01(\x0b2\x06.AssetH\0R\x05asset\x12&\n\x06h\
|
R\x08mentions\x12\x1c\n\x05quote\x18\x05\x20\x01(\x0b2\x06.QuoteR\x05quo\
|
||||||
idden\x18\x0c\x20\x01(\x0b2\x0c.MessageHideH\0R\x06hidden\x12'\n\x08loca\
|
te\x12A\n\x19expects_read_confirmation\x18\x06\x20\x01(\x08:\x05falseR\
|
||||||
tion\x18\r\x20\x01(\x0b2\t.LocationH\0R\x08location\x12*\n\x07deleted\
|
\x17expectsReadConfirmation\x12E\n\x11legal_hold_status\x18\x07\x20\x01(\
|
||||||
\x18\x0e\x20\x01(\x0b2\x0e.MessageDeleteH\0R\x07deleted\x12&\n\x06edited\
|
\x0e2\x10.LegalHoldStatus:\x07UNKNOWNR\x0flegalHoldStatus\"\xb5\x01\n\
|
||||||
\x18\x0f\x20\x01(\x0b2\x0c.MessageEditH\0R\x06edited\x123\n\x0cconfirmat\
|
\x05Knock\x12\"\n\thot_knock\x18\x01\x20\x02(\x08:\x05falseR\x08hotKnock\
|
||||||
ion\x18\x10\x20\x01(\x0b2\r.ConfirmationH\0R\x0cconfirmation\x12'\n\x08r\
|
\x12A\n\x19expects_read_confirmation\x18\x02\x20\x01(\x08:\x05falseR\x17\
|
||||||
eaction\x18\x11\x20\x01(\x0b2\t.ReactionH\0R\x08reaction\x12*\n\tephemer\
|
expectsReadConfirmation\x12E\n\x11legal_hold_status\x18\x03\x20\x01(\x0e\
|
||||||
al\x18\x12\x20\x01(\x0b2\n.EphemeralH\0R\tephemeral\x123\n\x0cavailabili\
|
2\x10.LegalHoldStatus:\x07UNKNOWNR\x0flegalHoldStatus\"\x8f\x02\n\x0bLin\
|
||||||
ty\x18\x13\x20\x01(\x0b2\r.AvailabilityH\0R\x0cavailabilityB\t\n\x07cont\
|
kPreview\x12\x10\n\x03url\x18\x01\x20\x02(\tR\x03url\x12\x1d\n\nurl_offs\
|
||||||
ent\"k\n\x0cAvailability\x12&\n\x04type\x18\x01\x20\x02(\x0e2\x12.Availa\
|
et\x18\x02\x20\x02(\x05R\turlOffset\x12$\n\x07article\x18\x03\x20\x01(\
|
||||||
bility.TypeR\x04type\"3\n\x04Type\x12\x08\n\x04NONE\x10\0\x12\r\n\tAVAIL\
|
\x0b2\x08.ArticleH\0R\x07article\x12#\n\rpermanent_url\x18\x05\x20\x01(\
|
||||||
ABLE\x10\x01\x12\x08\n\x04AWAY\x10\x02\x12\x08\n\x04BUSY\x10\x03\"\xf1\
|
\tR\x0cpermanentUrl\x12\x14\n\x05title\x18\x06\x20\x01(\tR\x05title\x12\
|
||||||
\x01\n\tEphemeral\x12.\n\x13expire_after_millis\x18\x01\x20\x02(\x03R\
|
\x18\n\x07summary\x18\x07\x20\x01(\tR\x07summary\x12\x1c\n\x05image\x18\
|
||||||
\x11expireAfterMillis\x12\x1b\n\x04text\x18\x02\x20\x01(\x0b2\x05.TextH\
|
\x08\x20\x01(\x0b2\x06.AssetR\x05image\x12\x1e\n\x05tweet\x18\t\x20\x01(\
|
||||||
\0R\x04text\x12#\n\x05image\x18\x03\x20\x01(\x0b2\x0b.ImageAssetH\0R\x05\
|
\x0b2\x06.TweetH\x01R\x05tweetB\t\n\x07previewB\x0b\n\tmeta_data\";\n\
|
||||||
image\x12\x1e\n\x05knock\x18\x04\x20\x01(\x0b2\x06.KnockH\0R\x05knock\
|
\x05Tweet\x12\x16\n\x06author\x18\x01\x20\x01(\tR\x06author\x12\x1a\n\
|
||||||
\x12\x1e\n\x05asset\x18\x05\x20\x01(\x0b2\x06.AssetH\0R\x05asset\x12'\n\
|
\x08username\x18\x02\x20\x01(\tR\x08username\"|\n\x07Article\x12#\n\rper\
|
||||||
\x08location\x18\x06\x20\x01(\x0b2\t.LocationH\0R\x08locationB\t\n\x07co\
|
manent_url\x18\x01\x20\x02(\tR\x0cpermanentUrl\x12\x14\n\x05title\x18\
|
||||||
ntent\"\x9f\x02\n\x04Text\x12\x18\n\x07content\x18\x01\x20\x02(\tR\x07co\
|
\x02\x20\x01(\tR\x05title\x12\x18\n\x07summary\x18\x03\x20\x01(\tR\x07su\
|
||||||
ntent\x12/\n\x0clink_preview\x18\x03\x20\x03(\x0b2\x0c.LinkPreviewR\x0bl\
|
mmary\x12\x1c\n\x05image\x18\x04\x20\x01(\x0b2\x06.AssetR\x05image\"b\n\
|
||||||
inkPreview\x12$\n\x08mentions\x18\x04\x20\x03(\x0b2\x08.MentionR\x08ment\
|
\x07Mention\x12\x14\n\x05start\x18\x01\x20\x02(\x05R\x05start\x12\x16\n\
|
||||||
ions\x12\x1c\n\x05quote\x18\x05\x20\x01(\x0b2\x06.QuoteR\x05quote\x12A\n\
|
\x06length\x18\x02\x20\x02(\x05R\x06length\x12\x19\n\x07user_id\x18\x03\
|
||||||
\x19expects_read_confirmation\x18\x06\x20\x01(\x08:\x05falseR\x17expects\
|
\x20\x01(\tH\0R\x06userIdB\x0e\n\x0cmention_type\"c\n\x08LastRead\x12'\n\
|
||||||
ReadConfirmation\x12E\n\x11legal_hold_status\x18\x07\x20\x01(\x0e2\x10.L\
|
\x0fconversation_id\x18\x01\x20\x02(\tR\x0econversationId\x12.\n\x13last\
|
||||||
egalHoldStatus:\x07UNKNOWNR\x0flegalHoldStatus\"\xb5\x01\n\x05Knock\x12\
|
_read_timestamp\x18\x02\x20\x02(\x03R\x11lastReadTimestamp\"_\n\x07Clear\
|
||||||
\"\n\thot_knock\x18\x01\x20\x02(\x08:\x05falseR\x08hotKnock\x12A\n\x19ex\
|
ed\x12'\n\x0fconversation_id\x18\x01\x20\x02(\tR\x0econversationId\x12+\
|
||||||
pects_read_confirmation\x18\x02\x20\x01(\x08:\x05falseR\x17expectsReadCo\
|
\n\x11cleared_timestamp\x18\x02\x20\x02(\x03R\x10clearedTimestamp\"U\n\
|
||||||
nfirmation\x12E\n\x11legal_hold_status\x18\x03\x20\x01(\x0e2\x10.LegalHo\
|
\x0bMessageHide\x12'\n\x0fconversation_id\x18\x01\x20\x02(\tR\x0econvers\
|
||||||
ldStatus:\x07UNKNOWNR\x0flegalHoldStatus\"\x8f\x02\n\x0bLinkPreview\x12\
|
ationId\x12\x1d\n\nmessage_id\x18\x02\x20\x02(\tR\tmessageId\".\n\rMessa\
|
||||||
\x10\n\x03url\x18\x01\x20\x02(\tR\x03url\x12\x1d\n\nurl_offset\x18\x02\
|
geDelete\x12\x1d\n\nmessage_id\x18\x01\x20\x02(\tR\tmessageId\"g\n\x0bMe\
|
||||||
\x20\x02(\x05R\turlOffset\x12$\n\x07article\x18\x03\x20\x01(\x0b2\x08.Ar\
|
ssageEdit\x120\n\x14replacing_message_id\x18\x01\x20\x02(\tR\x12replacin\
|
||||||
ticleH\0R\x07article\x12#\n\rpermanent_url\x18\x05\x20\x01(\tR\x0cperman\
|
gMessageId\x12\x1b\n\x04text\x18\x02\x20\x01(\x0b2\x05.TextH\0R\x04textB\
|
||||||
entUrl\x12\x14\n\x05title\x18\x06\x20\x01(\tR\x05title\x12\x18\n\x07summ\
|
\t\n\x07content\"g\n\x05Quote\x12*\n\x11quoted_message_id\x18\x01\x20\
|
||||||
ary\x18\x07\x20\x01(\tR\x07summary\x12\x1c\n\x05image\x18\x08\x20\x01(\
|
\x02(\tR\x0fquotedMessageId\x122\n\x15quoted_message_sha256\x18\x02\x20\
|
||||||
\x0b2\x06.AssetR\x05image\x12\x1e\n\x05tweet\x18\t\x20\x01(\x0b2\x06.Twe\
|
\x01(\x0cR\x13quotedMessageSha256\"\xab\x01\n\x0cConfirmation\x12&\n\x04\
|
||||||
etH\x01R\x05tweetB\t\n\x07previewB\x0b\n\tmeta_data\";\n\x05Tweet\x12\
|
type\x18\x02\x20\x02(\x0e2\x12.Confirmation.TypeR\x04type\x12(\n\x10firs\
|
||||||
\x16\n\x06author\x18\x01\x20\x01(\tR\x06author\x12\x1a\n\x08username\x18\
|
t_message_id\x18\x01\x20\x02(\tR\x0efirstMessageId\x12(\n\x10more_messag\
|
||||||
\x02\x20\x01(\tR\x08username\"|\n\x07Article\x12#\n\rpermanent_url\x18\
|
e_ids\x18\x03\x20\x03(\tR\x0emoreMessageIds\"\x1f\n\x04Type\x12\r\n\tDEL\
|
||||||
\x01\x20\x02(\tR\x0cpermanentUrl\x12\x14\n\x05title\x18\x02\x20\x01(\tR\
|
IVERED\x10\0\x12\x08\n\x04READ\x10\x01\"\xf6\x01\n\x08Location\x12\x1c\n\
|
||||||
\x05title\x12\x18\n\x07summary\x18\x03\x20\x01(\tR\x07summary\x12\x1c\n\
|
\tlongitude\x18\x01\x20\x02(\x02R\tlongitude\x12\x1a\n\x08latitude\x18\
|
||||||
\x05image\x18\x04\x20\x01(\x0b2\x06.AssetR\x05image\"b\n\x07Mention\x12\
|
\x02\x20\x02(\x02R\x08latitude\x12\x12\n\x04name\x18\x03\x20\x01(\tR\x04\
|
||||||
\x14\n\x05start\x18\x01\x20\x02(\x05R\x05start\x12\x16\n\x06length\x18\
|
name\x12\x12\n\x04zoom\x18\x04\x20\x01(\x05R\x04zoom\x12A\n\x19expects_r\
|
||||||
\x02\x20\x02(\x05R\x06length\x12\x19\n\x07user_id\x18\x03\x20\x01(\tH\0R\
|
ead_confirmation\x18\x05\x20\x01(\x08:\x05falseR\x17expectsReadConfirmat\
|
||||||
\x06userIdB\x0e\n\x0cmention_type\"c\n\x08LastRead\x12'\n\x0fconversatio\
|
ion\x12E\n\x11legal_hold_status\x18\x06\x20\x01(\x0e2\x10.LegalHoldStatu\
|
||||||
n_id\x18\x01\x20\x02(\tR\x0econversationId\x12.\n\x13last_read_timestamp\
|
s:\x07UNKNOWNR\x0flegalHoldStatus\"\xa9\x02\n\nImageAsset\x12\x10\n\x03t\
|
||||||
\x18\x02\x20\x02(\x03R\x11lastReadTimestamp\"_\n\x07Cleared\x12'\n\x0fco\
|
ag\x18\x01\x20\x02(\tR\x03tag\x12\x14\n\x05width\x18\x02\x20\x02(\x05R\
|
||||||
nversation_id\x18\x01\x20\x02(\tR\x0econversationId\x12+\n\x11cleared_ti\
|
\x05width\x12\x16\n\x06height\x18\x03\x20\x02(\x05R\x06height\x12%\n\x0e\
|
||||||
mestamp\x18\x02\x20\x02(\x03R\x10clearedTimestamp\"U\n\x0bMessageHide\
|
original_width\x18\x04\x20\x02(\x05R\roriginalWidth\x12'\n\x0foriginal_h\
|
||||||
\x12'\n\x0fconversation_id\x18\x01\x20\x02(\tR\x0econversationId\x12\x1d\
|
eight\x18\x05\x20\x02(\x05R\x0eoriginalHeight\x12\x1b\n\tmime_type\x18\
|
||||||
\n\nmessage_id\x18\x02\x20\x02(\tR\tmessageId\".\n\rMessageDelete\x12\
|
\x06\x20\x02(\tR\x08mimeType\x12\x12\n\x04size\x18\x07\x20\x02(\x05R\x04\
|
||||||
\x1d\n\nmessage_id\x18\x01\x20\x02(\tR\tmessageId\"g\n\x0bMessageEdit\
|
size\x12\x17\n\x07otr_key\x18\x08\x20\x01(\x0cR\x06otrKey\x12\x17\n\x07m\
|
||||||
\x120\n\x14replacing_message_id\x18\x01\x20\x02(\tR\x12replacingMessageI\
|
ac_key\x18\t\x20\x01(\x0cR\x06macKey\x12\x10\n\x03mac\x18\n\x20\x01(\x0c\
|
||||||
d\x12\x1b\n\x04text\x18\x02\x20\x01(\x0b2\x05.TextH\0R\x04textB\t\n\x07c\
|
R\x03mac\x12\x16\n\x06sha256\x18\x0b\x20\x01(\x0cR\x06sha256\"\xa4\n\n\
|
||||||
ontent\"g\n\x05Quote\x12*\n\x11quoted_message_id\x18\x01\x20\x02(\tR\x0f\
|
|
||||||
quotedMessageId\x122\n\x15quoted_message_sha256\x18\x02\x20\x01(\x0cR\
|
|
||||||
\x13quotedMessageSha256\"\xab\x01\n\x0cConfirmation\x12&\n\x04type\x18\
|
|
||||||
\x02\x20\x02(\x0e2\x12.Confirmation.TypeR\x04type\x12(\n\x10first_messag\
|
|
||||||
e_id\x18\x01\x20\x02(\tR\x0efirstMessageId\x12(\n\x10more_message_ids\
|
|
||||||
\x18\x03\x20\x03(\tR\x0emoreMessageIds\"\x1f\n\x04Type\x12\r\n\tDELIVERE\
|
|
||||||
D\x10\0\x12\x08\n\x04READ\x10\x01\"\xf6\x01\n\x08Location\x12\x1c\n\tlon\
|
|
||||||
gitude\x18\x01\x20\x02(\x02R\tlongitude\x12\x1a\n\x08latitude\x18\x02\
|
|
||||||
\x20\x02(\x02R\x08latitude\x12\x12\n\x04name\x18\x03\x20\x01(\tR\x04name\
|
|
||||||
\x12\x12\n\x04zoom\x18\x04\x20\x01(\x05R\x04zoom\x12A\n\x19expects_read_\
|
|
||||||
confirmation\x18\x05\x20\x01(\x08:\x05falseR\x17expectsReadConfirmation\
|
|
||||||
\x12E\n\x11legal_hold_status\x18\x06\x20\x01(\x0e2\x10.LegalHoldStatus:\
|
|
||||||
\x07UNKNOWNR\x0flegalHoldStatus\"\xa9\x02\n\nImageAsset\x12\x10\n\x03tag\
|
|
||||||
\x18\x01\x20\x02(\tR\x03tag\x12\x14\n\x05width\x18\x02\x20\x02(\x05R\x05\
|
|
||||||
width\x12\x16\n\x06height\x18\x03\x20\x02(\x05R\x06height\x12%\n\x0eorig\
|
|
||||||
inal_width\x18\x04\x20\x02(\x05R\roriginalWidth\x12'\n\x0foriginal_heigh\
|
|
||||||
t\x18\x05\x20\x02(\x05R\x0eoriginalHeight\x12\x1b\n\tmime_type\x18\x06\
|
|
||||||
\x20\x02(\tR\x08mimeType\x12\x12\n\x04size\x18\x07\x20\x02(\x05R\x04size\
|
|
||||||
\x12\x17\n\x07otr_key\x18\x08\x20\x01(\x0cR\x06otrKey\x12\x17\n\x07mac_k\
|
|
||||||
ey\x18\t\x20\x01(\x0cR\x06macKey\x12\x10\n\x03mac\x18\n\x20\x01(\x0cR\
|
|
||||||
\x03mac\x12\x16\n\x06sha256\x18\x0b\x20\x01(\x0cR\x06sha256\"\xa4\n\n\
|
|
||||||
\x05Asset\x12+\n\x08original\x18\x01\x20\x01(\x0b2\x0f.Asset.OriginalR\
|
\x05Asset\x12+\n\x08original\x18\x01\x20\x01(\x0b2\x0f.Asset.OriginalR\
|
||||||
\x08original\x127\n\x0cnot_uploaded\x18\x03\x20\x01(\x0e2\x12.Asset.NotU\
|
\x08original\x127\n\x0cnot_uploaded\x18\x03\x20\x01(\x0e2\x12.Asset.NotU\
|
||||||
ploadedH\0R\x0bnotUploaded\x12/\n\x08uploaded\x18\x04\x20\x01(\x0b2\x11.\
|
ploadedH\0R\x0bnotUploaded\x12/\n\x08uploaded\x18\x04\x20\x01(\x0b2\x11.\
|
||||||
103
src/net/wire_api/auth.rs
Normal file
103
src/net/wire_api/auth.rs
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
use hyper::body::Buf;
|
||||||
|
use hyper::client::connect::HttpConnector;
|
||||||
|
use hyper::{header, Body, Client, Method, Request};
|
||||||
|
use hyper_tls::HttpsConnector;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
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,
|
||||||
|
pub rest_url: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum Config {
|
||||||
|
Default,
|
||||||
|
Custom(ConnectionUrls),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Config {
|
||||||
|
pub fn fetch(&mut self) -> ConnectionUrls {
|
||||||
|
match self {
|
||||||
|
Config::Default => ConnectionUrls {
|
||||||
|
websocket: String::from("wss://prod-nginz-ssl.wire.com"),
|
||||||
|
rest_url: String::from("https://prod-nginz-https.wire.com"),
|
||||||
|
},
|
||||||
|
Config::Custom(urls) => urls.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct LoginInfo {
|
||||||
|
email: String,
|
||||||
|
password: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct AuthResponse {
|
||||||
|
expires_in: u32,
|
||||||
|
token_type: String,
|
||||||
|
user: String,
|
||||||
|
access_token: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AuthResponse {
|
||||||
|
pub fn token_string(&self) -> String {
|
||||||
|
[&self.token_type, " ", &self.access_token].concat()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct WireClient {
|
||||||
|
login_info: LoginInfo,
|
||||||
|
pub client: Client<HttpsConnector<HttpConnector>>,
|
||||||
|
pub config: Config,
|
||||||
|
}
|
||||||
|
|
||||||
|
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> {
|
||||||
|
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, CONTENT_TYPE)
|
||||||
|
.header(header::USER_AGENT, 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
114
src/net/wire_api/conversations.rs
Normal file
114
src/net/wire_api/conversations.rs
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
use hyper::body::Buf;
|
||||||
|
use hyper::client::connect::HttpConnector;
|
||||||
|
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";
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct Conversations {
|
||||||
|
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>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct Access {
|
||||||
|
#[serde(rename = "0")]
|
||||||
|
_0: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct ConversationMembers {
|
||||||
|
#[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>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct OtherMember {
|
||||||
|
status: Option<u32>,
|
||||||
|
conversation_role: Option<String>,
|
||||||
|
id: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct ServiceRef {
|
||||||
|
id: String,
|
||||||
|
provider: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
let fetch_request = Request::builder()
|
||||||
|
.method(Method::GET)
|
||||||
|
.uri(endpoint)
|
||||||
|
.header(header::CONTENT_TYPE, CONTENT_TYPE)
|
||||||
|
.header(header::USER_AGENT, USER_AGENT)
|
||||||
|
.header(header::AUTHORIZATION, auth_token)
|
||||||
|
.body(Body::empty())
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let fetch_result = self
|
||||||
|
.client
|
||||||
|
.request(fetch_request)
|
||||||
|
.await
|
||||||
|
.map_err(|e| ApiError::HttpError(e))?;
|
||||||
|
|
||||||
|
let fetch_body = hyper::body::aggregate(fetch_result)
|
||||||
|
.await
|
||||||
|
.map_err(|e| ApiError::HttpError(e))?;
|
||||||
|
|
||||||
|
let fetch_response = serde_json::from_reader(fetch_body.bytes())
|
||||||
|
.map_err(|e| ApiError::JsonParseError(Box::new(e)))?;
|
||||||
|
|
||||||
|
Ok(fetch_response)
|
||||||
|
}
|
||||||
|
}
|
||||||
5
src/net/wire_api/error.rs
Normal file
5
src/net/wire_api/error.rs
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#[derive(Debug)]
|
||||||
|
pub enum ApiError {
|
||||||
|
JsonParseError(Box<dyn std::error::Error>),
|
||||||
|
HttpError(hyper::error::Error),
|
||||||
|
}
|
||||||
3
src/net/wire_api/mod.rs
Normal file
3
src/net/wire_api/mod.rs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
pub mod auth;
|
||||||
|
pub mod conversations;
|
||||||
|
pub mod error;
|
||||||
Reference in New Issue
Block a user