mas_oidc_client/requests/
client_credentials.rs

1// Copyright 2024 New Vector Ltd.
2// Copyright 2022-2024 Kévin Commaille.
3//
4// SPDX-License-Identifier: AGPL-3.0-only
5// Please see LICENSE in the repository root for full details.
6
7//! Requests for the [Client Credentials flow].
8//!
9//! [Client Credentials flow]: https://www.rfc-editor.org/rfc/rfc6749#section-4.4
10
11use chrono::{DateTime, Utc};
12use oauth2_types::{
13    requests::{AccessTokenRequest, AccessTokenResponse, ClientCredentialsGrant},
14    scope::Scope,
15};
16use rand::Rng;
17use url::Url;
18
19use crate::{
20    error::TokenRequestError, requests::token::request_access_token,
21    types::client_credentials::ClientCredentials,
22};
23
24/// Exchange an authorization code for an access token.
25///
26/// This should be used as the first step for logging in, and to request a
27/// token with a new scope.
28///
29/// # Arguments
30///
31/// * `http_client` - The reqwest client to use for making HTTP requests.
32///
33/// * `client_credentials` - The credentials obtained when registering the
34///   client.
35///
36/// * `token_endpoint` - The URL of the issuer's Token endpoint.
37///
38/// * `scope` - The scope to authorize.
39///
40/// * `now` - The current time.
41///
42/// * `rng` - A random number generator.
43///
44/// # Errors
45///
46/// Returns an error if the request fails or the response is invalid.
47#[tracing::instrument(skip_all, fields(token_endpoint))]
48pub async fn access_token_with_client_credentials(
49    http_client: &reqwest::Client,
50    client_credentials: ClientCredentials,
51    token_endpoint: &Url,
52    scope: Option<Scope>,
53    now: DateTime<Utc>,
54    rng: &mut impl Rng,
55) -> Result<AccessTokenResponse, TokenRequestError> {
56    tracing::debug!("Requesting access token with client credentials...");
57
58    request_access_token(
59        http_client,
60        client_credentials,
61        token_endpoint,
62        AccessTokenRequest::ClientCredentials(ClientCredentialsGrant { scope }),
63        now,
64        rng,
65    )
66    .await
67}