Skip to content

Commit

Permalink
Add basic auth to http server
Browse files Browse the repository at this point in the history
  • Loading branch information
var77 committed Mar 14, 2024
1 parent 2e88d8e commit a81c989
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 17 deletions.
25 changes: 13 additions & 12 deletions lantern_cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@ clap = { version = "4.4.0", features = ["derive"] }
anyhow = "1.0.75"
postgres = "0.19.7"
rand = "0.8.5"
linfa-clustering = { version = "0.7.0", features = ["ndarray-linalg"], optional=true }
linfa-clustering = { version = "0.7.0", features = ["ndarray-linalg"], optional = true }
linfa = {version = "0.7.0", optional = true}
ndarray = { version = "0.15.6", features = ["rayon"] }
rayon = { version="1.8.1", optional = true }
md5 = {version="0.7.0", optional = true }
isahc = "1.7.2"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0.111"
gcp_auth = {version="0.10.0", optional=true}
tokio-postgres = { version="0.7.10", optional=true }
gcp_auth = {version="0.10.0", optional = true}
tokio-postgres = { version="0.7.10", optional = true }
futures = "0.3.28"
tokio = { version = "1.33.0", features = ["full"] }
lazy_static = "1.4.0"
Expand All @@ -40,19 +40,20 @@ strum = { version = "0.25", features = ["derive"] }
tiktoken-rs = "0.5.8"
regex = "1.10.3"
postgres-types = { version = "0.2.6", features = ["derive"] }
usearch = { git = "https://github.com/Ngalstyan4/usearch.git", branch="main-lantern" }
actix-web = { version="4.5.1", optional = true }
env_logger = { version="0.11.2", optional = true }
deadpool-postgres = {version="0.12.1", optional = true}
deadpool = {version="0.10.0", optional=true}
bytes = {version="1.5.0", optional=true}
utoipa = {version="4.2.0", optional=true}
utoipa-swagger-ui = { version= "6.0.0", features=["actix-web"], optional=true }
usearch = { git = "https://github.com/Ngalstyan4/usearch.git", branch = "main-lantern" }
actix-web = { version = "4.5.1", optional = true }
env_logger = { version = "0.11.2", optional = true }
deadpool-postgres = { version = "0.12.1", optional = true }
deadpool = { version = "0.10.0", optional = true}
bytes = { version = "1.5.0", optional = true}
utoipa = { version = "4.2.0", optional = true}
utoipa-swagger-ui = { version = "6.0.0", features = ["actix-web"], optional = true }
actix-web-httpauth = { version = "0.8.1", optional = true }

[features]
default = ["cli", "daemon", "http-server", "autotune", "pq", "external-index", "embeddings"]
daemon = ["dep:tokio-postgres"]
http-server = ["dep:deadpool-postgres", "dep:deadpool", "dep:bytes", "dep:utoipa", "dep:utoipa-swagger-ui", "dep:actix-web", "dep:tokio-postgres", "dep:env_logger"]
http-server = ["dep:deadpool-postgres", "dep:deadpool", "dep:bytes", "dep:utoipa", "dep:utoipa-swagger-ui", "dep:actix-web", "dep:tokio-postgres", "dep:env_logger", "dep:actix-web-httpauth"]
autotune = []
pq = ["dep:gcp_auth", "dep:linfa", "dep:linfa-clustering", "dep:md5", "dep:rayon"]
cli = []
Expand Down
8 changes: 8 additions & 0 deletions lantern_cli/src/http_server/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,12 @@ pub struct HttpServerArgs {
/// Port to bind
#[arg(long, default_value_t = 8080)]
pub port: u16,

/// Username for HTTP Auth
#[arg(short, long)]
pub username: Option<String>,

/// Password for HTTP Auth
#[arg(short, long)]
pub password: Option<String>,
}
45 changes: 40 additions & 5 deletions lantern_cli/src/http_server/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
use crate::{logger::LogLevel, types::AnyhowVoidResult};
use actix_web::{
error::ErrorInternalServerError, middleware::Logger, web, App, HttpServer, Result,
dev::ServiceRequest,
error::{ErrorInternalServerError, ErrorUnauthorized},
middleware::Logger,
web, App, Error, HttpServer, Result,
};
use actix_web_httpauth::{extractors::basic::BasicAuth, middleware::HttpAuthentication};
use cli::HttpServerArgs;
use deadpool_postgres::{Config as PoolConfig, Manager, Pool};
use tokio_postgres::NoTls;
Expand Down Expand Up @@ -37,18 +41,37 @@ impl AppPool {
}
}

#[derive(Debug)]
pub struct AuthCredentials {
username: String,
password: String,
}

pub struct AppState {
db_uri: String,
auth_credentials: Option<AuthCredentials>,
pool: AppPool,
is_remote_database: bool,
#[allow(dead_code)]
logger: crate::logger::Logger,
}

/*
* PATCH - /collection/:name/:id -
* { row: Row }
* */
pub type AppData = web::Data<AppState>;

async fn auth_validator(
req: ServiceRequest,
credentials: BasicAuth,
) -> Result<ServiceRequest, (Error, ServiceRequest)> {
let data = req.app_data::<AppData>().unwrap();
if let Some(creds) = &data.auth_credentials {
if creds.username != credentials.user_id()
|| creds.password != credentials.password().unwrap_or("")
{
return Err((ErrorUnauthorized("Unauthorized"), req));
}
}
Ok(req)
}

#[derive(OpenApi)]
#[openapi(
Expand Down Expand Up @@ -103,7 +126,18 @@ pub async fn start(
let pool = config.create_pool(None, NoTls)?;

setup::setup_tables(&pool).await?;

let auth_credentials = if args.username.is_some() && args.password.is_some() {
Some(AuthCredentials {
username: args.username.clone().unwrap(),
password: args.password.clone().unwrap(),
})
} else {
None
};

let state = web::Data::new(AppState {
auth_credentials,
db_uri: args.db_uri.clone(),
is_remote_database: args.remote_database,
pool: AppPool::new(pool),
Expand All @@ -114,6 +148,7 @@ pub async fn start(
App::new()
.wrap(Logger::new("%r - %s %Dms"))
.app_data(state.clone())
.wrap(HttpAuthentication::basic(auth_validator))
.app_data(
web::JsonConfig::default()
// limit request payload size to 1GB
Expand Down
2 changes: 2 additions & 0 deletions lantern_cli/tests/http_server_test_with_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ fn start_server(db_uri: String) -> Sender<()> {
remote_database: true,
host: "127.0.0.1".to_owned(),
port: 7777,
username: None,
password: None,
},
None,
)
Expand Down

0 comments on commit a81c989

Please sign in to comment.