arminius_lib_authentication/
test_utils.rs1#![cfg(any(feature = "test_utils", test))]
9
10use arminius_lib_db::{Database, DefaultDb};
11use base64::prelude::{BASE64_URL_SAFE_NO_PAD, Engine as _};
12use color_eyre::eyre::Context as _;
13use jsonwebtoken::jwk::JwkSet;
14use ruma::{DeviceId, owned_device_id};
15use serde_json::json;
16use url::Url;
17use wiremock::{Mock, MockServer, ResponseTemplate};
18
19use super::*;
20
21pub(crate) static SECRET: Vec<u8> = Vec::new();
23
24#[must_use]
26pub fn test_jwk() -> jwk::Jwk {
27 jwk::Jwk {
28 common: jwk::CommonParameters {
29 key_algorithm: jwk::KeyAlgorithm::HS256.into(),
30 ..Default::default()
31 },
32 algorithm: jwk::AlgorithmParameters::OctetKey(jwk::OctetKeyParameters {
33 value: BASE64_URL_SAFE_NO_PAD.encode(&SECRET[..]),
34 ..Default::default()
35 }),
36 }
37}
38
39pub fn generate_auth_token(
41 user_id: &UserId,
42 device_id: &DeviceId,
43) -> color_eyre::eyre::Result<String> {
44 jsonwebtoken::encode(
45 &jsonwebtoken::Header::new(jsonwebtoken::Algorithm::HS256),
46 &Claims {
49 issued_at: 1,
50 subject: user_id.to_string(),
51 session_id: device_id.as_str().to_owned(),
52 },
53 &jsonwebtoken::EncodingKey::from_secret(&SECRET),
54 )
55 .context("Token generation failed")
56}
57
58pub async fn auth_header_for_new_user(
60 database: &mut DefaultDb,
61 user_id: &OwnedUserId,
62 device_id: &OwnedDeviceId,
63) -> color_eyre::eyre::Result<String> {
64 Ok(format!(
65 "Bearer {}",
66 auth_token_for_new_user_with_device(database, user_id, device_id).await?
67 ))
68}
69
70pub async fn auth_token_for_new_user_with_device(
72 database: &mut impl Database,
73 user_id: &UserId,
74 device_id: &DeviceId,
75) -> color_eyre::eyre::Result<String> {
76 use arminius_lib_db_devices::DeviceQueries as _;
77 database
78 .insert_test_user_with_device(user_id, device_id)
79 .await
80 .context("Failed to insert test user with device")?;
81
82 generate_auth_token(user_id, device_id)
83}
84pub async fn auth_token_for_new_user(
86 database: &mut DefaultDb,
87 user_id: &OwnedUserId,
88) -> color_eyre::eyre::Result<String> {
89 auth_token_for_new_user_with_device(database, user_id, &owned_device_id!("MYDEVICEID")).await
90}
91
92pub async fn mock_oidc_keys(keys: Vec<jwk::Jwk>) -> (MockServer, Url) {
95 let mock_server = MockServer::start().await;
96
97 let jwks_path = "/jwks";
98 let well_known_path = "/.well-known/openid-configuration";
99 let well_known_json = json!({
100 "jwks_uri": format!("{}{}", mock_server.uri(), jwks_path)
101 });
102
103 Mock::given(wiremock::matchers::path(jwks_path))
104 .respond_with(ResponseTemplate::new(200).set_body_json(JwkSet { keys }))
105 .mount(&mock_server)
106 .await;
107
108 Mock::given(wiremock::matchers::path(well_known_path))
109 .respond_with(ResponseTemplate::new(200).set_body_json(well_known_json))
110 .mount(&mock_server)
111 .await;
112
113 let Ok(mock_url) = Url::parse(&mock_server.uri()).and_then(|url| url.join(well_known_path))
114 else {
115 unreachable!("mock URL must be valid")
116 };
117 (mock_server, mock_url)
118}