Split the crate in 3, introduce JS frontend

This commit is contained in:
Valentin Tolmer 2021-05-08 11:34:55 +02:00
parent 9459f53a13
commit c58459547b
9 changed files with 119 additions and 39 deletions

3
.gitignore vendored
View File

@ -1,6 +1,9 @@
# Generated by Cargo # Generated by Cargo
# will have compiled files and executables # will have compiled files and executables
/target/ /target/
/app/target
/app/pkg
/model/target
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html

View File

@ -29,6 +29,8 @@ tracing-log = "*"
tracing-subscriber = "*" tracing-subscriber = "*"
async-trait = "0.1.48" async-trait = "0.1.48"
sea-query = { version = "0.9.4", features = [ "with-chrono" ] } sea-query = { version = "0.9.4", features = [ "with-chrono" ] }
lldap_model = { path = "model" }
lldap_app = { path = "app" }
[dependencies.figment] [dependencies.figment]
features = ["toml", "env"] features = ["toml", "env"]

13
app/Cargo.toml Normal file
View File

@ -0,0 +1,13 @@
[package]
name = "lldap_app"
version = "0.1.0"
authors = ["Valentin Tolmer <valentin@tolmer.fr>", "Steve Barrau <steve.barrau@gmail.com>", "Thomas Wickham <mackwic@gmail.com>"]
edition = "2018"
[dependencies]
yew = "0.17.4"
wasm-bindgen = "0.2.73"
lldap_model = { path = "../model" }
[lib]
crate-type = ["cdylib"]

32
app/src/app.rs Normal file
View File

@ -0,0 +1,32 @@
use lldap_model::*;
use yew::prelude::*;
pub struct App {}
pub enum Msg {
BindRequest(BindRequest),
ListUsersRequest(ListUsersRequest),
}
impl Component for App {
type Message = Msg;
type Properties = ();
fn create(_: Self::Properties, _: ComponentLink<Self>) -> Self {
App {}
}
fn update(&mut self, _msg: Self::Message) -> ShouldRender {
true
}
fn change(&mut self, _: Self::Properties) -> ShouldRender {
false
}
fn view(&self) -> Html {
html! {
<p>{ "Hello world!" }</p>
}
}
}

10
app/src/lib.rs Normal file
View File

@ -0,0 +1,10 @@
mod app;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn run_app() -> Result<(), JsValue> {
yew::start_app::<app::App>();
Ok(())
}

12
model/Cargo.toml Normal file
View File

@ -0,0 +1,12 @@
[package]
name = "lldap_model"
version = "0.1.0"
authors = ["Valentin Tolmer <valentin@tolmer.fr>", "Steve Barrau <steve.barrau@gmail.com>", "Thomas Wickham <mackwic@gmail.com>"]
edition = "2018"
[features]
js = []
[dependencies]
chrono = "*"
serde = "*"

36
model/src/lib.rs Normal file
View File

@ -0,0 +1,36 @@
#[cfg_attr(test, derive(PartialEq, Eq, Debug))]
pub struct BindRequest {
pub name: String,
pub password: String,
}
#[derive(PartialEq, Eq)]
#[cfg_attr(test, derive(Debug))]
pub enum RequestFilter {
And(Vec<RequestFilter>),
Or(Vec<RequestFilter>),
Not(Box<RequestFilter>),
Equality(String, String),
}
#[cfg_attr(test, derive(PartialEq, Eq, Debug))]
pub struct ListUsersRequest {
pub filters: Option<RequestFilter>,
}
#[cfg_attr(test, derive(PartialEq, Eq, Debug))]
pub struct User {
pub user_id: String,
pub email: String,
pub display_name: String,
pub first_name: String,
pub last_name: String,
// pub avatar: ?,
pub creation_date: chrono::NaiveDateTime,
}
#[cfg_attr(test, derive(PartialEq, Eq, Debug))]
pub struct Group {
pub display_name: String,
pub users: Vec<String>,
}

View File

@ -5,48 +5,11 @@ use anyhow::{bail, Result};
use async_trait::async_trait; use async_trait::async_trait;
use futures_util::StreamExt; use futures_util::StreamExt;
use futures_util::TryStreamExt; use futures_util::TryStreamExt;
pub use lldap_model::*;
use log::*; use log::*;
use sea_query::{Expr, Order, Query, SimpleExpr, SqliteQueryBuilder}; use sea_query::{Expr, Order, Query, SimpleExpr, SqliteQueryBuilder};
use sqlx::Row; use sqlx::Row;
#[cfg_attr(test, derive(PartialEq, Eq, Debug))]
pub struct BindRequest {
pub name: String,
pub password: String,
}
#[derive(PartialEq, Eq)]
#[cfg_attr(test, derive(Debug))]
pub enum RequestFilter {
And(Vec<RequestFilter>),
Or(Vec<RequestFilter>),
Not(Box<RequestFilter>),
Equality(String, String),
}
#[cfg_attr(test, derive(PartialEq, Eq, Debug))]
pub struct ListUsersRequest {
pub filters: Option<RequestFilter>,
}
#[derive(sqlx::FromRow)]
#[cfg_attr(test, derive(PartialEq, Eq, Debug))]
pub struct User {
pub user_id: String,
pub email: String,
pub display_name: String,
pub first_name: String,
pub last_name: String,
// pub avatar: ?,
pub creation_date: chrono::NaiveDateTime,
}
#[cfg_attr(test, derive(PartialEq, Eq, Debug))]
pub struct Group {
pub display_name: String,
pub users: Vec<String>,
}
#[async_trait] #[async_trait]
pub trait BackendHandler: Clone + Send { pub trait BackendHandler: Clone + Send {
async fn bind(&self, request: BindRequest) -> Result<()>; async fn bind(&self, request: BindRequest) -> Result<()>;
@ -142,7 +105,15 @@ impl BackendHandler for SqlBackendHandler {
query_builder.to_string(SqliteQueryBuilder) query_builder.to_string(SqliteQueryBuilder)
}; };
let results = sqlx::query_as::<_, User>(&query) let results = sqlx::query(&query)
.map(|row: DbRow| User {
user_id: row.get::<String, _>("user_id"),
email: row.get::<String, _>("email"),
display_name: row.get::<String, _>("display_name"),
first_name: row.get::<String, _>("first_name"),
last_name: row.get::<String, _>("last_name"),
creation_date: row.get::<chrono::NaiveDateTime, _>("creation_date"),
})
.fetch(&self.sql_pool) .fetch(&self.sql_pool)
.collect::<Vec<sqlx::Result<User>>>() .collect::<Vec<sqlx::Result<User>>>()
.await; .await;

View File

@ -2,6 +2,7 @@ use sea_query::*;
pub type Pool = sqlx::sqlite::SqlitePool; pub type Pool = sqlx::sqlite::SqlitePool;
pub type PoolOptions = sqlx::sqlite::SqlitePoolOptions; pub type PoolOptions = sqlx::sqlite::SqlitePoolOptions;
pub type DbRow = sqlx::sqlite::SqliteRow;
#[derive(Iden)] #[derive(Iden)]
pub enum Users { pub enum Users {