fix: align user group access controls

This commit is contained in:
fawney19
2026-05-10 17:28:23 +08:00
parent a8ac944959
commit d246f6b42c
33 changed files with 1958 additions and 1018 deletions

View File

@@ -356,6 +356,41 @@ fn memory_group_members(
.collect()
}
fn memory_export_row_from_auth_user(
repository: &InMemoryUserReadRepository,
user: &StoredUserAuthRecord,
) -> Result<StoredUserExportRow, DataLayerError> {
let model_capability_settings = repository
.model_settings_by_user_id
.read()
.expect("user repository lock")
.get(&user.id)
.cloned();
StoredUserExportRow::new(
user.id.clone(),
user.email.clone(),
user.email_verified,
user.username.clone(),
user.password_hash.clone(),
user.role.clone(),
user.auth_source.clone(),
user.allowed_providers.clone().map(serde_json::Value::from),
user.allowed_api_formats
.clone()
.map(serde_json::Value::from),
user.allowed_models.clone().map(serde_json::Value::from),
None,
model_capability_settings,
user.is_active,
)?
.with_policy_modes(
user.allowed_providers_mode.clone(),
user.allowed_api_formats_mode.clone(),
user.allowed_models_mode.clone(),
"system".to_string(),
)
}
#[async_trait]
impl UserReadRepository for InMemoryUserReadRepository {
async fn list_users_by_ids(
@@ -395,22 +430,36 @@ impl UserReadRepository for InMemoryUserReadRepository {
async fn list_non_admin_export_users(
&self,
) -> Result<Vec<StoredUserExportRow>, DataLayerError> {
let rows = self.export_rows.read().expect("user repository lock");
if !rows.is_empty() {
return Ok(rows
.iter()
.filter(|row| !row.role.eq_ignore_ascii_case("admin"))
.cloned()
.collect());
}
Ok(self
.export_rows
.auth_by_id
.read()
.expect("user repository lock")
.iter()
.filter(|row| !row.role.eq_ignore_ascii_case("admin"))
.cloned()
.collect())
.filter(|(_, user)| !user.role.eq_ignore_ascii_case("admin"))
.map(|(_, user)| memory_export_row_from_auth_user(self, user))
.collect::<Result<Vec<_>, _>>()?)
}
async fn list_export_users(&self) -> Result<Vec<StoredUserExportRow>, DataLayerError> {
let rows = self.export_rows.read().expect("user repository lock");
if !rows.is_empty() {
return Ok(rows.clone());
}
Ok(self
.export_rows
.auth_by_id
.read()
.expect("user repository lock")
.clone())
.values()
.map(|user| memory_export_row_from_auth_user(self, user))
.collect::<Result<Vec<_>, _>>()?)
}
async fn list_export_users_page(
@@ -500,10 +549,8 @@ impl UserReadRepository for InMemoryUserReadRepository {
.cloned()
.collect::<Vec<_>>();
groups.sort_by(|left, right| {
right
.priority
.cmp(&left.priority)
.then_with(|| left.name.cmp(&right.name))
left.name
.cmp(&right.name)
.then_with(|| left.id.cmp(&right.id))
});
Ok(groups)
@@ -687,7 +734,6 @@ impl UserReadRepository for InMemoryUserReadRepository {
memberships.sort_by(|left, right| {
left.user_id
.cmp(&right.user_id)
.then_with(|| right.group_priority.cmp(&left.group_priority))
.then_with(|| left.group_name.cmp(&right.group_name))
.then_with(|| left.group_id.cmp(&right.group_id))
});

View File

@@ -370,7 +370,7 @@ WHERE is_deleted = 0
async fn list_user_groups(&self) -> Result<Vec<StoredUserGroup>, DataLayerError> {
let mut builder = QueryBuilder::<MySql>::new(USER_GROUP_COLUMNS);
builder.push(" ORDER BY priority DESC, name ASC, id ASC");
builder.push(" ORDER BY name ASC, id ASC");
self.fetch_group_rows(builder).await
}
@@ -401,7 +401,7 @@ WHERE is_deleted = 0
separated.push_bind(group_id);
}
}
builder.push(") ORDER BY priority DESC, name ASC, id ASC");
builder.push(") ORDER BY name ASC, id ASC");
self.fetch_group_rows(builder).await
}
@@ -568,7 +568,7 @@ WHERE id = ?
builder
.push(" WHERE id IN (SELECT group_id FROM user_group_members WHERE user_id = ")
.push_bind(user_id)
.push(") ORDER BY priority DESC, name ASC, id ASC");
.push(") ORDER BY name ASC, id ASC");
self.fetch_group_rows(builder).await
}
@@ -598,7 +598,9 @@ WHERE user_group_members.user_id IN (
separated.push_bind(user_id);
}
}
builder.push(") ORDER BY user_group_members.user_id ASC, user_groups.priority DESC, user_groups.name ASC, user_groups.id ASC");
builder.push(
") ORDER BY user_group_members.user_id ASC, user_groups.name ASC, user_groups.id ASC",
);
let rows = builder.build().fetch_all(&self.pool).await.map_sql_err()?;
rows.iter().map(map_user_group_membership_row).collect()
}

