Initial commit

With instance configuration
This commit is contained in:
Bat
2018-04-22 14:35:37 +01:00
commit f060fa08af
18 changed files with 1234 additions and 0 deletions
+35
View File
@@ -0,0 +1,35 @@
use std::ops::Deref;
use rocket::http::Status;
use rocket::request::{self, FromRequest};
use rocket::{Request, State, Outcome};
use diesel::pg::PgConnection;
use diesel::r2d2::{ConnectionManager, Pool, PooledConnection};
// From rocket documentation
// Connection request guard type: a wrapper around an r2d2 pooled connection.
pub struct DbConn(pub PooledConnection<ConnectionManager<PgConnection>>);
/// Attempts to retrieve a single connection from the managed database pool. If
/// no pool is currently managed, fails with an `InternalServerError` status. If
/// no connections are available, fails with a `ServiceUnavailable` status.
impl<'a, 'r> FromRequest<'a, 'r> for DbConn {
type Error = ();
fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, Self::Error> {
let pool = request.guard::<State<Pool<ConnectionManager<PgConnection>>>>()?;
match pool.get() {
Ok(conn) => Outcome::Success(DbConn(conn)),
Err(_) => Outcome::Failure((Status::ServiceUnavailable, ()))
}
}
}
// For the convenience of using an &DbConn as an &PgConnection.
impl Deref for DbConn {
type Target = PgConnection;
fn deref(&self) -> &Self::Target {
&self.0
}
}
+56
View File
@@ -0,0 +1,56 @@
#![feature(plugin, custom_derive)]
#![plugin(rocket_codegen)]
#[macro_use]
extern crate diesel;
extern crate dotenv;
extern crate rocket;
extern crate rocket_contrib;
use diesel::pg::PgConnection;
use diesel::r2d2::{ConnectionManager, Pool};
use dotenv::dotenv;
use std::env;
use rocket_contrib::Template;
mod db_conn;
mod models;
mod schema;
mod routes;
use db_conn::DbConn;
use models::instance::*;
type PgPool = Pool<ConnectionManager<PgConnection>>;
/// Initializes a database pool.
fn init_pool() -> PgPool {
dotenv().ok();
let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
let manager = ConnectionManager::<PgConnection>::new(database_url);
Pool::new(manager).expect("db pool")
}
#[get("/")]
fn index(conn: DbConn) -> String {
match Instance::get_local(&*conn) {
Some(inst) => {
format!("Welcome on {}", inst.name)
}
None => {
String::from("Not initialized")
}
}
}
fn main() {
rocket::ignite()
.mount("/", routes![
routes::instance::configure,
routes::instance::post_config
])
.manage(init_pool())
.attach(Template::fairing())
.launch();
}
+55
View File
@@ -0,0 +1,55 @@
use diesel;
use diesel::{ QueryDsl, RunQueryDsl, ExpressionMethods, PgConnection };
use std::iter::Iterator;
use schema::instances;
#[derive(Identifiable, Queryable)]
pub struct Instance {
pub id: i32,
pub local_domain: String,
pub public_domain: String,
pub name: String,
pub local: bool,
pub blocked: bool
}
#[derive(Insertable)]
#[table_name = "instances"]
pub struct NewInstance {
pub local_domain: String,
pub public_domain: String,
pub name: String,
pub local: bool
}
impl Instance {
pub fn get_local(conn: &PgConnection) -> Option<Instance> {
instances::table.filter(instances::local.eq(true))
.limit(1)
.load::<Instance>(conn)
.expect("Error loading local instance infos")
.into_iter().nth(0)
}
pub fn insert<'a>(conn: &PgConnection, loc_dom: String, pub_dom: String, name: String, local: bool) -> Instance {
diesel::insert_into(instances::table)
.values(NewInstance {
local_domain: loc_dom,
public_domain: pub_dom,
name: name,
local: local
})
.get_result(conn)
.expect("Error saving new instance")
}
pub fn get(id: i32) -> Option<Instance> {
None
}
pub fn block(&self) {}
pub fn has_admin(&self, conn: &PgConnection) -> bool {
false
}
}
+1
View File
@@ -0,0 +1 @@
pub mod instance;
+35
View File
@@ -0,0 +1,35 @@
use rocket_contrib::Template;
use rocket::response::Redirect;
use rocket::request::Form;
use std::collections::HashMap;
use db_conn::DbConn;
use models::instance::*;
#[get("/configure")]
fn configure() -> Template {
Template::render("instance/configure", HashMap::<String, i32>::new())
}
#[derive(FromForm)]
struct NewInstanceForm {
local_domain: String,
public_domain: String,
name: String
}
#[post("/configure", data = "<data>")]
fn post_config(conn: DbConn, data: Form<NewInstanceForm>) -> Redirect {
let form = data.get();
let inst = Instance::insert(
&*conn,
form.local_domain.to_string(),
form.public_domain.to_string(),
form.name.to_string(),
true);
if inst.has_admin(&*conn) {
Redirect::to("/")
} else {
Redirect::to("/users/new")
}
}
+1
View File
@@ -0,0 +1 @@
pub mod instance;
+10
View File
@@ -0,0 +1,10 @@
table! {
instances (id) {
id -> Int4,
local_domain -> Varchar,
public_domain -> Varchar,
name -> Varchar,
local -> Bool,
blocked -> Bool,
}
}