Skip to content

Commit

Permalink
Update documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
TobiasDeBruijn committed Dec 25, 2024
1 parent 88c5a22 commit fe73998
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 8 deletions.
29 changes: 29 additions & 0 deletions server/wilford/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,46 +6,75 @@ use tokio::io::AsyncReadExt;

#[derive(Debug, Deserialize)]
struct EnvConfig {
/// The path to the JSON configuration file.
config_path: PathBuf,
}

/* ANCHOR: config */
#[derive(Debug, Deserialize)]
pub struct Config {
/// Configuration for the basic functioning of the system
pub http: HttpConfig,
/// Database configuration
pub database: DatabaseConfig,
/// EspoCRM configuration
pub espo: EspoConfig,
/// Options for the default OAuth2 client.
/// This client is used by Wilford itself.
pub default_client: DefaultClientConfig,
/// The path to the private key used to sign OIDC ID tokens.
/// Should be the matching private key of [oidc_public_key]
pub oidc_signing_key: PathBuf,
/// The path to the public key used to sign OIDC ID tokens.
/// Should be the matching public key of [oidc_signing_key]
pub oidc_public_key: PathBuf,
/// The issuer of OpenID Connect ID tokens.
/// E.g. `mrfriendly.nl`.
pub oidc_issuer: String,
}

#[derive(Debug, Deserialize)]
pub struct HttpConfig {
/// The URL at which the frontend's login page can be found.
pub ui_login_path: String,
/// The URL at which the OAuth2 authorization endpoint can be found.
/// Should point to the route `/oauth/authorize`.
pub authorization_endpoint: String,
/// The URL at which the OAuth2 token endpoint can be found.
/// Should point to the route `/oauth/token`.
pub token_endpoint: String,
/// The URL at which the JWKS document can be found.
/// Should point to the route `/.well-known/jwks.json`.
pub jwks_uri_endpoint: String,
}

#[derive(Debug, Deserialize)]
pub struct EspoConfig {
/// The base URI at which EspoCRM can be found.
/// Should not end with a slash character.
pub host: String,
/// The API key of the EspoCRM API client.
pub api_key: String,
/// The secret key of the EspoCRM API client.
pub secret_key: String,
}

#[derive(Debug, Deserialize)]
pub struct DatabaseConfig {
/// The MySQL username.
pub user: String,
/// The MySQL password.
pub password: String,
/// The address at which the MySQL database can be reacher.
pub host: String,
/// The MySQL database name.
pub database: String,
}

#[derive(Debug, Deserialize)]
pub struct DefaultClientConfig {
/// The redict URI for the default OAuth2 client used by Wilford itself.
/// Should be the location at which the frontend's `login-ok` page can be found.
pub redirect_uri: String,
}
/* ANCHOR_END: config */
Expand Down
34 changes: 26 additions & 8 deletions server/wilford/src/routes/well_known/jwks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,43 +9,61 @@ use serde::{Serialize, Serializer};
use crate::routes::appdata::WOidcPublicKey;
use crate::routes::error::WebResult;

/// The JWKS (JSON Web Key Set) document.
/// See also [RFC 7517, Section 5.1](https://datatracker.ietf.org/doc/html/rfc7517#section-5.1)
#[derive(Serialize)]
pub struct Jwks {
keys: Vec<Key>,
/// The public keys we use
keys: Vec<JWK>,
}

/// A JWK, a JSON Web Key.
///
/// # Further reading
/// - General format: [RFC 7517, Section 4](https://datatracker.ietf.org/doc/html/rfc7517#section-4)
/// - RSA Public key extra's: [RFC 7518, Section 6.3.1](https://datatracker.ietf.org/doc/html/rfc7518#section-6.3.1)
#[derive(Serialize)]
pub struct Key {
pub struct JWK {
kty: String,
r#use: String,
alg: String,
kid: String,
key_ops: Vec<String>,
// k: String,
#[serde(serialize_with = "serialize")]
#[serde(serialize_with = "serialize_bigint")]
n: BigUint,
#[serde(serialize_with = "serialize")]
#[serde(serialize_with = "serialize_bigint")]
e: BigUint,
}

/// Endpoint for fetching the JWKS document.
/// This endpoint is used by OAuth clients to get our public keys,
/// so they can validate that the ID tokens are issued by us.
///
/// # Further reading
/// - [RFC 7517](https://datatracker.ietf.org/doc/html/rfc7517)
pub async fn jwks(oidc_public_key: WOidcPublicKey) -> WebResult<web::Json<Jwks>> {
let public_key = RsaPublicKey::from_public_key_pem(&oidc_public_key.0)?;

Ok(web::Json(Jwks {
keys: vec![Key {
keys: vec![JWK {
kty: "RSA".to_string(),
r#use: "sig".to_string(),
alg: "RS256".to_string(),
kid: "rsa".to_string(), // We dont have a kid
kid: "rsa".to_string(), // We don't have a kid
key_ops: vec!["verify".to_string()],
// k: (**oidc_public_key).0.clone(),
n: public_key.n().clone(),
e: public_key.e().clone(),
}],
}))
}

pub fn serialize<S>(value: &BigUint, serializer: S) -> Result<S::Ok, S::Error>
/// Base64 BigInt serializer.
/// Uses base64 in the format URL safe, without padding.
///
/// # Further reading
/// - [RFC 7518, Section 6.3.1.1](https://datatracker.ietf.org/doc/html/rfc7518#section-6.3.1.1)
pub fn serialize_bigint<S>(value: &BigUint, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
Expand Down
2 changes: 2 additions & 0 deletions server/wilford/src/routes/well_known/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ impl Routable for Router {
fn configure(config: &mut ServiceConfig) {
config.service(
web::scope("/.well-known")
// Route defined in
// OpenID Connect Discovery 1.0, Section 4, https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig
.route(
"/openid-configuration",
web::get().to(openid_configuration::openid_configuration),
Expand Down
13 changes: 13 additions & 0 deletions server/wilford/src/routes/well_known/openid_configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,30 @@ use crate::routes::appdata::WConfig;
use actix_web::web;
use serde::Serialize;

/// # Further reading
/// - [OpenID Connect Discovery 1.0, Section 4.1](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig)
#[derive(Serialize)]
pub struct OpenidConfiguration {
/// The isser of all JWT tokens
issuer: String,
/// The server's endpoint for authorization
authorization_endpoint: String,
/// The server's endpoint for exchanging a code or refresh token for an access token
token_endpoint: String,
/// The response types we support in the authorization endpoint
response_types_supported: Vec<String>,
/// The grant types we support in the token endpoint
grant_types_supported: Vec<String>,
/// The algorithms we support for signing JWTs
id_token_signing_alg_values_supported: Vec<String>,
/// The endpoint for where the JWKS document can found
jwks_uri: String,
}

/// Get the OpenID configuration for this server
///
/// # Further reading
/// - [OpenID Connect Discovery 1.0, Section 4](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig)
pub async fn openid_configuration(config: WConfig) -> web::Json<OpenidConfiguration> {
web::Json(OpenidConfiguration {
issuer: config.oidc_issuer.clone(),
Expand Down

0 comments on commit fe73998

Please sign in to comment.