method handlers

This commit is contained in:
ntr 2018-09-15 14:11:23 +10:00
parent 2b30c87ef8
commit 7a174736f6
7 changed files with 89 additions and 29 deletions

View File

@ -4,17 +4,48 @@ const assert = require('assert');
const ws = new WebSocket('ws://localhost:40000'); const ws = new WebSocket('ws://localhost:40000');
ws.binaryType = 'arraybuffer'; ws.binaryType = 'arraybuffer';
// handle user auth within the socket itself
// https://www.christian-schneider.net/CrossSiteWebSocketHijacking.html
let user = null;
function user_login(res) {
user = res;
console.log(user);
return true;
}
function new_cryp(cryp) {
console.log('got a new cryp');
}
const handlers = {
'cryp_generate': new_cryp,
'user_login': user_login,
'user_create': user_login,
};
function receive(res) {
if (res.err) return console.error(res.err);
const { method, params } = res;
return handlers[method](params);
}
function send(msg) {
msg.token = user && user.token;
ws.send(cbor.encode(msg));
}
// Connection opened // Connection opened
ws.addEventListener('open', function (event) { ws.addEventListener('open', function (event) {
ws.send(cbor.encode({ method: 'cryp_generate', params: { level: 64 }})); send({ method: 'cryp_generate', params: { level: 64 }});
ws.send(cbor.encode({ method: 'account_create', params: { name: 'ntr', password: 'grep' }})); send({ method: 'user_create', params: { name: 'lichking', password: 'grepgrepgrep' }});
ws.send(cbor.encode({ method: 'account_create', params: { name: 'mashy', password: 'grepgrepgrep' }}));
}); });
// Listen for messages // Listen for messages
ws.addEventListener('message', function (event) { ws.addEventListener('message', function (event) {
console.log('Message from server ', event.data); console.log('Message from server ', event.data);
const blob = new Uint8Array(event.data); const blob = new Uint8Array(event.data);
const decoded = cbor.decodeAll(blob); const decoded = cbor.decode(blob);
console.log(decoded[0]); console.log(decoded);
return receive(decoded);
}); });

View File

@ -4,7 +4,7 @@
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"start": "parcel index.html", "start": "parcel index.html --port 40080",
"test": "echo \"Error: no test specified\" && exit 1" "test": "echo \"Error: no test specified\" && exit 1"
}, },
"author": "", "author": "",

View File

@ -2,10 +2,10 @@
sudo apt-get install -y postgresql postgresql-contrib sudo apt-get install -y postgresql postgresql-contrib
sudo service postgresql start sudo service postgresql start
sudo -u postgres dropdb cryps
sudo -u postgres createdb cryps sudo -u postgres createdb cryps
sudo -u postgres echo "craftbeer" > .pgpass sudo -u postgres echo "craftbeer" > /var/lib/postgres/.pgpass
sudo -u postgres createuser --encrypted cryps sudo -u postgres createuser --encrypted cryps
npm i npm i
npm i -g knex npm run migrate
knex migrate:latest

1
ops/package.json Normal file → Executable file
View File

@ -4,6 +4,7 @@
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"migrate": "knex migrate:latest",
"test": "echo \"Error: no test specified\" && exit 1" "test": "echo \"Error: no test specified\" && exit 1"
}, },
"author": "", "author": "",

View File

@ -13,3 +13,11 @@
* *
* Blockchain Integration? * Blockchain Integration?
# Mechanic Ideas
teams
gem td style attr combinations
stoney + spikey = jagged

View File

