mirror of
https://github.com/element-hq/matrix-authentication-service.git
synced 2026-10-23 00:03:24 +00:00
Upgrade to rand 0.10 and the next RustCrypto generation
`rand` 0.10 and the new RustCrypto generation both build on `rand_core` 0.10, so they have to move together: - `rand`, `rand_chacha` and `rand_core` 0.10 - `digest` 0.11, `sha2` 0.11, `hmac` 0.13, `const-oid` 0.10 - `elliptic-curve` 0.14, `ecdsa` 0.17, `p256`, `p384` and `k256` 0.14, `signature` 3 - `der`, `spki` and `sec1` 0.8, `pkcs8` 0.11, `pem-rfc7468` 1.0 - `rsa` 0.10.0-rc.19 and `pkcs1` 0.8.0-rc.5, which have no stable release yet. They are pinned exactly, because release candidates break their API between releases. - `argon2` 0.6 and `pbkdf2` 0.13 On the `rand` side, `RngCore` becomes `Rng` and the old `Rng` becomes `RngExt`. `gen_*` becomes `random_*`, `thread_rng` becomes `rng`, `distributions` becomes `distr`, and `from_rng` can no longer fail. On the crypto side, `mas-jose` and `mas-keystore` move to `BoxedUint` for RSA, to the `pkcs1` and `pkcs8` reference types, and to the `Generate` trait for key generation, and `mas-jose` no longer depends on `generic-array`. Password hashing goes through `hash_password_with_rng`. Stored data is unaffected. The password hashing snapshots are unchanged, so bcrypt, Argon2 and PBKDF2 produce the same hashes for the same input and salt, and `pbkdf2` 0.13 keeps the same defaults (SHA-256, 600 000 rounds). The keystore snapshots change only because keys generated from a seeded RNG differ. The snapshots of keys loaded from files are unchanged. `opa-wasm` 0.3.3 already uses this generation, so most of the duplicate crates it pulled in go away. The `deny.toml` skip list now names what still pulls the older versions: cookie, sqlx, headers, wasmtime and pest for RustCrypto, and opentelemetry_sdk, sentry and ulid for `rand` 0.9.
This commit is contained in:
125 files changed
+1026
-717
No files matched your search
Generated
+391
-151
File diff suppressed because it is too large.
Load diff
+37
-37
@@ -1,3 +1,4 @@
|
||||
# Copyright 2025, 2026 Element Creations Ltd.
|
||||
# Copyright 2025 New Vector Ltd.
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
@@ -122,12 +123,12 @@ features = ["alloc", "getrandom"]
|
||||
|
||||
# Argon2 password hashing
|
||||
[workspace.dependencies.argon2]
|
||||
version = "0.5.3"
|
||||
features = ["password-hash", "std"]
|
||||
version = "0.6.0"
|
||||
features = ["alloc", "password-hash", "rand_core"]
|
||||
|
||||
# Constant-time base64
|
||||
[workspace.dependencies.base64ct]
|
||||
version = "1.8.0"
|
||||
version = "1.8.3"
|
||||
features = ["std"]
|
||||
|
||||
# Bcrypt password hashing
|
||||
@@ -180,8 +181,8 @@ features = ["derive"]
|
||||
|
||||
# Object Identifiers (OIDs) as constants
|
||||
[workspace.dependencies.const-oid]
|
||||
version = "0.9.6"
|
||||
features = ["std"]
|
||||
version = "0.10.2"
|
||||
features = ["db"]
|
||||
|
||||
# Utility for converting between different cases
|
||||
[workspace.dependencies.convert_case]
|
||||
@@ -201,7 +202,7 @@ version = "1.4.0"
|
||||
|
||||
# DER encoding
|
||||
[workspace.dependencies.der]
|
||||
version = "0.7.10"
|
||||
version = "0.8.0"
|
||||
features = ["std"]
|
||||
|
||||
# Interactive CLI dialogs
|
||||
@@ -212,7 +213,7 @@ features = ["fuzzy-select", "password"]
|
||||
|
||||
# Cryptographic digest algorithms
|
||||
[workspace.dependencies.digest]
|
||||
version = "0.10.7"
|
||||
version = "0.11.3"
|
||||
|
||||
# Load environment variables from .env files
|
||||
[workspace.dependencies.dotenvy]
|
||||
@@ -220,13 +221,13 @@ version = "0.15.7"
|
||||
|
||||
# ECDSA algorithms
|
||||
[workspace.dependencies.ecdsa]
|
||||
version = "0.16.9"
|
||||
features = ["signing", "verifying"]
|
||||
version = "0.17.0"
|
||||
features = ["alloc", "der", "pem", "pkcs8", "std"]
|
||||
|
||||
# Elliptic curve cryptography
|
||||
[workspace.dependencies.elliptic-curve]
|
||||
version = "0.13.8"
|
||||
features = ["std", "pem", "sec1"]
|
||||
version = "0.14.1"
|
||||
features = ["std", "pem", "pkcs8", "arithmetic"]
|
||||
|
||||
# Configuration loading
|
||||
[workspace.dependencies.figment]
|
||||
@@ -241,10 +242,6 @@ version = "1.2.2"
|
||||
[workspace.dependencies.futures-util]
|
||||
version = "0.3.31"
|
||||
|
||||
# Fixed-size arrays with trait implementations
|
||||
[workspace.dependencies.generic-array]
|
||||
version = "0.14.7"
|
||||
|
||||
# Rate-limiting
|
||||
[workspace.dependencies.governor]
|
||||
version = "0.10.1"
|
||||
@@ -253,7 +250,7 @@ features = ["std", "dashmap", "quanta"]
|
||||
|
||||
# HMAC calculation
|
||||
[workspace.dependencies.hmac]
|
||||
version = "0.12.1"
|
||||
version = "0.13.0"
|
||||
|
||||
# HTTP headers
|
||||
[workspace.dependencies.headers]
|
||||
@@ -349,8 +346,8 @@ version = "0.15.0"
|
||||
|
||||
# K256 elliptic curve
|
||||
[workspace.dependencies.k256]
|
||||
version = "0.13.4"
|
||||
features = ["std"]
|
||||
version = "0.14.0"
|
||||
features = ["std", "ecdsa", "pem", "pkcs8"]
|
||||
|
||||
# RFC 5646 language tags
|
||||
[workspace.dependencies.language-tags]
|
||||
@@ -439,13 +436,13 @@ default-features = false
|
||||
|
||||
# P256 elliptic curve
|
||||
[workspace.dependencies.p256]
|
||||
version = "0.13.2"
|
||||
features = ["std"]
|
||||
version = "0.14.0"
|
||||
features = ["std", "ecdsa", "pem", "pkcs8"]
|
||||
|
||||
# P384 elliptic curve
|
||||
[workspace.dependencies.p384]
|
||||
version = "0.13.1"
|
||||
features = ["std"]
|
||||
version = "0.14.0"
|
||||
features = ["std", "ecdsa", "pem", "pkcs8"]
|
||||
|
||||
# Text padding utilities
|
||||
[workspace.dependencies.pad]
|
||||
@@ -453,12 +450,12 @@ version = "0.1.6"
|
||||
|
||||
# PBKDF2 password hashing
|
||||
[workspace.dependencies.pbkdf2]
|
||||
version = "0.12.2"
|
||||
features = ["password-hash", "std", "simple", "parallel"]
|
||||
version = "0.13.0"
|
||||
features = ["phc", "sha2", "alloc"]
|
||||
|
||||
# PEM encoding/decoding
|
||||
[workspace.dependencies.pem-rfc7468]
|
||||
version = "0.7.0"
|
||||
version = "1.0.0"
|
||||
features = ["std"]
|
||||
|
||||
# Parser generator
|
||||
@@ -474,14 +471,15 @@ version = "2.8.3"
|
||||
version = "0.2.16"
|
||||
|
||||
# PKCS#1 encoding
|
||||
# Pinned: release candidates break their API between releases
|
||||
[workspace.dependencies.pkcs1]
|
||||
version = "0.7.5"
|
||||
version = "=0.8.0-rc.5"
|
||||
features = ["std"]
|
||||
|
||||
# PKCS#8 encoding
|
||||
[workspace.dependencies.pkcs8]
|
||||
version = "0.10.2"
|
||||
features = ["std", "pkcs5", "encryption"]
|
||||
version = "0.11.0"
|
||||
features = ["std", "pem", "encryption"]
|
||||
|
||||
# Public Suffix List
|
||||
[workspace.dependencies.psl]
|
||||
@@ -493,11 +491,11 @@ version = "0.12.6"
|
||||
|
||||
# Random values
|
||||
[workspace.dependencies.rand]
|
||||
version = "0.8.5"
|
||||
version = "0.10.1"
|
||||
[workspace.dependencies.rand_chacha]
|
||||
version = "0.3.1"
|
||||
version = "0.10.0"
|
||||
[workspace.dependencies.rand_core]
|
||||
version = "0.6.4"
|
||||
version = "0.10.1"
|
||||
|
||||
# Regular expressions
|
||||
[workspace.dependencies.regex]
|
||||
@@ -518,9 +516,10 @@ features = [
|
||||
]
|
||||
|
||||
# RSA cryptography
|
||||
# Pinned: release candidates break their API between releases
|
||||
[workspace.dependencies.rsa]
|
||||
version = "0.9.10"
|
||||
features = ["std", "pem"]
|
||||
version = "=0.10.0-rc.19"
|
||||
features = ["std", "encoding"]
|
||||
|
||||
# Fast hash algorithm for HashMap
|
||||
[workspace.dependencies.rustc-hash]
|
||||
@@ -549,7 +548,7 @@ features = ["url2", "chrono04", "preserve_order"]
|
||||
|
||||
# SEC1 encoding format
|
||||
[workspace.dependencies.sec1]
|
||||
version = "0.7.3"
|
||||
version = "0.8.1"
|
||||
features = ["std"]
|
||||
|
||||
# Query builder
|
||||
@@ -607,12 +606,13 @@ version = "0.9.34"
|
||||
|
||||
# SHA-2 cryptographic hash algorithm
|
||||
[workspace.dependencies.sha2]
|
||||
version = "0.10.9"
|
||||
version = "0.11.0"
|
||||
features = ["oid"]
|
||||
|
||||
# Digital signature traits
|
||||
[workspace.dependencies.signature]
|
||||
version = "2.2.0"
|
||||
version = "3.0.0"
|
||||
features = ["alloc", "rand_core"]
|
||||
|
||||
# Low-level socket manipulation
|
||||
[workspace.dependencies.socket2]
|
||||
@@ -620,7 +620,7 @@ version = "0.6.2"
|
||||
|
||||
# Subject Public Key Info
|
||||
[workspace.dependencies.spki]
|
||||
version = "0.7.3"
|
||||
version = "0.8.0"
|
||||
features = ["std"]
|
||||
|
||||
# SQL database support
|
||||
|
||||
+2
-1
@@ -1,3 +1,4 @@
|
||||
# Copyright 2025, 2026 Element Creations Ltd.
|
||||
# Copyright 2025 New Vector Ltd.
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
@@ -6,7 +7,7 @@
|
||||
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" },
|
||||
{ path = "rand::rng", reason = "do not create rngs on the fly, pass them as parameters" },
|
||||
{ path = "chrono::Utc::now", reason = "source the current time from the clock instead" },
|
||||
# ulid's own constructors/accessors below either use ulid's (separate) `rand`
|
||||
# or its `std`-only SystemTime API. Use `mas_data_model::UlidExt` instead so our
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
// Copyright 2022-2024 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
@@ -7,7 +8,10 @@
|
||||
use base64ct::{Base64UrlUnpadded, Encoding};
|
||||
use chrono::{DateTime, Duration, Utc};
|
||||
use mas_data_model::Clock;
|
||||
use rand::{Rng, RngCore, distributions::Standard, prelude::Distribution as _};
|
||||
use rand::{
|
||||
Rng, RngExt,
|
||||
distr::{Distribution as _, StandardUniform},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::{TimestampSeconds, serde_as};
|
||||
use thiserror::Error;
|
||||
@@ -55,8 +59,8 @@ impl CsrfToken {
|
||||
}
|
||||
|
||||
/// Generate a new random token valid for a specified duration
|
||||
fn generate(now: DateTime<Utc>, mut rng: impl Rng, ttl: Duration) -> Self {
|
||||
let token = Standard.sample(&mut rng);
|
||||
fn generate(now: DateTime<Utc>, mut rng: impl RngExt, ttl: Duration) -> Self {
|
||||
let token = StandardUniform.sample(&mut rng);
|
||||
Self::new(token, now, ttl)
|
||||
}
|
||||
|
||||
@@ -108,7 +112,7 @@ pub trait CsrfExt {
|
||||
/// if necessary
|
||||
fn csrf_token<C, R>(self, clock: &C, rng: R) -> (CsrfToken, Self)
|
||||
where
|
||||
R: RngCore,
|
||||
R: Rng,
|
||||
C: Clock;
|
||||
|
||||
/// Verify that the given CSRF-protected form is valid, returning the inner
|
||||
@@ -126,7 +130,7 @@ pub trait CsrfExt {
|
||||
impl CsrfExt for CookieJar {
|
||||
fn csrf_token<C, R>(self, clock: &C, rng: R) -> (CsrfToken, Self)
|
||||
where
|
||||
R: RngCore,
|
||||
R: Rng,
|
||||
C: Clock,
|
||||
{
|
||||
let now = clock.now();
|
||||
|
||||
@@ -243,9 +243,9 @@ impl FromRequestParts<AppState> for BoxRng {
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send {
|
||||
// This rng is used to source the local rng
|
||||
#[expect(clippy::disallowed_methods)]
|
||||
let rng = rand::thread_rng();
|
||||
let mut rng = rand::rng();
|
||||
|
||||
let rng = rand_chacha::ChaChaRng::from_rng(rng).expect("Failed to seed RNG");
|
||||
let rng = rand_chacha::ChaChaRng::from_rng(&mut rng);
|
||||
let rng: Self = Box::new(rng);
|
||||
ready(Ok(rng))
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
// Copyright 2021-2024 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
@@ -98,8 +99,10 @@ impl Options {
|
||||
let _span = info_span!("cli.config.generate").entered();
|
||||
let clock = SystemClock::default();
|
||||
|
||||
// XXX: we should disallow SeedableRng::from_entropy
|
||||
let mut rng = rand_chacha::ChaChaRng::from_entropy();
|
||||
// Seed the RNG from the thread RNG. `rand::rng()` is normally
|
||||
// disallowed (we inject RNGs), but this is a top-level entry point.
|
||||
#[expect(clippy::disallowed_methods)]
|
||||
let mut rng = rand_chacha::ChaChaRng::from_rng(&mut rand::rng());
|
||||
let mut config = RootConfig::generate(&mut rng).await?;
|
||||
|
||||
if !synapse_config.is_empty() {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
// Copyright 2021-2024 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
@@ -33,8 +34,8 @@ use mas_storage::{
|
||||
};
|
||||
use mas_storage_pg::{DatabaseError, PgRepository};
|
||||
use rand::{
|
||||
RngCore, SeedableRng,
|
||||
distributions::{Alphanumeric, DistString as _},
|
||||
Rng, SeedableRng,
|
||||
distr::{Alphanumeric, SampleString as _},
|
||||
};
|
||||
use sqlx::{Acquire, types::Uuid};
|
||||
use tracing::{error, info, info_span, warn};
|
||||
@@ -222,8 +223,10 @@ impl Options {
|
||||
pub async fn run(self, figment: &Figment) -> anyhow::Result<ExitCode> {
|
||||
use Subcommand as SC;
|
||||
let clock = SystemClock::default();
|
||||
// XXX: we should disallow SeedableRng::from_entropy
|
||||
let mut rng = rand_chacha::ChaChaRng::from_entropy();
|
||||
// Seed the RNG from the thread RNG. `rand::rng()` is normally disallowed
|
||||
// (we inject RNGs), but this is a top-level entry point.
|
||||
#[expect(clippy::disallowed_methods)]
|
||||
let mut rng = rand_chacha::ChaChaRng::from_rng(&mut rand::rng());
|
||||
|
||||
match self.subcommand {
|
||||
SC::SetPassword {
|
||||
@@ -1112,7 +1115,7 @@ impl UserCreationRequest<'_> {
|
||||
async fn do_register<E: std::error::Error + Send + Sync + 'static>(
|
||||
self,
|
||||
repo: &mut dyn RepositoryAccess<Error = E>,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
) -> Result<User, E> {
|
||||
let Self {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
@@ -14,7 +15,7 @@ use mas_config::{
|
||||
UpstreamOAuth2Config,
|
||||
};
|
||||
use mas_data_model::SystemClock;
|
||||
use rand::thread_rng;
|
||||
use rand::rng;
|
||||
use sqlx::{Connection, Either, PgConnection, postgres::PgConnectOptions, types::Uuid};
|
||||
use syn2mas::{
|
||||
LockedMasDatabase, MasWriter, Progress, ProgressStage, SynapseReader, synapse_config,
|
||||
@@ -257,7 +258,7 @@ impl Options {
|
||||
let clock = SystemClock::default();
|
||||
// TODO is this rng ok?
|
||||
#[expect(clippy::disallowed_methods)]
|
||||
let mut rng = thread_rng();
|
||||
let mut rng = rng();
|
||||
|
||||
let progress = Progress::default();
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
// Copyright 2021-2024 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
@@ -73,11 +74,13 @@ impl Options {
|
||||
} else {
|
||||
SystemClock::default().now()
|
||||
};
|
||||
// `rand::rng()` is normally disallowed (we inject RNGs), but this
|
||||
// is a top-level entry point.
|
||||
#[expect(clippy::disallowed_methods)]
|
||||
let rng = if stabilise {
|
||||
rand_chacha::ChaChaRng::from_seed([42; 32])
|
||||
} else {
|
||||
// XXX: we should disallow SeedableRng::from_entropy
|
||||
rand_chacha::ChaChaRng::from_entropy()
|
||||
rand_chacha::ChaChaRng::from_rng(&mut rand::rng())
|
||||
};
|
||||
let url_builder =
|
||||
mas_router::UrlBuilder::new("https://example.com/".parse()?, None, None);
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
use anyhow::bail;
|
||||
use camino::Utf8PathBuf;
|
||||
use rand::{
|
||||
Rng,
|
||||
distributions::{Alphanumeric, DistString},
|
||||
RngExt,
|
||||
distr::{Alphanumeric, SampleString},
|
||||
};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -143,7 +143,7 @@ impl MatrixConfig {
|
||||
|
||||
pub(crate) fn generate<R>(mut rng: R) -> Self
|
||||
where
|
||||
R: Rng + Send,
|
||||
R: RngExt + Send,
|
||||
{
|
||||
Self {
|
||||
kind: HomeserverKind::default(),
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
// Copyright 2022-2024 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
@@ -6,7 +7,7 @@
|
||||
|
||||
use anyhow::bail;
|
||||
use camino::Utf8PathBuf;
|
||||
use rand::Rng;
|
||||
use rand::RngExt;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@@ -172,7 +173,7 @@ impl RootConfig {
|
||||
/// Returns an error if the secrets could not be generated
|
||||
pub async fn generate<R>(mut rng: R) -> anyhow::Result<Self>
|
||||
where
|
||||
R: Rng + Send,
|
||||
R: RngExt + Send,
|
||||
{
|
||||
Ok(Self {
|
||||
clients: ClientsConfig::default(),
|
||||
|
||||
@@ -12,7 +12,10 @@ use camino::Utf8PathBuf;
|
||||
use futures_util::future::{try_join, try_join_all};
|
||||
use mas_jose::jwk::{JsonWebKey, JsonWebKeySet, Thumbprint};
|
||||
use mas_keystore::{Encrypter, Keystore, PrivateKey};
|
||||
use rand::{Rng, SeedableRng, distributions::Standard, prelude::Distribution as _};
|
||||
use rand::{
|
||||
RngExt, SeedableRng,
|
||||
distr::{Distribution as _, StandardUniform},
|
||||
};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::serde_as;
|
||||
@@ -347,12 +350,12 @@ impl SecretsConfig {
|
||||
#[tracing::instrument(skip_all)]
|
||||
pub(crate) async fn generate<R>(mut rng: R) -> anyhow::Result<Self>
|
||||
where
|
||||
R: Rng + Send,
|
||||
R: RngExt + Send,
|
||||
{
|
||||
info!("Generating keys...");
|
||||
|
||||
let span = tracing::info_span!("rsa");
|
||||
let key_rng = rand_chacha::ChaChaRng::from_rng(&mut rng)?;
|
||||
let key_rng = rand_chacha::ChaChaRng::from_rng(&mut rng);
|
||||
let rsa_key = task::spawn_blocking(move || {
|
||||
let _entered = span.enter();
|
||||
let ret = PrivateKey::generate_rsa(key_rng).unwrap();
|
||||
@@ -368,7 +371,7 @@ impl SecretsConfig {
|
||||
};
|
||||
|
||||
let span = tracing::info_span!("ec_p256");
|
||||
let key_rng = rand_chacha::ChaChaRng::from_rng(&mut rng)?;
|
||||
let key_rng = rand_chacha::ChaChaRng::from_rng(&mut rng);
|
||||
let ec_p256_key = task::spawn_blocking(move || {
|
||||
let _entered = span.enter();
|
||||
let ret = PrivateKey::generate_ec_p256(key_rng);
|
||||
@@ -384,7 +387,7 @@ impl SecretsConfig {
|
||||
};
|
||||
|
||||
let span = tracing::info_span!("ec_p384");
|
||||
let key_rng = rand_chacha::ChaChaRng::from_rng(&mut rng)?;
|
||||
let key_rng = rand_chacha::ChaChaRng::from_rng(&mut rng);
|
||||
let ec_p384_key = task::spawn_blocking(move || {
|
||||
let _entered = span.enter();
|
||||
let ret = PrivateKey::generate_ec_p384(key_rng);
|
||||
@@ -400,7 +403,7 @@ impl SecretsConfig {
|
||||
};
|
||||
|
||||
let span = tracing::info_span!("ec_k256");
|
||||
let key_rng = rand_chacha::ChaChaRng::from_rng(&mut rng)?;
|
||||
let key_rng = rand_chacha::ChaChaRng::from_rng(&mut rng);
|
||||
let ec_k256_key = task::spawn_blocking(move || {
|
||||
let _entered = span.enter();
|
||||
let ret = PrivateKey::generate_ec_k256(key_rng);
|
||||
@@ -416,7 +419,7 @@ impl SecretsConfig {
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
encryption: Encryption::Value(Standard.sample(&mut rng)),
|
||||
encryption: Encryption::Value(StandardUniform.sample(&mut rng)),
|
||||
keys: Some(vec![rsa_key, ec_p256_key, ec_p384_key, ec_k256_key]),
|
||||
keys_dir: None,
|
||||
})
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
// Copyright 2023, 2024 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
@@ -6,8 +7,8 @@
|
||||
|
||||
use oauth2_types::scope::ScopeToken;
|
||||
use rand::{
|
||||
RngCore,
|
||||
distributions::{Alphanumeric, DistString},
|
||||
Rng,
|
||||
distr::{Alphanumeric, SampleString},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use thiserror::Error;
|
||||
@@ -58,7 +59,7 @@ impl Device {
|
||||
}
|
||||
|
||||
/// Generate a random device ID
|
||||
pub fn generate<R: RngCore + ?Sized>(rng: &mut R) -> Self {
|
||||
pub fn generate<R: Rng + ?Sized>(rng: &mut R) -> Self {
|
||||
let id: String = Alphanumeric.sample_string(rng, GENERATED_DEVICE_ID_LENGTH);
|
||||
Self { id }
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
// Copyright 2021-2024 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
@@ -14,8 +15,8 @@ use oauth2_types::{
|
||||
scope::{OPENID, PROFILE, Scope},
|
||||
};
|
||||
use rand::{
|
||||
RngCore,
|
||||
distributions::{Alphanumeric, DistString},
|
||||
Rng,
|
||||
distr::{Alphanumeric, SampleString},
|
||||
};
|
||||
use serde::Serialize;
|
||||
use ulid::Ulid;
|
||||
@@ -224,7 +225,7 @@ impl AuthorizationGrant {
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn sample(now: DateTime<Utc>, rng: &mut impl RngCore) -> Self {
|
||||
pub fn sample(now: DateTime<Utc>, rng: &mut impl Rng) -> Self {
|
||||
Self {
|
||||
id: Ulid::from_datetime_with_rng(now, rng),
|
||||
stage: AuthorizationGrantStage::Pending,
|
||||
|
||||
@@ -13,7 +13,7 @@ use oauth2_types::{
|
||||
registration::{ClientMetadata, Localized},
|
||||
requests::GrantType,
|
||||
};
|
||||
use rand::RngCore;
|
||||
use rand::Rng;
|
||||
use serde::Serialize;
|
||||
use thiserror::Error;
|
||||
use ulid::Ulid;
|
||||
@@ -181,7 +181,7 @@ impl Client {
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn samples(now: DateTime<Utc>, rng: &mut impl RngCore) -> Vec<Client> {
|
||||
pub fn samples(now: DateTime<Utc>, rng: &mut impl Rng) -> Vec<Client> {
|
||||
vec![
|
||||
// A client with all the URIs set
|
||||
Self {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
// Copyright 2023, 2024 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
@@ -8,7 +9,7 @@ use std::net::IpAddr;
|
||||
|
||||
use chrono::{DateTime, Utc};
|
||||
use oauth2_types::scope::Scope;
|
||||
use rand::{Rng, RngCore};
|
||||
use rand::{Rng, RngExt};
|
||||
use serde::Serialize;
|
||||
use ulid::Ulid;
|
||||
|
||||
@@ -30,9 +31,9 @@ const USER_CODE_ALPHABET: &[u8; 32] = b"0123456789ABCDEFGHJKMNPQRSTVWXYZ";
|
||||
const USER_CODE_LENGTH: usize = 6;
|
||||
|
||||
/// Generate a random user code for a device code grant.
|
||||
pub fn generate_user_code<R: RngCore + ?Sized>(rng: &mut R) -> String {
|
||||
pub fn generate_user_code<R: Rng + ?Sized>(rng: &mut R) -> String {
|
||||
(0..USER_CODE_LENGTH)
|
||||
.map(|_| char::from(USER_CODE_ALPHABET[rng.gen_range(0..USER_CODE_ALPHABET.len())]))
|
||||
.map(|_| char::from(USER_CODE_ALPHABET[rng.random_range(0..USER_CODE_ALPHABET.len())]))
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
// Copyright 2021-2024 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
@@ -8,7 +9,7 @@ use base64ct::{Base64UrlUnpadded, Encoding};
|
||||
use chrono::{DateTime, Utc};
|
||||
use crc::{CRC_32_ISO_HDLC, Crc};
|
||||
use mas_iana::oauth::OAuthTokenTypeHint;
|
||||
use rand::{Rng, RngCore, distributions::Alphanumeric};
|
||||
use rand::{Rng, RngExt, distr::Alphanumeric};
|
||||
use thiserror::Error;
|
||||
use ulid::Ulid;
|
||||
|
||||
@@ -280,7 +281,7 @@ impl TokenType {
|
||||
}
|
||||
|
||||
/// Generate a token for the given type
|
||||
pub fn generate(self, rng: &mut (impl RngCore + ?Sized)) -> String {
|
||||
pub fn generate(self, rng: &mut (impl Rng + ?Sized)) -> String {
|
||||
let random_part: String = rng
|
||||
.sample_iter(&Alphanumeric)
|
||||
.take(30)
|
||||
@@ -409,7 +410,7 @@ pub enum TokenFormatError {
|
||||
mod tests {
|
||||
use std::collections::HashSet;
|
||||
|
||||
use rand::thread_rng;
|
||||
use rand::rng;
|
||||
|
||||
use super::*;
|
||||
|
||||
@@ -469,7 +470,7 @@ mod tests {
|
||||
const COUNT: usize = 500; // Generate 500 of each token type
|
||||
|
||||
#[expect(clippy::disallowed_methods)]
|
||||
let mut rng = thread_rng();
|
||||
let mut rng = rng();
|
||||
|
||||
for t in [
|
||||
TokenType::CompatAccessToken,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
// Copyright 2021-2024 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
@@ -7,7 +8,7 @@
|
||||
use std::net::IpAddr;
|
||||
|
||||
use chrono::{DateTime, Utc};
|
||||
use rand::Rng;
|
||||
use rand::RngExt;
|
||||
use serde::Serialize;
|
||||
use ulid::Ulid;
|
||||
use url::Url;
|
||||
@@ -57,7 +58,7 @@ impl User {
|
||||
impl User {
|
||||
#[doc(hidden)]
|
||||
#[must_use]
|
||||
pub fn samples(now: chrono::DateTime<Utc>, rng: &mut impl Rng) -> Vec<Self> {
|
||||
pub fn samples(now: chrono::DateTime<Utc>, rng: &mut impl RngExt) -> Vec<Self> {
|
||||
vec![User {
|
||||
id: Ulid::from_datetime_with_rng(now, rng),
|
||||
username: "john".to_owned(),
|
||||
@@ -173,7 +174,7 @@ impl BrowserSession {
|
||||
|
||||
impl BrowserSession {
|
||||
#[must_use]
|
||||
pub fn samples(now: chrono::DateTime<Utc>, rng: &mut impl Rng) -> Vec<Self> {
|
||||
pub fn samples(now: chrono::DateTime<Utc>, rng: &mut impl RngExt) -> Vec<Self> {
|
||||
User::samples(now, rng)
|
||||
.into_iter()
|
||||
.map(|user| BrowserSession {
|
||||
@@ -201,7 +202,7 @@ pub struct UserEmail {
|
||||
|
||||
impl UserEmail {
|
||||
#[must_use]
|
||||
pub fn samples(now: chrono::DateTime<Utc>, rng: &mut impl Rng) -> Vec<Self> {
|
||||
pub fn samples(now: chrono::DateTime<Utc>, rng: &mut impl RngExt) -> Vec<Self> {
|
||||
vec![
|
||||
Self {
|
||||
id: Ulid::from_datetime_with_rng(now, rng),
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
// Please see LICENSE files in the repository root for full details.
|
||||
|
||||
use chrono::{DateTime, Utc};
|
||||
use rand::Rng;
|
||||
use rand_chacha::rand_core::CryptoRngCore;
|
||||
use rand::{CryptoRng, RngExt};
|
||||
use ulid::Ulid;
|
||||
|
||||
use crate::clock::Clock;
|
||||
@@ -14,7 +13,7 @@ use crate::clock::Clock;
|
||||
/// A boxed [`Clock`]
|
||||
pub type BoxClock = Box<dyn Clock + Send>;
|
||||
/// A boxed random number generator
|
||||
pub type BoxRng = Box<dyn CryptoRngCore + Send>;
|
||||
pub type BoxRng = Box<dyn CryptoRng + Send>;
|
||||
|
||||
/// Extension trait on [`Ulid`] to build and inspect ULIDs using `chrono`
|
||||
/// timestamps and an injected RNG.
|
||||
@@ -25,19 +24,19 @@ pub trait UlidExt: Sized {
|
||||
/// This reproduces the exact bit layout of `ulid`'s own
|
||||
/// `Ulid::from_datetime_with_source` (48 timestamp bits, then 80 random
|
||||
/// bits drawn as a `u16` followed by a `u64`).
|
||||
fn from_datetime_with_rng<R: Rng + ?Sized>(datetime: DateTime<Utc>, rng: &mut R) -> Self;
|
||||
fn from_datetime_with_rng<R: RngExt + ?Sized>(datetime: DateTime<Utc>, rng: &mut R) -> Self;
|
||||
|
||||
/// The creation timestamp encoded in this [`Ulid`], as a `chrono` datetime.
|
||||
fn datetime_utc(&self) -> DateTime<Utc>;
|
||||
}
|
||||
|
||||
impl UlidExt for Ulid {
|
||||
fn from_datetime_with_rng<R: Rng + ?Sized>(datetime: DateTime<Utc>, rng: &mut R) -> Self {
|
||||
fn from_datetime_with_rng<R: RngExt + ?Sized>(datetime: DateTime<Utc>, rng: &mut R) -> Self {
|
||||
let timestamp_ms = u64::try_from(datetime.timestamp_millis()).unwrap_or(0);
|
||||
let timebits = timestamp_ms & ((1 << Ulid::TIME_BITS) - 1);
|
||||
|
||||
let msb = timebits << 16 | u64::from(rng.r#gen::<u16>());
|
||||
let lsb = rng.r#gen::<u64>();
|
||||
let msb = timebits << 16 | u64::from(rng.random::<u16>());
|
||||
let lsb = rng.random::<u64>();
|
||||
Ulid::from(u128::from(msb) << 64 | u128::from(lsb))
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2025 New Vector Ltd.
|
||||
// Copyright 2025 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
@@ -10,7 +11,7 @@ use chrono::{DateTime, Utc};
|
||||
use hyper::StatusCode;
|
||||
use mas_axum_utils::record_error;
|
||||
use mas_data_model::BoxRng;
|
||||
use rand::distributions::{Alphanumeric, DistString};
|
||||
use rand::distr::{Alphanumeric, SampleString};
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ use mas_storage::{
|
||||
user::{UserPasswordRepository, UserRepository},
|
||||
};
|
||||
use opentelemetry::{Key, KeyValue, metrics::Counter};
|
||||
use rand::{CryptoRng, RngCore};
|
||||
use rand::{CryptoRng, Rng};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::{DurationMilliSeconds, serde_as, skip_serializing_none};
|
||||
use thiserror::Error;
|
||||
@@ -533,7 +533,7 @@ pub(crate) async fn post(
|
||||
/// [`Policy::evaluate_compat_login`], return the appropriate `RouteError`
|
||||
/// response.
|
||||
async fn process_violations_for_compat_login(
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
repo: &mut BoxRepository,
|
||||
session_limit_config: Option<&SessionLimitConfig>,
|
||||
@@ -772,7 +772,7 @@ async fn find_lru_compat_sessions_flawed(
|
||||
}
|
||||
|
||||
async fn token_login(
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
repo: &mut BoxRepository,
|
||||
policy: &mut Policy,
|
||||
@@ -913,7 +913,7 @@ async fn token_login(
|
||||
}
|
||||
|
||||
async fn user_password_login(
|
||||
mut rng: &mut (impl RngCore + CryptoRng + Send),
|
||||
mut rng: &mut (impl CryptoRng + Send),
|
||||
clock: &impl Clock,
|
||||
password_manager: &PasswordManager,
|
||||
limiter: &Limiter,
|
||||
@@ -1036,7 +1036,7 @@ mod tests {
|
||||
use assert_matches::assert_matches;
|
||||
use hyper::Request;
|
||||
use mas_matrix::{HomeserverConnection, ProvisionRequest};
|
||||
use rand::distributions::{Alphanumeric, DistString};
|
||||
use rand::distr::{Alphanumeric, SampleString};
|
||||
use sqlx::PgPool;
|
||||
|
||||
use super::*;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
// Copyright 2022-2024 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
@@ -11,7 +12,7 @@ use mas_axum_utils::{GenericError, InternalError};
|
||||
use mas_data_model::{BoxClock, BoxRng};
|
||||
use mas_router::{CompatLoginSsoAction, CompatLoginSsoComplete, UrlBuilder};
|
||||
use mas_storage::{BoxRepository, compat::CompatSsoLoginRepository};
|
||||
use rand::distributions::{Alphanumeric, DistString};
|
||||
use rand::distr::{Alphanumeric, SampleString};
|
||||
use serde::Deserialize;
|
||||
use thiserror::Error;
|
||||
use url::Url;
|
||||
|
||||
@@ -46,7 +46,7 @@ use mas_storage::{BoxRepository, BoxRepositoryFactory, RepositoryError};
|
||||
use opentelemetry_semantic_conventions::trace::{
|
||||
GRAPHQL_DOCUMENT, GRAPHQL_OPERATION_NAME, GRAPHQL_OPERATION_TYPE,
|
||||
};
|
||||
use rand::{SeedableRng, thread_rng};
|
||||
use rand::{SeedableRng, rng};
|
||||
use rand_chacha::ChaChaRng;
|
||||
use state::has_session_ended;
|
||||
use tracing::{Instrument, info_span};
|
||||
@@ -125,9 +125,9 @@ impl state::State for GraphQLState {
|
||||
|
||||
fn rng(&self) -> BoxRng {
|
||||
#[expect(clippy::disallowed_methods)]
|
||||
let rng = thread_rng();
|
||||
let mut rng = rng();
|
||||
|
||||
let rng = ChaChaRng::from_rng(rng).expect("Failed to seed rng");
|
||||
let rng = ChaChaRng::from_rng(&mut rng);
|
||||
Box::new(rng)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ use oauth2_types::{
|
||||
requests::{AuthorizationRequest, GrantType, Prompt, ResponseMode},
|
||||
response_type::ResponseType,
|
||||
};
|
||||
use rand::{Rng, distributions::Alphanumeric};
|
||||
use rand::{RngExt, distr::Alphanumeric};
|
||||
use serde::Deserialize;
|
||||
use thiserror::Error;
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
// Copyright 2023, 2024 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
@@ -23,7 +24,7 @@ use oauth2_types::{
|
||||
requests::{DeviceAuthorizationRequest, DeviceAuthorizationResponse, GrantType},
|
||||
scope::ScopeToken,
|
||||
};
|
||||
use rand::distributions::{Alphanumeric, DistString};
|
||||
use rand::distr::{Alphanumeric, SampleString};
|
||||
use thiserror::Error;
|
||||
use ulid::Ulid;
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
// Copyright 2021-2024 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
@@ -45,7 +46,7 @@ pub(crate) enum IdTokenSignatureError {
|
||||
}
|
||||
|
||||
pub(crate) fn generate_id_token(
|
||||
rng: &mut (impl rand::RngCore + rand::CryptoRng),
|
||||
rng: &mut impl rand::CryptoRng,
|
||||
clock: &impl Clock,
|
||||
url_builder: &UrlBuilder,
|
||||
key_store: &Keystore,
|
||||
@@ -96,7 +97,7 @@ pub(crate) fn generate_id_token(
|
||||
}
|
||||
|
||||
pub(crate) async fn generate_token_pair<R: RepositoryAccess>(
|
||||
rng: &mut (impl rand::RngCore + Send),
|
||||
rng: &mut (impl rand::Rng + Send),
|
||||
clock: &impl Clock,
|
||||
repo: &mut R,
|
||||
session: &Session,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
// Copyright 2022-2024 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
@@ -25,7 +26,7 @@ use oauth2_types::{
|
||||
};
|
||||
use opentelemetry::{Key, KeyValue, metrics::Counter};
|
||||
use psl::Psl;
|
||||
use rand::distributions::{Alphanumeric, DistString};
|
||||
use rand::distr::{Alphanumeric, SampleString};
|
||||
use serde::Serialize;
|
||||
use sha2::Digest as _;
|
||||
use thiserror::Error;
|
||||
|
||||
@@ -8,10 +8,13 @@
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
|
||||
use anyhow::Context;
|
||||
use argon2::{Argon2, PasswordHash, PasswordHasher, PasswordVerifier, password_hash::SaltString};
|
||||
use argon2::{Argon2, PasswordHash, PasswordHasher, PasswordVerifier};
|
||||
use futures_util::future::OptionFuture;
|
||||
use pbkdf2::{Pbkdf2, password_hash};
|
||||
use rand::{CryptoRng, RngCore, SeedableRng, distributions::Standard, prelude::Distribution};
|
||||
use rand::{
|
||||
CryptoRng, SeedableRng,
|
||||
distr::{Distribution, StandardUniform},
|
||||
};
|
||||
use thiserror::Error;
|
||||
use zeroize::Zeroizing;
|
||||
use zxcvbn::zxcvbn;
|
||||
@@ -163,16 +166,16 @@ impl PasswordManager {
|
||||
/// Returns an error if the hashing failed or if the password manager is
|
||||
/// disabled
|
||||
#[tracing::instrument(name = "passwords.hash", skip_all)]
|
||||
pub async fn hash<R: CryptoRng + RngCore + Send>(
|
||||
pub async fn hash<R: CryptoRng + Send>(
|
||||
&self,
|
||||
rng: R,
|
||||
mut rng: R,
|
||||
password: Zeroizing<String>,
|
||||
) -> Result<(SchemeVersion, String), anyhow::Error> {
|
||||
let inner = self.get_inner()?;
|
||||
|
||||
// Seed a future-local RNG so the RNG passed in parameters doesn't have to be
|
||||
// 'static
|
||||
let rng = rand_chacha::ChaChaRng::from_rng(rng)?;
|
||||
let rng = rand_chacha::ChaChaRng::from_rng(&mut rng);
|
||||
let span = tracing::Span::current();
|
||||
|
||||
// `inner` is being moved in the blocking task, so we need to copy the version
|
||||
@@ -230,7 +233,7 @@ impl PasswordManager {
|
||||
/// Returns an error if the password hash verification failed or if the
|
||||
/// password manager is disabled
|
||||
#[tracing::instrument(name = "passwords.verify_and_upgrade", skip_all, fields(%scheme))]
|
||||
pub async fn verify_and_upgrade<R: CryptoRng + RngCore + Send>(
|
||||
pub async fn verify_and_upgrade<R: CryptoRng + Send>(
|
||||
&self,
|
||||
rng: R,
|
||||
scheme: SchemeVersion,
|
||||
@@ -311,7 +314,7 @@ impl Hasher {
|
||||
}
|
||||
}
|
||||
|
||||
fn hash_blocking<R: CryptoRng + RngCore>(
|
||||
fn hash_blocking<R: CryptoRng>(
|
||||
&self,
|
||||
rng: R,
|
||||
password: Zeroizing<String>,
|
||||
@@ -342,7 +345,7 @@ enum Algorithm {
|
||||
}
|
||||
|
||||
impl Algorithm {
|
||||
fn hash_blocking<R: CryptoRng + RngCore>(
|
||||
fn hash_blocking<R: CryptoRng>(
|
||||
self,
|
||||
mut rng: R,
|
||||
password: &[u8],
|
||||
@@ -355,7 +358,7 @@ impl Algorithm {
|
||||
password.extend_from_slice(pepper);
|
||||
}
|
||||
|
||||
let salt = Standard.sample(&mut rng);
|
||||
let salt = StandardUniform.sample(&mut rng);
|
||||
|
||||
let hashed = bcrypt::hash_with_salt(password, cost.unwrap_or(12), salt)?;
|
||||
Ok(hashed.format_for_version(bcrypt::Version::TwoB))
|
||||
@@ -372,8 +375,7 @@ impl Algorithm {
|
||||
Argon2::new(algorithm, version, params)
|
||||
};
|
||||
|
||||
let salt = SaltString::generate(rng);
|
||||
let hashed = phf.hash_password(password.as_ref(), &salt)?;
|
||||
let hashed = phf.hash_password_with_rng(&mut rng, password.as_ref())?;
|
||||
Ok(hashed.to_string())
|
||||
}
|
||||
|
||||
@@ -383,8 +385,8 @@ impl Algorithm {
|
||||
password.extend_from_slice(pepper);
|
||||
}
|
||||
|
||||
let salt = SaltString::generate(rng);
|
||||
let hashed = Pbkdf2.hash_password(password.as_ref(), &salt)?;
|
||||
let hashed =
|
||||
Pbkdf2::default().hash_password_with_rng(&mut rng, password.as_ref())?;
|
||||
Ok(hashed.to_string())
|
||||
}
|
||||
}
|
||||
@@ -422,7 +424,9 @@ impl Algorithm {
|
||||
|
||||
match phf.verify_password(password.as_ref(), &hashed_password) {
|
||||
Ok(()) => PasswordVerificationResult::success(),
|
||||
Err(password_hash::Error::Password) => PasswordVerificationResult::failure(),
|
||||
Err(password_hash::Error::PasswordInvalid) => {
|
||||
PasswordVerificationResult::failure()
|
||||
}
|
||||
Err(e) => Err(e)?,
|
||||
}
|
||||
}
|
||||
@@ -435,9 +439,11 @@ impl Algorithm {
|
||||
|
||||
let hashed_password = PasswordHash::new(hashed_password)?;
|
||||
|
||||
match Pbkdf2.verify_password(password.as_ref(), &hashed_password) {
|
||||
match Pbkdf2::default().verify_password(password.as_ref(), &hashed_password) {
|
||||
Ok(()) => PasswordVerificationResult::success(),
|
||||
Err(password_hash::Error::Password) => PasswordVerificationResult::failure(),
|
||||
Err(password_hash::Error::PasswordInvalid) => {
|
||||
PasswordVerificationResult::failure()
|
||||
}
|
||||
Err(e) => Err(e)?,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ use mas_storage::{
|
||||
personal::PersonalSessionFilter,
|
||||
};
|
||||
use mas_templates::{AccountInactiveContext, TemplateContext, Templates};
|
||||
use rand::RngCore;
|
||||
use rand::Rng;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
@@ -60,7 +60,7 @@ pub fn render_account_inactive(
|
||||
templates: &Templates,
|
||||
locale: &DataLocale,
|
||||
clock: &impl Clock,
|
||||
rng: impl RngCore,
|
||||
rng: impl Rng,
|
||||
cookie_jar: CookieJar,
|
||||
user: User,
|
||||
action: Option<PostAuthAction>,
|
||||
@@ -93,7 +93,7 @@ pub fn render_account_inactive(
|
||||
pub async fn load_session_or_fallback(
|
||||
cookie_jar: CookieJar,
|
||||
clock: &impl Clock,
|
||||
rng: impl RngCore,
|
||||
rng: impl Rng,
|
||||
templates: &Templates,
|
||||
locale: &DataLocale,
|
||||
action: Option<PostAuthAction>,
|
||||
|
||||
@@ -469,7 +469,7 @@ impl TestState {
|
||||
/// Panics if the RNG is already locked.
|
||||
pub fn rng(&self) -> ChaChaRng {
|
||||
let mut parent_rng = self.rng.try_lock().expect("Failed to lock RNG");
|
||||
ChaChaRng::from_rng(&mut *parent_rng).unwrap()
|
||||
ChaChaRng::from_rng(&mut *parent_rng)
|
||||
}
|
||||
|
||||
/// Do a call to the userinfo endpoint to check if the given token is valid.
|
||||
@@ -546,7 +546,7 @@ impl graphql::State for TestGraphQLState {
|
||||
|
||||
fn rng(&self) -> BoxRng {
|
||||
let mut parent_rng = self.rng.lock().expect("Failed to lock RNG");
|
||||
let rng = ChaChaRng::from_rng(&mut *parent_rng).expect("Failed to seed RNG");
|
||||
let rng = ChaChaRng::from_rng(&mut *parent_rng);
|
||||
Box::new(rng)
|
||||
}
|
||||
}
|
||||
@@ -684,7 +684,7 @@ impl FromRequestParts<TestState> for BoxRng {
|
||||
state: &TestState,
|
||||
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send {
|
||||
let mut parent_rng = state.rng.lock().expect("Failed to lock RNG");
|
||||
let rng = ChaChaRng::from_rng(&mut *parent_rng).expect("Failed to seed RNG");
|
||||
let rng = ChaChaRng::from_rng(&mut *parent_rng);
|
||||
let rng: Self = Box::new(rng);
|
||||
ready(Ok(rng))
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ use mas_templates::{
|
||||
ToFormState,
|
||||
};
|
||||
use opentelemetry::{Key, KeyValue, metrics::Counter};
|
||||
use rand::Rng;
|
||||
use rand::RngExt;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use zeroize::Zeroizing;
|
||||
|
||||
@@ -430,7 +430,7 @@ async fn render(
|
||||
action: OptionalPostAuthAction,
|
||||
repo: &mut impl RepositoryAccess,
|
||||
clock: &impl Clock,
|
||||
rng: impl Rng,
|
||||
rng: impl RngExt,
|
||||
templates: &Templates,
|
||||
homeserver: &dyn HomeserverConnection,
|
||||
site_config: &SiteConfig,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# Copyright 2025, 2026 Element Creations Ltd.
|
||||
# Copyright 2025 New Vector Ltd.
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
@@ -23,7 +24,6 @@ chrono.workspace = true
|
||||
digest.workspace = true
|
||||
ecdsa.workspace = true
|
||||
elliptic-curve.workspace = true
|
||||
generic-array.workspace = true
|
||||
hmac.workspace = true
|
||||
k256.workspace = true
|
||||
p256.workspace = true
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
// Copyright 2022-2024 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
@@ -7,7 +8,7 @@
|
||||
use digest::Digest;
|
||||
use mas_iana::jose::{JsonWebKeyEcEllipticCurve, JsonWebSignatureAlg};
|
||||
use sha2::{Sha256, Sha384, Sha512};
|
||||
use signature::rand_core::CryptoRngCore;
|
||||
use signature::rand_core::TryCryptoRng;
|
||||
use thiserror::Error;
|
||||
|
||||
use super::signature::Signature;
|
||||
@@ -231,9 +232,9 @@ impl From<super::Es256KSigningKey> for AsymmetricSigningKey {
|
||||
}
|
||||
|
||||
impl signature::RandomizedSigner<Signature> for AsymmetricSigningKey {
|
||||
fn try_sign_with_rng(
|
||||
fn try_sign_with_rng<R: TryCryptoRng + ?Sized>(
|
||||
&self,
|
||||
rng: &mut impl CryptoRngCore,
|
||||
rng: &mut R,
|
||||
msg: &[u8],
|
||||
) -> Result<Signature, signature::Error> {
|
||||
match self {
|
||||
|
||||
+17
-16
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
// Copyright 2022-2024 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
@@ -7,32 +8,32 @@
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use digest::{
|
||||
Digest, Mac, OutputSizeUser,
|
||||
crypto_common::BlockSizeUser,
|
||||
generic_array::{ArrayLength, GenericArray},
|
||||
Digest, KeyInit, Mac, OutputSizeUser,
|
||||
array::{Array, ArraySize},
|
||||
block_api::BlockSizeUser,
|
||||
};
|
||||
use signature::{Signer, Verifier};
|
||||
use thiserror::Error;
|
||||
|
||||
pub struct Signature<S: ArrayLength<u8>> {
|
||||
signature: GenericArray<u8, S>,
|
||||
pub struct Signature<S: ArraySize> {
|
||||
signature: Array<u8, S>,
|
||||
}
|
||||
|
||||
impl<S: ArrayLength<u8>> PartialEq for Signature<S> {
|
||||
impl<S: ArraySize> PartialEq for Signature<S> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.signature == other.signature
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: ArrayLength<u8>> Eq for Signature<S> {}
|
||||
impl<S: ArraySize> Eq for Signature<S> {}
|
||||
|
||||
impl<S: ArrayLength<u8>> std::fmt::Debug for Signature<S> {
|
||||
impl<S: ArraySize> std::fmt::Debug for Signature<S> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{:?}", self.signature)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: ArrayLength<u8>> Clone for Signature<S> {
|
||||
impl<S: ArraySize> Clone for Signature<S> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
signature: self.signature.clone(),
|
||||
@@ -40,30 +41,30 @@ impl<S: ArrayLength<u8>> Clone for Signature<S> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: ArrayLength<u8>> From<Signature<S>> for GenericArray<u8, S> {
|
||||
impl<S: ArraySize> From<Signature<S>> for Array<u8, S> {
|
||||
fn from(val: Signature<S>) -> Self {
|
||||
val.signature
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, S: ArrayLength<u8>> TryFrom<&'a [u8]> for Signature<S> {
|
||||
impl<'a, S: ArraySize> TryFrom<&'a [u8]> for Signature<S> {
|
||||
type Error = InvalidLength;
|
||||
|
||||
fn try_from(value: &'a [u8]) -> Result<Self, Self::Error> {
|
||||
if value.len() != S::to_usize() {
|
||||
return Err(InvalidLength);
|
||||
}
|
||||
let mut signature = GenericArray::default();
|
||||
let mut signature = Array::default();
|
||||
signature.copy_from_slice(value);
|
||||
Ok(Self { signature })
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: ArrayLength<u8>> signature::SignatureEncoding for Signature<S> {
|
||||
type Repr = GenericArray<u8, S>;
|
||||
impl<S: ArraySize> signature::SignatureEncoding for Signature<S> {
|
||||
type Repr = Array<u8, S>;
|
||||
}
|
||||
|
||||
impl<S: ArrayLength<u8>> AsRef<[u8]> for Signature<S> {
|
||||
impl<S: ArraySize> AsRef<[u8]> for Signature<S> {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
self.signature.as_ref()
|
||||
}
|
||||
@@ -104,7 +105,7 @@ impl<D: Digest + BlockSizeUser>
|
||||
msg: &[u8],
|
||||
) -> Result<Signature<<hmac::SimpleHmac<D> as OutputSizeUser>::OutputSize>, signature::Error>
|
||||
{
|
||||
let mut mac = <hmac::SimpleHmac<D> as Mac>::new_from_slice(&self.key)
|
||||
let mut mac = <hmac::SimpleHmac<D> as KeyInit>::new_from_slice(&self.key)
|
||||
.map_err(signature::Error::from_source)?;
|
||||
mac.update(msg);
|
||||
let signature = mac.finalize().into_bytes();
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
// Copyright 2022-2024 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
@@ -80,9 +81,9 @@ impl From<super::Hs512Key> for SymmetricKey {
|
||||
}
|
||||
|
||||
impl signature::RandomizedSigner<Signature> for SymmetricKey {
|
||||
fn try_sign_with_rng(
|
||||
fn try_sign_with_rng<R: signature::rand_core::TryCryptoRng + ?Sized>(
|
||||
&self,
|
||||
_rng: &mut (impl rand::CryptoRng + rand::RngCore),
|
||||
_rng: &mut R,
|
||||
msg: &[u8],
|
||||
) -> Result<Signature, signature::Error> {
|
||||
// XXX: is that implementation alright?
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
// Copyright 2022-2024 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
@@ -200,7 +201,7 @@ struct RsaOtherPrimeInfo {
|
||||
}
|
||||
|
||||
mod rsa_impls {
|
||||
use rsa::{BigUint, RsaPrivateKey};
|
||||
use rsa::{BoxedUint, RsaPrivateKey};
|
||||
|
||||
use super::RsaPrivateParameters;
|
||||
|
||||
@@ -215,14 +216,14 @@ mod rsa_impls {
|
||||
type Error = rsa::errors::Error;
|
||||
|
||||
fn try_from(value: &RsaPrivateParameters) -> Result<Self, Self::Error> {
|
||||
let n = BigUint::from_bytes_be(value.n.as_bytes());
|
||||
let e = BigUint::from_bytes_be(value.e.as_bytes());
|
||||
let d = BigUint::from_bytes_be(value.d.as_bytes());
|
||||
let n = BoxedUint::from_be_slice_vartime(value.n.as_bytes());
|
||||
let e = BoxedUint::from_be_slice_vartime(value.e.as_bytes());
|
||||
let d = BoxedUint::from_be_slice_vartime(value.d.as_bytes());
|
||||
|
||||
let primes = [&value.p, &value.q]
|
||||
.into_iter()
|
||||
.chain(value.oth.iter().flatten().map(|o| &o.r))
|
||||
.map(|i| BigUint::from_bytes_be(i.as_bytes()))
|
||||
.map(|i| BoxedUint::from_be_slice_vartime(i.as_bytes()))
|
||||
.collect();
|
||||
|
||||
let key = RsaPrivateKey::from_components(n, e, d, primes)?;
|
||||
@@ -273,7 +274,7 @@ impl From<EcPrivateParameters> for super::public_parameters::EcPublicParameters
|
||||
mod ec_impls {
|
||||
use elliptic_curve::{
|
||||
AffinePoint, Curve, SecretKey,
|
||||
sec1::{Coordinates, FromEncodedPoint, ModulusSize, ToEncodedPoint},
|
||||
sec1::{Coordinates, FromSec1Point, ModulusSize, ToSec1Point},
|
||||
};
|
||||
|
||||
use super::{super::JwkEcCurve, EcPrivateParameters};
|
||||
@@ -303,7 +304,7 @@ mod ec_impls {
|
||||
impl<C> From<SecretKey<C>> for EcPrivateParameters
|
||||
where
|
||||
C: elliptic_curve::CurveArithmetic + JwkEcCurve,
|
||||
AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
|
||||
AffinePoint<C>: FromSec1Point<C> + ToSec1Point<C>,
|
||||
C::FieldBytesSize: ModulusSize,
|
||||
{
|
||||
fn from(key: SecretKey<C>) -> Self {
|
||||
@@ -314,11 +315,11 @@ mod ec_impls {
|
||||
impl<C> From<&SecretKey<C>> for EcPrivateParameters
|
||||
where
|
||||
C: elliptic_curve::CurveArithmetic + JwkEcCurve,
|
||||
AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
|
||||
AffinePoint<C>: FromSec1Point<C> + ToSec1Point<C>,
|
||||
C::FieldBytesSize: ModulusSize,
|
||||
{
|
||||
fn from(key: &SecretKey<C>) -> Self {
|
||||
let point = key.public_key().to_encoded_point(false);
|
||||
let point = key.public_key().to_sec1_point(false);
|
||||
let Coordinates::Uncompressed { x, y } = point.coordinates() else {
|
||||
unreachable!()
|
||||
};
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
// Copyright 2022-2024 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
@@ -176,7 +177,7 @@ impl OkpPublicParameters {
|
||||
}
|
||||
|
||||
mod rsa_impls {
|
||||
use rsa::{BigUint, RsaPublicKey, traits::PublicKeyParts};
|
||||
use rsa::{BoxedUint, RsaPublicKey, traits::PublicKeyParts};
|
||||
|
||||
use super::{JsonWebKeyPublicParameters, RsaPublicParameters};
|
||||
use crate::base64::Base64UrlNoPad;
|
||||
@@ -202,8 +203,8 @@ mod rsa_impls {
|
||||
impl From<&RsaPublicKey> for RsaPublicParameters {
|
||||
fn from(key: &RsaPublicKey) -> Self {
|
||||
Self {
|
||||
n: Base64UrlNoPad::new(key.n().to_bytes_be()),
|
||||
e: Base64UrlNoPad::new(key.e().to_bytes_be()),
|
||||
n: Base64UrlNoPad::new(key.n().to_be_bytes_trimmed_vartime().into_vec()),
|
||||
e: Base64UrlNoPad::new(key.e().to_be_bytes_trimmed_vartime().into_vec()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -218,8 +219,8 @@ mod rsa_impls {
|
||||
impl TryFrom<&RsaPublicParameters> for RsaPublicKey {
|
||||
type Error = rsa::errors::Error;
|
||||
fn try_from(value: &RsaPublicParameters) -> Result<Self, Self::Error> {
|
||||
let n = BigUint::from_bytes_be(value.n.as_bytes());
|
||||
let e = BigUint::from_bytes_be(value.e.as_bytes());
|
||||
let n = BoxedUint::from_be_slice_vartime(value.n.as_bytes());
|
||||
let e = BoxedUint::from_be_slice_vartime(value.e.as_bytes());
|
||||
let key = RsaPublicKey::new(n, e)?;
|
||||
Ok(key)
|
||||
}
|
||||
@@ -228,10 +229,9 @@ mod rsa_impls {
|
||||
|
||||
mod ec_impls {
|
||||
use digest::typenum::Unsigned;
|
||||
use ecdsa::EncodedPoint;
|
||||
use elliptic_curve::{
|
||||
AffinePoint, FieldBytes, PublicKey,
|
||||
sec1::{Coordinates, FromEncodedPoint, ModulusSize, ToEncodedPoint},
|
||||
sec1::{Coordinates, FromSec1Point, ModulusSize, Sec1Point, ToSec1Point},
|
||||
};
|
||||
|
||||
use super::{super::JwkEcCurve, EcPublicParameters, JsonWebKeyPublicParameters};
|
||||
@@ -240,7 +240,7 @@ mod ec_impls {
|
||||
impl<C> TryFrom<&EcPublicParameters> for PublicKey<C>
|
||||
where
|
||||
C: elliptic_curve::CurveArithmetic,
|
||||
AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
|
||||
AffinePoint<C>: FromSec1Point<C> + ToSec1Point<C>,
|
||||
C::FieldBytesSize: ModulusSize + Unsigned,
|
||||
{
|
||||
type Error = elliptic_curve::Error;
|
||||
@@ -256,10 +256,10 @@ mod ec_impls {
|
||||
.get(..C::FieldBytesSize::USIZE)
|
||||
.ok_or(elliptic_curve::Error)?;
|
||||
|
||||
let x = FieldBytes::<C>::from_slice(x);
|
||||
let y = FieldBytes::<C>::from_slice(y);
|
||||
let pubkey = EncodedPoint::<C>::from_affine_coordinates(x, y, false);
|
||||
let pubkey: Option<_> = PublicKey::from_encoded_point(&pubkey).into();
|
||||
let x = FieldBytes::<C>::try_from(x).map_err(|_| elliptic_curve::Error)?;
|
||||
let y = FieldBytes::<C>::try_from(y).map_err(|_| elliptic_curve::Error)?;
|
||||
let pubkey = Sec1Point::<C>::from_affine_coordinates(&x, &y, false);
|
||||
let pubkey: Option<_> = PublicKey::from_sec1_point(&pubkey).into();
|
||||
pubkey.ok_or(elliptic_curve::Error)
|
||||
}
|
||||
}
|
||||
@@ -267,7 +267,7 @@ mod ec_impls {
|
||||
impl<C> From<PublicKey<C>> for JsonWebKeyPublicParameters
|
||||
where
|
||||
C: elliptic_curve::CurveArithmetic + JwkEcCurve,
|
||||
AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
|
||||
AffinePoint<C>: FromSec1Point<C> + ToSec1Point<C>,
|
||||
C::FieldBytesSize: ModulusSize,
|
||||
{
|
||||
fn from(key: PublicKey<C>) -> Self {
|
||||
@@ -278,7 +278,7 @@ mod ec_impls {
|
||||
impl<C> From<&PublicKey<C>> for JsonWebKeyPublicParameters
|
||||
where
|
||||
C: elliptic_curve::CurveArithmetic + JwkEcCurve,
|
||||
AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
|
||||
AffinePoint<C>: FromSec1Point<C> + ToSec1Point<C>,
|
||||
C::FieldBytesSize: ModulusSize,
|
||||
{
|
||||
fn from(key: &PublicKey<C>) -> Self {
|
||||
@@ -289,7 +289,7 @@ mod ec_impls {
|
||||
impl<C> From<PublicKey<C>> for EcPublicParameters
|
||||
where
|
||||
C: elliptic_curve::CurveArithmetic + JwkEcCurve,
|
||||
AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
|
||||
AffinePoint<C>: FromSec1Point<C> + ToSec1Point<C>,
|
||||
C::FieldBytesSize: ModulusSize,
|
||||
{
|
||||
fn from(key: PublicKey<C>) -> Self {
|
||||
@@ -300,11 +300,11 @@ mod ec_impls {
|
||||
impl<C> From<&PublicKey<C>> for EcPublicParameters
|
||||
where
|
||||
C: elliptic_curve::CurveArithmetic + JwkEcCurve,
|
||||
AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
|
||||
AffinePoint<C>: FromSec1Point<C> + ToSec1Point<C>,
|
||||
C::FieldBytesSize: ModulusSize,
|
||||
{
|
||||
fn from(key: &PublicKey<C>) -> Self {
|
||||
let point = key.to_encoded_point(false);
|
||||
let point = key.to_sec1_point(false);
|
||||
let Coordinates::Uncompressed { x, y } = point.coordinates() else {
|
||||
unreachable!()
|
||||
};
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
// Copyright 2022-2024 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
@@ -5,9 +6,9 @@
|
||||
// Please see LICENSE files in the repository root for full details.
|
||||
|
||||
use base64ct::{Base64UrlUnpadded, Encoding};
|
||||
use rand::thread_rng;
|
||||
use rand::rng;
|
||||
use serde::{Serialize, de::DeserializeOwned};
|
||||
use signature::{RandomizedSigner, SignatureEncoding, Verifier, rand_core::CryptoRngCore};
|
||||
use signature::{RandomizedSigner, SignatureEncoding, Verifier, rand_core::CryptoRng};
|
||||
use thiserror::Error;
|
||||
|
||||
use super::{header::JsonWebSignatureHeader, raw::RawJwt};
|
||||
@@ -325,7 +326,7 @@ impl<T> Jwt<'static, T> {
|
||||
T: Serialize,
|
||||
{
|
||||
#[expect(clippy::disallowed_methods)]
|
||||
Self::sign_with_rng(&mut thread_rng(), header, payload, key)
|
||||
Self::sign_with_rng(&mut rng(), header, payload, key)
|
||||
}
|
||||
|
||||
/// Sign the given payload with the given key using the given RNG.
|
||||
@@ -341,7 +342,7 @@ impl<T> Jwt<'static, T> {
|
||||
key: &K,
|
||||
) -> Result<Self, JwtSignatureError>
|
||||
where
|
||||
R: CryptoRngCore,
|
||||
R: CryptoRng,
|
||||
K: RandomizedSigner<S>,
|
||||
S: SignatureEncoding,
|
||||
T: Serialize,
|
||||
@@ -378,7 +379,7 @@ impl<T> Jwt<'static, T> {
|
||||
mod tests {
|
||||
#![allow(clippy::disallowed_methods)]
|
||||
use mas_iana::jose::JsonWebSignatureAlg;
|
||||
use rand::thread_rng;
|
||||
use rand::rng;
|
||||
|
||||
use super::*;
|
||||
|
||||
@@ -406,7 +407,10 @@ mod tests {
|
||||
let header = JsonWebSignatureHeader::new(JsonWebSignatureAlg::Es256);
|
||||
let payload = serde_json::json!({"hello": "world"});
|
||||
|
||||
let key = ecdsa::SigningKey::<p256::NistP256>::random(&mut thread_rng());
|
||||
let key =
|
||||
<ecdsa::SigningKey<p256::NistP256> as elliptic_curve::Generate>::generate_from_rng(
|
||||
&mut rng(),
|
||||
);
|
||||
let signed = Jwt::sign::<_, ecdsa::Signature<_>>(header, payload, &key).unwrap();
|
||||
signed
|
||||
.verify::<_, ecdsa::Signature<_>>(key.verifying_key())
|
||||
|
||||
+39
-39
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
// Copyright 2022-2024 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
@@ -8,19 +9,18 @@
|
||||
|
||||
use std::{ops::Deref, sync::Arc};
|
||||
|
||||
use der::{Decode, Encode, EncodePem, zeroize::Zeroizing};
|
||||
use elliptic_curve::{pkcs8::EncodePrivateKey, sec1::ToEncodedPoint};
|
||||
use der::{Decode, Encode, EncodePem, pem::PemLabel, zeroize::Zeroizing};
|
||||
use elliptic_curve::{Generate, pkcs8::EncodePrivateKey, sec1::ToSec1Point};
|
||||
use mas_iana::jose::{JsonWebKeyType, JsonWebSignatureAlg};
|
||||
pub use mas_jose::jwk::{JsonWebKey, JsonWebKeySet};
|
||||
use mas_jose::{
|
||||
jwa::{AsymmetricSigningKey, AsymmetricVerifyingKey},
|
||||
jwk::{JsonWebKeyPublicParameters, ParametersInfo, PublicJsonWebKeySet, Thumbprint},
|
||||
};
|
||||
use pem_rfc7468::PemLabel;
|
||||
use pkcs1::EncodeRsaPrivateKey;
|
||||
use pkcs8::{AssociatedOid, PrivateKeyInfo};
|
||||
use rand::{CryptoRng, RngCore};
|
||||
use rsa::BigUint;
|
||||
use pkcs8::{AssociatedOid, PrivateKeyInfoRef};
|
||||
use rand::CryptoRng;
|
||||
use rsa::BoxedUint;
|
||||
use thiserror::Error;
|
||||
|
||||
mod encrypter;
|
||||
@@ -133,7 +133,7 @@ pub enum PrivateKey {
|
||||
pub struct WrongAlgorithmError;
|
||||
|
||||
impl PrivateKey {
|
||||
fn from_pkcs1_private_key(pkcs1_key: &pkcs1::RsaPrivateKey) -> Result<Self, LoadError> {
|
||||
fn from_pkcs1_private_key(pkcs1_key: &pkcs1::RsaPrivateKeyRef<'_>) -> Result<Self, LoadError> {
|
||||
// Taken from `TryFrom<pkcs8::PrivateKeyInfo<'_>> for RsaPrivateKey`
|
||||
|
||||
// Multi-prime RSA keys not currently supported
|
||||
@@ -141,17 +141,17 @@ impl PrivateKey {
|
||||
return Err(pkcs1::Error::Version.into());
|
||||
}
|
||||
|
||||
let n = BigUint::from_bytes_be(pkcs1_key.modulus.as_bytes());
|
||||
let e = BigUint::from_bytes_be(pkcs1_key.public_exponent.as_bytes());
|
||||
let d = BigUint::from_bytes_be(pkcs1_key.private_exponent.as_bytes());
|
||||
let first_prime = BigUint::from_bytes_be(pkcs1_key.prime1.as_bytes());
|
||||
let second_prime = BigUint::from_bytes_be(pkcs1_key.prime2.as_bytes());
|
||||
let n = BoxedUint::from_be_slice_vartime(pkcs1_key.modulus.as_bytes());
|
||||
let e = BoxedUint::from_be_slice_vartime(pkcs1_key.public_exponent.as_bytes());
|
||||
let d = BoxedUint::from_be_slice_vartime(pkcs1_key.private_exponent.as_bytes());
|
||||
let first_prime = BoxedUint::from_be_slice_vartime(pkcs1_key.prime1.as_bytes());
|
||||
let second_prime = BoxedUint::from_be_slice_vartime(pkcs1_key.prime2.as_bytes());
|
||||
let primes = vec![first_prime, second_prime];
|
||||
let key = rsa::RsaPrivateKey::from_components(n, e, d, primes)?;
|
||||
Ok(Self::Rsa(Box::new(key)))
|
||||
}
|
||||
|
||||
fn from_private_key_info(info: PrivateKeyInfo) -> Result<Self, LoadError> {
|
||||
fn from_private_key_info(info: PrivateKeyInfoRef<'_>) -> Result<Self, LoadError> {
|
||||
match info.algorithm.oid {
|
||||
pkcs1::ALGORITHM_OID => Ok(Self::Rsa(Box::new(info.try_into()?))),
|
||||
elliptic_curve::ALGORITHM_OID => match info.algorithm.parameters_oid()? {
|
||||
@@ -287,16 +287,16 @@ impl PrivateKey {
|
||||
/// - the key could not be decrypted
|
||||
/// - the PKCS8 key could not be loaded
|
||||
pub fn load_encrypted_der(der: &[u8], password: impl AsRef<[u8]>) -> Result<Self, LoadError> {
|
||||
if let Ok(info) = pkcs8::EncryptedPrivateKeyInfo::from_der(der) {
|
||||
if let Ok(info) = pkcs8::EncryptedPrivateKeyInfoRef::from_der(der) {
|
||||
let decrypted = info.decrypt(password)?;
|
||||
return Self::load_der(decrypted.as_bytes()).map_err(|inner| LoadError::InEncrypted {
|
||||
inner: Box::new(inner),
|
||||
});
|
||||
}
|
||||
|
||||
if pkcs8::PrivateKeyInfo::from_der(der).is_ok()
|
||||
if pkcs8::PrivateKeyInfoRef::from_der(der).is_ok()
|
||||
|| sec1::EcPrivateKey::from_der(der).is_ok()
|
||||
|| pkcs1::RsaPrivateKey::from_der(der).is_ok()
|
||||
|| pkcs1::RsaPrivateKeyRef::from_der(der).is_ok()
|
||||
{
|
||||
return Err(LoadError::Unencrypted);
|
||||
}
|
||||
@@ -317,11 +317,11 @@ impl PrivateKey {
|
||||
/// - the PKCS8/SEC1/PKCS1 key could not be loaded
|
||||
pub fn load_der(der: &[u8]) -> Result<Self, LoadError> {
|
||||
// Let's try evey known DER format one after the other
|
||||
if pkcs8::EncryptedPrivateKeyInfo::from_der(der).is_ok() {
|
||||
if pkcs8::EncryptedPrivateKeyInfoRef::from_der(der).is_ok() {
|
||||
return Err(LoadError::Encrypted);
|
||||
}
|
||||
|
||||
if let Ok(info) = pkcs8::PrivateKeyInfo::from_der(der) {
|
||||
if let Ok(info) = pkcs8::PrivateKeyInfoRef::from_der(der) {
|
||||
return Self::from_private_key_info(info);
|
||||
}
|
||||
|
||||
@@ -329,7 +329,7 @@ impl PrivateKey {
|
||||
return Self::from_ec_private_key(info);
|
||||
}
|
||||
|
||||
if let Ok(pkcs1_key) = pkcs1::RsaPrivateKey::from_der(der) {
|
||||
if let Ok(pkcs1_key) = pkcs1::RsaPrivateKeyRef::from_der(der) {
|
||||
return Self::from_pkcs1_private_key(&pkcs1_key);
|
||||
}
|
||||
|
||||
@@ -351,16 +351,16 @@ impl PrivateKey {
|
||||
let (label, doc) = pem_rfc7468::decode_vec(pem.as_bytes())?;
|
||||
|
||||
match label {
|
||||
pkcs8::EncryptedPrivateKeyInfo::PEM_LABEL => {
|
||||
let info = pkcs8::EncryptedPrivateKeyInfo::from_der(&doc)?;
|
||||
pkcs8::EncryptedPrivateKeyInfoRef::PEM_LABEL => {
|
||||
let info = pkcs8::EncryptedPrivateKeyInfoRef::from_der(&doc)?;
|
||||
let decrypted = info.decrypt(password)?;
|
||||
Self::load_der(decrypted.as_bytes()).map_err(|inner| LoadError::InEncrypted {
|
||||
inner: Box::new(inner),
|
||||
})
|
||||
}
|
||||
|
||||
pkcs1::RsaPrivateKey::PEM_LABEL
|
||||
| pkcs8::PrivateKeyInfo::PEM_LABEL
|
||||
pkcs1::RsaPrivateKeyRef::PEM_LABEL
|
||||
| pkcs8::PrivateKeyInfoRef::PEM_LABEL
|
||||
| sec1::EcPrivateKey::PEM_LABEL => Err(LoadError::Unencrypted),
|
||||
|
||||
label => Err(LoadError::UnsupportedPemLabel {
|
||||
@@ -383,13 +383,13 @@ impl PrivateKey {
|
||||
let (label, doc) = pem_rfc7468::decode_vec(pem.as_bytes())?;
|
||||
|
||||
match label {
|
||||
pkcs1::RsaPrivateKey::PEM_LABEL => {
|
||||
let pkcs1_key = pkcs1::RsaPrivateKey::from_der(&doc)?;
|
||||
pkcs1::RsaPrivateKeyRef::PEM_LABEL => {
|
||||
let pkcs1_key = pkcs1::RsaPrivateKeyRef::from_der(&doc)?;
|
||||
Self::from_pkcs1_private_key(&pkcs1_key)
|
||||
}
|
||||
|
||||
pkcs8::PrivateKeyInfo::PEM_LABEL => {
|
||||
let info = pkcs8::PrivateKeyInfo::from_der(&doc)?;
|
||||
pkcs8::PrivateKeyInfoRef::PEM_LABEL => {
|
||||
let info = pkcs8::PrivateKeyInfoRef::from_der(&doc)?;
|
||||
Self::from_private_key_info(info)
|
||||
}
|
||||
|
||||
@@ -398,7 +398,7 @@ impl PrivateKey {
|
||||
Self::from_ec_private_key(key)
|
||||
}
|
||||
|
||||
pkcs8::EncryptedPrivateKeyInfo::PEM_LABEL => Err(LoadError::Encrypted),
|
||||
pkcs8::EncryptedPrivateKeyInfoRef::PEM_LABEL => Err(LoadError::Encrypted),
|
||||
|
||||
label => Err(LoadError::UnsupportedPemLabel {
|
||||
label: label.to_owned(),
|
||||
@@ -495,26 +495,26 @@ impl PrivateKey {
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns any error from the underlying key generator
|
||||
pub fn generate_rsa<R: RngCore + CryptoRng>(mut rng: R) -> Result<Self, rsa::errors::Error> {
|
||||
pub fn generate_rsa<R: CryptoRng>(mut rng: R) -> Result<Self, rsa::errors::Error> {
|
||||
let key = rsa::RsaPrivateKey::new(&mut rng, 2048)?;
|
||||
Ok(Self::Rsa(Box::new(key)))
|
||||
}
|
||||
|
||||
/// Generate an Elliptic Curve key for the P-256 curve
|
||||
pub fn generate_ec_p256<R: RngCore + CryptoRng>(mut rng: R) -> Self {
|
||||
let key = elliptic_curve::SecretKey::random(&mut rng);
|
||||
pub fn generate_ec_p256<R: CryptoRng>(mut rng: R) -> Self {
|
||||
let key = elliptic_curve::SecretKey::generate_from_rng(&mut rng);
|
||||
Self::EcP256(Box::new(key))
|
||||
}
|
||||
|
||||
/// Generate an Elliptic Curve key for the P-384 curve
|
||||
pub fn generate_ec_p384<R: RngCore + CryptoRng>(mut rng: R) -> Self {
|
||||
let key = elliptic_curve::SecretKey::random(&mut rng);
|
||||
pub fn generate_ec_p384<R: CryptoRng>(mut rng: R) -> Self {
|
||||
let key = elliptic_curve::SecretKey::generate_from_rng(&mut rng);
|
||||
Self::EcP384(Box::new(key))
|
||||
}
|
||||
|
||||
/// Generate an Elliptic Curve key for the secp256k1 curve
|
||||
pub fn generate_ec_k256<R: RngCore + CryptoRng>(mut rng: R) -> Self {
|
||||
let key = elliptic_curve::SecretKey::random(&mut rng);
|
||||
pub fn generate_ec_k256<R: CryptoRng>(mut rng: R) -> Self {
|
||||
let key = elliptic_curve::SecretKey::generate_from_rng(&mut rng);
|
||||
Self::EcK256(Box::new(key))
|
||||
}
|
||||
}
|
||||
@@ -525,11 +525,11 @@ impl PrivateKey {
|
||||
fn to_sec1_der<C>(key: &elliptic_curve::SecretKey<C>) -> Result<Zeroizing<Vec<u8>>, der::Error>
|
||||
where
|
||||
C: elliptic_curve::Curve + elliptic_curve::CurveArithmetic + AssociatedOid,
|
||||
elliptic_curve::PublicKey<C>: elliptic_curve::sec1::ToEncodedPoint<C>,
|
||||
elliptic_curve::PublicKey<C>: elliptic_curve::sec1::ToSec1Point<C>,
|
||||
C::FieldBytesSize: elliptic_curve::sec1::ModulusSize,
|
||||
{
|
||||
let private_key_bytes = Zeroizing::new(key.to_bytes());
|
||||
let public_key_bytes = key.public_key().to_encoded_point(false);
|
||||
let public_key_bytes = key.public_key().to_sec1_point(false);
|
||||
Ok(Zeroizing::new(
|
||||
sec1::EcPrivateKey {
|
||||
private_key: &private_key_bytes,
|
||||
@@ -546,11 +546,11 @@ fn to_sec1_pem<C>(
|
||||
) -> Result<Zeroizing<String>, der::Error>
|
||||
where
|
||||
C: elliptic_curve::Curve + elliptic_curve::CurveArithmetic + AssociatedOid,
|
||||
elliptic_curve::PublicKey<C>: elliptic_curve::sec1::ToEncodedPoint<C>,
|
||||
elliptic_curve::PublicKey<C>: elliptic_curve::sec1::ToSec1Point<C>,
|
||||
C::FieldBytesSize: elliptic_curve::sec1::ModulusSize,
|
||||
{
|
||||
let private_key_bytes = Zeroizing::new(key.to_bytes());
|
||||
let public_key_bytes = key.public_key().to_encoded_point(false);
|
||||
let public_key_bytes = key.public_key().to_sec1_point(false);
|
||||
Ok(Zeroizing::new(
|
||||
sec1::EcPrivateKey {
|
||||
private_key: &private_key_bytes,
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
---
|
||||
source: crates/keystore/tests/keystore.rs
|
||||
expression: "ec_p256.to_pem(LineEnding::LF).unwrap()"
|
||||
expression: "&*ec_p256.to_pem(LineEnding::LF).unwrap()"
|
||||
---
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIH3L+ZYgfEaJtclP07qPQBrmkHEhYkyYooxvU8AlSW+CoAoGCCqGSM49
|
||||
AwEHoUQDQgAEXcA+X+lhDCmmzaUQFh7i7gkT7mwdrRUsMl9RSfyWh93n+xq3O4/m
|
||||
vMmUnlvy7tBoHkcAdTJ+Zkv+loLw+mkcBA==
|
||||
MHcCAQEEILI2J4kLaLQCw/EUtQupK0g4Hd5K2rpL7DPf8JxJR8sXoAoGCCqGSM49
|
||||
AwEHoUQDQgAExoXwK0I+5KIXMQcact2A5BTX8T8UDH5zHCBL7hKxO6y69kAn2NIP
|
||||
9VZgChemq1baX+/4eZMgYbsFjjZxCepjFw==
|
||||
-----END EC PRIVATE KEY-----
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
---
|
||||
source: crates/keystore/tests/keystore.rs
|
||||
expression: "ec_p384.to_pem(LineEnding::LF).unwrap()"
|
||||
expression: "&*ec_p384.to_pem(LineEnding::LF).unwrap()"
|
||||
---
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MIGkAgEBBDAl3R97SR8hWLuMH6737YdvXVb7P7T9pKSIhQozmzN+r+V5Ncvjn+DQ
|
||||
Q/QxYr9nLwOgBwYFK4EEACKhZANiAASa86XQW7CDF9GhvcBY53sJ4lP0z9rfrjwo
|
||||
nwixQJIWBROjlpsm5hdIwLfj46IUPYCNEoD8VP8eR2s/uzlgEv1hnz/2wmLlMqU0
|
||||
2R5QcY7Gc9CyDTO1bh5V2FFYjks4xfs=
|
||||
MIGkAgEBBDDSnZxO7HGescWZ8Lx5EnOSp/ep8AeJi5Phq3DGbqshMxDMIE89tQz5
|
||||
bKFDIry98DCgBwYFK4EEACKhZANiAAQvXEB4cXKh8IOp3H7DGeBEMl7tpkROyGqh
|
||||
bcdbCIZ55BookRp7GpfUldNOW/z/iLs5m8as3P6h+2GtvmxitErGxLe+ziBh4MCH
|
||||
/FiUkahhEaRkZN3wZax5cquzSESgYns=
|
||||
-----END EC PRIVATE KEY-----
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
---
|
||||
source: crates/keystore/tests/keystore.rs
|
||||
expression: "ec_k256.to_pem(LineEnding::LF).unwrap()"
|
||||
expression: "&*ec_k256.to_pem(LineEnding::LF).unwrap()"
|
||||
---
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHQCAQEEIBcikq9QkV39T8VFZWD4j5wO9xm0FWxhuAmvDRpix8XUoAcGBSuBBAAK
|
||||
oUQDQgAEf4htTtPsdxlZn1htWE3ueHT4JB/4n4lxVOQdT/3RFuCS5aKQ04oS9pKM
|
||||
QAHAn1bjbLRQ88Yxi3CgHuCitS+RrA==
|
||||
MHQCAQEEILWCa5ChwVAT7+XP9fGxVPzVBEE9SiFmzQrUYujA+qxPoAcGBSuBBAAK
|
||||
oUQDQgAEljNWxpBfmKyeamlQsZHUq7Npp3a7NwI4tVTtZi10UvZSccc8LeOoJoFW
|
||||
KneiunxfPzfWhQQH/ChWKtAAyrdm5Q==
|
||||
-----END EC PRIVATE KEY-----
|
||||
|
||||
@@ -4,18 +4,17 @@ expression: jwks
|
||||
---
|
||||
keys:
|
||||
- kty: RSA
|
||||
n: vClyfM076hWBZonjThx_PX46UQUWb2LfOpUV1655ZGoKMKgqanLMMfLBPjW9ouY6UtrZ7BxEgl01xLZ1dLdD2Ggb2IpwW56PUuZD2w9hJMungjR0ImymFBwjA9j2ucr0eIHdVQoOakEsrB0dqEC-3R7ax7piGCj9YB6uGZbDVfIJUv40o1pb-hvmmyQHwpoU4jR1y_V-OhrdFMPtwCXov2nlrqDb_e-T7TQlu4FN0URI6VxLNcSkgZfJH50PdJPr7AHqtnWhOGBfLaC9jDpGxfbjmC1iSMSzOt6WyVdcnqHv_JpzXu0SzFqpUSm3OI_l2DUjwTJBL1TOIRTVsjQN1w
|
||||
n: yiR2hY43e0aMz4lhaQvnyjlbVhudk6KexRnJ35Cz5X_yifzlr2Ui006UOKoWPJoUCFrwOXC-rGnPlzqYDtjOLKWWvMdNUyIwfGoovRxqRrcoAHKl76Iuq9DFFSksI_aFmpwltVZaUbrsg6q8ptQ_E9uZfb7lTNoFBhjA3VUPhlWAQEvBpo78YlB8rD8z-OqAN92JeYM841c1r4W3-U9H7g9WuBO2FMedA0Zl1k2MEz50NcGUUe8YB1GcV8IsP2RiTKd8PwsjlM37xQ2j_l4MuU0zxXfWw35ukSjpQaOJcyU9FTLj6f-reLH0gpVCq8N4qRNQsbEhDxaJNE-VnDYMew
|
||||
e: AQAB
|
||||
- kty: EC
|
||||
crv: P-256
|
||||
x: XcA-X-lhDCmmzaUQFh7i7gkT7mwdrRUsMl9RSfyWh90
|
||||
y: 5_satzuP5rzJlJ5b8u7QaB5HAHUyfmZL_paC8PppHAQ
|
||||
x: xoXwK0I-5KIXMQcact2A5BTX8T8UDH5zHCBL7hKxO6w
|
||||
y: uvZAJ9jSD_VWYAoXpqtW2l_v-HmTIGG7BY42cQnqYxc
|
||||
- kty: EC
|
||||
crv: P-384
|
||||
x: mvOl0FuwgxfRob3AWOd7CeJT9M_a3648KJ8IsUCSFgUTo5abJuYXSMC34-OiFD2A
|
||||
y: jRKA_FT_HkdrP7s5YBL9YZ8_9sJi5TKlNNkeUHGOxnPQsg0ztW4eVdhRWI5LOMX7
|
||||
x: L1xAeHFyofCDqdx-wxngRDJe7aZETshqoW3HWwiGeeQaKJEaexqX1JXTTlv8_4i7
|
||||
y: OZvGrNz-ofthrb5sYrRKxsS3vs4gYeDAh_xYlJGoYRGkZGTd8GWseXKrs0hEoGJ7
|
||||
- kty: EC
|
||||
crv: secp256k1
|
||||
x: f4htTtPsdxlZn1htWE3ueHT4JB_4n4lxVOQdT_3RFuA
|
||||
y: kuWikNOKEvaSjEABwJ9W42y0UPPGMYtwoB7gorUvkaw
|
||||
|
||||
x: ljNWxpBfmKyeamlQsZHUq7Npp3a7NwI4tVTtZi10UvY
|
||||
y: UnHHPC3jqCaBVip3orp8Xz831oUEB_woVirQAMq3ZuU
|
||||
@@ -1,32 +1,31 @@
|
||||
---
|
||||
source: crates/keystore/tests/keystore.rs
|
||||
expression: "rsa.to_pem(LineEnding::LF).unwrap()"
|
||||
expression: "&*rsa.to_pem(LineEnding::LF).unwrap()"
|
||||
---
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAvClyfM076hWBZonjThx/PX46UQUWb2LfOpUV1655ZGoKMKgq
|
||||
anLMMfLBPjW9ouY6UtrZ7BxEgl01xLZ1dLdD2Ggb2IpwW56PUuZD2w9hJMungjR0
|
||||
ImymFBwjA9j2ucr0eIHdVQoOakEsrB0dqEC+3R7ax7piGCj9YB6uGZbDVfIJUv40
|
||||
o1pb+hvmmyQHwpoU4jR1y/V+OhrdFMPtwCXov2nlrqDb/e+T7TQlu4FN0URI6VxL
|
||||
NcSkgZfJH50PdJPr7AHqtnWhOGBfLaC9jDpGxfbjmC1iSMSzOt6WyVdcnqHv/Jpz
|
||||
Xu0SzFqpUSm3OI/l2DUjwTJBL1TOIRTVsjQN1wIDAQABAoIBAD4bcC7Bj4U0lAHE
|
||||
gcLGpTkm8RjNFRqvB//ONed7L5Z1aeelmlqIid3ywtZF5tJeK+ItWsEUk4h0O8sy
|
||||
bpKX600DEC3phCy5qZUzbDJiYS5ECoZvyeWS9z6sCuK6OrYYx5j/RI9NQnTQDm7B
|
||||
LYjb1iQmixBh9P8EiJ2xgsXvfYpgSDv2nUBVywp8HUmadAqE89cBsyurvMpR6eY4
|
||||
HI0Wge+vIbh0KHj5h7sJ7C8mWBcnjkJ9hWSCumMth3wufEpfs4lCUjhojTkr6ioT
|
||||
9Mok8VpZvsxzDw3Ubnut1lX7II2EYwNEfgm/Tcw4/NC2eLc1AjoshxLVLg5JWy85
|
||||
RGj7FAECgYEAyLTpdQjD0PrQBi6O5HWQnVMVvJQz6bihdKUrjwJOfWvqgKVpAVVQ
|
||||
IbLUT3J6ooe4Tei6xc7viNA7JZ+KyRvaQuZT4nWW2AkOCOnaxH3NKI4cDpWsdNdC
|
||||
jNBHnIUUvDU4c4CkgIc8f1Gezm9epDVsgb1+wxwSbB8Je4S7M8is1WUCgYEA7//M
|
||||
f1UPl32yaXH7ag8DbWHMzeNRw5T+F3zTagp93mCM0mPYyjggMfwPFr7167ISWrG4
|
||||
6DfHHABqhjnAkKfrrFMN5Xm8oup60XXIox1FB4Ew4K0VzyMTnSMPMMEGJZx6VQJP
|
||||
TlGpexs4t+1N/gWgcGv1OgZ+fw7hjcaFtTMAcIsCgYBY/W3tyF8aT7rgotAUl9Px
|
||||
DZ+7p3KFFKnx0DJKDFnE3o5xT+YJA0yuRF5Cg53AZrDfSmtVvXUTklBHVD/y/3h8
|
||||
5ScYZ87kJs+kQBwRtz2515i1FsQKYk9NpCO8UH1rHaXUAJvvqQa35PamzVaHNHDR
|
||||
7bVAyTeZ3QEVVTqzsSyAyQKBgQDDIcL+QIW10VBPJYqZ9+z8cUkYmVuwXqKdLDOk
|
||||
gzVFqlC0+tOXzzx2B4+pGchPQ3Bi5x8FR9yOqtPxoGEt/CnE6Z5h1rIF8Am95jsk
|
||||
TDcE3AiGlJQn30giOhAuvrIlwG1CUudyMTlQS5i5Cquf/qks3sn6zK7q1YmUQTYT
|
||||
Vo1j8wKBgQCgSISkWgRrQhEdZKBBzcxkWyUXUMieZa+pPTooZGY1VAqyTSXHUlLi
|
||||
mrWtJ4temNK6OE7xAWJMWL6cVAxQUrs8C11DS//IGMxlMF/7uMU6pOFmMqq52G3D
|
||||
k3NkZSJmC1liFiu3Q6Q2UqGHRX8CS5MeLncReuNUnFOiX8X2fcjoRw==
|
||||
MIIEpQIBAAKCAQEAyiR2hY43e0aMz4lhaQvnyjlbVhudk6KexRnJ35Cz5X/yifzl
|
||||
r2Ui006UOKoWPJoUCFrwOXC+rGnPlzqYDtjOLKWWvMdNUyIwfGoovRxqRrcoAHKl
|
||||
76Iuq9DFFSksI/aFmpwltVZaUbrsg6q8ptQ/E9uZfb7lTNoFBhjA3VUPhlWAQEvB
|
||||
po78YlB8rD8z+OqAN92JeYM841c1r4W3+U9H7g9WuBO2FMedA0Zl1k2MEz50NcGU
|
||||
Ue8YB1GcV8IsP2RiTKd8PwsjlM37xQ2j/l4MuU0zxXfWw35ukSjpQaOJcyU9FTLj
|
||||
6f+reLH0gpVCq8N4qRNQsbEhDxaJNE+VnDYMewIDAQABAoIBACC/QXgnbvOInV0t
|
||||
u1siM52+Jv7PIHr/WEtD/0E5lvsx/B/AmZENiFPFIhv/6fRNXbtwyAP2MN2LkrbE
|
||||
JkgZdWUkOkRA4VT7b/Fn3Uuto8Xq/A7+g8VLd9YbzyG7dsworsI6U52J7L3a02AN
|
||||
M9yu+70C0V3epBUMKM4xCmWQ1yACxim7NHzMa9tFzYPzZjQ7icDoY2Ku+Yh60HOc
|
||||
HudGcw3T4QM4XYT4rubUnVA8iUWlFmqhSqJoaNXo5hZ4a5kmZJndTj9PsgZrweG/
|
||||
nksx7HVrljwOEUhFAr5TeOxwzIPiOaFPrKMHz7gux6S1hg5av/EgZFHWcG69bSsp
|
||||
Oqk0ockCgYEA7dviO07nt6S6komg5ScXqpfNcY7FmANN9P1Qc5XHQC3m3JKbYOhb
|
||||
o4HCBveJVgYoPRPsg9NLMZjFcI9ioM4MAM3Kmw0qEiiETtu/AVCHExQmY7RbpF2C
|
||||
nknhSdi8tkKwoJqy+VgWZ1JtcbcIxbZTjPNFP8YleZGIrpC/tTldXS0CgYEA2Y86
|
||||
Ct0FRDesm/5Igz+jF66fjeuyVIWnrAijA4qVsanCaeqaVljOvdb7jdgv+xFxQwa8
|
||||
tGSfPZcJ2CDaXvdKBBQSYdGmAk1Csx7AhEcqGTlSB8AunEqVxSeRIo77TB63E45c
|
||||
YETiww1xrWnwMrIk/yv4nQ4arobjk0z3Gv4ZKUcCgYEAkiItc9Keei0ykyULPL4v
|
||||
xBdPmRzmOOaO1p1q+BhlOgD5fTp1S6x14Jav5ifesINH5X6AKN1/rRD2/JibN8Bf
|
||||
j37fozMLTeymnOxVBTG8SvRuQYNlai4pOaaaSwxlpHSEn6drndWIriHuK5cQRKgn
|
||||
3Mj5Gp1aGL5ZAybbITQFMGECgYEAsIq+IeSainHXOrqMoxy3vtbwGJ1Dl7zhhAN6
|
||||
LLx/nqzP210JornsAjb66G6e+NB9pVNJO+VPJw5yaZS3P0rSIB8dj40tdj61ul5h
|
||||
ALYy3kcaXrm/2QnZISRrbKy0FV/zVgY2xdQAYyF8tqj5xlmzFfHbi67PTgKdl4Fk
|
||||
H95EEq8CgYEAtnRVj6QTwewhyrohk7Um4hNDTztWsl/fp5nXLt6oMpdTpSNcZ8mN
|
||||
BL9tkexGnVkFUFuLDFih5lR3vfWybgW5SYeqtPTN6H1WILg4/+hzz9Q7rocsD8IS
|
||||
fvPh2AABTi/IG3o5LYYIhc2i6D+dgOIJIz9mSq8tEG19umGOcQrfC2w=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
source: crates/keystore/tests/keystore.rs
|
||||
expression: token.as_str()
|
||||
---
|
||||
eyJhbGciOiJFUzI1NiJ9.IiI.Yvudbc_oPln_H02H9woFZurQrgzsuWGnRK2kZzat_rp2HYFZtYobvMw9LqPDgeqq9a1HiL_Hx796SqyobiTXJg
|
||||
eyJhbGciOiJFUzI1NiJ9.IiI.1bCvHBi8U9PPx2AeivKsulmaWl3lBebZLkOmsDuEfgg-xDk70BiFMVYa_K3cB6eLJ4YevF8699mOPvoJTZHvxg
|
||||
@@ -2,4 +2,4 @@
|
||||
source: crates/keystore/tests/keystore.rs
|
||||
expression: token.as_str()
|
||||
---
|
||||
eyJhbGciOiJFUzI1NksifQ.IiI.4q4ua7R-we5m58rKtLQDHJmQJb15dEUhj7A_H5kh591mrScXFmCYXVQI5iKKXGFHBV_AFISrJF4YjWCHDnLPeQ
|
||||
eyJhbGciOiJFUzI1NksifQ.IiI.OZ2SAGjxchqzA-QlD5Ejp-Vbt4WFPvWX7x9mkeeuu6c6I1xFTyXZrk7MKp7DdQX4pxb_swhlhzU4DEDLgRrBLw
|
||||
@@ -2,4 +2,4 @@
|
||||
source: crates/keystore/tests/keystore.rs
|
||||
expression: token.as_str()
|
||||
---
|
||||
eyJhbGciOiJFUzM4NCJ9.IiI.p9Otttjs3JOxZCeuIKwkql3YM-nfdxo__EVt84sex_PcokYjY47sa0qsvCqUUhpUoLSBihdchynuYqc5lOFuAM3Pi2pjg-ZrTqrzI23UlzFonlr4Zag9Qo3IYD10HKFq
|
||||
eyJhbGciOiJFUzM4NCJ9.IiI.Yve7Rrfz6HK76aL_gQB8CchNTfj4IJw9hPxbQxjceOeOufe6ikY_1ZwndJaaP3Rh3DI6BwzazcTxrh7Y0l42O4WrFRg86QA1xi83jY_SFup20h933Xdy2Cox0LuzR4kU
|
||||
@@ -2,4 +2,4 @@
|
||||
source: crates/keystore/tests/keystore.rs
|
||||
expression: token.as_str()
|
||||
---
|
||||
eyJhbGciOiJQUzI1NiJ9.IiI.HlJaOfS2PMi4mWzE8-0EgXt06-MeqzaLRy_04gs4HTS7FugbSJ0rJiwUwhss6O1KWT9TvDqo6AQBO_2hV1DKDiBIIh5Z6M92uC4MJNVLbAVQo6dSBt2DfSzioBI5MoDOBvgbIwSZAIFMqKTbYDa9rQ3XRAaClpqrIN-ACa3gz99ds5mYvUyiYsL5uuEBuWrp8DRk6WKjduhpOi4sMvylZbnfop1uHbvg6_dk5lzXt-1MKIW1QJW_63cFn7vdap5T9U4DBsEkCzYtuwgU-UCmsC8W07QEfcrJhHIlYoPQPHePKF0A4dVHKrgRmf1ik2p6e-VNw129JMvx0KO6v_JBww
|
||||
eyJhbGciOiJQUzI1NiJ9.IiI.cG5_Q1ghrgjQ8gr8Zv7QJB0c-zK3kcoJ1uCn20BdI-1c8ixqpCHIq4xa-m04E84H5lN8jpWzbEl0XAf1c56n2DBGG8SgK9K5UgwajNEEiOzUXu7pXHq-6flPJ6KXK0NeSDtLFxNEfEzKkgJflMMHOXpBfkYKCvgmQlPHkcVO19id1_Yeq5L-POyeTjxlma2WyUliBzHOx2UXnu7wkj_K0a-sfRXhqV64bN-ywpC90x_enTer1Dur3PHDZnlmw5TGrxkg2Mpm_3gcrYv4SFAEE7QA1R9WFFDQt21c5kr-v9TMDg8LSRTGk7pGcMkgoREsywIoK3qZYzMmYs0mmG1ApA
|
||||
@@ -2,4 +2,4 @@
|
||||
source: crates/keystore/tests/keystore.rs
|
||||
expression: token.as_str()
|
||||
---
|
||||
eyJhbGciOiJQUzM4NCJ9.IiI.AHBo1kZW72IQfs7NvjfrD_WpDa9avLdKyf_rqcCp0mJtGID60cgOG5RDTmI6K7TwzykW6l6LjEuYXDR8hemri6mQrtpQ6rMVTJwqJ6D8M92vH4b2gDBwSwbKz427bGdd_fnqm5K2ntwZGC7pceYg1zbcUQ6NJXs3vqKI6YSKustmm9yA1iMfugFG4eLAPrpfTtLmT1sSWYTYWHVT-6G5q7Bfk7Yu5aHiGDQTo427-Y9YF2fabIuDyCGG48UrBp0ajlm1MHKCBuOvK6NI5Jojd9IWDIf7tvAArsrKVR8QRvDXqqPInJEEZ5x7H1YEEZ5Qrh4XKVhRh9b3O-grDMxMng
|
||||
eyJhbGciOiJQUzM4NCJ9.IiI.rDDCp3s3RQQGM0MVSclGp9Rv4Ngc87cF7z5NY8g-Mp60D_PcRoJ0M1mBmLR_O1s1kheNyyFiQvZY-N1vM2hXPXBLdzCmMjog69W9iWRyzAh4BTFO9DKoYw1ERZXN13UDQ0RdM_TQlDGo_Prk6LOn15E4Xz6uBbaum7YaHN99T5Ilj12OvDQ8bkUqEk9wgMPVWOdP-iEsdpFd2M3poE-VYLV6qIQ9B2jWOq56_wAS2cB-rCMJsL-4Ev_SrZAVjnc73GIvB75Sx5I9NexdGWzJh9wyJWw60J9cl178Ny2jVSHg-m8x2u8do8I0ObO0-27-cbcrVfn10hIjJpSNpNB1hg
|
||||
@@ -2,4 +2,4 @@
|
||||
source: crates/keystore/tests/keystore.rs
|
||||
expression: token.as_str()
|
||||
---
|
||||
eyJhbGciOiJQUzUxMiJ9.IiI.o_-UDhc26qYAstuaFJQUz8OKw3UeMc4N7b3U4qcLM-84dxRdw-wBw1rf94jX71vsrFQ2bEh6J5fc4_VtYgKBb2P6QvoL55c7Gqr-5JBw8BkoiiCzlvKIsi_j41FH5Gb4ZBE5Nf9vZD7DnD9BhYXadxaiksx20oNRKIKQ3oMiJxH1w0c-miCSoIR0jnS1QLlKoHYVb7wnkCiR2SOYQ42Je8B8REVzWm2GrqS2cRWnpi3nHihrapruL_BA161Ip1uH4lUFdZLXeG-R6pAlg1OJ_QXSZlP16nzT6MAW_-IFXfioR1QKT8AFNBodY8zlQCGglMyppZi5Y9i7YaMxFgnM4A
|
||||
eyJhbGciOiJQUzUxMiJ9.IiI.H-pMk9Ig2jCvM2eJnmclfN4V4fwQZO8kQKilXfNxJC2R-q1QbRv0iK6OU5uJk6zO03jc9s86GwHg_hkoT68oszC--ca83hSOQ3KAzF5YukrRuQbskbz3SZAvdjXNAd29JlGAAGc0tl86ghBrNkLLkhEDKAlHGMZqZXSUmAMecCgpu9IN6vXOdaqDOdyYR7BRmEm8sSnAvYVwxDCSdSYq7Yn0Dc3c5SlzjgF0UEEihy9dGmBVDVcMC3II9DOdSBghEyokjWXVSr423nosOd_XWO_TqcTjLo4evdwmNIhgyj1KtQ8YQfrMLisxk8570NSQSEzzRRk1st9zOS3zPlbY2A
|
||||
@@ -2,4 +2,4 @@
|
||||
source: crates/keystore/tests/keystore.rs
|
||||
expression: token.as_str()
|
||||
---
|
||||
eyJhbGciOiJSUzI1NiJ9.IiI.H_iz_ry505dPMNxQIi4raU88i3wu7DS0Rre6Qm_LJz0Ee_gd5C_t92fBcrFkber1XL_p8AvlXx4DT2Zr_PMBL_2IblJ7t0Od5wnGC__twarj0v1t6KfUkLXcJ3Jy-StnHNbFTmdFnLuGGWIO7xG9h6xgKIvTroVoLJekMzYCc0wSFiyCfaow4yuKesQHUO-N9VDDPoYhkCPqbhVI_d0y6u7KmQy97FbCdCIxvPGHWrwxWcmYbTh4K9xhGDspDUUEubjYTg3t-oaMc2TJqWvu2FE8jyD02A8OCgca6bCU3NmV_Qr6LSUpFNsL4c-0sIp3-L9ndEWzGnN-ZeeGKur-FQ
|
||||
eyJhbGciOiJSUzI1NiJ9.IiI.gq_hQ6VcQNMVmKlQltK5pS_Yu8PoTCFoWHqQVj1VymYymuKJ9GSgPDxgtkPQVotB985ZaNCuLjoXA4x-xVgMTroSdTQiupBDPpzhZhOuHPgKFQzmC8aBkWxAF_xxLBlZOMwiSly6k_0afE5GgY1SnHu9I57TkGLwHQnTOvL-ED7LvkZxTefxxsDMjgZjboNEPEjbkHl859we5_nKMeL_8jUAhijvaksWZK8pNQdeqg9V9ZNHOgtUG1pPwlSYMjrOTk_a1y6yXAihvuZCwbCCiuquiPi1oWI9Nfv5YGeT8SjSDHAYYJTRyaNOo62fwFC-BuYjVDBdl3uZtO-Ys2g8CA
|
||||
@@ -2,4 +2,4 @@
|
||||
source: crates/keystore/tests/keystore.rs
|
||||
expression: token.as_str()
|
||||
---
|
||||
eyJhbGciOiJSUzM4NCJ9.IiI.bxKYTQQ4RlxOUvxbU_kuwJKGXXiuIPeRgO78a_3zHjvxIzDNKDvQK3w4DUVTlibR-iTVOASRSycWifBJZx_tsU7-BSqrBcjMtgP7mW-HwZ6pANO071iPkkiQU7gqMzbc2tz4uqGI0Z0izkX0_9dOOFSb7jKIUMzzW1O14fBPhZ4kPqkj07A9S9LW9lauQUTXrFgyEaT6G372cyNxi3-T55u9lkjjiiVN4TAhkaXUSN79IE2rNstU8DtKKs725WNUFy30f1-Ftc-J2uGEOsMZ9CQvEVPwOKbvFY2Uh1S8-FT4ahhwj1fxrmUwDH2lSmz6Rj5zf9-FF-IzivSVq4Z4ig
|
||||
eyJhbGciOiJSUzM4NCJ9.IiI.KXWxSvxoLuCwtpP-N0fCAFho6zFI44P-42ALMx70vQiM9C_MKbLGpmSET_-GJIQ-fjxJ8jpFmVQjfKuhzHpJZP6JVTHVFg34Z0KOKYM45QqLPooXOf7c9O46DczFoJC0mGuMAWsAtEvgvFgRYHe8KgPg_HBczcHZ71uYDLyz5BINqG_TaDRQBT5vNoPKrnP526CJrHHNT-h2XJumhOjC1XVDj8lj1hlWk63xepZ7fybhLIDAKuEgjfTLBkAaJ1V2hz46uD7g_vvGXGEiBDW93_zWKoTs9ZDrBt-kL82GGay3zLTRHFRORah4hI4GbnJHgy22Dj-RhTJm3deTejkSjg
|
||||
@@ -2,4 +2,4 @@
|
||||
source: crates/keystore/tests/keystore.rs
|
||||
expression: token.as_str()
|
||||
---
|
||||
eyJhbGciOiJSUzUxMiJ9.IiI.nFsZ3X8GCgpPEojuEktc9a4C-YGQYx8XpbzhOkgnMVrw_wpqIQgWI--4r6BYV6TYAH8NBdQ8Dkdw6POh1Ni-vAtE2rAzjU19ySth5mfP7WEJXRxA1oEV3-dOqCgUI2JJEM13DuLlWFsUaOCbc1_kCkiziTcLtNap__EPGp5koRy-ZyVa1p_mQSQ4NlhJ3hZfHMGnQ0k3RWnpBn3AqERWllQllLniWGQ4l7rZStsD8PRr-rg7P7W7CRIyjrDqy_3bNJyKQCzs_oUrxO-Z7CU6-KfAeyM2U80TQvhZb-Z8_1dJ8e9WsfudQMLtHgO4tlD678Ywezjvr5ackZdn4QEEEA
|
||||
eyJhbGciOiJSUzUxMiJ9.IiI.AwxfqjEihH6xYO8xNF24sg5cO8z2bS50V-27YQEViePcRlaqPZHXn6h45YxFXbElrXgKtM97y0KXa8Rr5TrfyH8VXB1OzHNyQ76cZ4zbfYveMZhBh7pGiHVMEPQ0ZErobZXyk9Rxe-HxK1zi9qmmJZLHsQLEFh5zDkTg5dgpEJcklxmCTCT0RLDcilsNdaL7XkTMyjmMck25xciteEy3mpGXppRuDQwsN4ywfNp9VDBC5NjxBYF39D7hkvybOF5eKeaXVo2zw9OmJ4wNg_KgQdNAf-y8wgU71ydo5FHa8d9--HZFTn9ifxZYOCXd34k5vKyScdaXTLUtGFlt0zjDxA
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
// Copyright 2022-2024 Kévin Commaille.
|
||||
//
|
||||
@@ -25,8 +26,8 @@ use oauth2_types::{
|
||||
scope::{OPENID, Scope},
|
||||
};
|
||||
use rand::{
|
||||
Rng,
|
||||
distributions::{Alphanumeric, DistString},
|
||||
RngExt,
|
||||
distr::{Alphanumeric, SampleString},
|
||||
};
|
||||
use serde::Serialize;
|
||||
use url::Url;
|
||||
@@ -214,7 +215,7 @@ struct FullAuthorizationRequest {
|
||||
/// Build the authorization request.
|
||||
fn build_authorization_request(
|
||||
authorization_data: AuthorizationRequestData,
|
||||
rng: &mut impl Rng,
|
||||
rng: &mut impl RngExt,
|
||||
) -> Result<(FullAuthorizationRequest, AuthorizationValidationData), AuthorizationError> {
|
||||
let AuthorizationRequestData {
|
||||
client_id,
|
||||
@@ -327,7 +328,7 @@ fn build_authorization_request(
|
||||
pub fn build_authorization_url(
|
||||
authorization_endpoint: Url,
|
||||
authorization_data: AuthorizationRequestData,
|
||||
rng: &mut impl Rng,
|
||||
rng: &mut impl RngExt,
|
||||
) -> Result<(Url, AuthorizationValidationData), AuthorizationError> {
|
||||
tracing::debug!(
|
||||
scope = ?authorization_data.scope,
|
||||
@@ -403,7 +404,7 @@ pub async fn access_token_with_authorization_code(
|
||||
validation_data: AuthorizationValidationData,
|
||||
id_token_verification_data: Option<JwtVerificationData<'_>>,
|
||||
now: DateTime<Utc>,
|
||||
rng: &mut impl Rng,
|
||||
rng: &mut impl RngExt,
|
||||
) -> Result<(AccessTokenResponse, Option<IdToken<'static>>), TokenAuthorizationCodeError> {
|
||||
tracing::debug!("Exchanging authorization code for access token...");
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
// Copyright 2022-2024 Kévin Commaille.
|
||||
//
|
||||
@@ -13,7 +14,7 @@ use oauth2_types::{
|
||||
requests::{AccessTokenRequest, AccessTokenResponse, ClientCredentialsGrant},
|
||||
scope::Scope,
|
||||
};
|
||||
use rand::Rng;
|
||||
use rand::RngExt;
|
||||
use url::Url;
|
||||
|
||||
use crate::{
|
||||
@@ -51,7 +52,7 @@ pub async fn access_token_with_client_credentials(
|
||||
token_endpoint: &Url,
|
||||
scope: Option<Scope>,
|
||||
now: DateTime<Utc>,
|
||||
rng: &mut impl Rng,
|
||||
rng: &mut impl RngExt,
|
||||
) -> Result<AccessTokenResponse, TokenRequestError> {
|
||||
tracing::debug!("Requesting access token with client credentials...");
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
// Copyright 2022-2024 Kévin Commaille.
|
||||
//
|
||||
@@ -14,7 +15,7 @@ use oauth2_types::{
|
||||
requests::{AccessTokenRequest, AccessTokenResponse, RefreshTokenGrant},
|
||||
scope::Scope,
|
||||
};
|
||||
use rand::Rng;
|
||||
use rand::RngExt;
|
||||
use url::Url;
|
||||
|
||||
use super::jose::JwtVerificationData;
|
||||
@@ -75,7 +76,7 @@ pub async fn refresh_access_token(
|
||||
id_token_verification_data: Option<JwtVerificationData<'_>>,
|
||||
auth_id_token: Option<&IdToken<'_>>,
|
||||
now: DateTime<Utc>,
|
||||
rng: &mut impl Rng,
|
||||
rng: &mut impl RngExt,
|
||||
) -> Result<(AccessTokenResponse, Option<IdToken<'static>>), TokenRefreshError> {
|
||||
tracing::debug!("Refreshing access token…");
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
// Copyright 2022-2024 Kévin Commaille.
|
||||
//
|
||||
@@ -11,7 +12,7 @@ use http::header::ACCEPT;
|
||||
use mas_http::RequestBuilderExt;
|
||||
use mime::APPLICATION_JSON;
|
||||
use oauth2_types::requests::{AccessTokenRequest, AccessTokenResponse};
|
||||
use rand::Rng;
|
||||
use rand::RngExt;
|
||||
use url::Url;
|
||||
|
||||
use crate::{
|
||||
@@ -46,7 +47,7 @@ pub async fn request_access_token(
|
||||
token_endpoint: &Url,
|
||||
request: AccessTokenRequest,
|
||||
now: DateTime<Utc>,
|
||||
rng: &mut impl Rng,
|
||||
rng: &mut impl RngExt,
|
||||
) -> Result<AccessTokenResponse, TokenRequestError> {
|
||||
tracing::debug!(?request, "Requesting access token...");
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
// Copyright 2022-2024 Kévin Commaille.
|
||||
//
|
||||
@@ -18,7 +19,7 @@ use mas_jose::{
|
||||
jwt::{JsonWebSignatureHeader, Jwt},
|
||||
};
|
||||
use mas_keystore::Keystore;
|
||||
use rand::Rng;
|
||||
use rand::RngExt;
|
||||
use serde::Serialize;
|
||||
use serde_json::Value;
|
||||
use url::Url;
|
||||
@@ -135,7 +136,7 @@ impl ClientCredentials {
|
||||
request: reqwest::RequestBuilder,
|
||||
form: &T,
|
||||
now: DateTime<Utc>,
|
||||
rng: &mut impl Rng,
|
||||
rng: &mut impl RngExt,
|
||||
) -> Result<reqwest::RequestBuilder, CredentialsError> {
|
||||
let request = match self {
|
||||
ClientCredentials::None { client_id } => request.form(&RequestWithClientCredentials {
|
||||
@@ -331,7 +332,7 @@ fn prepare_claims(
|
||||
iss: String,
|
||||
aud: String,
|
||||
now: DateTime<Utc>,
|
||||
rng: &mut impl Rng,
|
||||
rng: &mut impl RngExt,
|
||||
) -> Result<HashMap<String, Value>, ClaimError> {
|
||||
let mut claims = HashMap::new();
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
// Copyright 2022-2024 Kévin Commaille.
|
||||
//
|
||||
@@ -19,7 +20,7 @@ use mas_keystore::{JsonWebKey, JsonWebKeySet, Keystore, PrivateKey};
|
||||
use mas_oidc_client::types::{IdToken, client_credentials::ClientCredentials};
|
||||
use rand::{
|
||||
SeedableRng,
|
||||
distributions::{Alphanumeric, DistString},
|
||||
distr::{Alphanumeric, SampleString},
|
||||
};
|
||||
use url::Url;
|
||||
use wiremock::MockServer;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
// Copyright 2022-2024 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
@@ -8,7 +9,7 @@ use async_trait::async_trait;
|
||||
use chrono::{DateTime, Duration, Utc};
|
||||
use mas_data_model::{Clock, CompatAccessToken, CompatSession, UlidExt as _};
|
||||
use mas_storage::compat::CompatAccessTokenRepository;
|
||||
use rand::RngCore;
|
||||
use rand::Rng;
|
||||
use sqlx::PgConnection;
|
||||
use ulid::Ulid;
|
||||
use uuid::Uuid;
|
||||
@@ -136,7 +137,7 @@ impl CompatAccessTokenRepository for PgCompatAccessTokenRepository<'_> {
|
||||
)]
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
compat_session: &CompatSession,
|
||||
token: String,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
// Copyright 2023, 2024 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
@@ -11,7 +12,7 @@ use mas_data_model::{
|
||||
UlidExt as _,
|
||||
};
|
||||
use mas_storage::compat::CompatRefreshTokenRepository;
|
||||
use rand::RngCore;
|
||||
use rand::Rng;
|
||||
use sqlx::PgConnection;
|
||||
use ulid::Ulid;
|
||||
use uuid::Uuid;
|
||||
@@ -148,7 +149,7 @@ impl CompatRefreshTokenRepository for PgCompatRefreshTokenRepository<'_> {
|
||||
)]
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
compat_session: &CompatSession,
|
||||
compat_access_token: &CompatAccessToken,
|
||||
|
||||
@@ -18,7 +18,7 @@ use mas_storage::{
|
||||
compat::{CompatSessionFilter, CompatSessionRepository},
|
||||
pagination::Node,
|
||||
};
|
||||
use rand::RngCore;
|
||||
use rand::Rng;
|
||||
use sea_query::{Expr, ExprTrait, PostgresQueryBuilder, Query, enum_def};
|
||||
use sea_query_sqlx::SqlxBinder;
|
||||
use sqlx::PgConnection;
|
||||
@@ -337,7 +337,7 @@ impl CompatSessionRepository for PgCompatSessionRepository<'_> {
|
||||
)]
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
user: &User,
|
||||
device: Device,
|
||||
|
||||
@@ -15,7 +15,7 @@ use mas_storage::{
|
||||
compat::{CompatSsoLoginFilter, CompatSsoLoginRepository},
|
||||
pagination::Node,
|
||||
};
|
||||
use rand::RngCore;
|
||||
use rand::Rng;
|
||||
use sea_query::{Expr, ExprTrait, PostgresQueryBuilder, Query, enum_def};
|
||||
use sea_query_sqlx::SqlxBinder;
|
||||
use sqlx::PgConnection;
|
||||
@@ -274,7 +274,7 @@ impl CompatSsoLoginRepository for PgCompatSsoLoginRepository<'_> {
|
||||
)]
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
login_token: String,
|
||||
redirect_uri: Url,
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
//! ```rust
|
||||
//! # use async_trait::async_trait;
|
||||
//! # use ulid::Ulid;
|
||||
//! # use rand::RngCore;
|
||||
//! # use rand::Rng;
|
||||
//! # use mas_data_model::Clock;
|
||||
//! # use mas_data_model::UlidExt;
|
||||
//! # use mas_storage_pg::{DatabaseError, ExecuteExt};
|
||||
@@ -42,7 +42,7 @@
|
||||
//! # async fn lookup(&mut self, id: Ulid) -> Result<Option<FakeData>, Self::Error>;
|
||||
//! # async fn add(
|
||||
//! # &mut self,
|
||||
//! # rng: &mut (dyn RngCore + Send),
|
||||
//! # rng: &mut (dyn Rng + Send),
|
||||
//! # clock: &dyn Clock,
|
||||
//! # ) -> Result<FakeData, Self::Error>;
|
||||
//! # }
|
||||
@@ -116,7 +116,7 @@
|
||||
//! )]
|
||||
//! async fn add(
|
||||
//! &mut self,
|
||||
//! rng: &mut (dyn RngCore + Send),
|
||||
//! rng: &mut (dyn Rng + Send),
|
||||
//! clock: &dyn Clock,
|
||||
//! ) -> Result<FakeData, Self::Error> {
|
||||
//! let created_at = clock.now();
|
||||
|
||||
@@ -9,7 +9,7 @@ use async_trait::async_trait;
|
||||
use chrono::{DateTime, Duration, Utc};
|
||||
use mas_data_model::{AccessToken, AccessTokenState, Clock, Session, UlidExt as _};
|
||||
use mas_storage::oauth2::OAuth2AccessTokenRepository;
|
||||
use rand::RngCore;
|
||||
use rand::Rng;
|
||||
use sqlx::PgConnection;
|
||||
use ulid::Ulid;
|
||||
use uuid::Uuid;
|
||||
@@ -139,7 +139,7 @@ impl OAuth2AccessTokenRepository for PgOAuth2AccessTokenRepository<'_> {
|
||||
)]
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
session: &Session,
|
||||
access_token: String,
|
||||
|
||||
@@ -16,7 +16,7 @@ use mas_data_model::{
|
||||
use mas_iana::oauth::PkceCodeChallengeMethod;
|
||||
use mas_storage::oauth2::OAuth2AuthorizationGrantRepository;
|
||||
use oauth2_types::{requests::ResponseMode, scope::Scope};
|
||||
use rand::RngCore;
|
||||
use rand::Rng;
|
||||
use sqlx::{PgConnection, types::Json};
|
||||
use ulid::Ulid;
|
||||
use url::Url;
|
||||
@@ -200,7 +200,7 @@ impl OAuth2AuthorizationGrantRepository for PgOAuth2AuthorizationGrantRepository
|
||||
)]
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
client: &Client,
|
||||
redirect_uri: Url,
|
||||
|
||||
@@ -21,7 +21,7 @@ use mas_storage::{
|
||||
};
|
||||
use oauth2_types::{oidc::ApplicationType, requests::GrantType};
|
||||
use opentelemetry_semantic_conventions::attribute::DB_QUERY_TEXT;
|
||||
use rand::RngCore;
|
||||
use rand::Rng;
|
||||
use sea_query::{
|
||||
Expr, ExprTrait, PostgresQueryBuilder, Query, SimpleExpr, enum_def,
|
||||
extension::postgres::PgExpr as _,
|
||||
@@ -492,7 +492,7 @@ impl OAuth2ClientRepository for PgOAuth2ClientRepository<'_> {
|
||||
)]
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
redirect_uris: Vec<Url>,
|
||||
metadata_digest: Option<String>,
|
||||
|
||||
@@ -14,7 +14,7 @@ use mas_data_model::{
|
||||
};
|
||||
use mas_storage::oauth2::{OAuth2DeviceCodeGrantParams, OAuth2DeviceCodeGrantRepository};
|
||||
use oauth2_types::scope::Scope;
|
||||
use rand::RngCore;
|
||||
use rand::Rng;
|
||||
use sqlx::PgConnection;
|
||||
use ulid::Ulid;
|
||||
use uuid::Uuid;
|
||||
@@ -157,7 +157,7 @@ impl OAuth2DeviceCodeGrantRepository for PgOAuth2DeviceCodeGrantRepository<'_> {
|
||||
)]
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
params: OAuth2DeviceCodeGrantParams<'_>,
|
||||
) -> Result<DeviceCodeGrant, Self::Error> {
|
||||
|
||||
@@ -9,7 +9,7 @@ use async_trait::async_trait;
|
||||
use chrono::{DateTime, Utc};
|
||||
use mas_data_model::{AccessToken, Clock, RefreshToken, RefreshTokenState, Session, UlidExt as _};
|
||||
use mas_storage::oauth2::OAuth2RefreshTokenRepository;
|
||||
use rand::RngCore;
|
||||
use rand::Rng;
|
||||
use sqlx::PgConnection;
|
||||
use ulid::Ulid;
|
||||
use uuid::Uuid;
|
||||
@@ -170,7 +170,7 @@ impl OAuth2RefreshTokenRepository for PgOAuth2RefreshTokenRepository<'_> {
|
||||
)]
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
session: &Session,
|
||||
access_token: &AccessToken,
|
||||
|
||||
@@ -16,7 +16,7 @@ use mas_storage::{
|
||||
pagination::Node,
|
||||
};
|
||||
use oauth2_types::scope::{Scope, ScopeToken};
|
||||
use rand::RngCore;
|
||||
use rand::Rng;
|
||||
use sea_query::{
|
||||
Condition, Expr, ExprTrait, PgFunc, PostgresQueryBuilder, Query, SimpleExpr, enum_def,
|
||||
extension::postgres::PgExpr,
|
||||
@@ -272,7 +272,7 @@ impl OAuth2SessionRepository for PgOAuth2SessionRepository<'_> {
|
||||
)]
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
client: &Client,
|
||||
user: Option<&User>,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2025 New Vector Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
@@ -10,7 +11,7 @@ use mas_data_model::{
|
||||
personal::{PersonalAccessToken, session::PersonalSession},
|
||||
};
|
||||
use mas_storage::personal::PersonalAccessTokenRepository;
|
||||
use rand::RngCore;
|
||||
use rand::Rng;
|
||||
use sha2::{Digest, Sha256};
|
||||
use sqlx::PgConnection;
|
||||
use ulid::Ulid;
|
||||
@@ -177,7 +178,7 @@ impl PersonalAccessTokenRepository for PgPersonalAccessTokenRepository<'_> {
|
||||
)]
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
session: &PersonalSession,
|
||||
access_token: &str,
|
||||
|
||||
@@ -22,7 +22,7 @@ use mas_storage::{
|
||||
};
|
||||
use oauth2_types::scope::Scope;
|
||||
use opentelemetry_semantic_conventions::trace::DB_QUERY_TEXT;
|
||||
use rand::RngCore;
|
||||
use rand::Rng;
|
||||
use sea_query::{
|
||||
Cond, Condition, Expr, ExprTrait, PgFunc, PostgresQueryBuilder, Query, SimpleExpr, enum_def,
|
||||
extension::postgres::PgExpr as _,
|
||||
@@ -243,7 +243,7 @@ impl PersonalSessionRepository for PgPersonalSessionRepository<'_> {
|
||||
)]
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
owner: PersonalSessionOwner,
|
||||
actor_user: &User,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2025 New Vector Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
@@ -9,7 +10,7 @@
|
||||
use async_trait::async_trait;
|
||||
use mas_data_model::{Clock, PolicyData, UlidExt as _};
|
||||
use mas_storage::policy_data::PolicyDataRepository;
|
||||
use rand::RngCore;
|
||||
use rand::Rng;
|
||||
use serde_json::Value;
|
||||
use sqlx::{PgConnection, types::Json};
|
||||
use ulid::Ulid;
|
||||
@@ -90,7 +91,7 @@ impl PolicyDataRepository for PgPolicyDataRepository<'_> {
|
||||
)]
|
||||
async fn set(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
data: Value,
|
||||
) -> Result<PolicyData, Self::Error> {
|
||||
|
||||
@@ -12,7 +12,7 @@ use chrono::{DateTime, Duration, Utc};
|
||||
use mas_data_model::{Clock, UlidExt as _};
|
||||
use mas_storage::queue::{Job, QueueJobRepository, Worker};
|
||||
use opentelemetry_semantic_conventions::trace::DB_QUERY_TEXT;
|
||||
use rand::RngCore;
|
||||
use rand::Rng;
|
||||
use sqlx::PgConnection;
|
||||
use tracing::Instrument;
|
||||
use ulid::Ulid;
|
||||
@@ -90,7 +90,7 @@ impl QueueJobRepository for PgQueueJobRepository<'_> {
|
||||
)]
|
||||
async fn schedule(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
queue_name: &str,
|
||||
payload: serde_json::Value,
|
||||
@@ -132,7 +132,7 @@ impl QueueJobRepository for PgQueueJobRepository<'_> {
|
||||
)]
|
||||
async fn schedule_later(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
queue_name: &str,
|
||||
payload: serde_json::Value,
|
||||
@@ -335,7 +335,7 @@ impl QueueJobRepository for PgQueueJobRepository<'_> {
|
||||
)]
|
||||
async fn retry(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
id: Ulid,
|
||||
delay: Duration,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
@@ -10,7 +11,7 @@ use async_trait::async_trait;
|
||||
use chrono::Duration;
|
||||
use mas_data_model::{Clock, UlidExt as _};
|
||||
use mas_storage::queue::{QueueWorkerRepository, Worker};
|
||||
use rand::RngCore;
|
||||
use rand::Rng;
|
||||
use sqlx::PgConnection;
|
||||
use ulid::Ulid;
|
||||
use uuid::Uuid;
|
||||
@@ -46,7 +47,7 @@ impl QueueWorkerRepository for PgQueueWorkerRepository<'_> {
|
||||
)]
|
||||
async fn register(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
) -> Result<Worker, Self::Error> {
|
||||
let now = clock.now();
|
||||
|
||||
@@ -14,7 +14,7 @@ use mas_storage::{
|
||||
upstream_oauth2::{UpstreamOAuthLinkFilter, UpstreamOAuthLinkRepository},
|
||||
};
|
||||
use opentelemetry_semantic_conventions::trace::DB_QUERY_TEXT;
|
||||
use rand::RngCore;
|
||||
use rand::Rng;
|
||||
use sea_query::{
|
||||
Expr, ExprTrait, PostgresQueryBuilder, Query, enum_def, extension::postgres::PgExpr as _,
|
||||
};
|
||||
@@ -221,7 +221,7 @@ impl UpstreamOAuthLinkRepository for PgUpstreamOAuthLinkRepository<'_> {
|
||||
)]
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
upstream_oauth_provider: &UpstreamOAuthProvider,
|
||||
subject: String,
|
||||
|
||||
@@ -18,7 +18,7 @@ use mas_storage::{
|
||||
},
|
||||
};
|
||||
use opentelemetry_semantic_conventions::attribute::DB_QUERY_TEXT;
|
||||
use rand::RngCore;
|
||||
use rand::Rng;
|
||||
use sea_query::{Expr, ExprTrait, PostgresQueryBuilder, Query, enum_def};
|
||||
use sea_query_sqlx::SqlxBinder;
|
||||
use sqlx::{PgConnection, types::Json};
|
||||
@@ -330,7 +330,7 @@ impl UpstreamOAuthProviderRepository for PgUpstreamOAuthProviderRepository<'_> {
|
||||
)]
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
params: UpstreamOAuthProviderParams,
|
||||
) -> Result<UpstreamOAuthProvider, Self::Error> {
|
||||
|
||||
@@ -16,7 +16,7 @@ use mas_storage::{
|
||||
pagination::Node,
|
||||
upstream_oauth2::{UpstreamOAuthSessionFilter, UpstreamOAuthSessionRepository},
|
||||
};
|
||||
use rand::RngCore;
|
||||
use rand::Rng;
|
||||
use sea_query::{
|
||||
Expr, ExprTrait, PostgresQueryBuilder, Query, enum_def, extension::postgres::PgExpr,
|
||||
};
|
||||
@@ -253,7 +253,7 @@ impl UpstreamOAuthSessionRepository for PgUpstreamOAuthSessionRepository<'_> {
|
||||
)]
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
upstream_oauth_provider: &UpstreamOAuthProvider,
|
||||
state_str: String,
|
||||
|
||||
@@ -16,7 +16,7 @@ use mas_storage::{
|
||||
pagination::Node,
|
||||
user::{UserEmailFilter, UserEmailRepository},
|
||||
};
|
||||
use rand::RngCore;
|
||||
use rand::Rng;
|
||||
use sea_query::{Expr, ExprTrait, Func, PostgresQueryBuilder, Query, SimpleExpr, enum_def};
|
||||
use sea_query_sqlx::SqlxBinder;
|
||||
use sqlx::PgConnection;
|
||||
@@ -354,7 +354,7 @@ impl UserEmailRepository for PgUserEmailRepository<'_> {
|
||||
)]
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
user: &User,
|
||||
email: String,
|
||||
@@ -448,7 +448,7 @@ impl UserEmailRepository for PgUserEmailRepository<'_> {
|
||||
)]
|
||||
async fn add_authentication_for_session(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
email: String,
|
||||
session: &BrowserSession,
|
||||
@@ -500,7 +500,7 @@ impl UserEmailRepository for PgUserEmailRepository<'_> {
|
||||
)]
|
||||
async fn add_authentication_for_registration(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
email: String,
|
||||
user_registration: &UserRegistration,
|
||||
@@ -553,7 +553,7 @@ impl UserEmailRepository for PgUserEmailRepository<'_> {
|
||||
)]
|
||||
async fn add_authentication_code(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
duration: chrono::Duration,
|
||||
user_email_authentication: &UserEmailAuthentication,
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
use async_trait::async_trait;
|
||||
use mas_data_model::{Clock, UlidExt as _, User};
|
||||
use mas_storage::user::{UserFilter, UserRepository};
|
||||
use rand::RngCore;
|
||||
use rand::Rng;
|
||||
use sea_query::{
|
||||
Expr, ExprTrait, PostgresQueryBuilder, Query, SimpleExpr, extension::postgres::PgExpr as _,
|
||||
};
|
||||
@@ -295,7 +295,7 @@ impl UserRepository for PgUserRepository<'_> {
|
||||
)]
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
username: String,
|
||||
) -> Result<User, Self::Error> {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
// Copyright 2022-2024 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
@@ -8,7 +9,7 @@ use async_trait::async_trait;
|
||||
use chrono::{DateTime, Utc};
|
||||
use mas_data_model::{Clock, Password, UlidExt as _, User};
|
||||
use mas_storage::user::UserPasswordRepository;
|
||||
use rand::RngCore;
|
||||
use rand::Rng;
|
||||
use sqlx::PgConnection;
|
||||
use ulid::Ulid;
|
||||
use uuid::Uuid;
|
||||
@@ -108,7 +109,7 @@ impl UserPasswordRepository for PgUserPasswordRepository<'_> {
|
||||
)]
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
user: &User,
|
||||
version: u16,
|
||||
|
||||
@@ -11,7 +11,7 @@ use async_trait::async_trait;
|
||||
use chrono::{DateTime, Duration, Utc};
|
||||
use mas_data_model::{Clock, UlidExt as _, UserEmail, UserRecoverySession, UserRecoveryTicket};
|
||||
use mas_storage::user::UserRecoveryRepository;
|
||||
use rand::RngCore;
|
||||
use rand::Rng;
|
||||
use sqlx::PgConnection;
|
||||
use ulid::Ulid;
|
||||
use uuid::Uuid;
|
||||
@@ -134,7 +134,7 @@ impl UserRecoveryRepository for PgUserRecoveryRepository<'_> {
|
||||
)]
|
||||
async fn add_session(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
email: String,
|
||||
user_agent: String,
|
||||
@@ -232,7 +232,7 @@ impl UserRecoveryRepository for PgUserRecoveryRepository<'_> {
|
||||
)]
|
||||
async fn add_ticket(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
user_recovery_session: &UserRecoverySession,
|
||||
user_email: &UserEmail,
|
||||
|
||||
@@ -13,7 +13,7 @@ use mas_data_model::{
|
||||
UserRegistration, UserRegistrationPassword, UserRegistrationToken,
|
||||
};
|
||||
use mas_storage::user::UserRegistrationRepository;
|
||||
use rand::RngCore;
|
||||
use rand::Rng;
|
||||
use sqlx::PgConnection;
|
||||
use ulid::Ulid;
|
||||
use url::Url;
|
||||
@@ -167,7 +167,7 @@ impl UserRegistrationRepository for PgUserRegistrationRepository<'_> {
|
||||
)]
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
username: String,
|
||||
ip_address: Option<IpAddr>,
|
||||
|
||||
@@ -12,7 +12,7 @@ use mas_storage::{
|
||||
pagination::Node,
|
||||
user::{UserRegistrationTokenFilter, UserRegistrationTokenRepository},
|
||||
};
|
||||
use rand::RngCore;
|
||||
use rand::Rng;
|
||||
use sea_query::{Condition, Expr, ExprTrait, PostgresQueryBuilder, Query, enum_def};
|
||||
use sea_query_sqlx::SqlxBinder;
|
||||
use sqlx::PgConnection;
|
||||
@@ -435,7 +435,7 @@ impl UserRegistrationTokenRepository for PgUserRegistrationTokenRepository<'_> {
|
||||
)]
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn mas_data_model::Clock,
|
||||
token: String,
|
||||
usage_limit: Option<u32>,
|
||||
|
||||
@@ -18,7 +18,7 @@ use mas_storage::{
|
||||
pagination::Node,
|
||||
user::{BrowserSessionFilter, BrowserSessionRepository},
|
||||
};
|
||||
use rand::RngCore;
|
||||
use rand::Rng;
|
||||
use sea_query::{Expr, ExprTrait, PostgresQueryBuilder, Query};
|
||||
use sea_query_sqlx::SqlxBinder;
|
||||
use sqlx::PgConnection;
|
||||
@@ -240,7 +240,7 @@ impl BrowserSessionRepository for PgBrowserSessionRepository<'_> {
|
||||
)]
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
user: &User,
|
||||
user_agent: Option<String>,
|
||||
@@ -469,7 +469,7 @@ impl BrowserSessionRepository for PgBrowserSessionRepository<'_> {
|
||||
)]
|
||||
async fn authenticate_with_password(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
user_session: &BrowserSession,
|
||||
user_password: &Password,
|
||||
@@ -518,7 +518,7 @@ impl BrowserSessionRepository for PgBrowserSessionRepository<'_> {
|
||||
)]
|
||||
async fn authenticate_with_upstream(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
user_session: &BrowserSession,
|
||||
upstream_oauth_session: &UpstreamOAuthAuthorizationSession,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
// Copyright 2024 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
@@ -7,7 +8,7 @@
|
||||
use async_trait::async_trait;
|
||||
use mas_data_model::{Clock, UlidExt as _, User};
|
||||
use mas_storage::user::UserTermsRepository;
|
||||
use rand::RngCore;
|
||||
use rand::Rng;
|
||||
use sqlx::PgConnection;
|
||||
use ulid::Ulid;
|
||||
use url::Url;
|
||||
@@ -45,7 +46,7 @@ impl UserTermsRepository for PgUserTermsRepository<'_> {
|
||||
)]
|
||||
async fn accept_terms(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
user: &User,
|
||||
terms_url: Url,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
// Copyright 2022-2024 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
@@ -7,7 +8,7 @@
|
||||
use async_trait::async_trait;
|
||||
use chrono::Duration;
|
||||
use mas_data_model::{Clock, CompatAccessToken, CompatSession};
|
||||
use rand_core::RngCore;
|
||||
use rand_core::Rng;
|
||||
use ulid::Ulid;
|
||||
|
||||
use crate::repository_impl;
|
||||
@@ -66,7 +67,7 @@ pub trait CompatAccessTokenRepository: Send + Sync {
|
||||
/// Returns [`Self::Error`] if the underlying repository fails
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
compat_session: &CompatSession,
|
||||
token: String,
|
||||
@@ -98,7 +99,7 @@ repository_impl!(CompatAccessTokenRepository:
|
||||
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
compat_session: &CompatSession,
|
||||
token: String,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
// Copyright 2023, 2024 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
@@ -6,7 +7,7 @@
|
||||
|
||||
use async_trait::async_trait;
|
||||
use mas_data_model::{Clock, CompatAccessToken, CompatRefreshToken, CompatSession};
|
||||
use rand_core::RngCore;
|
||||
use rand_core::Rng;
|
||||
use ulid::Ulid;
|
||||
|
||||
use crate::repository_impl;
|
||||
@@ -62,7 +63,7 @@ pub trait CompatRefreshTokenRepository: Send + Sync {
|
||||
/// * `token`: The token of the refresh token
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
compat_session: &CompatSession,
|
||||
compat_access_token: &CompatAccessToken,
|
||||
@@ -114,7 +115,7 @@ repository_impl!(CompatRefreshTokenRepository:
|
||||
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
compat_session: &CompatSession,
|
||||
compat_access_token: &CompatAccessToken,
|
||||
|
||||
@@ -10,7 +10,7 @@ use std::net::IpAddr;
|
||||
use async_trait::async_trait;
|
||||
use chrono::{DateTime, Utc};
|
||||
use mas_data_model::{BrowserSession, Clock, CompatSession, CompatSsoLogin, Device, User};
|
||||
use rand_core::RngCore;
|
||||
use rand_core::Rng;
|
||||
use ulid::Ulid;
|
||||
|
||||
use crate::{Page, Pagination, repository_impl, user::BrowserSessionFilter};
|
||||
@@ -274,7 +274,7 @@ pub trait CompatSessionRepository: Send + Sync {
|
||||
#[expect(clippy::too_many_arguments)]
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
user: &User,
|
||||
device: Device,
|
||||
@@ -449,7 +449,7 @@ repository_impl!(CompatSessionRepository:
|
||||
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
user: &User,
|
||||
device: Device,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
// Copyright 2023, 2024 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
@@ -6,7 +7,7 @@
|
||||
|
||||
use async_trait::async_trait;
|
||||
use mas_data_model::{BrowserSession, Clock, CompatSession, CompatSsoLogin, User};
|
||||
use rand_core::RngCore;
|
||||
use rand_core::Rng;
|
||||
use ulid::Ulid;
|
||||
use url::Url;
|
||||
|
||||
@@ -162,7 +163,7 @@ pub trait CompatSsoLoginRepository: Send + Sync {
|
||||
/// Returns [`Self::Error`] if the underlying repository fails
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
login_token: String,
|
||||
redirect_uri: Url,
|
||||
@@ -255,7 +256,7 @@ repository_impl!(CompatSsoLoginRepository:
|
||||
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
login_token: String,
|
||||
redirect_uri: Url,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2024, 2025 New Vector Ltd.
|
||||
// Copyright 2021-2024 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
@@ -58,7 +59,7 @@
|
||||
//! /// Returns [`Self::Error`] if the underlying repository fails
|
||||
//! async fn add(
|
||||
//! &mut self,
|
||||
//! rng: &mut (dyn RngCore + Send),
|
||||
//! rng: &mut (dyn Rng + Send),
|
||||
//! clock: &dyn Clock,
|
||||
//! ) -> Result<FakeData, Self::Error>;
|
||||
//! }
|
||||
@@ -67,7 +68,7 @@
|
||||
//! async fn lookup(&mut self, id: Ulid) -> Result<Option<FakeData>, Self::Error>;
|
||||
//! async fn add(
|
||||
//! &mut self,
|
||||
//! rng: &mut (dyn RngCore + Send),
|
||||
//! rng: &mut (dyn Rng + Send),
|
||||
//! clock: &dyn Clock,
|
||||
//! ) -> Result<FakeData, Self::Error>;
|
||||
//! );
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
use async_trait::async_trait;
|
||||
use chrono::{DateTime, Duration, Utc};
|
||||
use mas_data_model::{AccessToken, Clock, Session};
|
||||
use rand_core::RngCore;
|
||||
use rand_core::Rng;
|
||||
use ulid::Ulid;
|
||||
|
||||
use crate::repository_impl;
|
||||
@@ -67,7 +67,7 @@ pub trait OAuth2AccessTokenRepository: Send + Sync {
|
||||
/// Returns [`Self::Error`] if the underlying repository fails
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
session: &Session,
|
||||
access_token: String,
|
||||
@@ -163,7 +163,7 @@ repository_impl!(OAuth2AccessTokenRepository:
|
||||
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
session: &Session,
|
||||
access_token: String,
|
||||
|
||||
@@ -12,7 +12,7 @@ use mas_data_model::{
|
||||
AuthorizationCode, AuthorizationGrant, BrowserSession, Client, Clock, Session,
|
||||
};
|
||||
use oauth2_types::{requests::ResponseMode, scope::Scope};
|
||||
use rand_core::RngCore;
|
||||
use rand_core::Rng;
|
||||
use ulid::Ulid;
|
||||
use url::Url;
|
||||
|
||||
@@ -56,7 +56,7 @@ pub trait OAuth2AuthorizationGrantRepository: Send + Sync {
|
||||
#[expect(clippy::too_many_arguments)]
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
client: &Client,
|
||||
redirect_uri: Url,
|
||||
@@ -167,7 +167,7 @@ pub trait OAuth2AuthorizationGrantRepository: Send + Sync {
|
||||
repository_impl!(OAuth2AuthorizationGrantRepository:
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
client: &Client,
|
||||
redirect_uri: Url,
|
||||
|
||||
@@ -12,7 +12,7 @@ use mas_data_model::{Client, Clock};
|
||||
use mas_iana::{jose::JsonWebSignatureAlg, oauth::OAuthClientAuthenticationMethod};
|
||||
use mas_jose::jwk::PublicJsonWebKeySet;
|
||||
use oauth2_types::{oidc::ApplicationType, requests::GrantType};
|
||||
use rand_core::RngCore;
|
||||
use rand_core::Rng;
|
||||
use ulid::Ulid;
|
||||
use url::Url;
|
||||
|
||||
@@ -232,7 +232,7 @@ pub trait OAuth2ClientRepository: Send + Sync {
|
||||
#[expect(clippy::too_many_arguments)]
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
redirect_uris: Vec<Url>,
|
||||
metadata_digest: Option<String>,
|
||||
@@ -360,7 +360,7 @@ repository_impl!(OAuth2ClientRepository:
|
||||
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
redirect_uris: Vec<Url>,
|
||||
metadata_digest: Option<String>,
|
||||
|
||||
@@ -11,7 +11,7 @@ use async_trait::async_trait;
|
||||
use chrono::Duration;
|
||||
use mas_data_model::{BrowserSession, Client, Clock, DeviceCodeGrant, Session};
|
||||
use oauth2_types::scope::Scope;
|
||||
use rand_core::RngCore;
|
||||
use rand_core::Rng;
|
||||
use ulid::Ulid;
|
||||
|
||||
use crate::repository_impl;
|
||||
@@ -63,7 +63,7 @@ pub trait OAuth2DeviceCodeGrantRepository: Send + Sync {
|
||||
/// Returns [`Self::Error`] if the underlying repository fails
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
params: OAuth2DeviceCodeGrantParams<'_>,
|
||||
) -> Result<DeviceCodeGrant, Self::Error>;
|
||||
@@ -216,7 +216,7 @@ pub trait OAuth2DeviceCodeGrantRepository: Send + Sync {
|
||||
repository_impl!(OAuth2DeviceCodeGrantRepository:
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
params: OAuth2DeviceCodeGrantParams<'_>,
|
||||
) -> Result<DeviceCodeGrant, Self::Error>;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
use async_trait::async_trait;
|
||||
use mas_data_model::{AccessToken, Clock, RefreshToken, Session};
|
||||
use rand_core::RngCore;
|
||||
use rand_core::Rng;
|
||||
use ulid::Ulid;
|
||||
|
||||
use crate::repository_impl;
|
||||
@@ -66,7 +66,7 @@ pub trait OAuth2RefreshTokenRepository: Send + Sync {
|
||||
/// Returns [`Self::Error`] if the underlying repository fails
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
session: &Session,
|
||||
access_token: &AccessToken,
|
||||
@@ -170,7 +170,7 @@ repository_impl!(OAuth2RefreshTokenRepository:
|
||||
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
session: &Session,
|
||||
access_token: &AccessToken,
|
||||
|
||||
@@ -11,7 +11,7 @@ use async_trait::async_trait;
|
||||
use chrono::{DateTime, Utc};
|
||||
use mas_data_model::{BrowserSession, Client, Clock, Device, Session, User};
|
||||
use oauth2_types::scope::Scope;
|
||||
use rand_core::RngCore;
|
||||
use rand_core::Rng;
|
||||
use ulid::Ulid;
|
||||
|
||||
use crate::{Pagination, pagination::Page, repository_impl, user::BrowserSessionFilter};
|
||||
@@ -348,7 +348,7 @@ pub trait OAuth2SessionRepository: Send + Sync {
|
||||
/// Returns [`Self::Error`] if the underlying repository fails
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
client: &Client,
|
||||
user: Option<&User>,
|
||||
@@ -374,7 +374,7 @@ pub trait OAuth2SessionRepository: Send + Sync {
|
||||
/// Returns [`Self::Error`] if the underlying repository fails
|
||||
async fn add_from_browser_session(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
client: &Client,
|
||||
user_session: &BrowserSession,
|
||||
@@ -408,7 +408,7 @@ pub trait OAuth2SessionRepository: Send + Sync {
|
||||
/// Returns [`Self::Error`] if the underlying repository fails
|
||||
async fn add_from_client_credentials(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
client: &Client,
|
||||
scope: Scope,
|
||||
@@ -568,7 +568,7 @@ repository_impl!(OAuth2SessionRepository:
|
||||
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
client: &Client,
|
||||
user: Option<&User>,
|
||||
@@ -578,7 +578,7 @@ repository_impl!(OAuth2SessionRepository:
|
||||
|
||||
async fn add_from_browser_session(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
client: &Client,
|
||||
user_session: &BrowserSession,
|
||||
@@ -587,7 +587,7 @@ repository_impl!(OAuth2SessionRepository:
|
||||
|
||||
async fn add_from_client_credentials(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
client: &Client,
|
||||
scope: Scope,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2025 New Vector Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
@@ -9,7 +10,7 @@ use mas_data_model::{
|
||||
Clock,
|
||||
personal::{PersonalAccessToken, session::PersonalSession},
|
||||
};
|
||||
use rand_core::RngCore;
|
||||
use rand_core::Rng;
|
||||
use ulid::Ulid;
|
||||
|
||||
use crate::repository_impl;
|
||||
@@ -84,7 +85,7 @@ pub trait PersonalAccessTokenRepository: Send + Sync {
|
||||
/// Returns [`Self::Error`] if the underlying repository fails
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
session: &PersonalSession,
|
||||
access_token: &str,
|
||||
@@ -125,7 +126,7 @@ repository_impl!(PersonalAccessTokenRepository:
|
||||
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
session: &PersonalSession,
|
||||
access_token: &str,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2025 New Vector Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
@@ -15,7 +16,7 @@ use mas_data_model::{
|
||||
},
|
||||
};
|
||||
use oauth2_types::scope::Scope;
|
||||
use rand_core::RngCore;
|
||||
use rand_core::Rng;
|
||||
use ulid::Ulid;
|
||||
|
||||
use crate::{Page, Pagination, repository_impl};
|
||||
@@ -61,7 +62,7 @@ pub trait PersonalSessionRepository: Send + Sync {
|
||||
/// Returns [`Self::Error`] if the underlying repository fails
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
owner: PersonalSessionOwner,
|
||||
actor_user: &User,
|
||||
@@ -154,7 +155,7 @@ repository_impl!(PersonalSessionRepository:
|
||||
|
||||
async fn add(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
owner: PersonalSessionOwner,
|
||||
actor_user: &User,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Copyright 2025, 2026 Element Creations Ltd.
|
||||
// Copyright 2025 New Vector Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
@@ -7,7 +8,7 @@
|
||||
|
||||
use async_trait::async_trait;
|
||||
use mas_data_model::{Clock, PolicyData};
|
||||
use rand_core::RngCore;
|
||||
use rand_core::Rng;
|
||||
|
||||
use crate::repository_impl;
|
||||
|
||||
@@ -43,7 +44,7 @@ pub trait PolicyDataRepository: Send + Sync {
|
||||
/// Returns [`Self::Error`] if the underlying repository fails
|
||||
async fn set(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
data: serde_json::Value,
|
||||
) -> Result<PolicyData, Self::Error>;
|
||||
@@ -67,7 +68,7 @@ repository_impl!(PolicyDataRepository:
|
||||
|
||||
async fn set(
|
||||
&mut self,
|
||||
rng: &mut (dyn RngCore + Send),
|
||||
rng: &mut (dyn Rng + Send),
|
||||
clock: &dyn Clock,
|
||||
data: serde_json::Value,
|
||||
) -> Result<PolicyData, Self::Error>;
|
||||
|
||||
Loaded 100 of 125 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user