Org fixes (#850)

* Org fixes

* payouts bug

* Update dockerfile fix test

* Update to bookworm

* clippy
This commit is contained in:
Geometrically 2024-01-12 14:19:39 -05:00 committed by GitHub
parent 4483bb147c
commit 7b00003958
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 129 additions and 32 deletions

View File

@ -0,0 +1,23 @@
{
"db_name": "PostgreSQL",
"query": "SELECT EXISTS(SELECT 1 FROM mods m INNER JOIN organizations o ON m.organization_id = o.id INNER JOIN team_members tm ON tm.team_id = o.team_id AND tm.user_id = $2 WHERE m.id = $1)",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "exists",
"type_info": "Bool"
}
],
"parameters": {
"Left": [
"Int8",
"Int8"
]
},
"nullable": [
null
]
},
"hash": "bad800084766fcbaf584066304a5a7e4484859e1326c765e5ebd403fbc7e188b"
}

View File

@ -0,0 +1,23 @@
{
"db_name": "PostgreSQL",
"query": "\n SELECT m.id FROM mods m\n INNER JOIN organizations o ON o.id = m.organization_id\n INNER JOIN team_members tm ON tm.team_id = o.team_id AND user_id = $2\n WHERE m.id = ANY($1)\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "id",
"type_info": "Int8"
}
],
"parameters": {
"Left": [
"Int8Array",
"Int8"
]
},
"nullable": [
false
]
},
"hash": "e4dbbb18adfd748ab7659462f940a5d1741a16971b01662b9281eb5720e109b1"
}

View File

