diff --git a/Cargo.toml b/Cargo.toml index 3d719a66..1d8a6ca0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -323,6 +323,7 @@ needless_continue = "deny" needless_lifetimes = "deny" option_option = "deny" redundant_clone = "deny" +ref_option = "deny" string_add_assign = "deny" unnecessary_join = "deny" unnecessary_self_imports = "deny" diff --git a/src/api/admin.rs b/src/api/admin.rs index 9a782046..02c976cc 100644 --- a/src/api/admin.rs +++ b/src/api/admin.rs @@ -469,7 +469,7 @@ async fn deauth_user(user_id: UserId, _token: AdminToken, conn: DbConn, nt: Noti if CONFIG.push_enabled() { for device in Device::find_push_devices_by_user(&user.uuid, &conn).await { - match unregister_push_device(&device.push_uuid).await { + match unregister_push_device(device.push_uuid.as_ref()).await { Ok(r) => r, Err(e) => error!("Unable to unregister devices from Bitwarden server: {e}"), }; diff --git a/src/api/core/accounts.rs b/src/api/core/accounts.rs index fa6a3fd2..a8f9768e 100644 --- a/src/api/core/accounts.rs +++ b/src/api/core/accounts.rs @@ -137,7 +137,7 @@ struct KeysData { } /// Trims whitespace from password hints, and converts blank password hints to `None`. -fn clean_password_hint(password_hint: &Option) -> Option { +fn clean_password_hint(password_hint: Option<&String>) -> Option { match password_hint { None => None, Some(h) => match h.trim() { @@ -147,7 +147,7 @@ fn clean_password_hint(password_hint: &Option) -> Option { } } -fn enforce_password_hint_setting(password_hint: &Option) -> EmptyResult { +fn enforce_password_hint_setting(password_hint: Option<&String>) -> EmptyResult { if password_hint.is_some() && !CONFIG.password_hints_allowed() { err!("Password hints have been disabled by the administrator. Remove the hint and try again."); } @@ -245,8 +245,8 @@ pub async fn _register(data: Json, email_verification: bool, conn: // Check against the password hint setting here so if it fails, the user // can retry without losing their invitation below. - let password_hint = clean_password_hint(&data.master_password_hint); - enforce_password_hint_setting(&password_hint)?; + let password_hint = clean_password_hint(data.master_password_hint.as_ref()); + enforce_password_hint_setting(password_hint.as_ref())?; let mut user = match User::find_by_mail(&email, &conn).await { Some(user) => { @@ -353,8 +353,8 @@ async fn post_set_password(data: Json, headers: Headers, conn: // Check against the password hint setting here so if it fails, // the user can retry without losing their invitation below. - let password_hint = clean_password_hint(&data.master_password_hint); - enforce_password_hint_setting(&password_hint)?; + let password_hint = clean_password_hint(data.master_password_hint.as_ref()); + enforce_password_hint_setting(password_hint.as_ref())?; set_kdf_data(&mut user, &data.kdf)?; @@ -515,8 +515,8 @@ async fn post_password(data: Json, headers: Headers, conn: DbCon err!("Invalid password") } - user.password_hint = clean_password_hint(&data.master_password_hint); - enforce_password_hint_setting(&user.password_hint)?; + user.password_hint = clean_password_hint(data.master_password_hint.as_ref()); + enforce_password_hint_setting(user.password_hint.as_ref())?; log_user_event(EventType::UserChangedPassword as i32, &user.uuid, headers.device.atype, &headers.ip.ip, &conn) .await; @@ -1438,7 +1438,7 @@ async fn put_clear_device_token(device_id: DeviceId, conn: DbConn) -> EmptyResul if let Some(device) = Device::find_by_uuid(&device_id, &conn).await { Device::clear_push_token_by_uuid(&device_id, &conn).await?; - unregister_push_device(&device.push_uuid).await?; + unregister_push_device(device.push_uuid.as_ref()).await?; } Ok(()) diff --git a/src/api/core/ciphers.rs b/src/api/core/ciphers.rs index 6d4e1f41..29aa859e 100644 --- a/src/api/core/ciphers.rs +++ b/src/api/core/ciphers.rs @@ -630,7 +630,7 @@ async fn post_ciphers_import(data: Json, headers: Headers, conn: DbC let mut user = headers.user; user.update_revision(&conn).await?; - nt.send_user_update(UpdateType::SyncVault, &user, &headers.device.push_uuid, &conn).await; + nt.send_user_update(UpdateType::SyncVault, &user, headers.device.push_uuid.as_ref(), &conn).await; Ok(()) } @@ -1005,7 +1005,7 @@ async fn put_cipher_share_selected( } // Multi share actions do not send out a push for each cipher, we need to send a general sync here - nt.send_user_update(UpdateType::SyncCiphers, &headers.user, &headers.device.push_uuid, &conn).await; + nt.send_user_update(UpdateType::SyncCiphers, &headers.user, headers.device.push_uuid.as_ref(), &conn).await; Ok(()) } @@ -1618,7 +1618,7 @@ async fn move_cipher_selected( .await; } else { // Multi move actions do not send out a push for each cipher, we need to send a general sync here - nt.send_user_update(UpdateType::SyncCiphers, &headers.user, &headers.device.push_uuid, &conn).await; + nt.send_user_update(UpdateType::SyncCiphers, &headers.user, headers.device.push_uuid.as_ref(), &conn).await; } if cipher_count != accessible_ciphers_count { @@ -1670,7 +1670,7 @@ async fn purge_org_vault( match Membership::find_confirmed_by_user_and_org(&user.uuid, &organization.org_id, &conn).await { Some(member) if member.atype == MembershipType::Owner => { Cipher::delete_all_by_organization(&organization.org_id, &conn).await?; - nt.send_user_update(UpdateType::SyncVault, &user, &headers.device.push_uuid, &conn).await; + nt.send_user_update(UpdateType::SyncVault, &user, headers.device.push_uuid.as_ref(), &conn).await; log_event( EventType::OrganizationPurgedVault as i32, @@ -1710,7 +1710,7 @@ async fn purge_personal_vault( } user.update_revision(&conn).await?; - nt.send_user_update(UpdateType::SyncVault, &user, &headers.device.push_uuid, &conn).await; + nt.send_user_update(UpdateType::SyncVault, &user, headers.device.push_uuid.as_ref(), &conn).await; Ok(()) } @@ -1805,7 +1805,7 @@ async fn _delete_multiple_ciphers( } // Multi delete actions do not send out a push for each cipher, we need to send a general sync here - nt.send_user_update(UpdateType::SyncCiphers, &headers.user, &headers.device.push_uuid, &conn).await; + nt.send_user_update(UpdateType::SyncCiphers, &headers.user, headers.device.push_uuid.as_ref(), &conn).await; Ok(()) } @@ -1873,7 +1873,7 @@ async fn _restore_multiple_ciphers( } // Multi move actions do not send out a push for each cipher, we need to send a general sync here - nt.send_user_update(UpdateType::SyncCiphers, &headers.user, &headers.device.push_uuid, conn).await; + nt.send_user_update(UpdateType::SyncCiphers, &headers.user, headers.device.push_uuid.as_ref(), conn).await; Ok(Json(json!({ "data": ciphers, diff --git a/src/api/core/mod.rs b/src/api/core/mod.rs index 038b9a6d..e0a56e4d 100644 --- a/src/api/core/mod.rs +++ b/src/api/core/mod.rs @@ -124,7 +124,7 @@ async fn post_eq_domains(data: Json, headers: Headers, conn: Db user.save(&conn).await?; - nt.send_user_update(UpdateType::SyncSettings, &user, &headers.device.push_uuid, &conn).await; + nt.send_user_update(UpdateType::SyncSettings, &user, headers.device.push_uuid.as_ref(), &conn).await; Ok(Json(json!({}))) } diff --git a/src/api/core/organizations.rs b/src/api/core/organizations.rs index 318001dc..434f0f9d 100644 --- a/src/api/core/organizations.rs +++ b/src/api/core/organizations.rs @@ -1463,7 +1463,7 @@ async fn _confirm_invite( let save_result = member_to_confirm.save(conn).await; if let Some(user) = User::find_by_uuid(&member_to_confirm.user_uuid, conn).await { - nt.send_user_update(UpdateType::SyncOrgKeys, &user, &headers.device.push_uuid, conn).await; + nt.send_user_update(UpdateType::SyncOrgKeys, &user, headers.device.push_uuid.as_ref(), conn).await; } save_result @@ -1721,7 +1721,7 @@ async fn _delete_member( .await; if let Some(user) = User::find_by_uuid(&member_to_delete.user_uuid, conn).await { - nt.send_user_update(UpdateType::SyncOrgKeys, &user, &headers.device.push_uuid, conn).await; + nt.send_user_update(UpdateType::SyncOrgKeys, &user, headers.device.push_uuid.as_ref(), conn).await; } member_to_delete.delete(conn).await diff --git a/src/api/identity.rs b/src/api/identity.rs index c38fcd34..72323f73 100644 --- a/src/api/identity.rs +++ b/src/api/identity.rs @@ -65,43 +65,43 @@ async fn login( let login_result = match data.grant_type.as_ref() { "refresh_token" => { - _check_is_some(&data.refresh_token, "refresh_token cannot be blank")?; + _check_is_some(data.refresh_token.as_ref(), "refresh_token cannot be blank")?; _refresh_login(data, &conn, &client_header.ip).await } "password" if CONFIG.sso_enabled() && CONFIG.sso_only() => err!("SSO sign-in is required"), "password" => { - _check_is_some(&data.client_id, "client_id cannot be blank")?; - _check_is_some(&data.password, "password cannot be blank")?; - _check_is_some(&data.scope, "scope cannot be blank")?; - _check_is_some(&data.username, "username cannot be blank")?; + _check_is_some(data.client_id.as_ref(), "client_id cannot be blank")?; + _check_is_some(data.password.as_ref(), "password cannot be blank")?; + _check_is_some(data.scope.as_ref(), "scope cannot be blank")?; + _check_is_some(data.username.as_ref(), "username cannot be blank")?; - _check_is_some(&data.device_identifier, "device_identifier cannot be blank")?; - _check_is_some(&data.device_name, "device_name cannot be blank")?; - _check_is_some(&data.device_type, "device_type cannot be blank")?; + _check_is_some(data.device_identifier.as_ref(), "device_identifier cannot be blank")?; + _check_is_some(data.device_name.as_ref(), "device_name cannot be blank")?; + _check_is_some(data.device_type.as_ref(), "device_type cannot be blank")?; - _password_login(data, &mut user_id, &conn, &client_header.ip, &client_version).await + _password_login(data, &mut user_id, &conn, &client_header.ip, client_version.as_ref()).await } "client_credentials" => { - _check_is_some(&data.client_id, "client_id cannot be blank")?; - _check_is_some(&data.client_secret, "client_secret cannot be blank")?; - _check_is_some(&data.scope, "scope cannot be blank")?; + _check_is_some(data.client_id.as_ref(), "client_id cannot be blank")?; + _check_is_some(data.client_secret.as_ref(), "client_secret cannot be blank")?; + _check_is_some(data.scope.as_ref(), "scope cannot be blank")?; - _check_is_some(&data.device_identifier, "device_identifier cannot be blank")?; - _check_is_some(&data.device_name, "device_name cannot be blank")?; - _check_is_some(&data.device_type, "device_type cannot be blank")?; + _check_is_some(data.device_identifier.as_ref(), "device_identifier cannot be blank")?; + _check_is_some(data.device_name.as_ref(), "device_name cannot be blank")?; + _check_is_some(data.device_type.as_ref(), "device_type cannot be blank")?; _api_key_login(data, &mut user_id, &conn, &client_header.ip).await } "authorization_code" if CONFIG.sso_enabled() => { - _check_is_some(&data.client_id, "client_id cannot be blank")?; - _check_is_some(&data.code, "code cannot be blank")?; - _check_is_some(&data.code_verifier, "code verifier cannot be blank")?; + _check_is_some(data.client_id.as_ref(), "client_id cannot be blank")?; + _check_is_some(data.code.as_ref(), "code cannot be blank")?; + _check_is_some(data.code_verifier.as_ref(), "code verifier cannot be blank")?; - _check_is_some(&data.device_identifier, "device_identifier cannot be blank")?; - _check_is_some(&data.device_name, "device_name cannot be blank")?; - _check_is_some(&data.device_type, "device_type cannot be blank")?; + _check_is_some(data.device_identifier.as_ref(), "device_identifier cannot be blank")?; + _check_is_some(data.device_name.as_ref(), "device_name cannot be blank")?; + _check_is_some(data.device_type.as_ref(), "device_type cannot be blank")?; - _sso_login(data, &mut user_id, &conn, &client_header.ip, &client_version).await + _sso_login(data, &mut user_id, &conn, &client_header.ip, client_version.as_ref()).await } "authorization_code" => err!("SSO sign-in is not available"), t => err!("Invalid type", t), @@ -177,7 +177,7 @@ async fn _sso_login( user_id: &mut Option, conn: &DbConn, ip: &ClientIp, - client_version: &Option, + client_version: Option<&ClientVersion>, ) -> JsonResult { AuthMethod::Sso.check_scope(data.scope.as_ref())?; @@ -320,7 +320,7 @@ async fn _password_login( user_id: &mut Option, conn: &DbConn, ip: &ClientIp, - client_version: &Option, + client_version: Option<&ClientVersion>, ) -> JsonResult { // Validate scope AuthMethod::Password.check_scope(data.scope.as_ref())?; @@ -734,7 +734,7 @@ async fn twofactor_auth( data: &ConnectData, device: &mut Device, ip: &ClientIp, - client_version: &Option, + client_version: Option<&ClientVersion>, conn: &DbConn, ) -> ApiResult> { let twofactors = TwoFactor::find_by_user(&user.uuid, conn).await; @@ -879,7 +879,7 @@ async fn _json_err_twofactor( providers: &[i32], user_id: &UserId, data: &ConnectData, - client_version: &Option, + client_version: Option<&ClientVersion>, conn: &DbConn, ) -> ApiResult { let mut result = json!({ @@ -1114,7 +1114,7 @@ struct ConnectData { #[field(name = uncased("code_verifier"))] code_verifier: Option, } -fn _check_is_some(value: &Option, msg: &str) -> EmptyResult { +fn _check_is_some(value: Option<&T>, msg: &str) -> EmptyResult { if value.is_none() { err!(msg) } diff --git a/src/api/notifications.rs b/src/api/notifications.rs index 492fdb19..b1d64472 100644 --- a/src/api/notifications.rs +++ b/src/api/notifications.rs @@ -338,7 +338,7 @@ impl WebSocketUsers { } // NOTE: The last modified date needs to be updated before calling these methods - pub async fn send_user_update(&self, ut: UpdateType, user: &User, push_uuid: &Option, conn: &DbConn) { + pub async fn send_user_update(&self, ut: UpdateType, user: &User, push_uuid: Option<&PushId>, conn: &DbConn) { // Skip any processing if both WebSockets and Push are not active if *NOTIFICATIONS_DISABLED { return; diff --git a/src/api/push.rs b/src/api/push.rs index 5000869d..e3ff1383 100644 --- a/src/api/push.rs +++ b/src/api/push.rs @@ -135,7 +135,7 @@ pub async fn register_push_device(device: &mut Device, conn: &DbConn) -> EmptyRe Ok(()) } -pub async fn unregister_push_device(push_id: &Option) -> EmptyResult { +pub async fn unregister_push_device(push_id: Option<&PushId>) -> EmptyResult { if !CONFIG.push_enabled() || push_id.is_none() { return Ok(()); } @@ -206,7 +206,7 @@ pub async fn push_logout(user: &User, acting_device: Option<&Device>, conn: &DbC } } -pub async fn push_user_update(ut: UpdateType, user: &User, push_uuid: &Option, conn: &DbConn) { +pub async fn push_user_update(ut: UpdateType, user: &User, push_uuid: Option<&PushId>, conn: &DbConn) { if Device::check_user_has_push_device(&user.uuid, conn).await { tokio::task::spawn(send_to_push_relay(json!({ "userId": user.uuid, diff --git a/src/config.rs b/src/config.rs index 6ff09467..ae995f69 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1076,7 +1076,7 @@ fn validate_config(cfg: &ConfigItems, on_update: bool) -> Result<(), Error> { validate_internal_sso_issuer_url(&cfg.sso_authority)?; validate_internal_sso_redirect_url(&cfg.sso_callback_path)?; - validate_sso_master_password_policy(&cfg.sso_master_password_policy)?; + validate_sso_master_password_policy(cfg.sso_master_password_policy.as_ref())?; } if cfg._enable_yubico { @@ -1271,7 +1271,7 @@ fn validate_internal_sso_redirect_url(sso_callback_path: &String) -> Result, + sso_master_password_policy: Option<&String>, ) -> Result, Error> { let policy = sso_master_password_policy.as_ref().map(|mpp| serde_json::from_str::(mpp)); @@ -1725,7 +1725,7 @@ impl Config { } pub fn sso_master_password_policy_value(&self) -> Option { - validate_sso_master_password_policy(&self.sso_master_password_policy()).ok().flatten() + validate_sso_master_password_policy(self.sso_master_password_policy().as_ref()).ok().flatten() } pub fn sso_scopes_vec(&self) -> Vec {