diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 2f82ada41..55da1a0b5 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -215,7 +215,7 @@ jobs:
uses: actions/checkout@v5
- name: Install Rust toolchain
- uses: dtolnay/rust-toolchain@1.87.0
+ uses: dtolnay/rust-toolchain@1.89.0
with:
components: clippy
diff --git a/Dockerfile b/Dockerfile
index 1c1c66b56..14eda1924 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -12,7 +12,7 @@
# The Debian version and version name must be in sync
ARG DEBIAN_VERSION=12
ARG DEBIAN_VERSION_NAME=bookworm
-ARG RUSTC_VERSION=1.87.0
+ARG RUSTC_VERSION=1.89.0
ARG NODEJS_VERSION=20.15.0
ARG OPA_VERSION=1.1.0
ARG CARGO_AUDITABLE_VERSION=0.6.6
diff --git a/clippy.toml b/clippy.toml
index 41d584369..218811441 100644
--- a/clippy.toml
+++ b/clippy.toml
@@ -3,7 +3,7 @@
# SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
# Please see LICENSE files in the repository root for full details.
-doc-valid-idents = ["OpenID", "OAuth", "..", "PostgreSQL", "SQLite"]
+doc-valid-idents = ["OpenID", "OAuth", "UserInfo", "..", "PostgreSQL", "SQLite"]
disallowed-methods = [
{ path = "rand::thread_rng", reason = "do not create rngs on the fly, pass them as parameters" },
diff --git a/crates/cli/build.rs b/crates/cli/build.rs
index 7bad5d337..fd111273b 100644
--- a/crates/cli/build.rs
+++ b/crates/cli/build.rs
@@ -12,13 +12,13 @@ fn main() -> anyhow::Result<()> {
// At build time, we override the version through the environment variable
// VERGEN_GIT_DESCRIBE. In some contexts, it means this variable is set but
// empty, so we unset it here.
- if let Ok(ver) = std::env::var("VERGEN_GIT_DESCRIBE") {
- if ver.is_empty() {
- #[allow(unsafe_code)]
- // SAFETY: This is safe because the build script is running a single thread
- unsafe {
- std::env::remove_var("VERGEN_GIT_DESCRIBE");
- }
+ if let Ok(ver) = std::env::var("VERGEN_GIT_DESCRIBE")
+ && ver.is_empty()
+ {
+ #[allow(unsafe_code)]
+ // SAFETY: This is safe because the build script is running a single thread
+ unsafe {
+ std::env::remove_var("VERGEN_GIT_DESCRIBE");
}
}
diff --git a/crates/cli/src/app_state.rs b/crates/cli/src/app_state.rs
index dd7dd6c99..40ae94806 100644
--- a/crates/cli/src/app_state.rs
+++ b/crates/cli/src/app_state.rs
@@ -275,10 +275,10 @@ fn infer_client_ip(
let peer = if let Some(info) = connection_info {
// We can always trust the proxy protocol to give us the correct IP address
- if let Some(proxy) = info.get_proxy_ref() {
- if let Some(source) = proxy.source() {
- return Some(source.ip());
- }
+ if let Some(proxy) = info.get_proxy_ref()
+ && let Some(source) = proxy.source()
+ {
+ return Some(source.ip());
}
info.get_peer_addr().map(|addr| addr.ip())
diff --git a/crates/cli/src/commands/manage.rs b/crates/cli/src/commands/manage.rs
index e991c1716..cedfcee2b 100644
--- a/crates/cli/src/commands/manage.rs
+++ b/crates/cli/src/commands/manage.rs
@@ -619,13 +619,12 @@ impl Options {
let txn = conn.begin().await?;
let mut repo = PgRepository::from_conn(txn);
- if let Some(password) = &password {
- if !ignore_password_complexity
- && !password_manager.is_password_complex_enough(password)?
- {
- error!("That password is too weak.");
- return Ok(ExitCode::from(1));
- }
+ if let Some(password) = &password
+ && !ignore_password_complexity
+ && !password_manager.is_password_complex_enough(password)?
+ {
+ error!("That password is too weak.");
+ return Ok(ExitCode::from(1));
}
// If the username is provided, check if it's available and normalize it.
diff --git a/crates/cli/src/sync.rs b/crates/cli/src/sync.rs
index 700b8eea8..965a4fc95 100644
--- a/crates/cli/src/sync.rs
+++ b/crates/cli/src/sync.rs
@@ -208,11 +208,11 @@ pub async fn config_sync(
// private key to hold the content of the private key file.
// private key (raw) takes precedence so both can be defined
// without issues
- if siwa.private_key.is_none() {
- if let Some(private_key_file) = siwa.private_key_file.take() {
- let key = tokio::fs::read_to_string(private_key_file).await?;
- siwa.private_key = Some(key);
- }
+ if siwa.private_key.is_none()
+ && let Some(private_key_file) = siwa.private_key_file.take()
+ {
+ let key = tokio::fs::read_to_string(private_key_file).await?;
+ siwa.private_key = Some(key);
}
let encoded = serde_json::to_vec(&siwa)?;
Some(encrypter.encrypt_to_string(&encoded)?)
diff --git a/crates/config/src/sections/secrets.rs b/crates/config/src/sections/secrets.rs
index 7886e9a57..4bfd30ce3 100644
--- a/crates/config/src/sections/secrets.rs
+++ b/crates/config/src/sections/secrets.rs
@@ -149,7 +149,7 @@ impl KeyConfig {
/// Returns the password in case any is provided.
///
/// If `password_file` was given, the password is read from that file.
- async fn password(&self) -> anyhow::Result>> {
+ async fn password(&self) -> anyhow::Result >> {
Ok(match &self.password {
Some(Password::File(path)) => Some(Cow::Owned(tokio::fs::read(path).await?)),
Some(Password::Value(password)) => Some(Cow::Borrowed(password.as_bytes())),
@@ -160,7 +160,7 @@ impl KeyConfig {
/// Returns the key.
///
/// If `key_file` was given, the key is read from that file.
- async fn key(&self) -> anyhow::Result> {
+ async fn key(&self) -> anyhow::Result> {
Ok(match &self.key {
Key::File(path) => Cow::Owned(tokio::fs::read(path).await?),
Key::Value(key) => Cow::Borrowed(key.as_bytes()),
diff --git a/crates/config/src/sections/telemetry.rs b/crates/config/src/sections/telemetry.rs
index 8e2d995e9..44e75a354 100644
--- a/crates/config/src/sections/telemetry.rs
+++ b/crates/config/src/sections/telemetry.rs
@@ -198,34 +198,34 @@ impl ConfigurationSection for TelemetryConfig {
&self,
_figment: &figment::Figment,
) -> Result<(), Box> {
- if let Some(sample_rate) = self.sentry.sample_rate {
- if !(0.0..=1.0).contains(&sample_rate) {
- return Err(figment::error::Error::custom(
- "Sentry sample rate must be between 0.0 and 1.0",
- )
- .with_path("sentry.sample_rate")
- .into());
- }
+ if let Some(sample_rate) = self.sentry.sample_rate
+ && !(0.0..=1.0).contains(&sample_rate)
+ {
+ return Err(figment::error::Error::custom(
+ "Sentry sample rate must be between 0.0 and 1.0",
+ )
+ .with_path("sentry.sample_rate")
+ .into());
}
- if let Some(sample_rate) = self.sentry.traces_sample_rate {
- if !(0.0..=1.0).contains(&sample_rate) {
- return Err(figment::error::Error::custom(
- "Sentry sample rate must be between 0.0 and 1.0",
- )
- .with_path("sentry.traces_sample_rate")
- .into());
- }
+ if let Some(sample_rate) = self.sentry.traces_sample_rate
+ && !(0.0..=1.0).contains(&sample_rate)
+ {
+ return Err(figment::error::Error::custom(
+ "Sentry sample rate must be between 0.0 and 1.0",
+ )
+ .with_path("sentry.traces_sample_rate")
+ .into());
}
- if let Some(sample_rate) = self.tracing.sample_rate {
- if !(0.0..=1.0).contains(&sample_rate) {
- return Err(figment::error::Error::custom(
- "Tracing sample rate must be between 0.0 and 1.0",
- )
- .with_path("tracing.sample_rate")
- .into());
- }
+ if let Some(sample_rate) = self.tracing.sample_rate
+ && !(0.0..=1.0).contains(&sample_rate)
+ {
+ return Err(figment::error::Error::custom(
+ "Tracing sample rate must be between 0.0 and 1.0",
+ )
+ .with_path("tracing.sample_rate")
+ .into());
}
Ok(())
diff --git a/crates/config/src/sections/upstream_oauth2.rs b/crates/config/src/sections/upstream_oauth2.rs
index 9b2768423..05f70cc67 100644
--- a/crates/config/src/sections/upstream_oauth2.rs
+++ b/crates/config/src/sections/upstream_oauth2.rs
@@ -652,7 +652,7 @@ pub struct Provider {
/// What to do when receiving an OIDC Backchannel logout request.
///
- /// Defaults to "do_nothing".
+ /// Defaults to `do_nothing`.
#[serde(default, skip_serializing_if = "OnBackchannelLogout::is_default")]
pub on_backchannel_logout: OnBackchannelLogout,
}
diff --git a/crates/context/src/fmt.rs b/crates/context/src/fmt.rs
index 579ea63a9..25908a2ca 100644
--- a/crates/context/src/fmt.rs
+++ b/crates/context/src/fmt.rs
@@ -129,31 +129,31 @@ where
field_fromatter.format_fields(writer.by_ref(), event)?;
// If we have a OTEL span, we can add the trace ID to the end of the log line
- if let Some(span) = ctx.lookup_current() {
- if let Some(otel) = span.extensions().get::() {
- let parent_cx_span = otel.parent_cx.span();
- let sc = parent_cx_span.span_context();
-
- // Check if the span is sampled, first from the span builder,
- // then from the parent context if nothing is set there
- if otel
- .builder
- .sampling_result
- .as_ref()
- .map_or(sc.is_sampled(), |r| {
- r.decision == SamplingDecision::RecordAndSample
- })
- {
- // If it is the root span, the trace ID will be in the span builder. Else, it
- // will be in the parent OTEL context
- let trace_id = otel.builder.trace_id.unwrap_or(sc.trace_id());
- if trace_id != TraceId::INVALID {
- let label = Style::new()
- .italic()
- .force_styling(ansi)
- .apply_to("trace.id");
- write!(&mut writer, " {label}={trace_id}")?;
- }
+ if let Some(span) = ctx.lookup_current()
+ && let Some(otel) = span.extensions().get::()
+ {
+ let parent_cx_span = otel.parent_cx.span();
+ let sc = parent_cx_span.span_context();
+
+ // Check if the span is sampled, first from the span builder,
+ // then from the parent context if nothing is set there
+ if otel
+ .builder
+ .sampling_result
+ .as_ref()
+ .map_or(sc.is_sampled(), |r| {
+ r.decision == SamplingDecision::RecordAndSample
+ })
+ {
+ // If it is the root span, the trace ID will be in the span builder. Else, it
+ // will be in the parent OTEL context
+ let trace_id = otel.builder.trace_id.unwrap_or(sc.trace_id());
+ if trace_id != TraceId::INVALID {
+ let label = Style::new()
+ .italic()
+ .force_styling(ansi)
+ .apply_to("trace.id");
+ write!(&mut writer, " {label}={trace_id}")?;
}
}
}
diff --git a/crates/data-model/src/oauth2/authorization_grant.rs b/crates/data-model/src/oauth2/authorization_grant.rs
index 383701bcb..d6699f575 100644
--- a/crates/data-model/src/oauth2/authorization_grant.rs
+++ b/crates/data-model/src/oauth2/authorization_grant.rs
@@ -173,7 +173,7 @@ impl std::ops::Deref for AuthorizationGrant {
impl AuthorizationGrant {
#[must_use]
- pub fn parse_login_hint(&self, homeserver: &str) -> LoginHint {
+ pub fn parse_login_hint(&self, homeserver: &str) -> LoginHint<'_> {
let Some(login_hint) = &self.login_hint else {
return LoginHint::None;
};
diff --git a/crates/data-model/src/upstream_oauth2/provider.rs b/crates/data-model/src/upstream_oauth2/provider.rs
index c54e40d15..be42cb5a5 100644
--- a/crates/data-model/src/upstream_oauth2/provider.rs
+++ b/crates/data-model/src/upstream_oauth2/provider.rs
@@ -289,7 +289,7 @@ pub struct UpstreamOAuthProvider {
impl PartialOrd for UpstreamOAuthProvider {
fn partial_cmp(&self, other: &Self) -> Option {
- Some(self.id.cmp(&other.id))
+ Some(self.cmp(other))
}
}
diff --git a/crates/data-model/src/user_agent.rs b/crates/data-model/src/user_agent.rs
index 4efb4ff9f..d0e930586 100644
--- a/crates/data-model/src/user_agent.rs
+++ b/crates/data-model/src/user_agent.rs
@@ -88,32 +88,31 @@ impl UserAgent {
#[must_use]
pub fn parse(user_agent: String) -> Self {
- if !user_agent.contains("Mozilla/") {
- if let Some((name, version, model, os, os_version)) =
+ if !user_agent.contains("Mozilla/")
+ && let Some((name, version, model, os, os_version)) =
UserAgent::parse_custom(&user_agent)
- {
- let mut device_type = DeviceType::Unknown;
-
- // Handle mobile simple mobile devices
- if os == "Android" || os == "iOS" {
- device_type = DeviceType::Mobile;
- }
-
- // Handle iPads
- if model.contains("iPad") {
- device_type = DeviceType::Tablet;
- }
-
- return Self {
- name: Some(name.to_owned()),
- version: Some(version.to_owned()),
- os: Some(os.to_owned()),
- os_version: os_version.map(std::borrow::ToOwned::to_owned),
- model: Some(model.to_owned()),
- device_type,
- raw: user_agent,
- };
+ {
+ let mut device_type = DeviceType::Unknown;
+
+ // Handle mobile simple mobile devices
+ if os == "Android" || os == "iOS" {
+ device_type = DeviceType::Mobile;
+ }
+
+ // Handle iPads
+ if model.contains("iPad") {
+ device_type = DeviceType::Tablet;
}
+
+ return Self {
+ name: Some(name.to_owned()),
+ version: Some(version.to_owned()),
+ os: Some(os.to_owned()),
+ os_version: os_version.map(std::borrow::ToOwned::to_owned),
+ model: Some(model.to_owned()),
+ device_type,
+ raw: user_agent,
+ };
}
let mut model = None;
@@ -205,11 +204,11 @@ impl UserAgent {
}
// Special handling for Electron applications e.g. Element Desktop
- if user_agent.contains("Electron/") {
- if let Some(app) = UserAgent::parse_electron(&user_agent) {
- result.name = app.0;
- result.version = app.1;
- }
+ if user_agent.contains("Electron/")
+ && let Some(app) = UserAgent::parse_electron(&user_agent)
+ {
+ result.name = app.0;
+ result.version = app.1;
}
Self {
diff --git a/crates/data-model/src/users.rs b/crates/data-model/src/users.rs
index c2addf8a3..920726ef8 100644
--- a/crates/data-model/src/users.rs
+++ b/crates/data-model/src/users.rs
@@ -223,17 +223,17 @@ impl UserRegistrationToken {
}
// Check if expired
- if let Some(expires_at) = self.expires_at {
- if now >= expires_at {
- return false;
- }
+ if let Some(expires_at) = self.expires_at
+ && now >= expires_at
+ {
+ return false;
}
// Check if usage limit exceeded
- if let Some(usage_limit) = self.usage_limit {
- if self.times_used >= usage_limit {
- return false;
- }
+ if let Some(usage_limit) = self.usage_limit
+ && self.times_used >= usage_limit
+ {
+ return false;
}
true
diff --git a/crates/handlers/src/admin/call_context.rs b/crates/handlers/src/admin/call_context.rs
index d5a5f4b94..a0470f851 100644
--- a/crates/handlers/src/admin/call_context.rs
+++ b/crates/handlers/src/admin/call_context.rs
@@ -187,10 +187,10 @@ where
};
// If there is a user for this session, check that it is not locked
- if let Some(user) = &user {
- if !user.is_valid() {
- return Err(Rejection::UserLocked);
- }
+ if let Some(user) = &user
+ && !user.is_valid()
+ {
+ return Err(Rejection::UserLocked);
}
if !session.is_valid() {
diff --git a/crates/handlers/src/graphql/model/oauth.rs b/crates/handlers/src/graphql/model/oauth.rs
index 4f628e8bd..20a4d527f 100644
--- a/crates/handlers/src/graphql/model/oauth.rs
+++ b/crates/handlers/src/graphql/model/oauth.rs
@@ -8,8 +8,7 @@ use anyhow::Context as _;
use async_graphql::{Context, Description, Enum, ID, Object};
use chrono::{DateTime, Utc};
use mas_storage::{oauth2::OAuth2ClientRepository, user::BrowserSessionRepository};
-use oauth2_types::{oidc::ApplicationType, scope::Scope};
-use ulid::Ulid;
+use oauth2_types::oidc::ApplicationType;
use url::Url;
use super::{BrowserSession, NodeType, SessionState, User, UserAgent};
@@ -200,33 +199,3 @@ impl OAuth2Client {
}
}
}
-
-/// An OAuth 2.0 consent represents the scope a user consented to grant to a
-/// client.
-#[derive(Description)]
-pub struct OAuth2Consent {
- scope: Scope,
- client_id: Ulid,
-}
-
-#[Object(use_type_description)]
-impl OAuth2Consent {
- /// Scope consented by the user for this client.
- pub async fn scope(&self) -> String {
- self.scope.to_string()
- }
-
- /// OAuth 2.0 client for which the user granted access.
- pub async fn client(&self, ctx: &Context<'_>) -> Result {
- let state = ctx.state();
- let mut repo = state.repository().await?;
- let client = repo
- .oauth2_client()
- .lookup(self.client_id)
- .await?
- .context("Could not load client")?;
- repo.cancel().await?;
-
- Ok(OAuth2Client(client))
- }
-}
diff --git a/crates/handlers/src/graphql/tests.rs b/crates/handlers/src/graphql/tests.rs
index bc5079924..328b6f152 100644
--- a/crates/handlers/src/graphql/tests.rs
+++ b/crates/handlers/src/graphql/tests.rs
@@ -348,7 +348,7 @@ async fn test_oauth2_admin(pool: PgPool) {
}
/// Test that we can query the GraphQL endpoint with a token from a
-/// client_credentials grant.
+/// `client_credentials` grant.
#[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")]
async fn test_oauth2_client_credentials(pool: PgPool) {
setup();
diff --git a/crates/handlers/src/lib.rs b/crates/handlers/src/lib.rs
index 08367bbf5..8de6707be 100644
--- a/crates/handlers/src/lib.rs
+++ b/crates/handlers/src/lib.rs
@@ -475,13 +475,13 @@ fn recover_error(
) -> axum::response::Response {
// Error responses should have an ErrorContext attached to them
let ext = response.extensions().get::();
- if let Some(ctx) = ext {
- if let Ok(res) = templates.render_error(ctx) {
- let (mut parts, _original_body) = response.into_parts();
- parts.headers.remove(CONTENT_TYPE);
- parts.headers.remove(CONTENT_LENGTH);
- return (parts, Html(res)).into_response();
- }
+ if let Some(ctx) = ext
+ && let Ok(res) = templates.render_error(ctx)
+ {
+ let (mut parts, _original_body) = response.into_parts();
+ parts.headers.remove(CONTENT_TYPE);
+ parts.headers.remove(CONTENT_LENGTH);
+ return (parts, Html(res)).into_response();
}
response
diff --git a/crates/handlers/src/oauth2/introspection.rs b/crates/handlers/src/oauth2/introspection.rs
index 678c7fa1c..e52e3c303 100644
--- a/crates/handlers/src/oauth2/introspection.rs
+++ b/crates/handlers/src/oauth2/introspection.rs
@@ -288,10 +288,10 @@ pub(crate) async fn post(
let token = &form.token;
let token_type = TokenType::check(token)?;
- if let Some(hint) = form.token_type_hint {
- if token_type != hint {
- return Err(RouteError::UnexpectedTokenType);
- }
+ if let Some(hint) = form.token_type_hint
+ && token_type != hint
+ {
+ return Err(RouteError::UnexpectedTokenType);
}
// Not all device IDs can be encoded as scope. On OAuth 2.0 sessions, we
diff --git a/crates/handlers/src/oauth2/registration.rs b/crates/handlers/src/oauth2/registration.rs
index 09ace7351..0cdfb32ea 100644
--- a/crates/handlers/src/oauth2/registration.rs
+++ b/crates/handlers/src/oauth2/registration.rs
@@ -241,34 +241,34 @@ pub(crate) async fn post(
// Some extra validation that is hard to do in OPA and not done by the
// `validate` method either
- if let Some(client_uri) = &metadata.client_uri {
- if localised_url_has_public_suffix(client_uri) {
- return Err(RouteError::UrlIsPublicSuffix("client_uri"));
- }
+ if let Some(client_uri) = &metadata.client_uri
+ && localised_url_has_public_suffix(client_uri)
+ {
+ return Err(RouteError::UrlIsPublicSuffix("client_uri"));
}
- if let Some(logo_uri) = &metadata.logo_uri {
- if localised_url_has_public_suffix(logo_uri) {
- return Err(RouteError::UrlIsPublicSuffix("logo_uri"));
- }
+ if let Some(logo_uri) = &metadata.logo_uri
+ && localised_url_has_public_suffix(logo_uri)
+ {
+ return Err(RouteError::UrlIsPublicSuffix("logo_uri"));
}
- if let Some(policy_uri) = &metadata.policy_uri {
- if localised_url_has_public_suffix(policy_uri) {
- return Err(RouteError::UrlIsPublicSuffix("policy_uri"));
- }
+ if let Some(policy_uri) = &metadata.policy_uri
+ && localised_url_has_public_suffix(policy_uri)
+ {
+ return Err(RouteError::UrlIsPublicSuffix("policy_uri"));
}
- if let Some(tos_uri) = &metadata.tos_uri {
- if localised_url_has_public_suffix(tos_uri) {
- return Err(RouteError::UrlIsPublicSuffix("tos_uri"));
- }
+ if let Some(tos_uri) = &metadata.tos_uri
+ && localised_url_has_public_suffix(tos_uri)
+ {
+ return Err(RouteError::UrlIsPublicSuffix("tos_uri"));
}
- if let Some(initiate_login_uri) = &metadata.initiate_login_uri {
- if host_is_public_suffix(initiate_login_uri) {
- return Err(RouteError::UrlIsPublicSuffix("initiate_login_uri"));
- }
+ if let Some(initiate_login_uri) = &metadata.initiate_login_uri
+ && host_is_public_suffix(initiate_login_uri)
+ {
+ return Err(RouteError::UrlIsPublicSuffix("initiate_login_uri"));
}
for redirect_uri in metadata.redirect_uris() {
diff --git a/crates/handlers/src/upstream_oauth2/authorize.rs b/crates/handlers/src/upstream_oauth2/authorize.rs
index 016dd36d3..c9e96f936 100644
--- a/crates/handlers/src/upstream_oauth2/authorize.rs
+++ b/crates/handlers/src/upstream_oauth2/authorize.rs
@@ -93,17 +93,15 @@ pub(crate) async fn get(
// Forward the raw login hint upstream for the provider to handle however it
// sees fit
- if provider.forward_login_hint {
- if let Some(PostAuthAction::ContinueAuthorizationGrant { id }) = &query.post_auth_action {
- if let Some(login_hint) = repo
- .oauth2_authorization_grant()
- .lookup(*id)
- .await?
- .and_then(|grant| grant.login_hint)
- {
- data = data.with_login_hint(login_hint);
- }
- }
+ if provider.forward_login_hint
+ && let Some(PostAuthAction::ContinueAuthorizationGrant { id }) = &query.post_auth_action
+ && let Some(login_hint) = repo
+ .oauth2_authorization_grant()
+ .lookup(*id)
+ .await?
+ .and_then(|grant| grant.login_hint)
+ {
+ data = data.with_login_hint(login_hint);
}
let data = if let Some(methods) = lazy_metadata.pkce_methods().await? {
diff --git a/crates/handlers/src/views/logout.rs b/crates/handlers/src/views/logout.rs
index 731071c8b..9d0c3ec5a 100644
--- a/crates/handlers/src/views/logout.rs
+++ b/crates/handlers/src/views/logout.rs
@@ -33,14 +33,14 @@ pub(crate) async fn post(
if let Some(session_id) = session_info.current_session_id() {
let maybe_session = repo.browser_session().lookup(session_id).await?;
- if let Some(session) = maybe_session {
- if session.finished_at.is_none() {
- activity_tracker
- .record_browser_session(&clock, &session)
- .await;
-
- repo.browser_session().finish(&clock, session).await?;
- }
+ if let Some(session) = maybe_session
+ && session.finished_at.is_none()
+ {
+ activity_tracker
+ .record_browser_session(&clock, &session)
+ .await;
+
+ repo.browser_session().finish(&clock, session).await?;
}
}
diff --git a/crates/i18n-scan/src/minijinja.rs b/crates/i18n-scan/src/minijinja.rs
index b6e9dda51..63aa63aea 100644
--- a/crates/i18n-scan/src/minijinja.rs
+++ b/crates/i18n-scan/src/minijinja.rs
@@ -110,36 +110,36 @@ fn find_in_call<'a>(
call: &'a Spanned>,
) -> Result<(), minijinja::Error> {
let span = call.span();
- if let Expr::Var(var_) = &call.expr {
- if var_.id == context.func() {
- let key = call
- .args
- .first()
- .and_then(as_const)
- .and_then(|const_| const_.value.as_str())
- .ok_or(minijinja::Error::new(
- ErrorKind::UndefinedError,
- "t() first argument must be a string literal",
- ))?;
-
- let has_count = call
- .args
- .iter()
- .any(|arg| matches!(arg, CallArg::Kwarg("count", _)));
-
- let key = Key::new(
- if has_count {
- crate::key::Kind::Plural
- } else {
- crate::key::Kind::Message
- },
- key.to_owned(),
- );
+ if let Expr::Var(var_) = &call.expr
+ && var_.id == context.func()
+ {
+ let key = call
+ .args
+ .first()
+ .and_then(as_const)
+ .and_then(|const_| const_.value.as_str())
+ .ok_or(minijinja::Error::new(
+ ErrorKind::UndefinedError,
+ "t() first argument must be a string literal",
+ ))?;
+
+ let has_count = call
+ .args
+ .iter()
+ .any(|arg| matches!(arg, CallArg::Kwarg("count", _)));
+
+ let key = Key::new(
+ if has_count {
+ crate::key::Kind::Plural
+ } else {
+ crate::key::Kind::Message
+ },
+ key.to_owned(),
+ );
- let key = context.set_key_location(key, span);
+ let key = context.set_key_location(key, span);
- context.record(key);
- }
+ context.record(key);
}
find_in_expr(context, &call.expr)?;
diff --git a/crates/i18n/src/sprintf/mod.rs b/crates/i18n/src/sprintf/mod.rs
index 72ca75373..d58514f97 100644
--- a/crates/i18n/src/sprintf/mod.rs
+++ b/crates/i18n/src/sprintf/mod.rs
@@ -72,6 +72,7 @@ pub(crate) use sprintf;
#[derive(Debug, thiserror::Error)]
#[error(transparent)]
+#[allow(dead_code)]
enum Error {
Format(#[from] self::formatter::FormatError),
Parse(Box),
diff --git a/crates/listener/src/server.rs b/crates/listener/src/server.rs
index 026706a45..2a0b6ccda 100644
--- a/crates/listener/src/server.rs
+++ b/crates/listener/src/server.rs
@@ -279,11 +279,11 @@ where
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll {
let mut this = self.project();
- if let Poll::Ready(()) = this.cancellation_future.poll(cx) {
- if !*this.did_start_shutdown {
- *this.did_start_shutdown = true;
- this.connection.as_mut().graceful_shutdown();
- }
+ if let Poll::Ready(()) = this.cancellation_future.poll(cx)
+ && !*this.did_start_shutdown
+ {
+ *this.did_start_shutdown = true;
+ this.connection.as_mut().graceful_shutdown();
}
this.connection.poll(cx)
diff --git a/crates/oauth2-types/src/oidc.rs b/crates/oauth2-types/src/oidc.rs
index a9befbea1..39e1074b1 100644
--- a/crates/oauth2-types/src/oidc.rs
+++ b/crates/oauth2-types/src/oidc.rs
@@ -577,7 +577,7 @@ pub struct ProviderMetadata {
pub require_request_uri_registration: Option,
/// Indicates where authorization request needs to be protected as [Request
- /// Object] and provided through either request or request_uri parameter.
+ /// Object] and provided through either request or `request_uri` parameter.
///
/// Defaults to `false`.
///
@@ -680,10 +680,10 @@ impl ProviderMetadata {
validate_url("registration_endpoint", url, ExtraUrlRestrictions::None)?;
}
- if let Some(scopes) = &metadata.scopes_supported {
- if !scopes.iter().any(|s| s == "openid") {
- return Err(ProviderMetadataVerificationError::ScopesMissingOpenid);
- }
+ if let Some(scopes) = &metadata.scopes_supported
+ && !scopes.iter().any(|s| s == "openid")
+ {
+ return Err(ProviderMetadataVerificationError::ScopesMissingOpenid);
}
validate_signing_alg_values_supported(
diff --git a/crates/oauth2-types/src/registration/mod.rs b/crates/oauth2-types/src/registration/mod.rs
index fd1ab2a64..e6b6aa862 100644
--- a/crates/oauth2-types/src/registration/mod.rs
+++ b/crates/oauth2-types/src/registration/mod.rs
@@ -911,7 +911,8 @@ pub struct ClientRegistrationResponse {
#[serde_as(as = "Option>")]
pub client_id_issued_at: Option>,
- /// Time at which the client_secret will expire or 0 if it will not expire.
+ /// Time at which the `client_secret` will expire or 0 if it will not
+ /// expire.
///
/// Required if `client_secret` is issued.
#[serde(default)]
diff --git a/crates/oidc-client/tests/it/main.rs b/crates/oidc-client/tests/it/main.rs
index ce595661d..cc8641085 100644
--- a/crates/oidc-client/tests/it/main.rs
+++ b/crates/oidc-client/tests/it/main.rs
@@ -74,7 +74,7 @@ fn keystore(alg: &JsonWebSignatureAlg) -> Keystore {
}
/// Generate an ID token.
-fn id_token(issuer: &str) -> (IdToken, PublicJsonWebKeySet) {
+fn id_token(issuer: &str) -> (IdToken<'_>, PublicJsonWebKeySet) {
let signing_alg = ID_TOKEN_SIGNING_ALG;
let keystore = keystore(&signing_alg);
diff --git a/crates/oidc-client/tests/it/requests/jose.rs b/crates/oidc-client/tests/it/requests/jose.rs
index dcca40252..6adedc570 100644
--- a/crates/oidc-client/tests/it/requests/jose.rs
+++ b/crates/oidc-client/tests/it/requests/jose.rs
@@ -34,7 +34,7 @@ fn id_token(
issuer: &str,
flag: Option,
auth_time: Option>,
-) -> (IdToken, PublicJsonWebKeySet) {
+) -> (IdToken<'_>, PublicJsonWebKeySet) {
let signing_alg = ID_TOKEN_SIGNING_ALG;
let keystore = keystore(&signing_alg);
diff --git a/crates/policy/src/lib.rs b/crates/policy/src/lib.rs
index b45da09ac..3a3a23c3f 100644
--- a/crates/policy/src/lib.rs
+++ b/crates/policy/src/lib.rs
@@ -397,7 +397,7 @@ impl Policy {
Ok(res)
}
- /// Evaluate the 'client_registration' entrypoint.
+ /// Evaluate the `client_registration` entrypoint.
///
/// # Errors
///
@@ -419,7 +419,7 @@ impl Policy {
Ok(res)
}
- /// Evaluate the 'authorization_grant' entrypoint.
+ /// Evaluate the `authorization_grant` entrypoint.
///
/// # Errors
///
diff --git a/crates/storage-pg/src/compat/mod.rs b/crates/storage-pg/src/compat/mod.rs
index 32f26303f..2e903af77 100644
--- a/crates/storage-pg/src/compat/mod.rs
+++ b/crates/storage-pg/src/compat/mod.rs
@@ -697,7 +697,7 @@ mod tests {
// List all logins
let logins = repo.compat_sso_login().list(all, pagination).await.unwrap();
assert!(!logins.has_next_page);
- assert_eq!(logins.edges, &[login.clone()]);
+ assert_eq!(logins.edges, vec![login.clone()]);
// List the logins for the user
let logins = repo
@@ -706,7 +706,7 @@ mod tests {
.await
.unwrap();
assert!(!logins.has_next_page);
- assert_eq!(logins.edges, &[login.clone()]);
+ assert_eq!(logins.edges, vec![login.clone()]);
// List only the pending logins for the user
let logins = repo
diff --git a/crates/storage-pg/src/user/registration.rs b/crates/storage-pg/src/user/registration.rs
index e8c228771..fdbdb7139 100644
--- a/crates/storage-pg/src/user/registration.rs
+++ b/crates/storage-pg/src/user/registration.rs
@@ -524,7 +524,7 @@ mod tests {
&mut rng,
&clock,
"alice".to_owned(),
- Some(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1))),
+ Some(IpAddr::V4(Ipv4Addr::LOCALHOST)),
Some("Mozilla/5.0".to_owned()),
Some(serde_json::json!({"action": "continue_compat_sso_login", "id": "01FSHN9AG0MKGTBNZ16RDR3PVY"})),
)
@@ -534,7 +534,7 @@ mod tests {
assert_eq!(registration.user_agent, Some("Mozilla/5.0".to_owned()));
assert_eq!(
registration.ip_address,
- Some(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)))
+ Some(IpAddr::V4(Ipv4Addr::LOCALHOST))
);
assert_eq!(
registration.post_auth_action,
diff --git a/crates/storage/src/oauth2/authorization_grant.rs b/crates/storage/src/oauth2/authorization_grant.rs
index f61f6b8c0..f87c07df0 100644
--- a/crates/storage/src/oauth2/authorization_grant.rs
+++ b/crates/storage/src/oauth2/authorization_grant.rs
@@ -38,7 +38,7 @@ pub trait OAuth2AuthorizationGrantRepository: Send + Sync {
/// * `response_mode`: The response mode the client requested
/// * `response_type_id_token`: Whether the `id_token` `response_type` was
/// requested
- /// * `login_hint`: The login_hint the client sent, if set
+ /// * `login_hint`: The `login_hint` the client sent, if set
/// * `locale`: The locale the detected when the user asked for the
/// authorization grant
///
diff --git a/crates/storage/src/oauth2/client.rs b/crates/storage/src/oauth2/client.rs
index bf2d10a29..779b754ca 100644
--- a/crates/storage/src/oauth2/client.rs
+++ b/crates/storage/src/oauth2/client.rs
@@ -24,7 +24,7 @@ pub trait OAuth2ClientRepository: Send + Sync {
/// The error type returned by the repository
type Error;
- /// Lookup an OAuth2 client by its ID
+ /// Lookup an OAuth client by its ID
///
/// Returns `None` if the client does not exist
///
@@ -37,7 +37,7 @@ pub trait OAuth2ClientRepository: Send + Sync {
/// Returns [`Self::Error`] if the underlying repository fails
async fn lookup(&mut self, id: Ulid) -> Result, Self::Error>;
- /// Find an OAuth2 client by its client ID
+ /// Find an OAuth client by its client ID
async fn find_by_client_id(&mut self, client_id: &str) -> Result , Self::Error> {
let Ok(id) = client_id.parse() else {
return Ok(None);
@@ -45,7 +45,7 @@ pub trait OAuth2ClientRepository: Send + Sync {
self.lookup(id).await
}
- /// Find an OAuth2 client by its metadata digest
+ /// Find an OAuth client by its metadata digest
///
/// Returns `None` if the client does not exist
///
@@ -62,7 +62,7 @@ pub trait OAuth2ClientRepository: Send + Sync {
digest: &str,
) -> Result , Self::Error>;
- /// Load a batch of OAuth2 clients by their IDs
+ /// Load a batch of OAuth clients by their IDs
///
/// Returns a map of client IDs to clients. If a client does not exist, it
/// is not present in the map.
@@ -79,7 +79,7 @@ pub trait OAuth2ClientRepository: Send + Sync {
ids: BTreeSet,
) -> Result, Self::Error>;
- /// Add a new OAuth2 client
+ /// Add a new OAuth client
///
/// Returns the client that was added
///
diff --git a/crates/syn2mas/src/synapse_reader/checks.rs b/crates/syn2mas/src/synapse_reader/checks.rs
index 655642770..aee91b62a 100644
--- a/crates/syn2mas/src/synapse_reader/checks.rs
+++ b/crates/syn2mas/src/synapse_reader/checks.rs
@@ -250,7 +250,8 @@ pub async fn synapse_config_check_against_mas_config(
///
/// - If there is some database connection error, or the given database is not a
/// Synapse database.
-/// - If the OAuth2 section of the MAS configuration could not be parsed.
+/// - If the Upstream OAuth section of the MAS configuration could not be
+/// parsed.
#[tracing::instrument(skip_all)]
pub async fn synapse_database_check(
synapse_connection: &mut PgConnection,
diff --git a/crates/syn2mas/src/synapse_reader/config/mod.rs b/crates/syn2mas/src/synapse_reader/config/mod.rs
index 4bd89921b..3c9454ba6 100644
--- a/crates/syn2mas/src/synapse_reader/config/mod.rs
+++ b/crates/syn2mas/src/synapse_reader/config/mod.rs
@@ -120,14 +120,14 @@ impl Config {
pub fn all_oidc_providers(&self) -> BTreeMap {
let mut out = BTreeMap::new();
- if let Some(provider) = &self.oidc_config {
- if provider.has_required_fields() {
- let mut provider = provider.clone();
- // The legacy configuration has an implied IdP ID of `oidc`.
- let idp_id = provider.idp_id.take().unwrap_or("oidc".to_owned());
- provider.idp_id = Some(idp_id.clone());
- out.insert(idp_id, provider);
- }
+ if let Some(provider) = &self.oidc_config
+ && provider.has_required_fields()
+ {
+ let mut provider = provider.clone();
+ // The legacy configuration has an implied IdP ID of `oidc`.
+ let idp_id = provider.idp_id.take().unwrap_or("oidc".to_owned());
+ provider.idp_id = Some(idp_id.clone());
+ out.insert(idp_id, provider);
}
for provider in &self.oidc_providers {
diff --git a/crates/tasks/src/matrix.rs b/crates/tasks/src/matrix.rs
index d5d6e6e65..87e052d20 100644
--- a/crates/tasks/src/matrix.rs
+++ b/crates/tasks/src/matrix.rs
@@ -29,7 +29,7 @@ use crate::{
/// Job to provision a user on the Matrix homeserver.
/// This works by doing a PUT request to the
-/// /_synapse/admin/v2/users/{user_id} endpoint.
+/// `/_synapse/admin/v2/users/{user_id}` endpoint.
#[async_trait]
impl RunnableJob for ProvisionUserJob {
#[tracing::instrument(
diff --git a/crates/templates/src/context.rs b/crates/templates/src/context.rs
index 230dee67f..0a04677eb 100644
--- a/crates/templates/src/context.rs
+++ b/crates/templates/src/context.rs
@@ -1637,7 +1637,7 @@ impl TemplateContext for DeviceConsentContext {
device_code: Alphanumeric.sample_string(rng, 32),
created_at: now - Duration::try_minutes(5).unwrap(),
expires_at: now + Duration::try_minutes(25).unwrap(),
- ip_address: Some(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1))),
+ ip_address: Some(IpAddr::V4(Ipv4Addr::LOCALHOST)),
user_agent: Some("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.0.0 Safari/537.36".to_owned()),
};
Self { grant, client }
diff --git a/crates/templates/src/lib.rs b/crates/templates/src/lib.rs
index d588e12ea..1c0bef423 100644
--- a/crates/templates/src/lib.rs
+++ b/crates/templates/src/lib.rs
@@ -328,7 +328,7 @@ register_templates! {
/// Render the Swagger API reference
pub fn render_swagger(ApiDocContext) { "swagger/doc.html" }
- /// Render the Swagger OAuth2 callback page
+ /// Render the Swagger OAuth callback page
pub fn render_swagger_callback(ApiDocContext) { "swagger/oauth2-redirect.html" }
/// Render the login page
@@ -382,7 +382,7 @@ register_templates! {
/// Render the account recovery disabled page
pub fn render_recovery_disabled(WithLanguage) { "pages/recovery/disabled.html" }
- /// Render the form used by the form_post response mode
+ /// Render the form used by the `form_post` response mode
pub fn render_form_post(WithLanguage>) { "form_post.html" }
/// Render the HTML error page
diff --git a/docs/config.schema.json b/docs/config.schema.json
index 6c4fadfcd..761f1dd62 100644
--- a/docs/config.schema.json
+++ b/docs/config.schema.json
@@ -2155,7 +2155,7 @@
"type": "boolean"
},
"on_backchannel_logout": {
- "description": "What to do when receiving an OIDC Backchannel logout request.\n\nDefaults to \"do_nothing\".",
+ "description": "What to do when receiving an OIDC Backchannel logout request.\n\nDefaults to `do_nothing`.",
"allOf": [
{
"$ref": "#/definitions/OnBackchannelLogout"