-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: port over infrastructure stuff
- Loading branch information
Showing
46 changed files
with
4,099 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,44 @@ | ||
[package] | ||
name = "trustify-auth" | ||
version = "0.1.0" | ||
edition = "2021" | ||
license = "Apache-2.0" | ||
description = "Authentication and authorization functionality" | ||
|
||
[dependencies] | ||
anyhow = "1" | ||
async-trait = "0.1" | ||
base64 = "0.22" | ||
biscuit = "0.6" | ||
chrono = { version = "0.4.26", default-features = false } | ||
clap = { version = "4", features = ["derive", "env"] } | ||
futures-util = "0.3" | ||
humantime = "2" | ||
jsonpath-rust = "0.5" | ||
log = "0.4" | ||
openid = "0.12" | ||
reqwest = "0.11" | ||
schemars = "0.8" | ||
serde = { version = "1", features = ["derive"] } | ||
serde_json = "1" | ||
serde_yaml = "0.9" | ||
thiserror = "1" | ||
tokio = "1" | ||
tracing = "0.1" | ||
url = "2" | ||
|
||
trustify-common = { path = ".." } | ||
|
||
# feature: actix | ||
actix-web = { version = "4.3.1", optional = true } | ||
actix-http = { version = "3.3.1", optional = true } | ||
actix-web-httpauth = { version = "0.8", optional = true } | ||
actix-web-extras = { version = "0.1", optional = true } | ||
|
||
# feature: swagger | ||
utoipa = { version = "4", features = ["actix_extras"], optional = true } | ||
utoipa-swagger-ui = { version = "6", features = ["actix-web"], optional = true } | ||
|
||
[features] | ||
actix = ["actix-web", "actix-http", "actix-web-httpauth", "actix-web-extras"] | ||
swagger = ["utoipa", "utoipa-swagger-ui", "actix"] |
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,13 @@ | ||
use trustification_auth::auth::AuthConfig; | ||
|
||
fn main() -> anyhow::Result<()> { | ||
let schema = schemars::schema_for!(AuthConfig); | ||
let path = "auth/schema/auth.json"; | ||
{ | ||
let file = std::fs::File::create(path)?; | ||
serde_json::to_writer_pretty(file, &schema)?; | ||
} | ||
println!("Wrote schema to: {path}"); | ||
|
||
Ok(()) | ||
} |
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,117 @@ | ||
{ | ||
"$schema": "http://json-schema.org/draft-07/schema#", | ||
"title": "AuthConfig", | ||
"type": "object", | ||
"required": [ | ||
"authentication" | ||
], | ||
"properties": { | ||
"authentication": { | ||
"$ref": "#/definitions/AuthenticatorConfig" | ||
}, | ||
"authorization": { | ||
"default": {}, | ||
"allOf": [ | ||
{ | ||
"$ref": "#/definitions/AuthorizerConfig" | ||
} | ||
] | ||
}, | ||
"disabled": { | ||
"type": "boolean" | ||
} | ||
}, | ||
"definitions": { | ||
"AuthenticatorClientConfig": { | ||
"description": "Configuration for OIDC client used to authenticate on the server side", | ||
"type": "object", | ||
"required": [ | ||
"clientId", | ||
"issuerUrl" | ||
], | ||
"properties": { | ||
"additionalPermissions": { | ||
"description": "Additional scopes which get added for client\n\nThis can be useful if a client is considered to only provide identities which are supposed to have certain scopes, but don't provide them.", | ||
"type": "array", | ||
"items": { | ||
"type": "string" | ||
} | ||
}, | ||
"clientId": { | ||
"description": "The ID of the client", | ||
"type": "string" | ||
}, | ||
"groupMappings": { | ||
"description": "Mapping table for groups returned found through the `groups_selector` to permissions.", | ||
"type": "object", | ||
"additionalProperties": { | ||
"type": "array", | ||
"items": { | ||
"type": "string" | ||
} | ||
} | ||
}, | ||
"groupSelector": { | ||
"description": "JSON path extracting a list of groups from the access token", | ||
"default": null, | ||
"type": [ | ||
"string", | ||
"null" | ||
] | ||
}, | ||
"issuerUrl": { | ||
"description": "The issuer URL", | ||
"type": "string" | ||
}, | ||
"requiredAudience": { | ||
"description": "Enforce an audience claim (`aud`) for tokens.\n\nIf present, the token must have one matching `aud` claim.", | ||
"default": null, | ||
"type": [ | ||
"string", | ||
"null" | ||
] | ||
}, | ||
"scopeMappings": { | ||
"description": "Mapping table for scopes returned by the issuer to permissions.", | ||
"type": "object", | ||
"additionalProperties": { | ||
"type": "array", | ||
"items": { | ||
"type": "string" | ||
} | ||
} | ||
}, | ||
"tlsCaCertificates": { | ||
"description": "Add additional certificates as trust anchor for contacting the issuer", | ||
"default": [], | ||
"type": "array", | ||
"items": { | ||
"type": "string" | ||
} | ||
}, | ||
"tlsInsecure": { | ||
"description": "Ignore TLS checks when contacting the issuer", | ||
"default": false, | ||
"type": "boolean" | ||
} | ||
} | ||
}, | ||
"AuthenticatorConfig": { | ||
"type": "object", | ||
"required": [ | ||
"clients" | ||
], | ||
"properties": { | ||
"clients": { | ||
"type": "array", | ||
"items": { | ||
"$ref": "#/definitions/AuthenticatorClientConfig" | ||
} | ||
} | ||
} | ||
}, | ||
"AuthorizerConfig": { | ||
"type": "object" | ||
} | ||
} | ||
} |
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,91 @@ | ||
//! Both authentication and authorization | ||
|
||
use crate::{ | ||
authenticator::config::{AuthenticatorConfig, SingleAuthenticatorClientConfig}, | ||
authorizer::AuthorizerConfig, | ||
}; | ||
use std::path::PathBuf; | ||
|
||
#[derive(Clone, Debug, Default, clap::Args)] | ||
#[command( | ||
rename_all_env = "SCREAMING_SNAKE_CASE", | ||
next_help_heading = "Authentication & authorization" | ||
)] | ||
pub struct AuthConfigArguments { | ||
/// Flag to disable authentication and authorization, default is on. | ||
#[arg( | ||
id = "auth-disabled", | ||
default_value_t = false, | ||
long = "auth-disabled", | ||
env = "AUTH_DISABLED" | ||
)] | ||
pub disabled: bool, | ||
|
||
/// Location of the AuthNZ configuration file | ||
#[arg( | ||
id = "auth-configuration", | ||
long = "auth-configuration", | ||
env = "AUTH_CONFIGURATION", | ||
conflicts_with = "SingleAuthenticatorClientConfig" | ||
)] | ||
pub config: Option<PathBuf>, | ||
|
||
#[command(flatten)] | ||
pub clients: SingleAuthenticatorClientConfig, | ||
} | ||
|
||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)] | ||
pub struct AuthConfig { | ||
#[serde(default, skip_serializing_if = "is_default")] | ||
pub disabled: bool, | ||
|
||
pub authentication: AuthenticatorConfig, | ||
|
||
#[serde(default)] | ||
pub authorization: AuthorizerConfig, | ||
} | ||
|
||
pub fn is_default<D: Default + PartialEq>(d: &D) -> bool { | ||
d == &D::default() | ||
} | ||
|
||
impl AuthConfigArguments { | ||
pub fn split( | ||
self, | ||
devmode: bool, | ||
) -> Result<Option<(AuthenticatorConfig, AuthorizerConfig)>, anyhow::Error> { | ||
// disabled overrides devmode | ||
if self.disabled { | ||
return Ok(None); | ||
} | ||
|
||
// check for devmode | ||
if devmode { | ||
log::warn!("Running in developer mode"); | ||
return Ok(Some((AuthenticatorConfig::devmode(), Default::default()))); | ||
} | ||
|
||
Ok(Some(match self.config { | ||
Some(config) => { | ||
let AuthConfig { | ||
disabled, | ||
authentication, | ||
authorization, | ||
} = serde_yaml::from_reader(std::fs::File::open(config)?)?; | ||
|
||
if disabled { | ||
return Ok(None); | ||
} | ||
|
||
(authentication, authorization) | ||
} | ||
None => { | ||
let authn = AuthenticatorConfig { | ||
clients: self.clients.expand().collect(), | ||
}; | ||
|
||
(authn, Default::default()) | ||
} | ||
})) | ||
} | ||
} |
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 super::user::UserInformation; | ||
use super::Authenticator; | ||
use actix_http::HttpMessage; | ||
use actix_web::dev::ServiceRequest; | ||
use actix_web_httpauth::extractors::bearer::BearerAuth; | ||
use std::sync::Arc; | ||
|
||
pub async fn openid_validator( | ||
req: ServiceRequest, | ||
auth: BearerAuth, | ||
authenticator: Arc<Authenticator>, | ||
) -> Result<ServiceRequest, (actix_web::Error, ServiceRequest)> { | ||
match authenticator.validate_token(auth.token()).await { | ||
Ok(payload) => { | ||
req.extensions_mut() | ||
.insert(UserInformation::Authenticated(payload.into())); | ||
Ok(req) | ||
} | ||
|
||
Err(err) => Err((err.into(), req)), | ||
} | ||
} |
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,48 @@ | ||
//! OpenID Connect tools | ||
|
||
use super::user::UserDetails; | ||
use biscuit::SingleOrMultiple; | ||
use openid::CompactJson; | ||
use serde::{Deserialize, Serialize}; | ||
use serde_json::Value; | ||
use url::Url; | ||
|
||
/// An OIDC access token, containing the claims that we need. | ||
#[derive(Clone, Debug, Deserialize, Serialize)] | ||
pub struct AccessTokenClaims { | ||
#[serde(default)] | ||
pub azp: Option<String>, | ||
pub sub: String, | ||
pub iss: Url, | ||
#[serde(default, skip_serializing_if = "Option::is_none")] | ||
pub aud: Option<SingleOrMultiple<String>>, | ||
|
||
pub exp: i64, | ||
pub iat: i64, | ||
#[serde(default)] | ||
pub auth_time: Option<i64>, | ||
|
||
#[serde(flatten)] | ||
pub extended_claims: Value, | ||
|
||
#[serde(default, skip_serializing_if = "String::is_empty")] | ||
pub scope: String, | ||
} | ||
|
||
impl CompactJson for AccessTokenClaims {} | ||
|
||
/// A validated access token, including post-processing according to our configuration. | ||
#[derive(Clone, Debug)] | ||
pub struct ValidatedAccessToken { | ||
pub access_token: AccessTokenClaims, | ||
pub permissions: Vec<String>, | ||
} | ||
|
||
impl From<ValidatedAccessToken> for UserDetails { | ||
fn from(token: ValidatedAccessToken) -> Self { | ||
Self { | ||
id: token.access_token.sub, | ||
permissions: token.permissions, | ||
} | ||
} | ||
} |
Oops, something went wrong.