feat(labrinth): hide orgs without a purpose, re-enable organization creation (#4426)

* chore(labrinth): set `DELPHI_URL` to a valid default in `.env.local`

* feat(labrinth): make orgs not publicly visible until they meet some conditions

* Revert "Org disabled frontend (#4424)"

This reverts commit 2492b11ec0.

* changelog: update for re-enabling organization creation

* chore: run `sqlx prepare`

* chore(labrinth): tweak tests to work with new org changes

* tweak: apply @triphora's suggestion

Co-authored-by: Emma Alexia <emma@modrinth.com>
Signed-off-by: Alejandro González <7822554+AlexTMjugador@users.noreply.github.com>

* tweak: document `is_visible_organization` relationship with `Project#is_searchable`

---------

Signed-off-by: Alejandro González <7822554+AlexTMjugador@users.noreply.github.com>
Co-authored-by: Emma Alexia <emma@modrinth.com>
This commit is contained in:
Alejandro González
2025-09-26 17:42:53 +02:00
committed by GitHub
parent 14af3d0763
commit bb9ce52c9d
10 changed files with 130 additions and 63 deletions

View File

@@ -22,6 +22,7 @@ use common::environment::{
use common::{database::*, scopes::ScopeTest};
use labrinth::models::ids::ProjectId;
use labrinth::models::pats::Scopes;
use labrinth::models::teams::ProjectPermissions;
use serde_json::json;
// For each scope, we (using test_scope):
// - create a PAT with a given set of scopes for a function
@@ -1093,6 +1094,7 @@ pub async fn organization_scopes() {
.await
.unwrap();
let organization_id = success["id"].as_str().unwrap();
let organization_team_id = success["team_id"].as_str().unwrap();
// Patch organization
let organization_edit = Scopes::ORGANIZATION_WRITE;
@@ -1154,6 +1156,27 @@ pub async fn organization_scopes() {
.await
.unwrap();
// Add two members to the organization
api.add_user_to_team(
organization_team_id,
FRIEND_USER_ID,
Some(ProjectPermissions::all()),
None,
USER_USER_PAT,
)
.await;
api.join_team(organization_team_id, FRIEND_USER_PAT).await;
api.add_user_to_team(
organization_team_id,
ENEMY_USER_ID,
Some(ProjectPermissions::all()),
None,
USER_USER_PAT,
)
.await;
api.join_team(organization_team_id, ENEMY_USER_PAT).await;
// Organization reads
let organization_read = Scopes::ORGANIZATION_READ;
let req_gen = |pat: Option<String>| async move {

View File

@@ -176,7 +176,7 @@ async fn test_get_team_organization() {
&test_env.dummy.organization_zeta.organization_id;
let zeta_team_id = &test_env.dummy.organization_zeta.team_id;
// A non-member of the team should get basic info but not be able to see private data
// A non-member of the team should get basic team info
let members = api
.get_team_members_deserialized_common(
zeta_team_id,
@@ -187,15 +187,6 @@ async fn test_get_team_organization() {
assert_eq!(members[0].user.id.0, USER_USER_ID_PARSED as u64);
assert!(members[0].permissions.is_none());
let members = api
.get_organization_members_deserialized_common(
zeta_organization_id,
FRIEND_USER_PAT,
)
.await;
assert_eq!(members.len(), 1);
assert_eq!(members[0].user.id.0, USER_USER_ID_PARSED as u64);
// A non-accepted member of the team should:
// - not be able to see private data about the team, but see all members including themselves
// - should not appear in the team members list to enemy users
@@ -262,15 +253,6 @@ async fn test_get_team_organization() {
.await;
assert_eq!(members.len(), 1); // Only USER_USER_ID should be in the team
// enemy team check via association
let members = api
.get_organization_members_deserialized_common(
zeta_organization_id,
ENEMY_USER_PAT,
)
.await;
assert_eq!(members.len(), 1); // Only USER_USER_ID should be in the team
// An accepted member of the team should appear in the team members list
// and should be able to see private data about the team
let resp = api.join_team(zeta_team_id, FRIEND_USER_PAT).await;