Simplify DB handling with sqlx::Any

This commit is contained in:
Valentin Tolmer 2021-03-10 12:06:32 +01:00
parent 285a51db6e
commit 1a947358fa
4 changed files with 21 additions and 38 deletions

View File

@ -17,7 +17,7 @@ http = "*"
ldap3_server = "*" ldap3_server = "*"
log = "*" log = "*"
serde = "*" serde = "*"
sqlx = { version = "0.5", features = [ "runtime-actix-native-tls", "sqlite", "macros" ] } sqlx = { version = "0.5", features = [ "runtime-actix-native-tls", "any", "sqlite", "mysql", "postgres", "macros" ] }
thiserror = "*" thiserror = "*"
tokio = { version = "1.2.0", features = ["full"] } tokio = { version = "1.2.0", features = ["full"] }
tokio-util = "0.6.3" tokio-util = "0.6.3"

View File

@ -6,25 +6,19 @@ use anyhow::bail;
use anyhow::Result; use anyhow::Result;
use futures_util::future::ok; use futures_util::future::ok;
use log::*; use log::*;
use std::rc::Rc; use sqlx::any::AnyPool;
use tokio::net::tcp::WriteHalf; use tokio::net::tcp::WriteHalf;
use tokio_util::codec::{FramedRead, FramedWrite}; use tokio_util::codec::{FramedRead, FramedWrite};
use ldap3_server::simple::*; use ldap3_server::simple::*;
use ldap3_server::LdapCodec; use ldap3_server::LdapCodec;
pub struct LdapSession<DB> pub struct LdapSession {
where
DB: sqlx::Database,
{
dn: String, dn: String,
sql_pool: Rc<sqlx::Pool<DB>>, sql_pool: AnyPool,
} }
impl<DB> LdapSession<DB> impl LdapSession {
where
DB: sqlx::Database,
{
pub fn do_bind(&mut self, sbr: &SimpleBindRequest) -> LdapMsg { pub fn do_bind(&mut self, sbr: &SimpleBindRequest) -> LdapMsg {
if sbr.dn == "cn=Directory Manager" && sbr.pw == "password" { if sbr.dn == "cn=Directory Manager" && sbr.pw == "password" {
self.dn = sbr.dn.to_string(); self.dn = sbr.dn.to_string();
@ -72,10 +66,8 @@ where
pub fn do_whoami(&mut self, wr: &WhoamiRequest) -> LdapMsg { pub fn do_whoami(&mut self, wr: &WhoamiRequest) -> LdapMsg {
wr.gen_success(format!("dn: {}", self.dn).as_str()) wr.gen_success(format!("dn: {}", self.dn).as_str())
} }
pub fn handle_ldap_message(&mut self, server_op: ServerOps) -> Option<Vec<LdapMsg>>
where pub fn handle_ldap_message(&mut self, server_op: ServerOps) -> Option<Vec<LdapMsg>> {
DB: sqlx::Database,
{
let result = match server_op { let result = match server_op {
ServerOps::SimpleBind(sbr) => vec![self.do_bind(&sbr)], ServerOps::SimpleBind(sbr) => vec![self.do_bind(&sbr)],
ServerOps::Search(sr) => self.do_search(&sr), ServerOps::Search(sr) => self.do_search(&sr),
@ -89,14 +81,11 @@ where
} }
} }
async fn handle_incoming_message<DB>( async fn handle_incoming_message(
msg: Result<LdapMsg, std::io::Error>, msg: Result<LdapMsg, std::io::Error>,
resp: &mut FramedWrite<WriteHalf<'_>, LdapCodec>, resp: &mut FramedWrite<WriteHalf<'_>, LdapCodec>,
session: &mut LdapSession<DB>, session: &mut LdapSession,
) -> Result<bool> ) -> Result<bool> {
where
DB: sqlx::Database,
{
use futures_util::SinkExt; use futures_util::SinkExt;
use std::convert::TryFrom; use std::convert::TryFrom;
let server_op = match msg let server_op = match msg
@ -133,19 +122,16 @@ where
Ok(true) Ok(true)
} }
pub fn build_ldap_server<DB>( pub fn build_ldap_server(
config: &Configuration, config: &Configuration,
sql_pool: sqlx::Pool<DB>, sql_pool: AnyPool,
server_builder: ServerBuilder, server_builder: ServerBuilder,
) -> Result<ServerBuilder> ) -> Result<ServerBuilder> {
where
DB: sqlx::Database,
{
use futures_util::StreamExt; use futures_util::StreamExt;
Ok( Ok(
server_builder.bind("ldap", ("0.0.0.0", config.ldap_port), move || { server_builder.bind("ldap", ("0.0.0.0", config.ldap_port), move || {
let sql_pool = std::rc::Rc::new(sql_pool.clone()); let sql_pool = sql_pool.clone();
pipeline_factory(fn_service(move |mut stream: TcpStream| { pipeline_factory(fn_service(move |mut stream: TcpStream| {
let sql_pool = sql_pool.clone(); let sql_pool = sql_pool.clone();
async move { async move {

View File

@ -5,16 +5,14 @@ use actix_service::pipeline_factory;
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use futures_util::future::ok; use futures_util::future::ok;
use log::*; use log::*;
use sqlx::any::AnyPool;
use std::sync::Arc; use std::sync::Arc;
pub fn build_tcp_server<DB>( pub fn build_tcp_server(
config: &Configuration, config: &Configuration,
sql_pool: sqlx::Pool<DB>, sql_pool: AnyPool,
server_builder: ServerBuilder, server_builder: ServerBuilder,
) -> Result<ServerBuilder> ) -> Result<ServerBuilder> {
where
DB: sqlx::Database,
{
use std::sync::atomic::AtomicUsize; use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering; use std::sync::atomic::Ordering;
use tokio::io::AsyncReadExt; use tokio::io::AsyncReadExt;

View File

@ -2,15 +2,14 @@ use crate::infra::configuration::Configuration;
use anyhow::Result; use anyhow::Result;
use futures_util::TryFutureExt; use futures_util::TryFutureExt;
use log::*; use log::*;
use sqlx::sqlite::{SqliteConnectOptions, SqlitePoolOptions}; use sqlx::any::AnyPoolOptions;
use std::str::FromStr;
mod infra; mod infra;
async fn run_server(config: Configuration) -> Result<()> { async fn run_server(config: Configuration) -> Result<()> {
let sql_pool = SqlitePoolOptions::new() let sql_pool = AnyPoolOptions::new()
.max_connections(5) .max_connections(5)
.connect_with(SqliteConnectOptions::from_str("sqlite://users.db")?.create_if_missing(true)) .connect("sqlite://users.db?mode=rwc")
.await?; .await?;
let server_builder = infra::ldap_server::build_ldap_server( let server_builder = infra::ldap_server::build_ldap_server(
&config, &config,