(
client: &impl PkceClient,
region: Region,
issuer_url: String,
timeout: Option<Duration>,
)
| 186 | |
| 187 | impl PkceRegistration { |
| 188 | pub async fn register( |
| 189 | client: &impl PkceClient, |
| 190 | region: Region, |
| 191 | issuer_url: String, |
| 192 | timeout: Option<Duration>, |
| 193 | ) -> Result<Self, AuthError> { |
| 194 | let listener = TcpListener::bind("127.0.0.1:0").await?; |
| 195 | let redirect_uri = format!("http://{}/oauth/callback", listener.local_addr()?); |
| 196 | let code_verifier = generate_code_verifier(); |
| 197 | let code_challenge = generate_code_challenge(&code_verifier); |
| 198 | let state = rand::rng() |
| 199 | .sample_iter(rand::distr::Alphanumeric) |
| 200 | .take(10) |
| 201 | .collect::<Vec<_>>(); |
| 202 | let state = String::from_utf8(state).unwrap_or("state".to_string()); |
| 203 | |
| 204 | let response = client.register_client(redirect_uri.clone(), issuer_url.clone()).await?; |
| 205 | |
| 206 | let query = PkceQueryParams { |
| 207 | client_id: response.client_id().to_string(), |
| 208 | redirect_uri: redirect_uri.clone(), |
| 209 | // Scopes must be space delimited. |
| 210 | scopes: SCOPES.join(" "), |
| 211 | state: state.clone(), |
| 212 | code_challenge: code_challenge.clone(), |
| 213 | code_challenge_method: "S256".to_string(), |
| 214 | }; |
| 215 | let url = format!("{}/authorize?{}", oidc_url(®ion), query.as_query_params()); |
| 216 | |
| 217 | Ok(Self { |
| 218 | url, |
| 219 | registered_client: response, |
| 220 | code_verifier, |
| 221 | state, |
| 222 | listener, |
| 223 | redirect_uri, |
| 224 | region, |
| 225 | issuer_url, |
| 226 | timeout: timeout.unwrap_or(DEFAULT_AUTHORIZATION_TIMEOUT), |
| 227 | }) |
| 228 | } |
| 229 | |
| 230 | /// Hosts a local HTTP server to listen for browser redirects. If a [`Database`] is passed, |
| 231 | /// then the access and refresh tokens will be saved. |
nothing calls this directly
no test coverage detected