@ -2,29 +2,11 @@ FROM rust:1.75.0 as build
ENV PKG_CONFIG_ALLOW_CROSS=1
WORKDIR /usr/src/labrinth
# Download and compile deps
COPY Cargo.toml .
COPY Cargo.lock .
COPY docker_utils/dummy.rs .
# Change temporarely the path of the code
RUN sed -i 's|src/main.rs|dummy.rs|' Cargo.toml
# Build only deps
RUN cargo build --release
# Now return the file back to normal
RUN sed -i 's|dummy.rs|src/main.rs|' Cargo.toml
# Copy everything
COPY . .
# Add the wait script
ADD https://github.com/ufoscout/docker-compose-wait/releases/download/2.2.1/wait /wait
RUN chmod +x /wait
# Build our code
ARG SQLX_OFFLINE=true
RUN cargo build --release
# Final Stage
FROM ubuntu:latest
FROM debian:bookworm-slim
RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates \
@ -34,9 +16,6 @@ RUN apt-get update \
RUN update-ca-certificates
COPY --from=build /usr/src/labrinth/target/release/labrinth /labrinth/labrinth
COPY --from=build /usr/src/labrinth/migrations/* /labrinth/migrations/
COPY --from=build /usr/src/labrinth/assets /labrinth/assets
COPY --from=build /wait /wait
WORKDIR /labrinth
CMD /wait && /labrinth/labrinth
CMD /labrinth/labrinth

View File

@ -1 +0,0 @@
fn main() {}

View File

@ -10,7 +10,6 @@ use serde::{Deserialize, Serialize};
#[serde(into = "Base62Id")]
pub struct TeamId(pub u64);
pub const OWNER_ROLE: &str = "Owner";
pub const DEFAULT_ROLE: &str = "Member";
/// A team of users who control a project

View File

@ -675,6 +675,13 @@ pub async fn process_payout(
all_team_members.push((user_id, payouts_split));
}
// if all team members are set to zero, we treat as an equal revenue distribution
if all_team_members.iter().all(|x| x.1 == Decimal::ZERO) {
all_team_members
.iter_mut()
.for_each(|x| x.1 = Decimal::from(1));
}
projects_map.insert(
project_id,
Project {

View File

@ -145,7 +145,7 @@ pub async fn organization_create(
let team = team_item::TeamBuilder {
members: vec![team_item::TeamMemberBuilder {
user_id: current_user.id.into(),
role: crate::models::teams::OWNER_ROLE.to_owned(),
role: crate::models::teams::DEFAULT_ROLE.to_owned(),
is_owner: true,
permissions: ProjectPermissions::all(),
organization_permissions: Some(OrganizationPermissions::all()),

View File

@ -617,7 +617,7 @@ async fn project_create_inner(
if project_create_data.organization_id.is_none() {
members.push(models::team_item::TeamMemberBuilder {
user_id: current_user.id.into(),
role: crate::models::teams::OWNER_ROLE.to_owned(),
role: crate::models::teams::DEFAULT_ROLE.to_owned(),
is_owner: true,
permissions: ProjectPermissions::all(),
organization_permissions: None,

View File

@ -504,9 +504,11 @@ pub async fn add_team_member(
.as_ref()
.map(|tm| tm.is_owner)
.unwrap_or(false)
&& new_member.permissions != ProjectPermissions::all()
{
return Err(ApiError::InvalidInput(
"You cannot add the owner of an organization to a project team owned by that organization".to_string(),
"You cannot override the owner of an organization's permissions in a project team"
.to_string(),
));
}
@ -634,6 +636,22 @@ pub async fn edit_team_member(
} else {
None
};
if organization_team_member
.as_ref()
.map(|x| x.is_owner)
.unwrap_or(false)
&& edit_member
.permissions
.map(|x| x != ProjectPermissions::all())
.unwrap_or(false)
{
return Err(ApiError::CustomAuthentication(
"You cannot override the project permissions of the organization owner!"
.to_string(),
));
}
let permissions = ProjectPermissions::get_permissions_by_role(
&current_user.role,
&member.clone(),

View File

@ -71,7 +71,20 @@ pub async fn is_authorized_thread(
.await?
.exists;
project_exists.unwrap_or(false)
if !project_exists.unwrap_or(false) {
let org_exists = sqlx::query!(
"SELECT EXISTS(SELECT 1 FROM mods m INNER JOIN organizations o ON m.organization_id = o.id INNER JOIN team_members tm ON tm.team_id = o.team_id AND tm.user_id = $2 WHERE m.id = $1)",
project_id as database::models::ids::ProjectId,
user_id as database::models::ids::UserId,
)
.fetch_one(pool)
.await?
.exists;
org_exists.unwrap_or(false)
} else {
true
}
} else {
false
}
@ -137,6 +150,42 @@ pub async fn filter_authorized_threads(
.await?;
}
let org_project_thread_ids = check_threads
.iter()
.filter(|x| x.type_ == ThreadType::Project)
.flat_map(|x| x.project_id.map(|x| x.0))
.collect::<Vec<_>>();
if !org_project_thread_ids.is_empty() {
sqlx::query!(
"
SELECT m.id FROM mods m
INNER JOIN organizations o ON o.id = m.organization_id
INNER JOIN team_members tm ON tm.team_id = o.team_id AND user_id = $2
WHERE m.id = ANY($1)
",
&*project_thread_ids,
user_id as database::models::ids::UserId,
)
.fetch_many(&***pool)
.try_for_each(|e| {
if let Some(row) = e.right() {
check_threads.retain(|x| {
let bool = x.project_id.map(|x| x.0) == Some(row.id);
if bool {
return_threads.push(x.clone());
}
!bool
});
}
futures::future::ready(Ok(()))
})
.await?;
}
let report_thread_ids = check_threads
.iter()
.filter(|x| x.type_ == ThreadType::Report)

View File

@ -302,7 +302,7 @@ async fn update_and_add_to_index(
// Check if any 'additional_fields' are not already in the index
// Only add if they are not already in the index
let new_fields = additional_fields
.into_iter()
.iter()
.filter(|x| !new_filterable_attributes.contains(x))
.collect::<Vec<_>>();
if !new_fields.is_empty() {

View File

@ -95,7 +95,7 @@ async fn create_organization() {
members[0].organization_permissions,
Some(OrganizationPermissions::all())
);
assert_eq!(members[0].role, "Owner");
assert_eq!(members[0].role, "Member");
assert!(members[0].is_owner);
})
.await;

View File

@ -535,7 +535,7 @@ async fn transfer_ownership_v3() {
.iter()
.find(|x| x.user.id.0 == USER_USER_ID_PARSED as u64)
.unwrap();
assert_eq!(user_member.role, "Owner"); // We are the 'owner', but we are not actually the owner!
assert_eq!(user_member.role, "Member"); // We are the 'owner', but we are not actually the owner!
assert!(!user_member.is_owner);
assert_eq!(user_member.permissions.unwrap(), ProjectPermissions::all());