Add client metadata GET endpoint

This commit is contained in:
Simon Bihel 2022-02-14 12:50:57 +00:00
parent c5addaa072
commit 27e36e2aa6
No known key found for this signature in database
GPG Key ID: B7013150BEAA28FD
4 changed files with 42 additions and 1 deletions

View File

@ -40,6 +40,7 @@ siweoidc.example.com/r*
siweoidc.example.com/a* siweoidc.example.com/a*
siweoidc.example.com/t* siweoidc.example.com/t*
siweoidc.example.com/j* siweoidc.example.com/j*
siweoidc.example.com/c*
siweoidc.example.com/.w* siweoidc.example.com/.w*
``` ```

View File

@ -1,7 +1,7 @@
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use async_redis_session::RedisSessionStore; use async_redis_session::RedisSessionStore;
use axum::{ use axum::{
extract::{self, Extension, Form, Query, TypedHeader}, extract::{self, Extension, Form, Path, Query, TypedHeader},
http::{ http::{
header::{self, HeaderMap}, header::{self, HeaderMap},
StatusCode, StatusCode,
@ -56,6 +56,7 @@ impl IntoResponse for CustomError {
CustomError::Unauthorized(_) => { CustomError::Unauthorized(_) => {
(StatusCode::UNAUTHORIZED, self.to_string()).into_response() (StatusCode::UNAUTHORIZED, self.to_string()).into_response()
} }
CustomError::NotFound => (StatusCode::NOT_FOUND, self.to_string()).into_response(),
CustomError::Redirect(uri) => Redirect::to( CustomError::Redirect(uri) => Redirect::to(
uri.parse().unwrap(), uri.parse().unwrap(),
// .map_err(|e| anyhow!("Could not parse URI: {}", e))?, // .map_err(|e| anyhow!("Could not parse URI: {}", e))?,
@ -286,6 +287,13 @@ async fn userinfo(
}) })
} }
async fn clientinfo(
Path(client_id): Path<String>,
Extension(redis_client): Extension<RedisClient>,
) -> Result<Json<CoreClientMetadata>, CustomError> {
Ok(oidc::clientinfo(client_id, &redis_client).await?.into())
}
async fn healthcheck() {} async fn healthcheck() {}
pub async fn main() { pub async fn main() {
@ -392,6 +400,7 @@ pub async fn main() {
.route(oidc::AUTHORIZE_PATH, get(authorize)) .route(oidc::AUTHORIZE_PATH, get(authorize))
.route(oidc::REGISTER_PATH, post(register)) .route(oidc::REGISTER_PATH, post(register))
.route(oidc::USERINFO_PATH, get(userinfo).post(userinfo)) .route(oidc::USERINFO_PATH, get(userinfo).post(userinfo))
.route(&format!("{}/:id", oidc::CLIENTINFO_PATH), get(clientinfo))
.route(oidc::SIGNIN_PATH, get(sign_in)) .route(oidc::SIGNIN_PATH, get(sign_in))
.route("/health", get(healthcheck)) .route("/health", get(healthcheck))
.layer(AddExtensionLayer::new(private_key)) .layer(AddExtensionLayer::new(private_key))

View File

@ -50,6 +50,7 @@ pub const AUTHORIZE_PATH: &str = "/authorize";
pub const REGISTER_PATH: &str = "/register"; pub const REGISTER_PATH: &str = "/register";
pub const USERINFO_PATH: &str = "/userinfo"; pub const USERINFO_PATH: &str = "/userinfo";
pub const SIGNIN_PATH: &str = "/sign_in"; pub const SIGNIN_PATH: &str = "/sign_in";
pub const CLIENTINFO_PATH: &str = "/clientinfo";
pub const SIWE_COOKIE_KEY: &str = "siwe"; pub const SIWE_COOKIE_KEY: &str = "siwe";
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
@ -73,6 +74,8 @@ pub enum CustomError {
BadRequestToken(TokenError), BadRequestToken(TokenError),
#[error("{0}")] #[error("{0}")]
Unauthorized(String), Unauthorized(String),
#[error("Not found")]
NotFound,
#[error("{0:?}")] #[error("{0:?}")]
Redirect(String), Redirect(String),
#[error(transparent)] #[error(transparent)]
@ -561,6 +564,17 @@ pub async fn register(
.set_client_secret(Some(ClientSecret::new(secret.to_string())))) .set_client_secret(Some(ClientSecret::new(secret.to_string()))))
} }
pub async fn clientinfo(
client_id: String,
db_client: &DBClientType,
) -> Result<CoreClientMetadata, CustomError> {
let client_entry = db_client
.get_client(client_id)
.await?
.ok_or_else(|| CustomError::NotFound)?;
Ok(client_entry.metadata)
}
#[derive(Deserialize)] #[derive(Deserialize)]
pub struct UserInfoPayload { pub struct UserInfoPayload {
pub access_token: Option<String>, pub access_token: Option<String>,

View File

@ -28,6 +28,7 @@ impl From<CustomError> for Result<Response> {
} }
CustomError::BadRequestToken(e) => Response::from_json(&e).map(|r| r.with_status(400)), CustomError::BadRequestToken(e) => Response::from_json(&e).map(|r| r.with_status(400)),
CustomError::Unauthorized(_) => Response::error(&error.to_string(), 401), CustomError::Unauthorized(_) => Response::error(&error.to_string(), 401),
CustomError::NotFound => Response::error(&error.to_string(), 404),
CustomError::Redirect(uri) => Response::redirect(uri.parse().unwrap()), CustomError::Redirect(uri) => Response::redirect(uri.parse().unwrap()),
CustomError::Other(_) => Response::error(&error.to_string(), 500), CustomError::Other(_) => Response::error(&error.to_string(), 500),
} }
@ -234,6 +235,22 @@ pub async fn main(req: Request, env: Env) -> Result<Response> {
}) })
.post_async(oidc::USERINFO_PATH, userinfo) .post_async(oidc::USERINFO_PATH, userinfo)
.get_async(oidc::USERINFO_PATH, userinfo) .get_async(oidc::USERINFO_PATH, userinfo)
.get_async(
&format!("{}/:id", oidc::CLIENTINFO_PATH),
|req, ctx| async move {
let client_id = if let Some(id) = ctx.param("id") {
id.clone()
} else {
return Response::error("Bad Request", 400);
};
let url = req.url()?;
let db_client = CFClient { ctx, url };
match oidc::clientinfo(client_id, &db_client).await {
Ok(r) => Ok(Response::from_json(&r)?),
Err(e) => e.into(),
}
},
)
.get_async(oidc::SIGNIN_PATH, |req, ctx| async move { .get_async(oidc::SIGNIN_PATH, |req, ctx| async move {
let url = req.url()?; let url = req.url()?;
let query = url.query().unwrap_or_default(); let query = url.query().unwrap_or_default();