diff --git a/client/index.js b/client/index.js index c844fa8e..1aa50bb2 100755 --- a/client/index.js +++ b/client/index.js @@ -8,6 +8,7 @@ ws.binaryType = 'arraybuffer'; ws.addEventListener('open', function (event) { ws.send(cbor.encode({ method: 'cryp_generate', params: { level: 64 }})); ws.send(cbor.encode({ method: 'account_create', params: { name: 'ntr', password: 'grep' }})); + ws.send(cbor.encode({ method: 'account_create', params: { name: 'mashy', password: 'grepgrepgrep' }})); }); // Listen for messages diff --git a/server/Cargo.toml b/server/Cargo.toml index 2cb579aa..9e3aea95 100755 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -19,3 +19,5 @@ postgres = { version = "0.15", features = ["with-uuid"] } r2d2 = "*" r2d2_postgres = "*" +failure = "0.1" + diff --git a/server/src/cryp.rs b/server/src/cryp.rs index 0ed27051..ec57c1cc 100755 --- a/server/src/cryp.rs +++ b/server/src/cryp.rs @@ -176,15 +176,12 @@ impl Cryp { } -pub fn generate(params: GenerateParams) -> Vec { - let level_two = Cryp::new() +pub fn generate(params: GenerateParams) -> Cryp { + Cryp::new() .named("hatchling".to_string()) .level(params.level) .learn(Skill::Stoney) - .create(); - - to_vec(&level_two) - .expect("couldn't serialize cryp") + .create() } diff --git a/server/src/main.rs b/server/src/main.rs index bd86f468..9849642d 100755 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -15,6 +15,9 @@ extern crate serde_cbor; #[macro_use] extern crate serde_derive; +extern crate failure; +// #[macro_use] extern crate failure_derive; + mod cryp; mod battle; mod net; diff --git a/server/src/net.rs b/server/src/net.rs index 6511bccb..d62a22c4 100755 --- a/server/src/net.rs +++ b/server/src/net.rs @@ -9,8 +9,7 @@ use r2d2_postgres::{TlsMode, PostgresConnectionManager}; pub type Db = PooledConnection; -use cryp::{generate}; -use rpc::{Rpc,RpcMessage}; +use rpc::{Rpc}; struct Server { out: Sender, @@ -28,11 +27,12 @@ impl Handler for Server { let db = self.db.get().expect("unable to get db connection"); match self.rpc.receive(msg, db) { Ok(reply) => { - println!("{:?}", reply); - self.out.send(reply) + let response = to_vec(&reply) + .expect("failed to serialize response"); + self.out.send(response) }, - Err(_e) => { - let response = to_vec(&"there was an error") + Err(e) => { + let response = to_vec(&e.to_string()) .expect("failed to serialize error response"); self.out.send(response) } diff --git a/server/src/rpc.rs b/server/src/rpc.rs index e53df43d..0655ab91 100644 --- a/server/src/rpc.rs +++ b/server/src/rpc.rs @@ -1,15 +1,16 @@ -use std::result::Result as StdResult; use ws::{Message}; use serde_cbor::{from_slice}; +use failure::Error; +use failure::err_msg; use net::Db; -use cryp::generate; -use user::{create}; +use cryp::{Cryp, generate}; +use user::{User, create}; pub struct Rpc; impl Rpc { - pub fn receive(&self, msg: Message, db: Db) -> StdResult, RpcError> { + pub fn receive(&self, msg: Message, db: Db) -> Result { // consume the ws data into bytes let data = msg.into_data(); @@ -22,25 +23,32 @@ impl Rpc { match v.method.as_ref() { "cryp_generate" => { match from_slice::(&data) { - Ok(v) => Ok(generate(v.params)), - Err(e) => Err(RpcError::Parse), + Ok(v) => Ok(RpcResult::Cryp(generate(v.params))), + Err(_e) => Err(err_msg("invalid params")), } }, "account_create" => { match from_slice::(&data) { - Ok(v) => Ok(create(v.params, db)), - Err(e) => Err(RpcError::Parse), + Ok(v) => create(v.params, db), + Err(_e) => Err(err_msg("invalid params")), } }, - _ => Err(RpcError::UnknownMethod), + _ => Err(err_msg("unknown method")), } }, - Err(e) => Err(RpcError::Parse), + Err(_e) => Err(err_msg("invalid message")), } } } + +#[derive(Debug,Clone,Serialize,Deserialize)] +pub enum RpcResult { + Cryp(Cryp), + User(User), +} + #[derive(Debug,Clone,Serialize,Deserialize)] pub struct RpcMessage { method: String, diff --git a/server/src/user.rs b/server/src/user.rs index a294ec2d..05937314 100644 --- a/server/src/user.rs +++ b/server/src/user.rs @@ -1,4 +1,3 @@ -use serde_cbor::to_vec; use uuid::Uuid; use bcrypt::{DEFAULT_COST, hash}; use rand::{thread_rng, Rng}; @@ -8,10 +7,13 @@ use std::iter; use std::str; use net::Db; -use rpc::{AccountCreateParams}; +use rpc::{AccountCreateParams, RpcResult}; + +use failure::Error; +use failure::err_msg; #[derive(Debug,Clone,Serialize,Deserialize)] -struct User { +pub struct User { id: Uuid, name: String, token: String, @@ -24,11 +26,15 @@ struct UserEntry { token: String, } -pub fn create(params: AccountCreateParams, db: Db) -> Vec { +static PASSWORD_MIN_LEN: usize = 12; +pub fn create(params: AccountCreateParams, db: Db) -> Result { let id = Uuid::new_v4(); - let password = hash(¶ms.password, DEFAULT_COST) - .expect("unable to hash password"); + + if params.password.len() < PASSWORD_MIN_LEN { + return Err(err_msg("password must be at least 12 characters")); + } + let password = hash(¶ms.password, DEFAULT_COST)?; let mut rng = thread_rng(); let token: String = iter::repeat(()) @@ -49,9 +55,11 @@ pub fn create(params: AccountCreateParams, db: Db) -> Vec { RETURNING id, name, token; "; - let result = db - .query(query, &[&user.id, &user.name, &user.password, &user.token]) - .expect("user insert failed"); + let tx = db.transaction()?; + + let result = tx + .query(query, &[&user.id, &user.name, &user.password, &user.token])?; + let returned = result.iter().next().expect("no row returned"); let entry = User { @@ -62,5 +70,7 @@ pub fn create(params: AccountCreateParams, db: Db) -> Vec { println!("{:?}", entry); - to_vec(&entry).expect("serialising user failed") + tx.commit()?; + + Ok(RpcResult::User(entry)) }