@ -7,9 +7,11 @@ use r2d2::{Pool};
use r2d2::{PooledConnection}; use r2d2::{PooledConnection};
use r2d2_postgres::{TlsMode, PostgresConnectionManager}; use r2d2_postgres::{TlsMode, PostgresConnectionManager};
static DB_POOL_SIZE: u32 = 20;
pub type Db = PooledConnection<PostgresConnectionManager>; pub type Db = PooledConnection<PostgresConnectionManager>;
use rpc::{Rpc}; use rpc::{Rpc, RpcResult};
struct Server { struct Server {
out: Sender, out: Sender,
@ -17,6 +19,11 @@ struct Server {
db: Pool<PostgresConnectionManager>, db: Pool<PostgresConnectionManager>,
} }
#[derive(Debug,Clone,Serialize,Deserialize)]
struct RpcErrorResponse {
err: String
}
impl Handler for Server { impl Handler for Server {
fn on_open(&mut self, _: Handshake) -> Result<()> { fn on_open(&mut self, _: Handshake) -> Result<()> {
println!("somebody joined"); println!("somebody joined");
@ -32,7 +39,7 @@ impl Handler for Server {
self.out.send(response) self.out.send(response)
}, },
Err(e) => { Err(e) => {
let response = to_vec(&e.to_string()) let response = to_vec(&RpcErrorResponse { err: e.to_string() })
.expect("failed to serialize error response"); .expect("failed to serialize error response");
self.out.send(response) self.out.send(response)
} }
@ -54,16 +61,21 @@ impl Handler for Server {
} }
} }
pub fn db_connection(url: String) -> Pool<PostgresConnectionManager> {
let manager = PostgresConnectionManager::new(url, TlsMode::None)
.expect("could not instantiate pg manager");
Pool::builder()
.max_size(DB_POOL_SIZE)
.build(manager)
.expect("Failed to create pool.")
}
pub fn start() { pub fn start() {
let database_url = env::var("DATABASE_URL") let database_url = env::var("DATABASE_URL")
.expect("DATABASE_URL must be set"); .expect("DATABASE_URL must be set");
let manager = PostgresConnectionManager::new(database_url, TlsMode::None) let pool = db_connection(database_url);
.expect("could not instantiate pg manager");
let pool = Pool::builder()
.build(manager)
.expect("Failed to create pool.");
listen("127.0.0.1:40000", |out| { Server { out, rpc: Rpc {}, db: pool.clone() } }).unwrap(); listen("127.0.0.1:40000", |out| { Server { out, rpc: Rpc {}, db: pool.clone() } }).unwrap();
} }

28
server/src/rpc.rs Normal file → Executable file
View File

@ -10,7 +10,7 @@ use user::{User, create};
pub struct Rpc; pub struct Rpc;
impl Rpc { impl Rpc {
pub fn receive(&self, msg: Message, db: Db) -> Result<RpcResult, Error> { pub fn receive(&self, msg: Message, db: Db) -> Result<RpcResponse, Error> {
// consume the ws data into bytes // consume the ws data into bytes
let data = msg.into_data(); let data = msg.into_data();
@ -18,18 +18,26 @@ impl Rpc {
match from_slice::<RpcMessage>(&data) { match from_slice::<RpcMessage>(&data) {
Ok(v) => { Ok(v) => {
println!("{:?}", v.token);
// now we have the method name // now we have the method name
// match on that to determine what fn to call // match on that to determine what fn to call
match v.method.as_ref() { match v.method.as_ref() {
"cryp_generate" => { "cryp_generate" => {
match from_slice::<GenerateMsg>(&data) { match from_slice::<GenerateMsg>(&data) {
Ok(v) => Ok(RpcResult::Cryp(generate(v.params))), Ok(v) => Ok(RpcResponse {
method: v.method,
params: RpcResult::Cryp(generate(v.params))
}),
Err(_e) => Err(err_msg("invalid params")), Err(_e) => Err(err_msg("invalid params")),
} }
}, },
"account_create" => { "user_create" => {
match from_slice::<AccountCreateMsg>(&data) { match from_slice::<AccountCreateMsg>(&data) {
Ok(v) => create(v.params, db), Ok(v) => Ok(RpcResponse {
method: v.method,
params: create(v.params, db)?
}),
Err(_e) => Err(err_msg("invalid params")), Err(_e) => Err(err_msg("invalid params")),
} }
}, },
@ -42,6 +50,11 @@ impl Rpc {
} }
} }
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct RpcResponse {
method: String,
params: RpcResult,
}
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
pub enum RpcResult { pub enum RpcResult {
@ -52,12 +65,7 @@ pub enum RpcResult {
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
pub struct RpcMessage { pub struct RpcMessage {
method: String, method: String,
} token: Option<String>,
#[derive(Debug,Clone,Serialize,Deserialize)]
pub enum RpcError {
Parse,
UnknownMethod,
} }
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]