sessions parsing

This commit is contained in:
ntr
2019-06-19 22:04:25 +10:00
parent 27864aa9fc
commit a43f0d309e
13 changed files with 568 additions and 134 deletions
+2 -1
View File
@@ -10,6 +10,7 @@ extern crate r2d2_postgres;
extern crate fallible_iterator;
extern crate actix;
extern crate actix_cors;
extern crate actix_web;
extern crate actix_web_actors;
@@ -58,7 +59,7 @@ fn setup_logger() -> Result<(), fern::InitError> {
))
})
.level_for("postgres", log::LevelFilter::Info)
.level(log::LevelFilter::Info)
.level(log::LevelFilter::Debug)
.chain(std::io::stdout())
.chain(fern::log_file("log/mnml.log")?)
.apply()?;
+107 -7
View File
@@ -1,15 +1,115 @@
use uuid::Uuid;
use actix_web::{web, HttpResponse};
use stripe::{CheckoutSession};
use actix::prelude::*;
use net::{State, MnmlError};
use stripe::{Event, EventObject, CheckoutSession};
pub fn stripe_payment(state: web::Data<State>, body: web::Json::<CheckoutSession>) -> Result<HttpResponse, MnmlError> {
let db = state.pool.get().or(Err(MnmlError::ServerError))?;
let mut tx = db.transaction().or(Err(MnmlError::ServerError))?;
use net::{State, PgPool, MnmlError};
let session = body.into_inner();
pub struct PaymentProcessor {
pool: PgPool,
}
info!("{:?}", session);
impl Actor for PaymentProcessor {
type Context = Context<Self>;
fn started(&mut self, _ctx: &mut Self::Context) {
info!("listening for PaymentProcessor");
}
}
impl Supervised for PaymentProcessor {
fn restarting(&mut self, _ctx: &mut Context<PaymentProcessor>) {
warn!("PaymentProcessor restarting");
}
}
impl PaymentProcessor {
pub fn new(pool: PgPool) -> PaymentProcessor {
PaymentProcessor { pool }
}
}
impl Handler<StripeEvent> for PaymentProcessor {
type Result = Result<Vec<Mtx>, MnmlError>;
fn handle(&mut self, msg: StripeEvent, _: &mut Context<Self>) -> Self::Result {
let event = msg.0;
match event.data.object {
EventObject::CheckoutSession(s) => process_stripe_checkout(s),
_ => Err(MnmlError::ServerError),
}
}
}
fn process_stripe_checkout(session: CheckoutSession) -> Result<Vec<Mtx>, MnmlError> {
let account = match session.client_reference_id {
Some(a) => Uuid::parse_str(&a).or(Err(MnmlError::UnknownUser))?,
None => {
warn!("unknown user checkout {:?}", session);
return Err(MnmlError::UnknownUser)
},
};
// checkout.session.completed
// assign stripe customer_id to account
// if subscription
// go get it
// set account sub to active and end date
// if just bits purchase
Ok(vec![])
}
#[derive(Debug,Clone,Copy,Serialize,Deserialize)]
enum Mtx {
Subscription,
Currency,
}
#[derive(Debug,Clone,Serialize,Deserialize)]
struct Order {
account: Uuid,
customer: String,
}
struct StripeEvent(Event);
impl Message for StripeEvent {
type Result = Result<Vec<Mtx>, MnmlError>;
}
pub fn post_stripe_event(state: web::Data<State>, body: web::Json::<Event>) -> Result<HttpResponse, MnmlError> {
let event: Event = body.into_inner();
info!("stripe event {:?}", event);
state.payments.do_send(StripeEvent(event));
Ok(HttpResponse::Ok().finish())
}
#[cfg(test)]
mod tests {
use super::*;
use std::io::prelude::*;
use std::fs::File;
#[test]
fn test_stripe_checkout() {
let mut f = File::open("./test/checkout.session.completed.purchase.json").expect("couldn't open file");
let mut checkout_str = String::new();
f.read_to_string(&mut checkout_str)
.expect("unable to read file");
let event: Event = serde_json::from_str(&checkout_str)
.expect("could not deserialize");
let mtx = match event.data.object {
EventObject::CheckoutSession(s) => process_stripe_checkout(s),
_ => panic!("unknown event obj"),
};
println!("got some fuckin bling {:?}", mtx);
}
}
+21 -8
View File
@@ -1,10 +1,10 @@
use std::env;
use actix_web::{middleware, web, App, HttpMessage, HttpRequest, HttpResponse, HttpServer};
use actix_web::middleware::cors::Cors;
use actix_web::error::ResponseError;
use actix_web::http::{Cookie};
use actix_web::cookie::{SameSite};
use actix_cors::Cors;
use actix::prelude::*;
@@ -17,7 +17,7 @@ use warden::{Warden};
use pubsub::PubSub;
use ws::{connect};
use account::{account_login, account_create, account_from_token, account_set_token};
use mtx::{stripe_payment};
use mtx::{PaymentProcessor, post_stripe_event};
pub type Db = PooledConnection<PostgresConnectionManager>;
pub type PgPool = Pool<PostgresConnectionManager>;
@@ -32,6 +32,9 @@ pub enum MnmlError {
Unauthorized,
#[fail(display="bad request")]
BadRequest,
#[fail(display="unknown user")]
UnknownUser,
}
impl ResponseError for MnmlError {
@@ -51,6 +54,9 @@ impl ResponseError for MnmlError {
.max_age(-1) // 1 week aligns with db set
.finish())
.json(RpcErrorResponse { err: "unauthorized ".to_string() }),
MnmlError::UnknownUser => HttpResponse::BadRequest()
.json(RpcErrorResponse { err: "unknown user".to_string() }),
}
}
}
@@ -139,6 +145,8 @@ fn create_pool(url: String) -> Pool<PostgresConnectionManager> {
pub struct State {
pub pool: PgPool,
pub payments: Addr<PaymentProcessor>,
pub pubsub: Addr<PubSub>,
secure: bool,
}
@@ -147,23 +155,28 @@ pub fn start() {
.expect("DATABASE_URL must be set");
let pool = create_pool(database_url);
let sys = System::new("mnml");
let _sys = System::new("mnml");
Warden::new(pool.clone()).start();
let _warden = Warden::new(pool.clone()).start();
let payments = PaymentProcessor::new(pool.clone()).start();
let pubsub_conn = pool.get().expect("could not get pubsub pg connection");
let pubsub_addr = Supervisor::start(move |_| PubSub::new(pubsub_conn));
let pubsub = Supervisor::start(move |_| PubSub::new(pubsub_conn));
HttpServer::new(move || App::new()
.data(State { pool: pool.clone(), secure: false })
.data(State { pool: pool.clone(), secure: false, payments: payments.clone(), pubsub: pubsub.clone() })
.wrap(middleware::Logger::default())
.wrap(Cors::new().supports_credentials())
.service(web::resource("/api/login").route(web::post().to(login)))
.service(web::resource("/api/logout").route(web::post().to(logout)))
.service(web::resource("/api/register").route(web::post().to(register)))
.service(web::resource("/api/payments/stripe").route(web::post().to(stripe_payment)))
.service(web::resource("/api/payments/crypto").route(web::post().to(stripe_payment)))
.service(web::resource("/api/payments/stripe")
.route(web::post().to(post_stripe_event)))
// .service(web::resource("/api/payments/crypto")
// .route(web::post().to(post_stripe_payment)))
.service(web::resource("/api/ws").route(web::get().to(connect))))
.bind("127.0.0.1:40000").expect("could not bind to port")