Skip to content

Commit

Permalink
add api_key authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
imor committed Oct 3, 2024
1 parent f14fec8 commit ed36508
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 56 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ members = ["api", "pg_replicate", "replicator"]

[workspace.dependencies]
actix-web = { version = "4", default-features = false }
actix-web-httpauth = { version = "0.8.2", default-features = false }
anyhow = { version = "1.0", default-features = false }
async-trait = { version = "0.1" }
aws-lc-rs = { version = "1.8.1", default-features = false }
Expand Down
1 change: 1 addition & 0 deletions api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ name = "api"

[dependencies]
actix-web = { workspace = true, features = ["macros", "http2"] }
actix-web-httpauth = { workspace = true }
anyhow = { workspace = true, features = ["std"] }
async-trait = { workspace = true }
aws-lc-rs = { workspace = true, features = ["alloc", "aws-lc-sys"] }
Expand Down
1 change: 1 addition & 0 deletions api/configuration/dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ application:
encryption_key:
id: 0
key: BlK9AlrzqRnCZy53j42uE1p2qGBiF7HYZjZYFaZObqg=
api_key: XOUbHmWbt9h7nWl15wWwyWQnctmFGNjpawMc3lT5CFs=
28 changes: 28 additions & 0 deletions api/src/authentication.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use actix_web::{dev::ServiceRequest, web::Data, Error};
use actix_web_httpauth::extractors::{
bearer::{BearerAuth, Config},
AuthenticationError,
};
use tracing::error;

pub async fn auth_validator(
req: ServiceRequest,
credentials: BearerAuth,
) -> Result<ServiceRequest, (Error, ServiceRequest)> {
let api_key: &str = req.app_data::<Data<String>>().expect("missing api_key");
let token = credentials.token();

//TODO: Do a constant time comparison
if api_key != token {
error!("authetication failed");
let config = req
.app_data::<Config>()
.cloned()
.unwrap_or_default()
.scope("v1");

return Err((AuthenticationError::from(config).into(), req));
}

Ok(req)
}
12 changes: 11 additions & 1 deletion api/src/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,30 @@ pub struct EncryptionKey {
pub key: String,
}

impl Display for EncryptionKey {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, " id: {}", self.id)?;
writeln!(f, " key: REDACTED")
}
}

#[derive(serde::Deserialize, Clone)]
pub struct Settings {
pub database: DatabaseSettings,
pub application: ApplicationSettings,
pub worker: WorkerSettings,
pub encryption_key: EncryptionKey,
pub api_key: String,
}

impl Display for Settings {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, "configuration:")?;
writeln!(f, " database:\n{}", self.database)?;
writeln!(f, " application:\n{}", self.application)?;
writeln!(f, " worker:\n{}", self.worker)
writeln!(f, " worker:\n{}", self.worker)?;
writeln!(f, " encryption_key:\n{}", self.encryption_key)?;
writeln!(f, " api_key: REDACTED")
}
}

Expand Down
1 change: 1 addition & 0 deletions api/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod authentication;
pub mod configuration;
pub mod db;
pub mod encryption;
Expand Down
19 changes: 17 additions & 2 deletions api/src/startup.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::{net::TcpListener, sync::Arc};

use actix_web::{dev::Server, web, App, HttpServer};
use actix_web_httpauth::middleware::HttpAuthentication;
use aws_lc_rs::aead::{RandomizedNonceKey, AES_256_GCM};
use base64::{prelude::BASE64_STANDARD, Engine};
use sqlx::{postgres::PgPoolOptions, PgPool};
Expand All @@ -9,6 +10,7 @@ use utoipa::OpenApi;
use utoipa_swagger_ui::SwaggerUi;

use crate::{
authentication::auth_validator,
configuration::{DatabaseSettings, Settings},
db::publications::Publication,
encryption,
Expand Down Expand Up @@ -66,8 +68,16 @@ impl Application {
id: configuration.encryption_key.id,
key,
};
let api_key = configuration.api_key;
let k8s_client = HttpK8sClient::new().await?;
let server = run(listener, connection_pool, encryption_key, Some(k8s_client)).await?;
let server = run(
listener,
connection_pool,
encryption_key,
api_key,
Some(k8s_client),
)
.await?;

Ok(Self { port, server })
}
Expand Down Expand Up @@ -100,10 +110,12 @@ pub async fn run(
listener: TcpListener,
connection_pool: PgPool,
encryption_key: encryption::EncryptionKey,
api_key: String,
http_k8s_client: Option<HttpK8sClient>,
) -> Result<Server, anyhow::Error> {
let connection_pool = web::Data::new(connection_pool);
let encryption_key = web::Data::new(encryption_key);
let api_key = web::Data::new(api_key);
let k8s_client = http_k8s_client.map(|client| web::Data::new(Arc::new(client)));

#[derive(OpenApi)]
Expand Down Expand Up @@ -170,6 +182,7 @@ pub async fn run(
let openapi = ApiDoc::openapi();

let server = HttpServer::new(move || {
let authentication = HttpAuthentication::bearer(auth_validator);
let app = App::new()
.wrap(TracingLogger::default())
.service(health_check)
Expand All @@ -178,6 +191,7 @@ pub async fn run(
)
.service(
web::scope("v1")
.wrap(authentication)
//tenants
.service(create_tenant)
.service(read_tenant)
Expand Down Expand Up @@ -220,7 +234,8 @@ pub async fn run(
.service(read_all_images),
)
.app_data(connection_pool.clone())
.app_data(encryption_key.clone());
.app_data(encryption_key.clone())
.app_data(api_key.clone());
if let Some(k8s_client) = k8s_client.clone() {
app.app_data(k8s_client.clone())
} else {
Expand Down
Loading

0 comments on commit ed36508

Please sign in to comment.