-
Notifications
You must be signed in to change notification settings - Fork 79
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add auth middleware, info endpoint to notary server (#368)
* Init auth middleware. * Add auth module and info endpoint. * Modify comment. * Make failure to load auth list fallible. * Uses hashmap for whitelist, remove expired session, and other fixes. * Turn off auth. * Fix argument type.
- Loading branch information
Showing
14 changed files
with
293 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
"Name","ApiKey","CreatedAt" | ||
"Jonas Nielsen","test_api_key_0","2023-09-18T07:38:53Z" | ||
"Eren Jaeger","test_api_key_1","2023-10-18T07:38:53Z" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,15 @@ | ||
pub mod auth; | ||
pub mod cli; | ||
pub mod notary; | ||
|
||
use serde::{Deserialize, Serialize}; | ||
|
||
/// Response object of the /info API | ||
#[derive(Debug, Clone, Serialize, Deserialize)] | ||
#[serde(rename_all = "camelCase")] | ||
pub struct InfoResponse { | ||
/// Current version of notary-server | ||
pub version: String, | ||
/// Public key of the notary signing key | ||
pub public_key: String, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
use serde::Deserialize; | ||
use std::collections::HashMap; | ||
|
||
/// Structure of each whitelisted record of the API key whitelist for authorization purpose | ||
#[derive(Clone, Debug, Deserialize)] | ||
#[serde(rename_all = "PascalCase")] | ||
pub struct AuthorizationWhitelistRecord { | ||
pub name: String, | ||
pub api_key: String, | ||
pub created_at: String, | ||
} | ||
|
||
/// Convert whitelist data structure from vector to hashmap using api_key as the key to speed up lookup | ||
pub fn authorization_whitelist_vec_into_hashmap( | ||
authorization_whitelist: Vec<AuthorizationWhitelistRecord>, | ||
) -> HashMap<String, AuthorizationWhitelistRecord> { | ||
let mut hashmap = HashMap::new(); | ||
authorization_whitelist.iter().for_each(|record| { | ||
hashmap.insert(record.api_key.clone(), record.to_owned()); | ||
}); | ||
hashmap | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
use async_trait::async_trait; | ||
use axum::http::{header, request::Parts}; | ||
use axum_core::extract::{FromRef, FromRequestParts}; | ||
use std::collections::HashMap; | ||
use tracing::{error, trace}; | ||
|
||
use crate::{ | ||
domain::{auth::AuthorizationWhitelistRecord, notary::NotaryGlobals}, | ||
NotaryServerError, | ||
}; | ||
|
||
/// Auth middleware to prevent DOS | ||
pub struct AuthorizationMiddleware; | ||
|
||
#[async_trait] | ||
impl<S> FromRequestParts<S> for AuthorizationMiddleware | ||
where | ||
NotaryGlobals: FromRef<S>, | ||
S: Send + Sync, | ||
{ | ||
type Rejection = NotaryServerError; | ||
|
||
async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> { | ||
let notary_globals = NotaryGlobals::from_ref(state); | ||
let Some(whitelist) = notary_globals.authorization_whitelist else { | ||
trace!("Skipping authorization as whitelist is not set."); | ||
return Ok(Self); | ||
}; | ||
let auth_header = parts | ||
.headers | ||
.get(header::AUTHORIZATION) | ||
.and_then(|value| std::str::from_utf8(value.as_bytes()).ok()); | ||
|
||
match auth_header { | ||
Some(auth_header) => { | ||
if api_key_is_valid(auth_header, &whitelist) { | ||
trace!("Request authorized."); | ||
Ok(Self) | ||
} else { | ||
let err_msg = "Invalid API key.".to_string(); | ||
error!(err_msg); | ||
Err(NotaryServerError::UnauthorizedProverRequest(err_msg)) | ||
} | ||
} | ||
None => { | ||
let err_msg = "Missing API key.".to_string(); | ||
error!(err_msg); | ||
Err(NotaryServerError::UnauthorizedProverRequest(err_msg)) | ||
} | ||
} | ||
} | ||
} | ||
|
||
/// Helper function to check if an API key is in whitelist | ||
fn api_key_is_valid( | ||
api_key: &str, | ||
whitelist: &HashMap<String, AuthorizationWhitelistRecord>, | ||
) -> bool { | ||
whitelist.get(api_key).is_some() | ||
} | ||
|
||
#[cfg(test)] | ||
mod test { | ||
use super::{api_key_is_valid, HashMap}; | ||
use crate::domain::auth::{ | ||
authorization_whitelist_vec_into_hashmap, AuthorizationWhitelistRecord, | ||
}; | ||
use std::sync::Arc; | ||
|
||
fn get_whitelist_fixture() -> HashMap<String, AuthorizationWhitelistRecord> { | ||
authorization_whitelist_vec_into_hashmap(vec![ | ||
AuthorizationWhitelistRecord { | ||
name: "test-name-0".to_string(), | ||
api_key: "test-api-key-0".to_string(), | ||
created_at: "2023-10-18T07:38:53Z".to_string(), | ||
}, | ||
AuthorizationWhitelistRecord { | ||
name: "test-name-1".to_string(), | ||
api_key: "test-api-key-1".to_string(), | ||
created_at: "2023-10-11T07:38:53Z".to_string(), | ||
}, | ||
AuthorizationWhitelistRecord { | ||
name: "test-name-2".to_string(), | ||
api_key: "test-api-key-2".to_string(), | ||
created_at: "2022-10-11T07:38:53Z".to_string(), | ||
}, | ||
]) | ||
} | ||
|
||
#[test] | ||
fn test_api_key_is_present() { | ||
let whitelist = get_whitelist_fixture(); | ||
assert!(api_key_is_valid("test-api-key-0", &Arc::new(whitelist))); | ||
} | ||
|
||
#[test] | ||
fn test_api_key_is_absent() { | ||
let whitelist = get_whitelist_fixture(); | ||
assert_eq!( | ||
api_key_is_valid("test-api-keY-0", &Arc::new(whitelist)), | ||
false | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.