use crate::{schema, UIDCError}; use microrm::prelude::*; pub fn change_auth( realm: &schema::Realm, username: &String, change_password: bool, change_totp: bool, ) -> Result<(), UIDCError> { // check that the user exists let user = realm .users .with(schema::User::Username, username) .first() .get()? .ok_or(UIDCError::Abort("no such user"))?; let user_id = user.id(); let user = crate::user::User::from_schema(realm, user); if change_password { let raw_pass = rpassword::prompt_password("Enter new user password: ").unwrap(); user.set_new_password(raw_pass.as_bytes())?; } if change_totp { let (new_secret, new_uri) = user.generate_totp_with_uri()?; println!("Please confirm you can generate tokens with the new secret:"); qr2term::print_qr(new_uri.as_str()) .map_err(|_| UIDCError::Abort("could not display QR code"))?; let new_challenge = schema::AuthChallenge { user_id, challenge_type: schema::AuthChallengeType::TOTP.into(), public: vec![], secret: new_secret.clone(), enabled: true, }; loop { let digits = rpassword::prompt_password("TOTP code: ").unwrap(); if new_challenge.verify_totp_challenge(digits.as_bytes())? { break; } } user.set_new_totp(new_secret.as_slice())?; } Ok(()) }