Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add diesel and users table #19

Merged
merged 7 commits into from
Dec 10, 2018
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DATABASE_URL=app2.db
10 changes: 10 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,17 @@ authors = ["Damon Myers <[email protected]>"]
edition = "2018"

[dependencies]
actix = "0.7"
actix-web = "0.7"
diesel = { version = "1.3", features = ["sqlite", "r2d2"] }
dotenv = "0.10"
futures = "0.1"
r2d2 = "0.8"
serde = "1.0"
serde_derive = "1.0"
serde_json = "1.0"
toml = "0.4"

# Use the bundled Sqlite on Windows
[target.'cfg(windows)'.dependencies]
libsqlite3-sys = { version = "0.9", features = ["bundled"] }
5 changes: 5 additions & 0 deletions diesel.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# For documentation on how to configure this file,
# see diesel.rs/guides/configuring-diesel-cli

[print_schema]
file = "src/schema.rs"
Empty file added migrations/.gitkeep
Empty file.
1 change: 1 addition & 0 deletions migrations/2018-12-08-194435_create_users/down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DROP TABLE users
6 changes: 6 additions & 0 deletions migrations/2018-12-08-194435_create_users/up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
CREATE TABLE users (
id INT PRIMARY KEY,
username VARCHAR NOT NULL,
password VARCHAR NOT NULL,
hash VARCHAR NOT NULL
)
22 changes: 22 additions & 0 deletions src/db/handlers/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use crate::db::messages;
use crate::db::models;
use crate::db::DbExecutor;
use crate::schema;
use actix_web::actix::*;
use actix_web::error;
use diesel;
use diesel::prelude::*;
use diesel::r2d2::{ConnectionManager, Pool};

impl Handler<messages::GetUser> for DbExecutor {
type Result = Result<Option<models::User>, actix_web::Error>;
fn handle(&mut self, msg: messages::GetUser, ctx: &mut Self::Context) -> Self::Result {
use crate::schema::users::dsl::*;
let conn = &self.0.get().unwrap();
let mut items = users
.filter(username.eq(msg.username.clone()))
.load::<models::User>(conn)
.map_err(|_| error::ErrorInternalServerError("Error loading person"))?;
Ok(items.pop())
}
}
11 changes: 11 additions & 0 deletions src/db/messages/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use crate::db::models;
use actix_web::actix::*;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need actix here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do. actix imports the prelude which has the Message trait. We need actix_web for the actix_web::Error type.

Copy link
Contributor

@damon-myers damon-myers Dec 10, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm, rather than use-ing the whole prelude of both, should we instead just use actix::Message and actix_web::Error? (super nit-picky for this stage in the development)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I made it more explicit. I also updated a few other places I was importing actix or actix_web wildcards.

use actix_web::*;

pub struct GetUser {
pub username: String,
}

impl Message for GetUser {
type Result = Result<Option<models::User>, Error>;
}
23 changes: 23 additions & 0 deletions src/db/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use actix_web::actix::*;
use actix_web::*;
use diesel;
use diesel::prelude::*;
use diesel::r2d2::{ConnectionManager, Pool};
use dotenv::dotenv;
use std::env;

pub mod handlers;
pub mod messages;
pub mod models;

pub type ConnectionType = SqliteConnection;

pub struct DbExecutor(pub Pool<ConnectionManager<ConnectionType>>);

impl Actor for DbExecutor {
type Context = SyncContext<Self>;
}

pub fn create_manager() -> ConnectionManager<ConnectionType> {
ConnectionManager::<SqliteConnection>::new("app2.db")
}
7 changes: 7 additions & 0 deletions src/db/models/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#[derive(Serialize, Queryable)]
pub struct User {
pub id: i32,
pub username: String,
pub password: String,
pub hash: String,
}
7 changes: 5 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
#[macro_use]
extern crate diesel;
#[macro_use]
extern crate serde_derive;
extern crate actix_web;
extern crate toml;

pub mod config;
pub mod routes;
pub mod state;

pub mod db;
pub mod schema;
15 changes: 12 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
use actix::SyncArbiter;
use actix_web::{http::Method, server, App};
use lighthouse::{config, routes, state::AppState};
use lighthouse::{config, db, routes, state::AppState};
use std::path::Path;
use std::result::Result;

fn main() {
let loaded_config = load_config_from_default_path();
let config_clone = loaded_config.clone();

// Start 3 db executor actors
let manager = db::create_manager();
let pool = r2d2::Pool::builder()
.build(manager)
.expect("Failed to create pool.");
let addr = SyncArbiter::start(3, move || db::DbExecutor(pool.clone()));

server::new(move || {
App::with_state(AppState::from(&config_clone))
App::with_state(AppState::from(&config_clone, &addr))
.resource("/_matrix/client/versions", |r| {
r.method(Method::GET).f(routes::version::versions)
})
Expand All @@ -17,7 +25,8 @@ fn main() {
})
.resource("/_matrix/client/r0/login", |r| {
r.method(Method::GET)
.f(routes::login::supported_login_types)
.f(routes::login::supported_login_types);
r.method(Method::POST).f(routes::login::login)
})
})
.bind(format!(
Expand Down
2 changes: 1 addition & 1 deletion src/routes/discovery/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::state::AppState;
use actix_web::error::Error;
use actix_web::{HttpRequest, Json};
use crate::state::AppState;

#[derive(Serialize)]
pub struct HomeserverData {
Expand Down
20 changes: 18 additions & 2 deletions src/routes/login/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use actix_web::error::Error;
use actix_web::{HttpRequest, Json};
use crate::db;
use crate::state::AppState;
use actix_web::error::Error;
use actix_web::*;
use actix_web::{AsyncResponder, FutureResponse, HttpRequest, HttpResponse, Json};
use futures::Future;

const DUMMY: &str = "m.login.dummy";

Expand All @@ -21,3 +24,16 @@ pub struct LoginFlow {
pub fn supported_login_types(_: &HttpRequest<AppState>) -> Result<Json<Response>, Error> {
Ok(Json(Response { flows: FLOWS }))
}

pub fn login(req: &HttpRequest<AppState>) -> FutureResponse<HttpResponse> {
let username = "username".to_string();
req.state()
.db
.send(db::messages::GetUser { username })
.from_err()
.and_then(|result| match result {
Ok(user) => Ok(HttpResponse::Ok().json(user)),
Err(_) => Ok(HttpResponse::Ok().json("{}".to_string())),
})
.responder()
}
2 changes: 1 addition & 1 deletion src/routes/version/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::state::AppState;
use actix_web::error::Error;
use actix_web::{HttpRequest, Json};
use crate::state::AppState;

const VERSION_SUPPORTED: &str = "r0.4.0";

Expand Down
8 changes: 8 additions & 0 deletions src/schema.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
table! {
users (id) {
id -> Integer,
username -> Text,
password -> Text,
hash -> Text,
}
}
6 changes: 5 additions & 1 deletion src/state.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
use crate::config::Config;
use crate::db;
use actix::Addr;

#[derive(Clone)]
pub struct AppState {
pub domain: String,
pub db: Addr<db::DbExecutor>,
}

impl AppState {
pub fn from(config: &Config) -> AppState {
pub fn from(config: &Config, db: &Addr<db::DbExecutor>) -> AppState {
AppState {
domain: config.domain.clone(),
db: db.clone(),
}
}
}