use std::sync::Arc;
use pgwire::api::PgWireServerHandlers;
use pgwire::api::auth::StartupHandler;
use pgwire::api::query::{ExtendedQueryHandler, SimpleQueryHandler};
use crate::config::auth::AuthMode;
use crate::control::security::credential::CredentialStore;
use crate::control::state::SharedState;
use super::super::handler::NodeDbPgHandler;
use super::auth::NodeDbAuthSource;
use super::provider::nodedb_parameter_provider;
use super::startup::AuthStartup;
pub struct NodeDbPgHandlerFactory {
handler: Arc<NodeDbPgHandler>,
auth_mode: AuthMode,
credentials: Arc<CredentialStore>,
state: Arc<SharedState>,
}
impl NodeDbPgHandlerFactory {
pub fn new(state: Arc<SharedState>, auth_mode: AuthMode) -> Self {
Self {
handler: Arc::new(NodeDbPgHandler::new(Arc::clone(&state), auth_mode.clone())),
auth_mode,
credentials: Arc::clone(&state.credentials),
state,
}
}
pub async fn on_connection_end(&self, addr: &std::net::SocketAddr) {
self.handler.reclaim_open_txn(addr).await;
self.handler.sessions.remove(addr);
}
pub fn session_idle_eligible(&self, addr: &std::net::SocketAddr, idle_ms: u64) -> bool {
self.handler.sessions.idle_eligible(
addr,
idle_ms,
crate::control::server::shared::session::now_unix_ms(),
)
}
}
impl PgWireServerHandlers for NodeDbPgHandlerFactory {
fn simple_query_handler(&self) -> Arc<impl SimpleQueryHandler> {
self.handler.clone()
}
fn extended_query_handler(&self) -> Arc<impl ExtendedQueryHandler> {
self.handler.clone()
}
fn copy_handler(&self) -> Arc<impl pgwire::api::copy::CopyHandler> {
Arc::new(super::super::handler::NodeDbCopyHandler {
state: Arc::clone(&self.state),
restore_state: Arc::clone(&self.handler.restore_state),
})
}
fn startup_handler(&self) -> Arc<impl StartupHandler> {
match self.auth_mode {
AuthMode::Trust => Arc::new(AuthStartup::Trust(self.handler.clone())),
AuthMode::Password | AuthMode::Certificate => {
let auth_source = Arc::new(NodeDbAuthSource::new(
Arc::clone(&self.credentials),
Arc::clone(&self.state),
));
let scram = pgwire::api::auth::sasl::scram::ScramAuth::new(auth_source);
let params = Arc::new(nodedb_parameter_provider());
let sasl =
pgwire::api::auth::sasl::SASLAuthStartupHandler::new(params).with_scram(scram);
Arc::new(AuthStartup::Scram {
sasl: Box::new(sasl),
state: Arc::clone(&self.state),
handler: self.handler.clone(),
})
}
}
}
}