You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-07-31 09:24:31 +03:00
storage-pg: add tests for most remaining repositories
Also fixes all the list_paginated() repository methods
This commit is contained in:
@ -35,11 +35,12 @@ mod tests {
|
|||||||
CompatAccessTokenRepository, CompatRefreshTokenRepository, CompatSessionRepository,
|
CompatAccessTokenRepository, CompatRefreshTokenRepository, CompatSessionRepository,
|
||||||
},
|
},
|
||||||
user::UserRepository,
|
user::UserRepository,
|
||||||
Clock, Repository, RepositoryAccess,
|
Clock, Pagination, Repository, RepositoryAccess,
|
||||||
};
|
};
|
||||||
use rand::SeedableRng;
|
use rand::SeedableRng;
|
||||||
use rand_chacha::ChaChaRng;
|
use rand_chacha::ChaChaRng;
|
||||||
use sqlx::PgPool;
|
use sqlx::PgPool;
|
||||||
|
use ulid::Ulid;
|
||||||
|
|
||||||
use crate::PgRepository;
|
use crate::PgRepository;
|
||||||
|
|
||||||
@ -323,4 +324,126 @@ mod tests {
|
|||||||
|
|
||||||
repo.save().await.unwrap();
|
repo.save().await.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[sqlx::test(migrator = "crate::MIGRATOR")]
|
||||||
|
async fn test_compat_sso_login_repository(pool: PgPool) {
|
||||||
|
let mut rng = ChaChaRng::seed_from_u64(42);
|
||||||
|
let clock = MockClock::default();
|
||||||
|
let mut repo = PgRepository::from_pool(&pool).await.unwrap().boxed();
|
||||||
|
|
||||||
|
// Create a user
|
||||||
|
let user = repo
|
||||||
|
.user()
|
||||||
|
.add(&mut rng, &clock, "john".to_owned())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// Lookup an unknown SSO login
|
||||||
|
let login = repo.compat_sso_login().lookup(Ulid::nil()).await.unwrap();
|
||||||
|
assert_eq!(login, None);
|
||||||
|
|
||||||
|
// Lookup an unknown login token
|
||||||
|
let login = repo
|
||||||
|
.compat_sso_login()
|
||||||
|
.find_by_token("login-token")
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(login, None);
|
||||||
|
|
||||||
|
// Start a new SSO login
|
||||||
|
let login = repo
|
||||||
|
.compat_sso_login()
|
||||||
|
.add(
|
||||||
|
&mut rng,
|
||||||
|
&clock,
|
||||||
|
"login-token".to_owned(),
|
||||||
|
"https://example.com/callback".parse().unwrap(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
assert!(login.is_pending());
|
||||||
|
|
||||||
|
// Lookup the login by ID
|
||||||
|
let login_lookup = repo
|
||||||
|
.compat_sso_login()
|
||||||
|
.lookup(login.id)
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.expect("login not found");
|
||||||
|
assert_eq!(login_lookup, login);
|
||||||
|
|
||||||
|
// Find the login by token
|
||||||
|
let login_lookup = repo
|
||||||
|
.compat_sso_login()
|
||||||
|
.find_by_token("login-token")
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.expect("login not found");
|
||||||
|
assert_eq!(login_lookup, login);
|
||||||
|
|
||||||
|
// Exchanging before fulfilling should not work
|
||||||
|
// Note: It should also not poison the SQL transaction
|
||||||
|
let res = repo
|
||||||
|
.compat_sso_login()
|
||||||
|
.exchange(&clock, login.clone())
|
||||||
|
.await;
|
||||||
|
assert!(res.is_err());
|
||||||
|
|
||||||
|
// Start a compat session for that user
|
||||||
|
let device = Device::generate(&mut rng);
|
||||||
|
let session = repo
|
||||||
|
.compat_session()
|
||||||
|
.add(&mut rng, &clock, &user, device)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// Associate the login with the session
|
||||||
|
let login = repo
|
||||||
|
.compat_sso_login()
|
||||||
|
.fulfill(&clock, login, &session)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
assert!(login.is_fulfilled());
|
||||||
|
|
||||||
|
// Fulfilling again should not work
|
||||||
|
// Note: It should also not poison the SQL transaction
|
||||||
|
let res = repo
|
||||||
|
.compat_sso_login()
|
||||||
|
.fulfill(&clock, login.clone(), &session)
|
||||||
|
.await;
|
||||||
|
assert!(res.is_err());
|
||||||
|
|
||||||
|
// Exchange that login
|
||||||
|
let login = repo
|
||||||
|
.compat_sso_login()
|
||||||
|
.exchange(&clock, login)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
assert!(login.is_exchanged());
|
||||||
|
|
||||||
|
// Exchange again should not work
|
||||||
|
// Note: It should also not poison the SQL transaction
|
||||||
|
let res = repo
|
||||||
|
.compat_sso_login()
|
||||||
|
.exchange(&clock, login.clone())
|
||||||
|
.await;
|
||||||
|
assert!(res.is_err());
|
||||||
|
|
||||||
|
// Fulfilling after exchanging should not work
|
||||||
|
// Note: It should also not poison the SQL transaction
|
||||||
|
let res = repo
|
||||||
|
.compat_sso_login()
|
||||||
|
.fulfill(&clock, login.clone(), &session)
|
||||||
|
.await;
|
||||||
|
assert!(res.is_err());
|
||||||
|
|
||||||
|
// List the logins for the user
|
||||||
|
let logins = repo
|
||||||
|
.compat_sso_login()
|
||||||
|
.list_paginated(&user, Pagination::first(10))
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
assert!(!logins.has_next_page);
|
||||||
|
assert_eq!(logins.edges, vec![login]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -323,12 +323,12 @@ impl<'c> CompatSsoLoginRepository for PgCompatSsoLoginRepository<'c> {
|
|||||||
, cl.compat_session_id
|
, cl.compat_session_id
|
||||||
|
|
||||||
FROM compat_sso_logins cl
|
FROM compat_sso_logins cl
|
||||||
INNER JOIN compat_sessions ON compat_session_id
|
INNER JOIN compat_sessions cs USING (compat_session_id)
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
|
|
||||||
query
|
query
|
||||||
.push(" WHERE user_id = ")
|
.push(" WHERE cs.user_id = ")
|
||||||
.push_bind(Uuid::from(user.id))
|
.push_bind(Uuid::from(user.id))
|
||||||
.generate_pagination("cl.compat_sso_login_id", pagination);
|
.generate_pagination("cl.compat_sso_login_id", pagination);
|
||||||
|
|
||||||
|
@ -176,6 +176,29 @@ mod tests {
|
|||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
// Lookup the consent the user gave to the client
|
||||||
|
let consent = repo
|
||||||
|
.oauth2_client()
|
||||||
|
.get_consent_for_user(&client, &user)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
assert!(consent.is_empty());
|
||||||
|
|
||||||
|
// Give consent to the client
|
||||||
|
let scope = Scope::from_iter([OPENID]);
|
||||||
|
repo.oauth2_client()
|
||||||
|
.give_consent_for_user(&mut rng, &clock, &client, &user, &scope)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// Lookup the consent the user gave to the client
|
||||||
|
let consent = repo
|
||||||
|
.oauth2_client()
|
||||||
|
.get_consent_for_user(&client, &user)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(scope, consent);
|
||||||
|
|
||||||
// Lookup a non-existing session
|
// Lookup a non-existing session
|
||||||
let session = repo.oauth2_session().lookup(Ulid::nil()).await.unwrap();
|
let session = repo.oauth2_session().lookup(Ulid::nil()).await.unwrap();
|
||||||
assert_eq!(session, None);
|
assert_eq!(session, None);
|
||||||
|
@ -249,7 +249,7 @@ impl<'c> UserEmailRepository for PgUserEmailRepository<'c> {
|
|||||||
query
|
query
|
||||||
.push(" WHERE user_id = ")
|
.push(" WHERE user_id = ")
|
||||||
.push_bind(Uuid::from(user.id))
|
.push_bind(Uuid::from(user.id))
|
||||||
.generate_pagination("ue.user_email_id", pagination);
|
.generate_pagination("user_email_id", pagination);
|
||||||
|
|
||||||
let edges: Vec<UserEmailLookup> = query
|
let edges: Vec<UserEmailLookup> = query
|
||||||
.build_query_as()
|
.build_query_as()
|
||||||
|
@ -16,7 +16,7 @@ use chrono::Duration;
|
|||||||
use mas_storage::{
|
use mas_storage::{
|
||||||
clock::MockClock,
|
clock::MockClock,
|
||||||
user::{BrowserSessionRepository, UserEmailRepository, UserPasswordRepository, UserRepository},
|
user::{BrowserSessionRepository, UserEmailRepository, UserPasswordRepository, UserRepository},
|
||||||
Repository, RepositoryAccess,
|
Pagination, Repository, RepositoryAccess,
|
||||||
};
|
};
|
||||||
use rand::SeedableRng;
|
use rand::SeedableRng;
|
||||||
use rand_chacha::ChaChaRng;
|
use rand_chacha::ChaChaRng;
|
||||||
@ -230,6 +230,16 @@ async fn test_user_email_repo(pool: PgPool) {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.is_some());
|
.is_some());
|
||||||
|
|
||||||
|
// Listing the user emails should work
|
||||||
|
let emails = repo
|
||||||
|
.user_email()
|
||||||
|
.list_paginated(&user, Pagination::first(10))
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
assert!(!emails.has_next_page);
|
||||||
|
assert_eq!(emails.edges.len(), 1);
|
||||||
|
assert_eq!(emails.edges[0], user_email);
|
||||||
|
|
||||||
// Deleting the user email should work
|
// Deleting the user email should work
|
||||||
repo.user_email().remove(user_email).await.unwrap();
|
repo.user_email().remove(user_email).await.unwrap();
|
||||||
assert_eq!(repo.user_email().count(&user).await.unwrap(), 0);
|
assert_eq!(repo.user_email().count(&user).await.unwrap(), 0);
|
||||||
|
Reference in New Issue
Block a user