View File

@@ -684,7 +684,7 @@ impl SqlxUserReadRepository {
pub async fn list_user_groups(&self) -> Result<Vec<StoredUserGroup>, DataLayerError> {
let mut builder = QueryBuilder::<Postgres>::new(USER_GROUP_COLUMNS);
builder.push(" ORDER BY priority DESC, name ASC, id ASC");
builder.push(" ORDER BY name ASC, id ASC");
collect_query_rows(builder.build().fetch(&self.pool), map_user_group_row).await
}
@@ -720,7 +720,7 @@ impl SqlxUserReadRepository {
separated.push_bind(group_id);
}
}
builder.push(") ORDER BY priority DESC, name ASC, id ASC");
builder.push(") ORDER BY name ASC, id ASC");
collect_query_rows(builder.build().fetch(&self.pool), map_user_group_row).await
}
@@ -872,7 +872,7 @@ WHERE id = $1
builder
.push(" WHERE id IN (SELECT group_id FROM user_group_members WHERE user_id = ")
.push_bind(user_id)
.push(") ORDER BY priority DESC, name ASC, id ASC");
.push(") ORDER BY name ASC, id ASC");
collect_query_rows(builder.build().fetch(&self.pool), map_user_group_row).await
}
@@ -902,7 +902,9 @@ WHERE user_group_members.user_id IN (
separated.push_bind(user_id);
}
}
builder.push(") ORDER BY user_group_members.user_id ASC, user_groups.priority DESC, user_groups.name ASC, user_groups.id ASC");
builder.push(
") ORDER BY user_group_members.user_id ASC, user_groups.name ASC, user_groups.id ASC",
);
collect_query_rows(
builder.build().fetch(&self.pool),
map_user_group_membership_row,

View File

@@ -370,7 +370,7 @@ WHERE is_deleted = 0
async fn list_user_groups(&self) -> Result<Vec<StoredUserGroup>, DataLayerError> {
let mut builder = QueryBuilder::<Sqlite>::new(USER_GROUP_COLUMNS);
builder.push(" ORDER BY priority DESC, name ASC, id ASC");
builder.push(" ORDER BY name ASC, id ASC");
self.fetch_group_rows(builder).await
}
@@ -401,7 +401,7 @@ WHERE is_deleted = 0
separated.push_bind(group_id);
}
}
builder.push(") ORDER BY priority DESC, name ASC, id ASC");
builder.push(") ORDER BY name ASC, id ASC");
self.fetch_group_rows(builder).await
}
@@ -568,7 +568,7 @@ WHERE id = ?
builder
.push(" WHERE id IN (SELECT group_id FROM user_group_members WHERE user_id = ")
.push_bind(user_id)
.push(") ORDER BY priority DESC, name ASC, id ASC");
.push(") ORDER BY name ASC, id ASC");
self.fetch_group_rows(builder).await
}
@@ -598,7 +598,9 @@ WHERE user_group_members.user_id IN (
separated.push_bind(user_id);
}
}
builder.push(") ORDER BY user_group_members.user_id ASC, user_groups.priority DESC, user_groups.name ASC, user_groups.id ASC");
builder.push(
") ORDER BY user_group_members.user_id ASC, user_groups.name ASC, user_groups.id ASC",
);
let rows = builder.build().fetch_all(&self.pool).await.map_sql_err()?;
rows.iter().map(map_user_group_membership_row).collect()
}