acp routing
This commit is contained in:
parent
99c575ac69
commit
f68a12eab8
@ -18,7 +18,7 @@ const store = createStore(
|
|||||||
document.fonts.load('16pt "Jura"').then(() => {
|
document.fonts.load('16pt "Jura"').then(() => {
|
||||||
const Acp = () => (
|
const Acp = () => (
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<div id="mnml">
|
<div id="mnml" class="acp">
|
||||||
<nav>
|
<nav>
|
||||||
<h1>acp</h1>
|
<h1>acp</h1>
|
||||||
<hr/>
|
<hr/>
|
||||||
|
|||||||
@ -35,54 +35,82 @@ class AccountStatus extends Component {
|
|||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
account: {},
|
account: {},
|
||||||
search: '',
|
name: null,
|
||||||
msg: '-',
|
id: null,
|
||||||
|
msg: '',
|
||||||
|
user: null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
render(args, state) {
|
render(args, state) {
|
||||||
const {
|
|
||||||
user,
|
|
||||||
} = args;
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
msg,
|
msg,
|
||||||
search,
|
name,
|
||||||
|
id,
|
||||||
|
user,
|
||||||
} = state;
|
} = state;
|
||||||
|
|
||||||
const getUser = () =>
|
console.log(user);
|
||||||
axios.get(`/api/acp/user/${search}`)
|
|
||||||
|
const getUser = () => {
|
||||||
|
this.setState({ msg: null });
|
||||||
|
axios.post('/api/acp/user', { id, name })
|
||||||
.then(response => {
|
.then(response => {
|
||||||
this.setState({ msg: response });
|
console.log(response);
|
||||||
|
this.setState({ user: JSON.parse(response.data.response) });
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
this.setState({ msg: error });
|
console.error(error);
|
||||||
|
this.setState({ msg: error.message });
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
if (!user) {
|
const userEl = user
|
||||||
return (
|
? (
|
||||||
<main>
|
<div>
|
||||||
<div>{msg.message}</div>
|
<h1>{user.name}</h1>
|
||||||
<label for="current">Username:</label>
|
<dl>
|
||||||
<input
|
<dt>Id</dt>
|
||||||
class="login-input"
|
<dd>{user.id}</dd>
|
||||||
type="text"
|
<dt>Credits</dt>
|
||||||
name="username"
|
<dd>{user.balance}</dd>
|
||||||
value={this.state.search}
|
<dt>Subscribed</dt>
|
||||||
onInput={linkState(this, 'search')}
|
<dd>{user.subscribed.toString()}</dd>
|
||||||
placeholder="username"
|
</dl>
|
||||||
/>
|
</div>
|
||||||
<button
|
) : null;
|
||||||
onClick={getUser}>
|
|
||||||
Search
|
|
||||||
</button>
|
|
||||||
</main>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main>
|
<main class='menu'>
|
||||||
{JSON.stringify(user)}
|
<div class="top">
|
||||||
|
<div>{msg}</div>
|
||||||
|
{userEl}
|
||||||
|
</div>
|
||||||
|
<div class="bottom acp">
|
||||||
|
<div>
|
||||||
|
<label for="current">Username:</label>
|
||||||
|
<input
|
||||||
|
class="login-input"
|
||||||
|
type="text"
|
||||||
|
name="name"
|
||||||
|
value={this.state.name}
|
||||||
|
onInput={linkState(this, 'name')}
|
||||||
|
placeholder="name"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
class="login-input"
|
||||||
|
type="text"
|
||||||
|
name="userid"
|
||||||
|
value={this.state.id}
|
||||||
|
onInput={linkState(this, 'id')}
|
||||||
|
placeholder="id"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
onClick={getUser}>
|
||||||
|
Search
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,11 +12,16 @@
|
|||||||
"bottom";
|
"bottom";
|
||||||
|
|
||||||
.top {
|
.top {
|
||||||
|
grid-area: top;
|
||||||
padding: 0 0 0.5em 2em;
|
padding: 0 0 0.5em 2em;
|
||||||
border-bottom: 0.1em solid #222;
|
border-bottom: 0.1em solid #222;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bottom {
|
||||||
|
grid-area: bottom;
|
||||||
|
}
|
||||||
|
|
||||||
.team {
|
.team {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-area: top;
|
grid-area: top;
|
||||||
@ -83,3 +88,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#mnml.acp, .acp {
|
||||||
|
user-select: text;
|
||||||
|
-moz-user-select: text;
|
||||||
|
-webkit-user-select: text;
|
||||||
|
-ms-user-select: text;
|
||||||
|
|
||||||
|
input {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -29,6 +29,7 @@ iron = "0.6"
|
|||||||
bodyparser = "0.8"
|
bodyparser = "0.8"
|
||||||
persistent = "0.4"
|
persistent = "0.4"
|
||||||
router = "0.6"
|
router = "0.6"
|
||||||
|
mount = "0.4"
|
||||||
cookie = "0.12"
|
cookie = "0.12"
|
||||||
crossbeam-channel = "0.3"
|
crossbeam-channel = "0.3"
|
||||||
ws = "0.8"
|
ws = "0.8"
|
||||||
|
|||||||
@ -8,7 +8,7 @@ use serde_cbor::{from_slice};
|
|||||||
|
|
||||||
use postgres::transaction::Transaction;
|
use postgres::transaction::Transaction;
|
||||||
|
|
||||||
use net::MnmlHttpError;
|
use http::MnmlHttpError;
|
||||||
use names::{name as generate_name};
|
use names::{name as generate_name};
|
||||||
use construct::{Construct, construct_recover, construct_spawn};
|
use construct::{Construct, construct_recover, construct_spawn};
|
||||||
use instance::{Instance, instance_delete};
|
use instance::{Instance, instance_delete};
|
||||||
@ -51,6 +51,29 @@ pub fn select(db: &Db, id: Uuid) -> Result<Account, Error> {
|
|||||||
Ok(Account { id, name: row.get(1), balance, subscribed })
|
Ok(Account { id, name: row.get(1), balance, subscribed })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn select_name(db: &Db, name: &String) -> Result<Account, Error> {
|
||||||
|
let query = "
|
||||||
|
SELECT id, name, balance, subscribed
|
||||||
|
FROM accounts
|
||||||
|
WHERE name = $1;
|
||||||
|
";
|
||||||
|
|
||||||
|
let result = db
|
||||||
|
.query(query, &[&name])?;
|
||||||
|
|
||||||
|
let row = result.iter().next()
|
||||||
|
.ok_or(format_err!("account not found name={:?}", name))?;
|
||||||
|
|
||||||
|
let id: Uuid = row.get(0);
|
||||||
|
let db_balance: i64 = row.get(2);
|
||||||
|
let balance = u32::try_from(db_balance)
|
||||||
|
.or(Err(format_err!("user {:?} has unparsable balance {:?}", name, db_balance)))?;
|
||||||
|
|
||||||
|
let subscribed: bool = row.get(3);
|
||||||
|
|
||||||
|
Ok(Account { id, name: row.get(1), balance, subscribed })
|
||||||
|
}
|
||||||
|
|
||||||
pub fn from_token(db: &Db, token: String) -> Result<Account, Error> {
|
pub fn from_token(db: &Db, token: String) -> Result<Account, Error> {
|
||||||
let query = "
|
let query = "
|
||||||
SELECT id, name, subscribed, balance
|
SELECT id, name, subscribed, balance
|
||||||
|
|||||||
@ -9,7 +9,9 @@ use iron::mime::Mime;
|
|||||||
use iron::{typemap, BeforeMiddleware,AfterMiddleware};
|
use iron::{typemap, BeforeMiddleware,AfterMiddleware};
|
||||||
use persistent::Read;
|
use persistent::Read;
|
||||||
use router::Router;
|
use router::Router;
|
||||||
|
use mount::{Mount};
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
use account;
|
use account;
|
||||||
use pg::PgPool;
|
use pg::PgPool;
|
||||||
@ -30,6 +32,8 @@ pub enum MnmlHttpError {
|
|||||||
Unauthorized,
|
Unauthorized,
|
||||||
#[fail(display="bad request")]
|
#[fail(display="bad request")]
|
||||||
BadRequest,
|
BadRequest,
|
||||||
|
#[fail(display="not found")]
|
||||||
|
NotFound,
|
||||||
#[fail(display="account name taken or invalid")]
|
#[fail(display="account name taken or invalid")]
|
||||||
AccountNameNotProvided,
|
AccountNameNotProvided,
|
||||||
#[fail(display="account name not provided")]
|
#[fail(display="account name not provided")]
|
||||||
@ -107,6 +111,8 @@ impl From<MnmlHttpError> for IronError {
|
|||||||
MnmlHttpError::InvalidCode |
|
MnmlHttpError::InvalidCode |
|
||||||
MnmlHttpError::TokenDoesNotMatch |
|
MnmlHttpError::TokenDoesNotMatch |
|
||||||
MnmlHttpError::Unauthorized => (m_err.compat(), status::Unauthorized),
|
MnmlHttpError::Unauthorized => (m_err.compat(), status::Unauthorized),
|
||||||
|
|
||||||
|
MnmlHttpError::NotFound => (m_err.compat(), status::NotFound),
|
||||||
};
|
};
|
||||||
IronError { error: Box::new(err), response: iron_response(res, m_err.to_string()) }
|
IronError { error: Box::new(err), response: iron_response(res, m_err.to_string()) }
|
||||||
}
|
}
|
||||||
@ -289,20 +295,89 @@ pub struct State {
|
|||||||
|
|
||||||
impl Key for State { type Value = State; }
|
impl Key for State { type Value = State; }
|
||||||
|
|
||||||
pub fn start(pool: PgPool) {
|
fn account_mount() -> Router {
|
||||||
let mut router = Router::new();
|
let mut router = Router::new();
|
||||||
|
|
||||||
// auth
|
router.post("login", login, "login");
|
||||||
router.post("/api/account/login", login, "login");
|
router.post("logout", logout, "logout");
|
||||||
router.post("/api/account/logout", logout, "logout");
|
router.post("register", register, "register");
|
||||||
router.post("/api/account/register", register, "register");
|
router.post("password", set_password, "set_password");
|
||||||
router.post("/api/account/password", set_password, "set_password");
|
router.post("email", logout, "email");
|
||||||
router.post("/api/account/email", logout, "email");
|
|
||||||
|
|
||||||
// payments
|
router
|
||||||
router.post("/api/payments/stripe", stripe, "stripe");
|
}
|
||||||
|
|
||||||
|
fn payment_mount() -> Router {
|
||||||
|
let mut router = Router::new();
|
||||||
|
router.post("stripe", stripe, "stripe");
|
||||||
|
|
||||||
|
router
|
||||||
|
}
|
||||||
|
|
||||||
|
struct AcpMiddleware;
|
||||||
|
impl BeforeMiddleware for AcpMiddleware {
|
||||||
|
fn before(&self, req: &mut Request) -> IronResult<()> {
|
||||||
|
match req.extensions.get::<account::Account>() {
|
||||||
|
Some(a) => {
|
||||||
|
if ["ntr", "mashy"].contains(&a.name.to_ascii_lowercase().as_ref()) {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
return Err(IronError::from(MnmlHttpError::Unauthorized));
|
||||||
|
},
|
||||||
|
None => Err(IronError::from(MnmlHttpError::Unauthorized)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug,Clone,Deserialize)]
|
||||||
|
struct GetUser {
|
||||||
|
name: Option<String>,
|
||||||
|
id: Option<Uuid>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn acp_user(req: &mut Request) -> IronResult<Response> {
|
||||||
|
let state = req.get::<Read<State>>().unwrap();
|
||||||
|
let params = match req.get::<bodyparser::Struct<GetUser>>() {
|
||||||
|
Ok(Some(b)) => b,
|
||||||
|
_ => return Err(IronError::from(MnmlHttpError::BadRequest)),
|
||||||
|
};
|
||||||
|
|
||||||
|
let db = state.pool.get().or(Err(MnmlHttpError::DbError))?;
|
||||||
|
|
||||||
|
println!("{:?}", params);
|
||||||
|
|
||||||
|
let user = match params.id {
|
||||||
|
Some(id) => account::select(&db, id)
|
||||||
|
.or(Err(MnmlHttpError::NotFound))?,
|
||||||
|
|
||||||
|
None => match params.name {
|
||||||
|
Some(n) => account::select_name(&db, &n)
|
||||||
|
.or(Err(MnmlHttpError::NotFound))?,
|
||||||
|
None => return Err(IronError::from(MnmlHttpError::BadRequest)),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(iron_response(status::Ok, serde_json::to_string(&user).unwrap()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn acp_mount() -> Chain {
|
||||||
|
let mut router = Router::new();
|
||||||
|
router.post("user", acp_user, "acp_user");
|
||||||
|
|
||||||
let mut chain = Chain::new(router);
|
let mut chain = Chain::new(router);
|
||||||
|
chain.link_before(AcpMiddleware);
|
||||||
|
chain
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn start(pool: PgPool) {
|
||||||
|
let mut mounts = Mount::new();
|
||||||
|
|
||||||
|
mounts.mount("/api/account/", account_mount());
|
||||||
|
mounts.mount("/api/payments/", payment_mount());
|
||||||
|
mounts.mount("/api/acp/", acp_mount());
|
||||||
|
|
||||||
|
let mut chain = Chain::new(mounts);
|
||||||
chain.link(Read::<State>::both(State { pool }));
|
chain.link(Read::<State>::both(State { pool }));
|
||||||
chain.link_before(Read::<bodyparser::MaxBodyLength>::one(MAX_BODY_LENGTH));
|
chain.link_before(Read::<bodyparser::MaxBodyLength>::one(MAX_BODY_LENGTH));
|
||||||
chain.link_before(AuthMiddleware);
|
chain.link_before(AuthMiddleware);
|
||||||
@ -23,6 +23,7 @@ extern crate iron;
|
|||||||
extern crate bodyparser;
|
extern crate bodyparser;
|
||||||
extern crate persistent;
|
extern crate persistent;
|
||||||
extern crate router;
|
extern crate router;
|
||||||
|
extern crate mount;
|
||||||
extern crate cookie;
|
extern crate cookie;
|
||||||
|
|
||||||
extern crate ws;
|
extern crate ws;
|
||||||
@ -38,7 +39,7 @@ mod img;
|
|||||||
mod mob;
|
mod mob;
|
||||||
mod mtx;
|
mod mtx;
|
||||||
mod names;
|
mod names;
|
||||||
mod net;
|
mod http;
|
||||||
mod payments;
|
mod payments;
|
||||||
mod pg;
|
mod pg;
|
||||||
mod player;
|
mod player;
|
||||||
@ -98,7 +99,7 @@ fn main() {
|
|||||||
|
|
||||||
let pg_pool = pool.clone();
|
let pg_pool = pool.clone();
|
||||||
|
|
||||||
spawn(move || net::start(http_pool));
|
spawn(move || http::start(http_pool));
|
||||||
spawn(move || warden.listen());
|
spawn(move || warden.listen());
|
||||||
spawn(move || warden::upkeep_tick(warden_tick_tx));
|
spawn(move || warden::upkeep_tick(warden_tick_tx));
|
||||||
spawn(move || pg::listen(pg_pool, pg_events_tx));
|
spawn(move || pg::listen(pg_pool, pg_events_tx));
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
|
|
||||||
use net::State;
|
use http::State;
|
||||||
use iron::prelude::*;
|
use iron::prelude::*;
|
||||||
use iron::response::HttpResponse;
|
use iron::response::HttpResponse;
|
||||||
use iron::status;
|
use iron::status;
|
||||||
@ -14,7 +14,7 @@ use failure::err_msg;
|
|||||||
|
|
||||||
use stripe::{Event, EventObject, CheckoutSession, SubscriptionStatus};
|
use stripe::{Event, EventObject, CheckoutSession, SubscriptionStatus};
|
||||||
|
|
||||||
use net::{MnmlHttpError};
|
use http::{MnmlHttpError};
|
||||||
use pg::{PgPool};
|
use pg::{PgPool};
|
||||||
use account;
|
use account;
|
||||||
|
|
||||||
|
|||||||
@ -26,7 +26,7 @@ use pg::{Db};
|
|||||||
use pg::{PgPool};
|
use pg::{PgPool};
|
||||||
use skill::{Skill, dev_resolve, Resolutions};
|
use skill::{Skill, dev_resolve, Resolutions};
|
||||||
use vbox::{vbox_accept, vbox_apply, vbox_discard, vbox_combine, vbox_reclaim, vbox_unequip};
|
use vbox::{vbox_accept, vbox_apply, vbox_discard, vbox_combine, vbox_reclaim, vbox_unequip};
|
||||||
use net::{AUTH_CLEAR, TOKEN_HEADER};
|
use http::{AUTH_CLEAR, TOKEN_HEADER};
|
||||||
|
|
||||||
#[derive(Debug,Clone,Serialize,Deserialize)]
|
#[derive(Debug,Clone,Serialize,Deserialize)]
|
||||||
pub enum RpcMessage {
|
pub enum RpcMessage {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user