You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-07-29 22:01:14 +03:00
Add types for the Device Authorization flow
This commit is contained in:
committed by
Quentin Gliech
parent
2e8f233ac5
commit
940ab48819
@ -225,6 +225,43 @@ pub enum ClientErrorCode {
|
|||||||
/// From [RFC7591](https://www.rfc-editor.org/rfc/rfc7591#section-3.2.2).
|
/// From [RFC7591](https://www.rfc-editor.org/rfc/rfc7591#section-3.2.2).
|
||||||
InvalidClientMetadata,
|
InvalidClientMetadata,
|
||||||
|
|
||||||
|
/// `authorization_pending`
|
||||||
|
///
|
||||||
|
/// The authorization request is still pending as the end user hasn't yet
|
||||||
|
/// completed the user-interaction steps.
|
||||||
|
///
|
||||||
|
/// The client should repeat the access token request to the token endpoint
|
||||||
|
/// (a process known as polling). Before each new request, the client
|
||||||
|
/// must wait at least the number of seconds specified by the `interval`
|
||||||
|
/// parameter of the device authorization response, or 5 seconds if none was
|
||||||
|
/// provided, and respect any increase in the polling interval required
|
||||||
|
/// by the [`ClientErrorCode::SlowDown`] error.
|
||||||
|
///
|
||||||
|
/// From [RFC8628](https://www.rfc-editor.org/rfc/rfc8628#section-3.5).
|
||||||
|
AuthorizationPending,
|
||||||
|
|
||||||
|
/// `slow_down`
|
||||||
|
///
|
||||||
|
/// A variant of [`ClientErrorCode::AuthorizationPending`], the
|
||||||
|
/// authorization request is still pending and polling should continue,
|
||||||
|
/// but the interval must be increased by 5 seconds for this and all
|
||||||
|
/// subsequent requests.
|
||||||
|
///
|
||||||
|
/// From [RFC8628](https://www.rfc-editor.org/rfc/rfc8628#section-3.5).
|
||||||
|
SlowDown,
|
||||||
|
|
||||||
|
/// `expired_token`
|
||||||
|
///
|
||||||
|
/// The `device_code` has expired, and the device authorization session has
|
||||||
|
/// concluded.
|
||||||
|
///
|
||||||
|
/// The client may commence a new device authorization request but should
|
||||||
|
/// wait for user interaction before restarting to avoid unnecessary
|
||||||
|
/// polling.
|
||||||
|
///
|
||||||
|
/// From [RFC8628](https://www.rfc-editor.org/rfc/rfc8628#section-3.5).
|
||||||
|
ExpiredToken,
|
||||||
|
|
||||||
/// Another error code.
|
/// Another error code.
|
||||||
#[display("{0}")]
|
#[display("{0}")]
|
||||||
Unknown(String),
|
Unknown(String),
|
||||||
@ -304,6 +341,15 @@ impl ClientErrorCode {
|
|||||||
ClientErrorCode::InvalidClientMetadata => {
|
ClientErrorCode::InvalidClientMetadata => {
|
||||||
"The value of one of the client metadata fields is invalid"
|
"The value of one of the client metadata fields is invalid"
|
||||||
}
|
}
|
||||||
|
ClientErrorCode::AuthorizationPending => {
|
||||||
|
"The authorization request is still pending"
|
||||||
|
}
|
||||||
|
ClientErrorCode::SlowDown => {
|
||||||
|
"The interval must be increased by 5 seconds for this and all subsequent requests"
|
||||||
|
}
|
||||||
|
ClientErrorCode::ExpiredToken => {
|
||||||
|
"The \"device_code\" has expired, and the device authorization session has concluded"
|
||||||
|
}
|
||||||
ClientErrorCode::Unknown(_) => "",
|
ClientErrorCode::Unknown(_) => "",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -357,6 +357,11 @@ pub struct ProviderMetadata {
|
|||||||
///
|
///
|
||||||
/// [prompt `create`]: https://openid.net/specs/openid-connect-prompt-create-1_0.html
|
/// [prompt `create`]: https://openid.net/specs/openid-connect-prompt-create-1_0.html
|
||||||
pub prompt_values_supported: Option<Vec<Prompt>>,
|
pub prompt_values_supported: Option<Vec<Prompt>>,
|
||||||
|
|
||||||
|
/// URL of the authorization server's [device authorization endpoint].
|
||||||
|
///
|
||||||
|
/// [device authorization endpoint]: https://www.rfc-editor.org/rfc/rfc8628
|
||||||
|
pub device_authorization_endpoint: Option<Url>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProviderMetadata {
|
impl ProviderMetadata {
|
||||||
|
@ -296,6 +296,65 @@ pub struct AuthorizationResponse<R> {
|
|||||||
pub response: R,
|
pub response: R,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A request to the [Device Authorization Endpoint].
|
||||||
|
///
|
||||||
|
/// [Device Authorization Endpoint]: https://www.rfc-editor.org/rfc/rfc8628
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct DeviceAuthorizationRequest {
|
||||||
|
/// The scope of the access request.
|
||||||
|
pub scope: Option<Scope>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const DEFAULT_DEVICE_AUTHORIZATION_INTERVAL_SECONDS: i64 = 5;
|
||||||
|
|
||||||
|
/// A successful response from the [Device Authorization Endpoint].
|
||||||
|
///
|
||||||
|
/// [Device Authorization Endpoint]: https://www.rfc-editor.org/rfc/rfc8628
|
||||||
|
#[serde_as]
|
||||||
|
#[skip_serializing_none]
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct DeviceAuthorizationResponse {
|
||||||
|
/// The device verification code.
|
||||||
|
device_code: String,
|
||||||
|
|
||||||
|
/// The end-user verification code.
|
||||||
|
user_code: String,
|
||||||
|
|
||||||
|
/// The end-user verification URI on the authorization server.
|
||||||
|
///
|
||||||
|
/// The URI should be short and easy to remember as end users will be asked
|
||||||
|
/// to manually type it into their user agent.
|
||||||
|
verification_uri: Url,
|
||||||
|
|
||||||
|
/// A verification URI that includes the `user_code` (or other information
|
||||||
|
/// with the same function as the `user_code`), which is designed for
|
||||||
|
/// non-textual transmission.
|
||||||
|
verification_uri_complete: Option<Url>,
|
||||||
|
|
||||||
|
/// The lifetime of the `device_code` and `user_code`.
|
||||||
|
#[serde_as(as = "DurationSeconds<i64>")]
|
||||||
|
expires_in: Duration,
|
||||||
|
|
||||||
|
/// The minimum amount of time in seconds that the client should wait
|
||||||
|
/// between polling requests to the token endpoint.
|
||||||
|
///
|
||||||
|
/// Defaults to [`DEFAULT_DEVICE_AUTHORIZATION_INTERVAL_SECONDS`].
|
||||||
|
#[serde_as(as = "Option<DurationSeconds<i64>>")]
|
||||||
|
interval: Option<Duration>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DeviceAuthorizationResponse {
|
||||||
|
///The minimum amount of time in seconds that the client should wait
|
||||||
|
/// between polling requests to the token endpoint.
|
||||||
|
///
|
||||||
|
/// Defaults to [`DEFAULT_DEVICE_AUTHORIZATION_INTERVAL_SECONDS`].
|
||||||
|
#[must_use]
|
||||||
|
pub fn interval(&self) -> Duration {
|
||||||
|
self.interval
|
||||||
|
.unwrap_or_else(|| Duration::seconds(DEFAULT_DEVICE_AUTHORIZATION_INTERVAL_SECONDS))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A request to the [Token Endpoint] for the [Authorization Code] grant type.
|
/// A request to the [Token Endpoint] for the [Authorization Code] grant type.
|
||||||
///
|
///
|
||||||
/// [Token Endpoint]: https://www.rfc-editor.org/rfc/rfc6749#section-3.2
|
/// [Token Endpoint]: https://www.rfc-editor.org/rfc/rfc6749#section-3.2
|
||||||
@ -347,6 +406,16 @@ pub struct ClientCredentialsGrant {
|
|||||||
pub scope: Option<Scope>,
|
pub scope: Option<Scope>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A request to the [Token Endpoint] for the [Device Authorization] grant type.
|
||||||
|
///
|
||||||
|
/// [Token Endpoint]: https://www.rfc-editor.org/rfc/rfc6749#section-3.2
|
||||||
|
/// [Device Authorization]: https://www.rfc-editor.org/rfc/rfc8628
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct DeviceCodeGrant {
|
||||||
|
/// The device verification code, from the device authorization response.
|
||||||
|
pub device_code: Option<Scope>,
|
||||||
|
}
|
||||||
|
|
||||||
/// All possible values for the `grant_type` parameter.
|
/// All possible values for the `grant_type` parameter.
|
||||||
#[derive(
|
#[derive(
|
||||||
Debug,
|
Debug,
|
||||||
@ -397,6 +466,8 @@ pub enum AccessTokenRequest {
|
|||||||
AuthorizationCode(AuthorizationCodeGrant),
|
AuthorizationCode(AuthorizationCodeGrant),
|
||||||
RefreshToken(RefreshTokenGrant),
|
RefreshToken(RefreshTokenGrant),
|
||||||
ClientCredentials(ClientCredentialsGrant),
|
ClientCredentials(ClientCredentialsGrant),
|
||||||
|
#[serde(rename = "urn:ietf:params:oauth:grant-type:device_code")]
|
||||||
|
DeviceCode(DeviceCodeGrant),
|
||||||
#[serde(skip, other)]
|
#[serde(skip, other)]
|
||||||
Unsupported,
|
Unsupported,
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user