Fix transferring ownership (#256)

This commit is contained in:
Geometrically
2021-11-13 16:35:21 -07:00
committed by GitHub
parent 7f791d4919
commit 77e8143290
4 changed files with 94 additions and 98 deletions

View File

@@ -171,21 +171,6 @@
] ]
} }
}, },
"0739834cfbef869855ed4e1aea7e1f7601f6519867ee48c573ee901c4498e04c": {
"query": "\n UPDATE team_members\n SET permissions = $1\n WHERE (team_id = $2 AND user_id = $3 AND NOT role = $4)\n ",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Int8",
"Int8",
"Int8",
"Text"
]
},
"nullable": []
}
},
"07ebc9dc82cd012cd4f5880b1eb3d82602c195a3e3ddd557103ee037aa6dad1c": { "07ebc9dc82cd012cd4f5880b1eb3d82602c195a3e3ddd557103ee037aa6dad1c": {
"query": "\n INSERT INTO mods_donations (joining_mod_id, joining_platform_id, url)\n VALUES ($1, $2, $3)\n ", "query": "\n INSERT INTO mods_donations (joining_mod_id, joining_platform_id, url)\n VALUES ($1, $2, $3)\n ",
"describe": { "describe": {
@@ -663,6 +648,20 @@
] ]
} }
}, },
"232d7d0319c20dd5fff29331b067d6c6373bcff761a77958a2bb5f59068a83a5": {
"query": "\n UPDATE team_members\n SET permissions = $1\n WHERE (team_id = $2 AND user_id = $3)\n ",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Int8",
"Int8",
"Int8"
]
},
"nullable": []
}
},
"24e5daad907eec54505274f93952d5c20f4bbdd3f771eb0a2fdfa6324768df39": { "24e5daad907eec54505274f93952d5c20f4bbdd3f771eb0a2fdfa6324768df39": {
"query": "\n SELECT short, name FROM licenses\n WHERE id = $1\n ", "query": "\n SELECT short, name FROM licenses\n WHERE id = $1\n ",
"describe": { "describe": {
@@ -933,20 +932,6 @@
"nullable": [] "nullable": []
} }
}, },
"3b52d9f68ba23d1e3764f8df9f28bcaec0741101f6afd0c7c234b7f1b91054a4": {
"query": "\n UPDATE team_members\n SET accepted = TRUE\n WHERE (team_id = $1 AND user_id = $2 AND NOT role = $3)\n ",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Int8",
"Int8",
"Text"
]
},
"nullable": []
}
},
"3bdcbfa5abe43cc9b4f996f147277a7f6921cca00f82cad0ef5d85032c761a36": { "3bdcbfa5abe43cc9b4f996f147277a7f6921cca00f82cad0ef5d85032c761a36": {
"query": "\n DELETE FROM mod_follows\n WHERE follower_id = $1 AND mod_id = $2\n ", "query": "\n DELETE FROM mod_follows\n WHERE follower_id = $1 AND mod_id = $2\n ",
"describe": { "describe": {
@@ -2232,21 +2217,6 @@
"nullable": [] "nullable": []
} }
}, },
"6c2299a7b7ab22f83049bc41fb5dd380adea3579e7b00df7d16fb6747a0a7313": {
"query": "\n UPDATE team_members\n SET role = $1\n WHERE (team_id = $2 AND user_id = $3 AND NOT role = $4)\n ",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Int8",
"Int8",
"Text"
]
},
"nullable": []
}
},
"6c7aeb0db4a4fb3387c37b8d7aca6fdafaa637fd883a44416b56270aeebb7a01": { "6c7aeb0db4a4fb3387c37b8d7aca6fdafaa637fd883a44416b56270aeebb7a01": {
"query": "\n INSERT INTO loaders_versions (loader_id, version_id)\n VALUES ($1, $2)\n ", "query": "\n INSERT INTO loaders_versions (loader_id, version_id)\n VALUES ($1, $2)\n ",
"describe": { "describe": {
@@ -4669,6 +4639,20 @@
"nullable": [] "nullable": []
} }
}, },
"cef01012769dcd499a0d16ce65ffc1e94bce362a7246b6a0a38d133afb90d3b6": {
"query": "\n UPDATE team_members\n SET role = $1\n WHERE (team_id = $2 AND user_id = $3)\n ",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Varchar",
"Int8",
"Int8"
]
},
"nullable": []
}
},
"d03630ab0ff37f5f0a8c088558fdc8a1955bad78bea282c40f72d15e5cf77a79": { "d03630ab0ff37f5f0a8c088558fdc8a1955bad78bea282c40f72d15e5cf77a79": {
"query": "\n SELECT v.id id\n FROM versions v\n INNER JOIN game_versions_versions gvv ON gvv.joining_version_id = v.id AND gvv.game_version_id = ANY($2)\n INNER JOIN loaders_versions lv ON lv.version_id = v.id AND lv.loader_id = ANY($3)\n WHERE v.mod_id = $1\n ORDER BY v.date_published DESC\n LIMIT 1\n ", "query": "\n SELECT v.id id\n FROM versions v\n INNER JOIN game_versions_versions gvv ON gvv.joining_version_id = v.id AND gvv.game_version_id = ANY($2)\n INNER JOIN loaders_versions lv ON lv.version_id = v.id AND lv.loader_id = ANY($3)\n WHERE v.mod_id = $1\n ORDER BY v.date_published DESC\n LIMIT 1\n ",
"describe": { "describe": {
@@ -4828,6 +4812,19 @@
"nullable": [] "nullable": []
} }
}, },
"d3991923355b2e0ed7bbe6c85d9158754d7e7d28f5ac75ee5b4e782dbc5c38a9": {
"query": "\n UPDATE team_members\n SET accepted = TRUE\n WHERE (team_id = $1 AND user_id = $2)\n ",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Int8",
"Int8"
]
},
"nullable": []
}
},
"d5807cb9a5766acc832b8715aab2b692a99e249a73974f0945710b1b394b1d74": { "d5807cb9a5766acc832b8715aab2b692a99e249a73974f0945710b1b394b1d74": {
"query": "\n SELECT id, filename, is_primary, url\n FROM files\n WHERE version_id = $1\n ", "query": "\n SELECT id, filename, is_primary, url\n FROM files\n WHERE version_id = $1\n ",
"describe": { "describe": {

View File

@@ -439,12 +439,11 @@ impl TeamMember {
" "
UPDATE team_members UPDATE team_members
SET permissions = $1 SET permissions = $1
WHERE (team_id = $2 AND user_id = $3 AND NOT role = $4) WHERE (team_id = $2 AND user_id = $3)
", ",
permissions.bits() as i64, permissions.bits() as i64,
id as TeamId, id as TeamId,
user_id as UserId, user_id as UserId,
crate::models::teams::OWNER_ROLE,
) )
.execute(&mut *transaction) .execute(&mut *transaction)
.await?; .await?;
@@ -455,12 +454,11 @@ impl TeamMember {
" "
UPDATE team_members UPDATE team_members
SET role = $1 SET role = $1
WHERE (team_id = $2 AND user_id = $3 AND NOT role = $4) WHERE (team_id = $2 AND user_id = $3)
", ",
role, role,
id as TeamId, id as TeamId,
user_id as UserId, user_id as UserId,
crate::models::teams::OWNER_ROLE,
) )
.execute(&mut *transaction) .execute(&mut *transaction)
.await?; .await?;
@@ -472,11 +470,10 @@ impl TeamMember {
" "
UPDATE team_members UPDATE team_members
SET accepted = TRUE SET accepted = TRUE
WHERE (team_id = $1 AND user_id = $2 AND NOT role = $3) WHERE (team_id = $1 AND user_id = $2)
", ",
id as TeamId, id as TeamId,
user_id as UserId, user_id as UserId,
crate::models::teams::OWNER_ROLE,
) )
.execute(&mut *transaction) .execute(&mut *transaction)
.await?; .await?;

View File

@@ -153,17 +153,13 @@ pub async fn add_team_member(
let mut transaction = pool.begin().await?; let mut transaction = pool.begin().await?;
let current_user = get_user_from_headers(req.headers(), &**pool).await?; let current_user = get_user_from_headers(req.headers(), &**pool).await?;
let team_member = let member = TeamMember::get_from_user_id(team_id, current_user.id.into(), &**pool)
TeamMember::get_from_user_id(team_id, current_user.id.into(), &**pool).await?; .await?
.ok_or_else(|| {
let member = match team_member { ApiError::CustomAuthenticationError(
Some(m) => m, "You don't have permission to edit members of this team".to_string(),
None => { )
return Err(ApiError::CustomAuthenticationError( })?;
"You don't have permission to invite users to this team".to_string(),
))
}
};
if !member.permissions.contains(Permissions::MANAGE_INVITES) { if !member.permissions.contains(Permissions::MANAGE_INVITES) {
return Err(ApiError::CustomAuthenticationError( return Err(ApiError::CustomAuthenticationError(
@@ -277,18 +273,21 @@ pub async fn edit_team_member(
let user_id = ids.1.into(); let user_id = ids.1.into();
let current_user = get_user_from_headers(req.headers(), &**pool).await?; let current_user = get_user_from_headers(req.headers(), &**pool).await?;
let team_member = TeamMember::get_from_user_id(id, current_user.id.into(), &**pool).await?; let member = TeamMember::get_from_user_id(id, current_user.id.into(), &**pool)
.await?
.ok_or_else(|| {
ApiError::CustomAuthenticationError(
"You don't have permission to edit members of this team".to_string(),
)
})?;
let mut transaction = pool.begin().await?; let mut transaction = pool.begin().await?;
let member = match team_member { if &*member.role == crate::models::teams::OWNER_ROLE {
Some(m) => m, return Err(ApiError::InvalidInputError(
None => { "The owner of a team cannot be edited".to_string(),
return Err(ApiError::CustomAuthenticationError( ));
"You don't have permission to edit members of this team".to_string(), }
))
}
};
if !member.permissions.contains(Permissions::EDIT_MEMBER) { if !member.permissions.contains(Permissions::EDIT_MEMBER) {
return Err(ApiError::CustomAuthenticationError( return Err(ApiError::CustomAuthenticationError(
@@ -340,17 +339,18 @@ pub async fn transfer_ownership(
let id = info.into_inner().0; let id = info.into_inner().0;
let current_user = get_user_from_headers(req.headers(), &**pool).await?; let current_user = get_user_from_headers(req.headers(), &**pool).await?;
let team_member = let member = TeamMember::get_from_user_id(id.into(), current_user.id.into(), &**pool)
TeamMember::get_from_user_id(id.into(), current_user.id.into(), &**pool).await?; .await?
.ok_or_else(|| {
let member = match team_member { ApiError::CustomAuthenticationError(
Some(m) => m,
None => {
return Err(ApiError::CustomAuthenticationError(
"You don't have permission to edit members of this team".to_string(), "You don't have permission to edit members of this team".to_string(),
)) )
} })?;
}; let new_member = TeamMember::get_from_user_id(id.into(), new_owner.user_id.into(), &**pool)
.await?
.ok_or_else(|| {
ApiError::InvalidInputError("The new owner specified does not exist".to_string())
})?;
if member.role != crate::models::teams::OWNER_ROLE { if member.role != crate::models::teams::OWNER_ROLE {
return Err(ApiError::CustomAuthenticationError( return Err(ApiError::CustomAuthenticationError(
@@ -358,12 +358,18 @@ pub async fn transfer_ownership(
)); ));
} }
if !new_member.accepted {
return Err(ApiError::InvalidInputError(
"You can only transfer ownership to members who are currently in your team".to_string(),
));
}
let mut transaction = pool.begin().await?; let mut transaction = pool.begin().await?;
TeamMember::edit_team_member( TeamMember::edit_team_member(
id.into(), id.into(),
current_user.id.into(), current_user.id.into(),
Some(Permissions::ALL), None,
Some(crate::models::teams::DEFAULT_ROLE.to_string()), Some(crate::models::teams::DEFAULT_ROLE.to_string()),
None, None,
&mut transaction, &mut transaction,
@@ -373,7 +379,7 @@ pub async fn transfer_ownership(
TeamMember::edit_team_member( TeamMember::edit_team_member(
id.into(), id.into(),
new_owner.user_id.into(), new_owner.user_id.into(),
None, Some(Permissions::ALL),
Some(crate::models::teams::OWNER_ROLE.to_string()), Some(crate::models::teams::OWNER_ROLE.to_string()),
None, None,
&mut transaction, &mut transaction,
@@ -396,17 +402,13 @@ pub async fn remove_team_member(
let user_id = ids.1.into(); let user_id = ids.1.into();
let current_user = get_user_from_headers(req.headers(), &**pool).await?; let current_user = get_user_from_headers(req.headers(), &**pool).await?;
let team_member = let member = TeamMember::get_from_user_id(id, current_user.id.into(), &**pool)
TeamMember::get_from_user_id_pending(id, current_user.id.into(), &**pool).await?; .await?
.ok_or_else(|| {
let member = match team_member { ApiError::CustomAuthenticationError(
Some(m) => m, "You don't have permission to edit members of this team".to_string(),
None => { )
return Err(ApiError::CustomAuthenticationError( })?;
"You don't have permission to remove members from this team".to_string(),
))
}
};
let delete_member = TeamMember::get_from_user_id_pending(id, user_id, &**pool).await?; let delete_member = TeamMember::get_from_user_id_pending(id, user_id, &**pool).await?;

View File

@@ -1,10 +1,10 @@
use crate::models::projects::SideType; use crate::models::projects::SideType;
use crate::util::validate::validation_errors_to_string;
use crate::validate::{SupportedGameVersions, ValidationError, ValidationResult}; use crate::validate::{SupportedGameVersions, ValidationError, ValidationResult};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::io::{Cursor, Read}; use std::io::{Cursor, Read};
use zip::ZipArchive;
use validator::Validate; use validator::Validate;
use crate::util::validate::validation_errors_to_string; use zip::ZipArchive;
#[derive(Serialize, Deserialize, Validate)] #[derive(Serialize, Deserialize, Validate)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
@@ -112,9 +112,9 @@ impl super::Validator for PackValidator {
let pack: PackFormat = serde_json::from_str(&contents)?; let pack: PackFormat = serde_json::from_str(&contents)?;
pack pack.validate().map_err(|err| {
.validate() ValidationError::InvalidInputError(validation_errors_to_string(err, None).into())
.map_err(|err| ValidationError::InvalidInputError(validation_errors_to_string(err, None).into()))?; })?;
if pack.game != "minecraft" { if pack.game != "minecraft" {
return Err(ValidationError::InvalidInputError( return Err(ValidationError::InvalidInputError(