Switch to Edition 2024, more clippy lints, and less macro calls (#7200)

* Update to Rust 2024 Edition

Updated to the Rust 2024 Edition and added and fixed several lint checks.
This is a large change which, because of the extra lints, added some possible fixes for issues.

Signed-off-by: BlackDex <black.dex@gmail.com>

* Reorder and merge imports

Signed-off-by: BlackDex <black.dex@gmail.com>

* Remove "db_run!" macro calls where possible

Signed-off-by: BlackDex <black.dex@gmail.com>

---------

Signed-off-by: BlackDex <black.dex@gmail.com>
This commit is contained in:
Mathijs van Veluw authored and GitHub committed 2026-05-17 19:38:49 +02:00
1 parent 22f5e0496c
commit 1ba2c6a26c
61 files changed
+3352 -3087

No files matched your search

+135 -133
View File
@@ -1,28 +1,28 @@
use num_traits::FromPrimitive;
use rocket::serde::json::Json;
use rocket::Route;
use serde_json::Value;
use std::collections::{HashMap, HashSet};
use crate::api::admin::FAKE_ADMIN_UUID;
use num_traits::FromPrimitive;
use rocket::{Route, serde::json::Json};
use serde_json::Value;
use crate::{
CONFIG,
api::admin::FAKE_ADMIN_UUID,
api::{
core::{accept_org_invite, log_event, two_factor, CipherSyncData, CipherSyncType},
EmptyResult, JsonResult, Notify, PasswordOrOtpData, UpdateType,
core::{CipherSyncData, CipherSyncType, accept_org_invite, log_event, two_factor},
},
auth::{decode_invite, AdminHeaders, Headers, ManagerHeaders, ManagerHeadersLoose, OrgMemberHeaders, OwnerHeaders},
auth::{AdminHeaders, Headers, ManagerHeaders, ManagerHeadersLoose, OrgMemberHeaders, OwnerHeaders, decode_invite},
db::{
DbConn,
models::{
Cipher, CipherId, Collection, CollectionCipher, CollectionGroup, CollectionId, CollectionUser, EventType,
Group, GroupId, GroupUser, Invitation, Membership, MembershipId, MembershipStatus, MembershipType,
OrgPolicy, OrgPolicyType, Organization, OrganizationApiKey, OrganizationId, User, UserId,
},
DbConn,
},
mail,
sso::FAKE_SSO_IDENTIFIER,
util::{convert_json_key_lcase_first, NumberOrString},
CONFIG,
util::{NumberOrString, convert_json_key_lcase_first},
};
pub fn routes() -> Vec<Route> {
@@ -97,7 +97,7 @@ pub fn routes() -> Vec<Route> {
get_reset_password_details,
put_reset_password,
get_org_export,
api_key,
post_api_key,
rotate_api_key,
get_billing_metadata,
get_billing_warnings,
@@ -286,9 +286,10 @@ async fn get_organization(org_id: OrganizationId, headers: OwnerHeaders, conn: D
if org_id != headers.org_id {
err!("Organization not found", "Organization id's do not match");
}
match Organization::find_by_uuid(&org_id, &conn).await {
Some(organization) => Ok(Json(organization.to_json())),
None => err!("Can't find organization details"),
if let Some(organization) = Organization::find_by_uuid(&org_id, &conn).await {
Ok(Json(organization.to_json()))
} else {
err!("Can't find organization details")
}
}
@@ -367,7 +368,7 @@ async fn get_auto_enroll_status(identifier: &str, headers: Headers, conn: DbConn
};
let (id, identifier, rp_auto_enroll) = match org {
None => (identifier.to_string(), identifier.to_string(), false),
None => (identifier.to_owned(), identifier.to_owned(), false),
Some(org) => (
org.uuid.to_string(),
org.uuid.to_string(),
@@ -393,7 +394,7 @@ async fn get_org_collections(org_id: OrganizationId, headers: ManagerHeadersLoos
}
Ok(Json(json!({
"data": _get_org_collections(&org_id, &conn).await,
"data": get_org_collections_impl(&org_id, &conn).await,
"object": "list",
"continuationToken": null,
})))
@@ -465,7 +466,7 @@ async fn get_org_collections_details(org_id: OrganizationId, headers: ManagerHea
CollectionGroup::find_by_collection(&col.uuid, &conn)
.await
.iter()
.map(|collection_group| collection_group.to_json_details_for_group())
.map(CollectionGroup::to_json_details_for_group)
.collect()
} else {
Vec::with_capacity(0)
@@ -477,7 +478,7 @@ async fn get_org_collections_details(org_id: OrganizationId, headers: ManagerHea
json_object["groups"] = json!(groups);
json_object["object"] = json!("collectionAccessDetails");
json_object["unmanaged"] = json!(false);
data.push(json_object)
data.push(json_object);
}
Ok(Json(json!({
@@ -487,7 +488,7 @@ async fn get_org_collections_details(org_id: OrganizationId, headers: ManagerHea
})))
}
async fn _get_org_collections(org_id: &OrganizationId, conn: &DbConn) -> Value {
async fn get_org_collections_impl(org_id: &OrganizationId, conn: &DbConn) -> Value {
Collection::find_by_organization(org_id, conn).await.iter().map(Collection::to_json).collect::<Value>()
}
@@ -573,7 +574,7 @@ async fn post_bulk_access_collections(
if Organization::find_by_uuid(&org_id, &conn).await.is_none() {
err!("Can't find organization details")
};
}
for col_id in data.collection_ids {
let Some(collection) = Collection::find_by_uuid_and_org(&col_id, &org_id, &conn).await else {
@@ -650,7 +651,7 @@ async fn post_organization_collection_update(
if Organization::find_by_uuid(&org_id, &conn).await.is_none() {
err!("Can't find organization details")
};
}
let Some(mut collection) = Collection::find_by_uuid_and_org(&col_id, &org_id, &conn).await else {
err!("Collection not found")
@@ -701,7 +702,7 @@ async fn post_organization_collection_update(
Ok(Json(collection.to_json_details(&headers.user.uuid, None, &conn).await))
}
async fn _delete_organization_collection(
async fn delete_organization_collection_impl(
org_id: &OrganizationId,
col_id: &CollectionId,
headers: &ManagerHeaders,
@@ -733,7 +734,7 @@ async fn delete_organization_collection(
headers: ManagerHeaders,
conn: DbConn,
) -> EmptyResult {
_delete_organization_collection(&org_id, &col_id, &headers, &conn).await
delete_organization_collection_impl(&org_id, &col_id, &headers, &conn).await
}
#[post("/organizations/<org_id>/collections/<col_id>/delete")]
@@ -743,7 +744,7 @@ async fn post_organization_collection_delete(
headers: ManagerHeaders,
conn: DbConn,
) -> EmptyResult {
_delete_organization_collection(&org_id, &col_id, &headers, &conn).await
delete_organization_collection_impl(&org_id, &col_id, &headers, &conn).await
}
#[derive(Deserialize, Debug)]
@@ -769,7 +770,7 @@ async fn bulk_delete_organization_collections(
let headers = ManagerHeaders::from_loose(headers, &collections, &conn).await?;
for col_id in collections {
_delete_organization_collection(&org_id, &col_id, &headers, &conn).await?
delete_organization_collection_impl(&org_id, &col_id, &headers, &conn).await?;
}
Ok(())
}
@@ -799,7 +800,7 @@ async fn get_org_collection_detail(
CollectionGroup::find_by_collection(&collection.uuid, &conn)
.await
.iter()
.map(|collection_group| collection_group.to_json_details_for_group())
.map(CollectionGroup::to_json_details_for_group)
.collect()
} else {
// The Bitwarden clients seem to call this API regardless of whether groups are enabled,
@@ -886,13 +887,13 @@ async fn get_org_details(data: OrgIdData, headers: ManagerHeadersLoose, conn: Db
}
Ok(Json(json!({
"data": _get_org_details(&data.organization_id, &headers.host, &headers.user.uuid, &conn).await?,
"data": get_org_details_impl(&data.organization_id, &headers.host, &headers.user.uuid, &conn).await?,
"object": "list",
"continuationToken": null,
})))
}
async fn _get_org_details(
async fn get_org_details_impl(
org_id: &OrganizationId,
host: &str,
user_id: &UserId,
@@ -975,14 +976,13 @@ async fn post_org_keys(
}
let data: OrgKeyData = data.into_inner();
let mut org = match Organization::find_by_uuid(&org_id, &conn).await {
Some(organization) => {
if organization.private_key.is_some() && organization.public_key.is_some() {
err!("Organization Keys already exist")
}
organization
let mut org = if let Some(organization) = Organization::find_by_uuid(&org_id, &conn).await {
if organization.private_key.is_some() && organization.public_key.is_some() {
err!("Organization Keys already exist")
}
None => err!("Can't find organization details"),
organization
} else {
err!("Can't find organization details")
};
org.private_key = Some(data.encrypted_private_key);
@@ -1043,9 +1043,10 @@ async fn send_invite(
// The from_str() will convert the custom role type into a manager role type
let raw_type = &data.r#type.into_string();
// Membership::from_str will convert custom (4) to manager (3)
let new_type = match MembershipType::from_str(raw_type) {
Some(new_type) => new_type as i32,
None => err!("Invalid type"),
let new_type = if let Some(new_type) = MembershipType::from_str(raw_type) {
new_type as i32
} else {
err!("Invalid type")
};
if new_type != MembershipType::User && headers.membership_type != MembershipType::Owner {
@@ -1062,7 +1063,7 @@ async fn send_invite(
&& data.permissions.get("createNewCollections") == Some(&json!(true)));
let mut user_created: bool = false;
for email in data.emails.iter() {
for email in &data.emails {
let mut member_status = MembershipStatus::Invited as i32;
let user = match User::find_by_mail(email, &conn).await {
None => {
@@ -1086,13 +1087,13 @@ async fn send_invite(
Some(user) => {
if Membership::find_by_user_and_org(&user.uuid, &org_id, &conn).await.is_some() {
err!(format!("User already in organization: {email}"))
} else {
// automatically accept existing users if mail is disabled
if !CONFIG.mail_enabled() && !user.password_hash.is_empty() {
member_status = MembershipStatus::Accepted as i32;
}
user
}
// automatically accept existing users if mail is disabled
if !CONFIG.mail_enabled() && !user.password_hash.is_empty() {
member_status = MembershipStatus::Accepted as i32;
}
user
}
};
@@ -1103,9 +1104,10 @@ async fn send_invite(
new_member.save(&conn).await?;
if CONFIG.mail_enabled() {
let org_name = match Organization::find_by_uuid(&org_id, &conn).await {
Some(org) => org.name,
None => err!("Error looking up organization"),
let org_name = if let Some(org) = Organization::find_by_uuid(&org_id, &conn).await {
org.name
} else {
err!("Error looking up organization")
};
if let Err(e) = mail::send_invite(
@@ -1159,7 +1161,7 @@ async fn send_invite(
}
}
for group_id in data.groups.iter() {
for group_id in &data.groups {
let mut group_entry = GroupUser::new(group_id.clone(), new_member.uuid.clone());
group_entry.save(&conn).await?;
}
@@ -1182,8 +1184,8 @@ async fn bulk_reinvite_members(
let mut bulk_response = Vec::new();
for member_id in data.ids {
let err_msg = match _reinvite_member(&org_id, &member_id, &headers.user.email, &conn).await {
Ok(_) => String::new(),
let err_msg = match reinvite_member_impl(&org_id, &member_id, &headers.user.email, &conn).await {
Ok(()) => String::new(),
Err(e) => format!("{e:?}"),
};
@@ -1193,7 +1195,7 @@ async fn bulk_reinvite_members(
"id": member_id,
"error": err_msg
}
))
));
}
Ok(Json(json!({
@@ -1213,10 +1215,10 @@ async fn reinvite_member(
if org_id != headers.org_id {
err!("Organization not found", "Organization id's do not match");
}
_reinvite_member(&org_id, &member_id, &headers.user.email, &conn).await
reinvite_member_impl(&org_id, &member_id, &headers.user.email, &conn).await
}
async fn _reinvite_member(
async fn reinvite_member_impl(
org_id: &OrganizationId,
member_id: &MembershipId,
invited_by_email: &str,
@@ -1238,13 +1240,14 @@ async fn _reinvite_member(
err!("Invitations are not allowed.")
}
let org_name = match Organization::find_by_uuid(org_id, conn).await {
Some(org) => org.name,
None => err!("Error looking up organization."),
let org_name = if let Some(org) = Organization::find_by_uuid(org_id, conn).await {
org.name
} else {
err!("Error looking up organization.")
};
if CONFIG.mail_enabled() {
mail::send_invite(&user, org_id.clone(), member.uuid, &org_name, Some(invited_by_email.to_string())).await?;
mail::send_invite(&user, org_id.clone(), member.uuid, &org_name, Some(invited_by_email.to_owned())).await?;
} else if user.password_hash.is_empty() {
let invitation = Invitation::new(&user.email);
invitation.save(conn).await?;
@@ -1352,8 +1355,8 @@ async fn bulk_confirm_invite(
for invite in keys {
let member_id = invite.id.unwrap();
let user_key = invite.key.unwrap_or_default();
let err_msg = match _confirm_invite(&org_id, &member_id, &user_key, &headers, &conn, &nt).await {
Ok(_) => String::new(),
let err_msg = match confirm_invite_impl(&org_id, &member_id, &user_key, &headers, &conn, &nt).await {
Ok(()) => String::new(),
Err(e) => format!("{e:?}"),
};
@@ -1387,10 +1390,10 @@ async fn confirm_invite(
) -> EmptyResult {
let data = data.into_inner();
let user_key = data.key.unwrap_or_default();
_confirm_invite(&org_id, &member_id, &user_key, &headers, &conn, &nt).await
confirm_invite_impl(&org_id, &member_id, &user_key, &headers, &conn, &nt).await
}
async fn _confirm_invite(
async fn confirm_invite_impl(
org_id: &OrganizationId,
member_id: &MembershipId,
key: &str,
@@ -1418,7 +1421,7 @@ async fn _confirm_invite(
}
member_to_confirm.status = MembershipStatus::Confirmed as i32;
member_to_confirm.akey = key.to_string();
member_to_confirm.akey = key.to_owned();
// This check is also done at accept_invite, _confirm_invite, _activate_member, edit_member, admin::update_membership_type
OrgPolicy::check_user_allowed(&member_to_confirm, "confirm", conn).await?;
@@ -1435,13 +1438,15 @@ async fn _confirm_invite(
.await;
if CONFIG.mail_enabled() {
let org_name = match Organization::find_by_uuid(org_id, conn).await {
Some(org) => org.name,
None => err!("Error looking up organization."),
let org_name = if let Some(org) = Organization::find_by_uuid(org_id, conn).await {
org.name
} else {
err!("Error looking up organization.")
};
let address = match User::find_by_uuid(&member_to_confirm.user_uuid, conn).await {
Some(user) => user.email,
None => err!("Error looking up user."),
let address = if let Some(user) = User::find_by_uuid(&member_to_confirm.user_uuid, conn).await {
user.email
} else {
err!("Error looking up user.")
};
mail::send_invite_confirmed(&address, &org_name).await?;
}
@@ -1637,8 +1642,8 @@ async fn bulk_delete_member(
let mut bulk_response = Vec::new();
for member_id in data.ids {
let err_msg = match _delete_member(&org_id, &member_id, &headers, &conn, &nt).await {
Ok(_) => String::new(),
let err_msg = match delete_member_impl(&org_id, &member_id, &headers, &conn, &nt).await {
Ok(()) => String::new(),
Err(e) => format!("{e:?}"),
};
@@ -1648,7 +1653,7 @@ async fn bulk_delete_member(
"id": member_id,
"error": err_msg
}
))
));
}
Ok(Json(json!({
@@ -1666,10 +1671,10 @@ async fn delete_member(
conn: DbConn,
nt: Notify<'_>,
) -> EmptyResult {
_delete_member(&org_id, &member_id, &headers, &conn, &nt).await
delete_member_impl(&org_id, &member_id, &headers, &conn, &nt).await
}
async fn _delete_member(
async fn delete_member_impl(
org_id: &OrganizationId,
member_id: &MembershipId,
headers: &AdminHeaders,
@@ -1753,8 +1758,8 @@ async fn bulk_public_keys(
})))
}
use super::ciphers::update_cipher_from_data;
use super::ciphers::CipherData;
use super::ciphers::update_cipher_from_data;
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
@@ -1902,24 +1907,24 @@ async fn post_bulk_collections(data: Json<BulkCollectionsData>, headers: Headers
}
}
for cipher_id in data.cipher_ids.iter() {
for cipher_id in &data.cipher_ids {
// Only act on existing cipher uuid's
// Do not abort the operation just ignore it, it could be a cipher was just deleted for example
if let Some(cipher) = Cipher::find_by_uuid_and_org(cipher_id, &data.organization_id, &conn).await {
if cipher.is_write_accessible_to_user(&headers.user.uuid, &conn).await {
// When selecting a specific collection from the left filter list, and use the bulk option, you can remove an item from that collection
// In these cases the client will call this endpoint twice, once for adding the new collections and a second for deleting.
if data.remove_collections {
for collection in &data.collection_ids {
CollectionCipher::delete(&cipher.uuid, collection, &conn).await?;
}
} else {
for collection in &data.collection_ids {
CollectionCipher::save(&cipher.uuid, collection, &conn).await?;
}
if let Some(cipher) = Cipher::find_by_uuid_and_org(cipher_id, &data.organization_id, &conn).await
&& cipher.is_write_accessible_to_user(&headers.user.uuid, &conn).await
{
// When selecting a specific collection from the left filter list, and use the bulk option, you can remove an item from that collection
// In these cases the client will call this endpoint twice, once for adding the new collections and a second for deleting.
if data.remove_collections {
for collection in &data.collection_ids {
CollectionCipher::delete(&cipher.uuid, collection, &conn).await?;
}
} else {
for collection in &data.collection_ids {
CollectionCipher::save(&cipher.uuid, collection, &conn).await?;
}
}
};
}
}
Ok(())
@@ -1969,7 +1974,7 @@ async fn list_policies_token(org_id: OrganizationId, token: &str, conn: DbConn)
fn get_dummy_master_password_policy() -> JsonResult {
let (enabled, data) = match CONFIG.sso_master_password_policy_value() {
Some(policy) if CONFIG.sso_enabled() => (true, policy.to_string()),
_ => (false, "null".to_string()),
_ => (false, "null".to_owned()),
};
let policy = OrgPolicy::new(FAKE_SSO_IDENTIFIER.into(), OrgPolicyType::MasterPassword, enabled, data);
Ok(Json(policy.to_json()))
@@ -1982,7 +1987,7 @@ async fn get_master_password_policy(org_id: OrganizationId, _headers: OrgMemberH
OrgPolicy::find_by_org_and_type(&org_id, OrgPolicyType::MasterPassword, &conn).await.unwrap_or_else(|| {
let (enabled, data) = match CONFIG.sso_master_password_policy_value() {
Some(policy) if CONFIG.sso_enabled() => (true, policy.to_string()),
_ => (false, "null".to_string()),
_ => (false, "null".to_owned()),
};
OrgPolicy::new(org_id, OrgPolicyType::MasterPassword, enabled, data)
@@ -2003,7 +2008,7 @@ async fn get_policy(org_id: OrganizationId, pol_type: i32, headers: AdminHeaders
let policy = match OrgPolicy::find_by_org_and_type(&org_id, pol_type_enum, &conn).await {
Some(p) => p,
None => OrgPolicy::new(org_id.clone(), pol_type_enum, false, "null".to_string()),
None => OrgPolicy::new(org_id.clone(), pol_type_enum, false, "null".to_owned()),
};
Ok(Json(policy.to_json()))
@@ -2078,7 +2083,7 @@ async fn put_policy(
// When enabling the SingleOrg policy, remove this org's members that are members of other orgs
if pol_type_enum == OrgPolicyType::SingleOrg && data.enabled {
for mut member in Membership::find_by_org(&org_id, &conn).await.into_iter() {
for mut member in Membership::find_by_org(&org_id, &conn).await {
// Policy only applies to non-Owner/non-Admin members who have accepted joining the org
// Exclude invited and revoked users when checking for this policy.
// Those users will not be allowed to accept or be activated because of the policy checks done there.
@@ -2113,7 +2118,7 @@ async fn put_policy(
let mut policy = match OrgPolicy::find_by_org_and_type(&org_id, pol_type_enum, &conn).await {
Some(p) => p,
None => OrgPolicy::new(org_id.clone(), pol_type_enum, false, "{}".to_string()),
None => OrgPolicy::new(org_id.clone(), pol_type_enum, false, "{}".to_owned()),
};
policy.enabled = data.enabled;
@@ -2187,7 +2192,7 @@ fn get_plans() -> Json<Value> {
#[get("/organizations/<_org_id>/billing/metadata")]
fn get_billing_metadata(_org_id: OrganizationId, _headers: OrgMemberHeaders) -> Json<Value> {
// Prevent a 404 error, which also causes Javascript errors.
Json(_empty_data_json())
Json(empty_data_json())
}
#[get("/organizations/<_org_id>/billing/vnext/warnings")]
@@ -2209,7 +2214,7 @@ fn get_self_host_billing_metadata(_org_id: OrganizationId, _headers: OrgMemberHe
}))
}
fn _empty_data_json() -> Value {
fn empty_data_json() -> Value {
json!({
"object": "list",
"data": [],
@@ -2230,7 +2235,7 @@ async fn revoke_member(
headers: AdminHeaders,
conn: DbConn,
) -> EmptyResult {
_revoke_member(&org_id, &member_id, &headers, &conn).await
revoke_member_impl(&org_id, &member_id, &headers, &conn).await
}
#[put("/organizations/<org_id>/users/revoke", data = "<data>")]
@@ -2249,8 +2254,8 @@ async fn bulk_revoke_members(
match data.ids {
Some(members) => {
for member_id in members {
let err_msg = match _revoke_member(&org_id, &member_id, &headers, &conn).await {
Ok(_) => String::new(),
let err_msg = match revoke_member_impl(&org_id, &member_id, &headers, &conn).await {
Ok(()) => String::new(),
Err(e) => format!("{e:?}"),
};
@@ -2273,7 +2278,7 @@ async fn bulk_revoke_members(
})))
}
async fn _revoke_member(
async fn revoke_member_impl(
org_id: &OrganizationId,
member_id: &MembershipId,
headers: &AdminHeaders,
@@ -2325,7 +2330,7 @@ async fn restore_member_vnext(
) -> EmptyResult {
// Vaultwarden does not (yet) support the per User Collection linked to the `Enforce organization data ownership` policy.
// Therefor we ignore the `defaultUserCollectionName` data sent and just call restore_member
_restore_member(&org_id, &member_id, &headers, &conn).await
restore_member_impl(&org_id, &member_id, &headers, &conn).await
}
#[put("/organizations/<org_id>/users/<member_id>/restore")]
@@ -2335,7 +2340,7 @@ async fn restore_member(
headers: AdminHeaders,
conn: DbConn,
) -> EmptyResult {
_restore_member(&org_id, &member_id, &headers, &conn).await
restore_member_impl(&org_id, &member_id, &headers, &conn).await
}
#[put("/organizations/<org_id>/users/restore", data = "<data>")]
@@ -2352,8 +2357,8 @@ async fn bulk_restore_members(
let mut bulk_response = Vec::new();
for member_id in data.ids {
let err_msg = match _restore_member(&org_id, &member_id, &headers, &conn).await {
Ok(_) => String::new(),
let err_msg = match restore_member_impl(&org_id, &member_id, &headers, &conn).await {
Ok(()) => String::new(),
Err(e) => format!("{e:?}"),
};
@@ -2373,7 +2378,7 @@ async fn bulk_restore_members(
})))
}
async fn _restore_member(
async fn restore_member_impl(
org_id: &OrganizationId,
member_id: &MembershipId,
headers: &AdminHeaders,
@@ -2429,11 +2434,11 @@ async fn get_groups_data(
if details {
for g in groups {
groups_json.push(g.to_json_details(&conn).await)
groups_json.push(g.to_json_details(&conn).await);
}
} else {
for g in groups {
groups_json.push(g.to_json())
groups_json.push(g.to_json());
}
}
groups_json
@@ -2672,15 +2677,15 @@ async fn post_delete_group(
headers: AdminHeaders,
conn: DbConn,
) -> EmptyResult {
_delete_group(&org_id, &group_id, &headers, &conn).await
delete_group_impl(&org_id, &group_id, &headers, &conn).await
}
#[delete("/organizations/<org_id>/groups/<group_id>")]
async fn delete_group(org_id: OrganizationId, group_id: GroupId, headers: AdminHeaders, conn: DbConn) -> EmptyResult {
_delete_group(&org_id, &group_id, &headers, &conn).await
delete_group_impl(&org_id, &group_id, &headers, &conn).await
}
async fn _delete_group(
async fn delete_group_impl(
org_id: &OrganizationId,
group_id: &GroupId,
headers: &AdminHeaders,
@@ -2728,7 +2733,7 @@ async fn bulk_delete_groups(
let data: BulkGroupIds = data.into_inner();
for group_id in data.ids {
_delete_group(&org_id, &group_id, &headers, &conn).await?
delete_group_impl(&org_id, &group_id, &headers, &conn).await?;
}
Ok(())
}
@@ -2765,7 +2770,7 @@ async fn get_group_members(
if Group::find_by_uuid_and_org(&group_id, &org_id, &conn).await.is_none() {
err!("Group could not be found!", "Group uuid is invalid or does not belong to the organization")
};
}
let group_members: Vec<MembershipId> = GroupUser::find_by_group(&group_id, &org_id, &conn)
.await
@@ -2793,7 +2798,7 @@ async fn put_group_members(
if Group::find_by_uuid_and_org(&group_id, &org_id, &conn).await.is_none() {
err!("Group could not be found!", "Group uuid is invalid or does not belong to the organization")
};
}
let assigned_members = data.into_inner();
@@ -3100,12 +3105,12 @@ async fn get_org_export(org_id: OrganizationId, headers: AdminHeaders, conn: DbC
}
Ok(Json(json!({
"collections": convert_json_key_lcase_first(_get_org_collections(&org_id, &conn).await),
"ciphers": convert_json_key_lcase_first(_get_org_details(&org_id, &headers.host, &headers.user.uuid, &conn).await?),
"collections": convert_json_key_lcase_first(get_org_collections_impl(&org_id, &conn).await),
"ciphers": convert_json_key_lcase_first(get_org_details_impl(&org_id, &headers.host, &headers.user.uuid, &conn).await?),
})))
}
async fn _api_key(
async fn api_key(
org_id: &OrganizationId,
data: Json<PasswordOrOtpData>,
rotate: bool,
@@ -3121,21 +3126,18 @@ async fn _api_key(
// Validate the admin users password/otp
data.validate(&user, true, &conn).await?;
let org_api_key = match OrganizationApiKey::find_by_org_uuid(org_id, &conn).await {
Some(mut org_api_key) => {
if rotate {
org_api_key.api_key = crate::crypto::generate_api_key();
org_api_key.revision_date = chrono::Utc::now().naive_utc();
org_api_key.save(&conn).await.expect("Error rotating organization API Key");
}
org_api_key
}
None => {
let api_key = crate::crypto::generate_api_key();
let new_org_api_key = OrganizationApiKey::new(org_id.clone(), api_key);
new_org_api_key.save(&conn).await.expect("Error creating organization API Key");
new_org_api_key
let org_api_key = if let Some(mut org_api_key) = OrganizationApiKey::find_by_org_uuid(org_id, &conn).await {
if rotate {
org_api_key.api_key = crate::crypto::generate_api_key();
org_api_key.revision_date = chrono::Utc::now().naive_utc();
org_api_key.save(&conn).await.expect("Error rotating organization API Key");
}
org_api_key
} else {
let api_key = crate::crypto::generate_api_key();
let new_org_api_key = OrganizationApiKey::new(org_id.clone(), api_key);
new_org_api_key.save(&conn).await.expect("Error creating organization API Key");
new_org_api_key
};
Ok(Json(json!({
@@ -3146,13 +3148,13 @@ async fn _api_key(
}
#[post("/organizations/<org_id>/api-key", data = "<data>")]
async fn api_key(
async fn post_api_key(
org_id: OrganizationId,
data: Json<PasswordOrOtpData>,
headers: AdminHeaders,
conn: DbConn,
) -> JsonResult {
_api_key(&org_id, data, false, headers, conn).await
api_key(&org_id, data, false, headers, conn).await
}
#[post("/organizations/<org_id>/rotate-api-key", data = "<data>")]
@@ -3162,5 +3164,5 @@ async fn rotate_api_key(
headers: AdminHeaders,
conn: DbConn,
) -> JsonResult {
_api_key(&org_id, data, true, headers, conn).await
api_key(&org_id, data, true, headers, conn).await
}