storage: Add an email filter on the user email list

This commit is contained in:
Quentin Gliech committed 2024-06-28 15:59:21 +02:00
1 parent 319c43abc5
commit b2ee5de050
3 files changed
+60 -2

No files matched your search

+11 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2022, 2023 The Matrix.org Foundation C.I.C.
// Copyright 2022-2024 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -270,6 +270,11 @@ impl<'c> UserEmailRepository for PgUserEmailRepository<'c> {
.and_where_option(filter.user().map(|user| {
Expr::col((UserEmails::Table, UserEmails::UserId)).eq(Uuid::from(user.id))
}))
.and_where_option(
filter
.email()
.map(|email| Expr::col((UserEmails::Table, UserEmails::Email)).eq(email)),
)
.and_where_option(filter.state().map(|state| {
if state.is_verified() {
Expr::col((UserEmails::Table, UserEmails::ConfirmedAt)).is_not_null()
@@ -305,6 +310,11 @@ impl<'c> UserEmailRepository for PgUserEmailRepository<'c> {
.and_where_option(filter.user().map(|user| {
Expr::col((UserEmails::Table, UserEmails::UserId)).eq(Uuid::from(user.id))
}))
.and_where_option(
filter
.email()
.map(|email| Expr::col((UserEmails::Table, UserEmails::Email)).eq(email)),
)
.and_where_option(filter.state().map(|state| {
if state.is_verified() {
Expr::col((UserEmails::Table, UserEmails::ConfirmedAt)).is_not_null()
+33 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2023 The Matrix.org Foundation C.I.C.
// Copyright 2023, 2024 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -321,6 +321,38 @@ async fn test_user_email_repo(pool: PgPool) {
assert!(!emails.has_next_page);
assert!(emails.edges.is_empty());
// Listing emails from the email address should work
let emails = repo
.user_email()
.list(all.for_email(EMAIL), Pagination::first(10))
.await
.unwrap();
assert!(!emails.has_next_page);
assert_eq!(emails.edges.len(), 1);
assert_eq!(emails.edges[0], user_email);
// Filtering on another email should not return anything
let emails = repo
.user_email()
.list(all.for_email("hello@example.com"), Pagination::first(10))
.await
.unwrap();
assert!(!emails.has_next_page);
assert!(emails.edges.is_empty());
// Counting also works with the email filter
assert_eq!(
repo.user_email().count(all.for_email(EMAIL)).await.unwrap(),
1
);
assert_eq!(
repo.user_email()
.count(all.for_email("hello@example.com"))
.await
.unwrap(),
0
);
// Deleting the user email should work
repo.user_email().remove(user_email).await.unwrap();
assert_eq!(repo.user_email().count(all).await.unwrap(), 0);
+16
View File
@@ -41,6 +41,7 @@ impl UserEmailState {
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
pub struct UserEmailFilter<'a> {
user: Option<&'a User>,
email: Option<&'a str>,
state: Option<UserEmailState>,
}
@@ -58,6 +59,13 @@ impl<'a> UserEmailFilter<'a> {
self
}
/// Filter for emails matching a specific email address
#[must_use]
pub fn for_email(mut self, email: &'a str) -> Self {
self.email = Some(email);
self
}
/// Get the user filter
///
/// Returns [`None`] if no user filter is set
@@ -66,6 +74,14 @@ impl<'a> UserEmailFilter<'a> {
self.user
}
/// Get the email filter
///
/// Returns [`None`] if no email filter is set
#[must_use]
pub fn email(&self) -> Option<&str> {
self.email
}
/// Filter for emails that are verified
#[must_use]
pub fn verified_only(mut self) -> Self {