1pub(super) mod account;
2pub(super) mod auth_issuer;
3pub(super) mod auth_metadata;
4pub(super) mod authorize;
5pub(super) mod complete;
6pub(super) mod device;
7pub(super) mod jwks;
8pub(super) mod native;
9pub(super) mod registration;
10pub(super) mod revoke;
11pub(super) mod token;
12pub(super) mod userinfo;
13
14use std::fmt::Write;
15
16use axum::{Json, body::Body, response::IntoResponse};
17use http::{Response, StatusCode};
18use serde_json::json;
19
20pub(super) use self::{
21 account::*, auth_issuer::*, auth_metadata::*, authorize::*, complete::*, device::*, jwks::*,
22 native::*, registration::*, revoke::*, token::*, userinfo::*,
23};
24
25const OIDC_REQ_ID_LENGTH: usize = 32;
26
27pub(crate) fn url_encode(s: &str) -> String {
28 s.bytes()
29 .fold(String::with_capacity(s.len()), |mut out, b| {
30 if b.is_ascii_alphanumeric() || matches!(b, b'-' | b'_' | b'.' | b'~') {
31 out.push(b.into());
32 } else {
33 write!(&mut out, "%{b:02X}").ok();
34 }
35
36 out
37 })
38}
39
40fn oauth_error(status: StatusCode, error: &str, description: &str) -> Response<Body> {
41 let body = json!({
42 "error": error,
43 "error_description": description,
44 });
45
46 (status, Json(body)).into_response()
47}