-
Notifications
You must be signed in to change notification settings - Fork 192
Open
Labels
Description
Versions/Environment
- What version of Rust are you using? 1.90
- What operating system are you using? NixOS Unstable
- What versions of the driver and its dependencies are you using? (Run
cargo pkgid mongodb&cargo pkgid bson) registry+https://github.com/rust-lang/crates.io-index#[email protected] registry+https://github.com/rust-lang/crates.io-index#[email protected] - What version of MongoDB are you using? cloud.mongodb.com
- What is your MongoDB topology (standalone, replica set, sharded cluster, serverless)? I guess sharded cluster
Describe the bug
I am using a enum ApplicationStatus for storing the current state of the Applicant. ApplicationStatus is internally tagged. I tried searching the applicants collection with different queries none of them worked only the first one worked (see below function).
The same queries ran on mongodb cloud without any issues
#[derive(serde::Deserialize, serde::Serialize)]
pub struct Applicant {
pub display_name: Option<String>,
pub email: String,
pub birth_date: Option<mongodb::bson::DateTime>,
pub password: Option<String>,
pub icon: Option<String>,
pub phone: Option<String>,
pub status: ApplicationStatus,
}
#[derive(serde::Deserialize, serde::Serialize, PartialEq, Debug, Clone)]
#[serde(tag = "tag", content = "value")]
pub enum ApplicationStatus {
Created(String), // OTP
EmailVerified,
PasswordSet,
OidcVerified,
Recovering(String), // HEX HASH
UpdatingEmail { old_email: String, otp: String }, // OTP
UpdatingPhone { old_phone: String, otp: String }, // OTP
}
impl crate::Db {
pub async fn verify_applicant_email(
self: Arc<Self>,
email: &str,
otp: &str,
) -> Result<(), AppError> {
let filter =
doc! {"email": email, "status": {"tag": "Created", "value": otp}}; // this query works
// doc! {"email": email, "status": {"tag": "Created", "value": {"$exists": true}}}; // this doesn't
// doc! {"email": email, "status": {"tag": "Created"}}; // neither this one
// doc! {"email": email, "status.tag": "Created"}; // nor this one
let applicant = match self.applicants.find_one(filter.clone()).await {
Ok(Some(v)) => v,
Ok(None) => return Err(AppError::UserNotFound),
Err(e) => {
tracing::error!("{e:?}");
return Err(AppError::ServerError);
}
};
if let ApplicationStatus::Created(db_otp) = applicant.status
&& db_otp == otp
{
let status_bson = bson::to_bson(&ApplicationStatus::EmailVerified).unwrap();
let update = doc! {"$set": {"status": status_bson }};
match self.applicants.update_one(filter, update).await {
Ok(_) => {
tracing::info!("[Email Verified] Email: {email}");
Ok(())
}
Err(e) => {
tracing::error!("{e:?}");
Err(AppError::ServerError)
}
}
} else {
Err(AppError::InvalidOTP)
}
}
}BE SPECIFIC:
- What is the expected behavior and what is actually happening? MongoDB should give out a document, but it returns None
- Do you have any particular output that demonstrates this problem?
- Do you have any ideas on why this may be happening that could give us a
clue in the right direction? - Did this issue arise out of nowhere, or after an update (of the driver,
server, and/or Rust)? - Are there multiple ways of triggering this bug (perhaps more than one
function produce a crash)? No - If you know how to reproduce this bug, please include a code snippet here:
To Reproduce
Steps to reproduce the behavior:
- Run the code
- Insert a document
- Find or try to update the document with the types specified above