associate cryps with account:

This commit is contained in:
ntr 2018-09-17 00:03:04 +10:00
parent a78b796c55
commit f53853e2ac
5 changed files with 62 additions and 55 deletions

View File

@ -6,9 +6,9 @@ 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 // handle account auth within the socket itself
// https://www.christian-schneider.net/CrossSiteWebSocketHijacking.html // https://www.christian-schneider.net/CrossSiteWebSocketHijacking.html
let user = null; let account = null;
function error_toast(err) { function error_toast(err) {
console.error(err); console.error(err);
@ -19,12 +19,12 @@ function error_toast(err) {
}); });
} }
function user_login(res) { function account_login(res) {
[struct, user] = res; [struct, account] = res;
user = user; account = account;
console.log(user); console.log(account);
return send({ method: 'cryp_spawn', params: { name: 'drake' }}); return send({ method: 'cryp_spawn', params: { name: 'drake' }});
} }
@ -34,8 +34,8 @@ function new_cryp(cryp) {
const handlers = { const handlers = {
'cryp_spawn': new_cryp, 'cryp_spawn': new_cryp,
'user_login': user_login, 'account_login': account_login,
'user_create': user_login, 'account_create': account_login,
}; };
function on_message(event) { function on_message(event) {
@ -51,14 +51,14 @@ function on_message(event) {
} }
function send(msg) { function send(msg) {
msg.token = user && user.token; msg.token = account && account.token;
ws.send(cbor.encode(msg)); ws.send(cbor.encode(msg));
} }
// Connection opened // Connection opened
ws.addEventListener('open', function (event) { ws.addEventListener('open', function (event) {
// send({ method: 'user_create', params: { name: 'ntr', password: 'grepgrepgrep' }}); // send({ method: 'account_create', params: { name: 'ntr', password: 'grepgrepgrep' }});
send({ method: 'user_login', params: { name: 'ntr', password: 'grepgrepgrep' }}); send({ method: 'account_login', params: { name: 'ntr', password: 'grepgrepgrep' }});
}); });
// Listen for messages // Listen for messages
@ -66,10 +66,10 @@ ws.addEventListener('message', on_message);
ws.addEventListener('error', function (event) { ws.addEventListener('error', function (event) {
console.error('WebSocket error', event); console.error('WebSocket error', event);
user = null; account = null;
}); });
ws.addEventListener('close', function (event) { ws.addEventListener('close', function (event) {
console.error('WebSocket closed', event); console.error('WebSocket closed', event);
user = null; account = null;
}); });

View File

@ -7,7 +7,7 @@ use std::iter;
use std::str; use std::str;
use net::Db; use net::Db;
use rpc::{UserCreateParams, UserLoginParams, RpcResult}; use rpc::{AccountCreateParams, AccountLoginParams, RpcResult};
use failure::Error; use failure::Error;
use failure::err_msg; use failure::err_msg;
@ -15,14 +15,14 @@ use failure::err_msg;
static PASSWORD_MIN_LEN: usize = 12; static PASSWORD_MIN_LEN: usize = 12;
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
pub struct User { pub struct Account {
pub id: Uuid, pub id: Uuid,
pub name: String, pub name: String,
token: String, token: String,
} }
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
struct UserEntry { struct AccountEntry {
id: Uuid, id: Uuid,
name: String, name: String,
password: String, password: String,
@ -31,10 +31,10 @@ struct UserEntry {
// MAYBE // MAYBE
// hash tokens with a secret // hash tokens with a secret
pub fn from_token(token: String, db: &Db) -> Result<User, Error> { pub fn from_token(token: String, db: &Db) -> Result<Account, Error> {
let query = " let query = "
SELECT id, name, token SELECT id, name, token
FROM users FROM accounts
WHERE token = $1; WHERE token = $1;
"; ";
@ -46,7 +46,7 @@ pub fn from_token(token: String, db: &Db) -> Result<User, Error> {
None => return Err(err_msg("invalid token")), None => return Err(err_msg("invalid token")),
}; };
let entry = User { let entry = Account {
id: returned.get(0), id: returned.get(0),
name: returned.get(1), name: returned.get(1),
token: returned.get(2), token: returned.get(2),
@ -55,7 +55,7 @@ pub fn from_token(token: String, db: &Db) -> Result<User, Error> {
return Ok(entry); return Ok(entry);
} }
pub fn create(params: UserCreateParams, db: Db) -> Result<RpcResult, Error> { pub fn create(params: AccountCreateParams, db: Db) -> Result<RpcResult, Error> {
let id = Uuid::new_v4(); let id = Uuid::new_v4();
if params.password.len() < PASSWORD_MIN_LEN { if params.password.len() < PASSWORD_MIN_LEN {
@ -69,7 +69,7 @@ pub fn create(params: UserCreateParams, db: Db) -> Result<RpcResult, Error> {
.take(64) .take(64)
.collect(); .collect();
let user = UserEntry { let account = AccountEntry {
name: params.name, name: params.name,
id, id,
password, password,
@ -77,7 +77,7 @@ pub fn create(params: UserCreateParams, db: Db) -> Result<RpcResult, Error> {
}; };
let query = " let query = "
INSERT INTO users (id, name, password, token) INSERT INTO accounts (id, name, password, token)
VALUES ($1, $2, $3, $4) VALUES ($1, $2, $3, $4)
RETURNING id, name, token; RETURNING id, name, token;
"; ";
@ -85,11 +85,11 @@ pub fn create(params: UserCreateParams, db: Db) -> Result<RpcResult, Error> {
let tx = db.transaction()?; let tx = db.transaction()?;
let result = tx let result = tx
.query(query, &[&user.id, &user.name, &user.password, &user.token])?; .query(query, &[&account.id, &account.name, &account.password, &account.token])?;
let returned = result.iter().next().expect("no row returned"); let returned = result.iter().next().expect("no row returned");
let entry = User { let entry = Account {
id: returned.get(0), id: returned.get(0),
name: returned.get(1), name: returned.get(1),
token: returned.get(2), token: returned.get(2),
@ -99,13 +99,13 @@ pub fn create(params: UserCreateParams, db: Db) -> Result<RpcResult, Error> {
tx.commit()?; tx.commit()?;
return Ok(RpcResult::User(entry)); return Ok(RpcResult::Account(entry));
} }
pub fn login(params: UserLoginParams, db: Db) -> Result<RpcResult, Error> { pub fn login(params: AccountLoginParams, db: Db) -> Result<RpcResult, Error> {
let query = " let query = "
SELECT id, name, token, password SELECT id, name, token, password
FROM users FROM accounts
WHERE name = $1; WHERE name = $1;
"; ";
@ -116,10 +116,10 @@ pub fn login(params: UserLoginParams, db: Db) -> Result<RpcResult, Error> {
Some(row) => row, Some(row) => row,
// MAYBE // MAYBE
// verify gibberish to delay response for timing attacks // verify gibberish to delay response for timing attacks
None => return Err(err_msg("user not found")), None => return Err(err_msg("account not found")),
}; };
let entry = UserEntry { let entry = AccountEntry {
id: returned.get(0), id: returned.get(0),
name: returned.get(1), name: returned.get(1),
token: returned.get(2), token: returned.get(2),
@ -136,11 +136,11 @@ pub fn login(params: UserLoginParams, db: Db) -> Result<RpcResult, Error> {
// update token? // update token?
// don't necessarily want to log every session out when logging in // don't necessarily want to log every session out when logging in
let user = User { let account = Account {
id: entry.id, id: entry.id,
name: entry.name, name: entry.name,
token: entry.token, token: entry.token,
}; };
return Ok(RpcResult::User(user)); return Ok(RpcResult::Account(account));
} }

View File

@ -7,7 +7,7 @@ use failure::Error;
use failure::err_msg; use failure::err_msg;
use net::Db; use net::Db;
use user::User; use account::Account;
use rpc::{CrypSpawnParams}; use rpc::{CrypSpawnParams};
use skill::{Skill}; use skill::{Skill};
@ -75,8 +75,7 @@ pub struct Turn {
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
pub struct Cryp { pub struct Cryp {
pub id: Uuid, pub id: Uuid,
// todo pub account: Uuid,
// make attributes hold this value
pub dmg: Stat, pub dmg: Stat,
pub def: Stat, pub def: Stat,
pub stam: Stat, pub stam: Stat,
@ -97,6 +96,7 @@ impl Cryp {
let id = Uuid::new_v4(); let id = Uuid::new_v4();
return Cryp { return Cryp {
id, id,
account: id,
dmg: Stat { value: 0, kind: StatKind::Dmg }, dmg: Stat { value: 0, kind: StatKind::Dmg },
def: Stat { value: 0, kind: StatKind::Def }, def: Stat { value: 0, kind: StatKind::Def },
stam: Stat { value: 0, kind: StatKind::Stam }, stam: Stat { value: 0, kind: StatKind::Stam },
@ -113,6 +113,12 @@ impl Cryp {
self self
} }
pub fn set_account(mut self, account: Uuid) -> Cryp {
self.account = account;
self
}
pub fn level(mut self, lvl: u8) -> Cryp { pub fn level(mut self, lvl: u8) -> Cryp {
self.lvl = check_lvl(lvl); self.lvl = check_lvl(lvl);
self self
@ -182,28 +188,29 @@ impl Cryp {
} }
pub fn spawn(params: CrypSpawnParams, db: Db, user: User) -> Result<Cryp, Error> { pub fn spawn(params: CrypSpawnParams, db: Db, account: Account) -> Result<Cryp, Error> {
let cryp = Cryp::new() let cryp = Cryp::new()
.named(params.name) .named(params.name)
.level(1) .level(1)
.set_account(account.id)
.create(); .create();
let cryp_bytes = to_vec(&cryp)?; let cryp_bytes = to_vec(&cryp)?;
let query = " let query = "
INSERT INTO cryps (id, user, data) INSERT INTO cryps (id, account, data)
VALUES ($1, $2, $3) VALUES ($1, $2, $3)
RETURNING id, user; RETURNING id, account;
"; ";
let tx = db.transaction()?; let tx = db.transaction()?;
let result = tx let result = tx
.query(query, &[&cryp.id, &user.id, &cryp_bytes])?; .query(query, &[&cryp.id, &account.id, &cryp_bytes])?;
let _returned = result.iter().next().expect("no row returned"); let _returned = result.iter().next().expect("no row returned");
println!("{:?} spawned cryp {:}", user.id, cryp.id); println!("{:?} spawned cryp {:}", account.id, cryp.id);
tx.commit()?; tx.commit()?;

View File

@ -24,7 +24,7 @@ mod net;
mod combat; mod combat;
mod skill; mod skill;
mod rpc; mod rpc;
mod user; mod account;
use dotenv::dotenv; use dotenv::dotenv;
use net::{start}; use net::{start};

View File

@ -5,7 +5,7 @@ use failure::err_msg;
use net::Db; use net::Db;
use cryp::{Cryp, spawn}; use cryp::{Cryp, spawn};
use user::{User, create, login, from_token}; use account::{Account, create, login, from_token};
pub struct Rpc; pub struct Rpc;
@ -18,12 +18,12 @@ impl Rpc {
match from_slice::<RpcMessage>(&data) { match from_slice::<RpcMessage>(&data) {
Ok(v) => { Ok(v) => {
let user: Option<User> = match v.token { let account: Option<Account> = match v.token {
Some(t) => Some(from_token(t, &db)?), Some(t) => Some(from_token(t, &db)?),
None => None, None => None,
}; };
println!("{:?}", user); println!("{:?}", account);
// 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
@ -31,7 +31,7 @@ impl Rpc {
"cryp_spawn" => { "cryp_spawn" => {
match from_slice::<CrypSpawnMsg>(&data) { match from_slice::<CrypSpawnMsg>(&data) {
Ok(v) => { Ok(v) => {
match user { match account {
Some(u) => Ok(RpcResponse { Some(u) => Ok(RpcResponse {
method: v.method, method: v.method,
params: RpcResult::SpawnCryp(spawn(v.params, db, u)?) params: RpcResult::SpawnCryp(spawn(v.params, db, u)?)
@ -42,8 +42,8 @@ impl Rpc {
Err(_e) => Err(err_msg("invalid params")), Err(_e) => Err(err_msg("invalid params")),
} }
}, },
"user_create" => { "account_create" => {
match from_slice::<UserCreateMsg>(&data) { match from_slice::<AccountCreateMsg>(&data) {
Ok(v) => Ok(RpcResponse { Ok(v) => Ok(RpcResponse {
method: v.method, method: v.method,
params: create(v.params, db)? params: create(v.params, db)?
@ -51,8 +51,8 @@ impl Rpc {
Err(_e) => Err(err_msg("invalid params")), Err(_e) => Err(err_msg("invalid params")),
} }
}, },
"user_login" => { "account_login" => {
match from_slice::<UserLoginMsg>(&data) { match from_slice::<AccountLoginMsg>(&data) {
Ok(v) => Ok(RpcResponse { Ok(v) => Ok(RpcResponse {
method: v.method, method: v.method,
params: login(v.params, db)? params: login(v.params, db)?
@ -78,7 +78,7 @@ pub struct RpcResponse {
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
pub enum RpcResult { pub enum RpcResult {
SpawnCryp(Cryp), SpawnCryp(Cryp),
User(User), Account(Account),
} }
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
@ -99,25 +99,25 @@ pub struct CrypSpawnParams {
} }
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
struct UserCreateMsg { struct AccountCreateMsg {
method: String, method: String,
params: UserCreateParams, params: AccountCreateParams,
} }
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
pub struct UserCreateParams { pub struct AccountCreateParams {
pub name: String, pub name: String,
pub password: String, pub password: String,
} }
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
struct UserLoginMsg { struct AccountLoginMsg {
method: String, method: String,
params: UserLoginParams, params: AccountLoginParams,
} }
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
pub struct UserLoginParams { pub struct AccountLoginParams {
pub name: String, pub name: String,
pub password: String, pub password: String,
} }