initial commit - added jsonrpclient, session, rawclient
This commit is contained in:
commit
239ca2d1a7
|
@ -0,0 +1 @@
|
|||
target/
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,6 @@
|
|||
[workspace]
|
||||
members = [
|
||||
"session",
|
||||
"rawclient",
|
||||
"jsonrpc2-client"
|
||||
]
|
|
@ -0,0 +1,2 @@
|
|||
/target
|
||||
Cargo.lock
|
|
@ -0,0 +1,12 @@
|
|||
[package]
|
||||
name = "jsonrpc2-client"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
tokio = {version = "1.11.0", features = ["full"]}
|
||||
reqwest = {version = "0.11.4", features = ["json"]}
|
||||
serde = { version = "1.0", features = ["derive"]}
|
||||
serde_json = "1.0.67"
|
|
@ -0,0 +1,107 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub struct Client {
|
||||
client: reqwest::Client,
|
||||
host_url: String,
|
||||
}
|
||||
|
||||
pub fn new(host: &str) -> Client {
|
||||
let client = reqwest::Client::new();
|
||||
Client {
|
||||
client,
|
||||
host_url: host.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
impl Client {
|
||||
pub async fn send_request<T: serde::de::DeserializeOwned + std::fmt::Debug>(
|
||||
&self,
|
||||
method: &str,
|
||||
params: serde_json::Value,
|
||||
) -> Result<T, RpcError> {
|
||||
let request = RawRequest {
|
||||
jsonrpc: "2.0".to_string(),
|
||||
id: Some(generate_id()),
|
||||
method: method.to_string(),
|
||||
params: Some(params),
|
||||
};
|
||||
|
||||
// println!(
|
||||
// "Request: {}",
|
||||
// serde_json::to_string_pretty(&request).unwrap()
|
||||
// );
|
||||
|
||||
//TODO: maybe check the response better as well??
|
||||
let resp = self
|
||||
.client
|
||||
.post(&self.host_url)
|
||||
.json(&request)
|
||||
.send()
|
||||
.await?
|
||||
.json::<RawResponse<T>>()
|
||||
.await?;
|
||||
|
||||
resp.result()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct RawRequest {
|
||||
jsonrpc: String,
|
||||
id: Option<String>,
|
||||
method: String,
|
||||
params: Option<serde_json::Value>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct RawResponse<T> {
|
||||
jsonrpc: String,
|
||||
result: Option<T>,
|
||||
error: Option<RpcError>,
|
||||
id: String,
|
||||
}
|
||||
|
||||
impl<T> RawResponse<T> {
|
||||
fn result(self) -> Result<T, RpcError> {
|
||||
if let Some(res) = self.result {
|
||||
return Ok(res);
|
||||
}
|
||||
if let Some(err) = self.error {
|
||||
return Err(err);
|
||||
}
|
||||
Err(RpcError {
|
||||
code: -1,
|
||||
message: format!("Neither result nor error was found. ID = {:?}", self.id),
|
||||
data: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_id() -> String {
|
||||
"1".to_string()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn it_works() {
|
||||
assert_eq!(2 + 2, 4);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct RpcError {
|
||||
code: i32,
|
||||
message: String,
|
||||
data: Option<serde_json::Value>,
|
||||
}
|
||||
|
||||
impl std::convert::From<reqwest::Error> for RpcError {
|
||||
fn from(error: reqwest::Error) -> Self {
|
||||
RpcError {
|
||||
code: -1,
|
||||
message: format!("An error occurred: {}", error),
|
||||
data: None,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
/target
|
||||
Cargo.lock
|
|
@ -0,0 +1,11 @@
|
|||
[package]
|
||||
name = "rawclient"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
jsonrpc2-client = {path = "../jsonrpc2-client"}
|
||||
serde = { version = "1.0", features = ["derive"]}
|
||||
serde_json = "1.0.67"
|
|
@ -0,0 +1,43 @@
|
|||
use jsonrpc2_client::RpcError;
|
||||
use std::convert::From;
|
||||
|
||||
//TODO: IMPLEMENT THIS
|
||||
|
||||
type ErrorCode = i32;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Error {
|
||||
kind: ErrorKind,
|
||||
code: ErrorCode,
|
||||
description: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ErrorKind {
|
||||
ValidationError(ValidationError),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum ValidationError {
|
||||
InvalidUsername,
|
||||
InvalidPassword,
|
||||
}
|
||||
|
||||
impl From<RpcError> for Error {
|
||||
fn from(error: RpcError) -> Self {
|
||||
let code = error.code();
|
||||
let kind = get_error_kind(error.code());
|
||||
let description = error.message();
|
||||
Self {
|
||||
code,
|
||||
kind,
|
||||
description,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<serde_json::Error> for Error {
|
||||
fn from(_error: serde_json::Error) -> Self {
|
||||
Self {}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/// # Raw client for SocialVoid.
|
||||
/// Makes a new client and makes JSONRPC requests. Also, useful in case we
|
||||
/// want to switch the JSONRPC client crate used in the future.
|
||||
mod error;
|
||||
|
||||
pub use error::Error;
|
||||
|
||||
const HOST: &str = "http://socialvoid.qlg1.com:5601/";
|
||||
|
||||
pub struct Client {
|
||||
client: jsonrpc2_client::Client,
|
||||
}
|
||||
|
||||
pub fn new() -> Client {
|
||||
let host = get_host();
|
||||
Client {
|
||||
client: jsonrpc2_client::new(&host),
|
||||
}
|
||||
}
|
||||
|
||||
impl Client {
|
||||
pub async fn send_request<T: serde::de::DeserializeOwned + std::fmt::Debug>(
|
||||
&self,
|
||||
method: &str,
|
||||
params: serde_json::Value,
|
||||
) -> Result<T, Error> {
|
||||
let response = self.client.send_request::<T>(method, params).await?;
|
||||
Ok(response)
|
||||
}
|
||||
}
|
||||
|
||||
fn get_host() -> String {
|
||||
HOST.to_string()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn it_works() {
|
||||
assert_eq!(2 + 2, 4);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
/target
|
||||
Cargo.lock
|
|
@ -0,0 +1,14 @@
|
|||
[package]
|
||||
name = "session"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
rawclient = {path = "../rawclient"}
|
||||
serde = { version = "1.0", features = ["derive"]}
|
||||
serde_json = "1.0.67"
|
||||
sha256 = "1.0.2"
|
||||
rand = "0.8.4"
|
||||
tokio = {version = "1.11.0", features = ["full"]}
|
|
@ -0,0 +1,47 @@
|
|||
use rand::distributions::Alphanumeric;
|
||||
use rand::{thread_rng, Rng};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct SessionEstablished {
|
||||
id: String,
|
||||
challenge: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct ClientInfo {
|
||||
pub public_hash: String,
|
||||
pub private_hash: String,
|
||||
pub name: String,
|
||||
pub platform: String,
|
||||
pub version: String,
|
||||
}
|
||||
|
||||
impl ClientInfo {
|
||||
///Generates client information
|
||||
pub fn generate() -> ClientInfo {
|
||||
let public_hash = generate_random_hash();
|
||||
let private_hash = generate_random_hash();
|
||||
let platform = String::from("Linux"); //TODO: auto detect platform?
|
||||
let name = String::from("Social Void rust");
|
||||
let version = String::from("0.0.1"); //maybe have a better way to set this?
|
||||
ClientInfo {
|
||||
public_hash,
|
||||
private_hash,
|
||||
platform,
|
||||
name,
|
||||
version,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_random_hash() -> String {
|
||||
//TODO: make it secure, more random idk
|
||||
sha256::digest::<String>(
|
||||
thread_rng()
|
||||
.sample_iter(&Alphanumeric)
|
||||
.take(30)
|
||||
.map(char::from)
|
||||
.collect(),
|
||||
)
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
mod entities;
|
||||
|
||||
use entities::ClientInfo;
|
||||
use entities::SessionEstablished;
|
||||
use rawclient::Error;
|
||||
|
||||
pub async fn create(client: &rawclient::Client) -> Result<SessionEstablished, Error> {
|
||||
let client_info = ClientInfo::generate();
|
||||
client
|
||||
.send_request("session.create", serde_json::value::to_value(client_info)?)
|
||||
.await
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
#[tokio::test]
|
||||
async fn it_should_establish_a_session() {
|
||||
let client = rawclient::new();
|
||||
let response = create(&client).await;
|
||||
match response {
|
||||
Ok(s_e) => {
|
||||
println!("Result: {:?}", s_e);
|
||||
}
|
||||
Err(err) => {
|
||||
println!("Error: {:?}", err);
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue