Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions nexus/db-queries/src/db/datastore/silo_group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,13 @@ impl From<SiloGroup> for user::Group {
}
}

impl From<SiloGroup> for user::UserGroup {
fn from(u: SiloGroup) -> user::UserGroup {
let group = user::Group::from(u);
user::UserGroup { id: group.id, display_name: group.display_name }
}
}

#[derive(Debug, Clone)]
pub struct SiloGroupApiOnly {
pub id: SiloGroupUuid,
Expand Down Expand Up @@ -571,6 +578,46 @@ impl DataStore {
.map_err(|e| public_error_from_diesel(e, ErrorHandler::Server))
}

/// Fetch the groups that each of the given users is a member of, for
/// embedding group memberships in `User` views
pub async fn silo_groups_for_users(
&self,
opctx: &OpContext,
authz_silo: &authz::Silo,
silo_user_ids: &[SiloUserUuid],
) -> ListResultVec<(SiloUserUuid, SiloGroup)> {
// Match the authz check used to list the silo's groups
// (silo_groups_list_by_id): anyone who can read the silo can see the
// groups in it.
opctx.authorize(authz::Action::Read, authz_silo).await?;

use nexus_db_schema::schema::{
silo_group as sg, silo_group_membership as sgm,
};

let user_ids: Vec<_> =
silo_user_ids.iter().map(|id| to_db_typed_uuid(*id)).collect();

Ok(sgm::dsl::silo_group_membership
.inner_join(sg::table.on(sg::id.eq(sgm::silo_group_id)))
.filter(sgm::silo_user_id.eq_any(user_ids))
.filter(sg::time_deleted.is_null())
.select((
SiloGroupMembership::as_select(),
model::SiloGroup::as_select(),
))
.get_results_async::<(SiloGroupMembership, model::SiloGroup)>(
&*self.pool_connection_authorized(opctx).await?,
)
.await
.map_err(|e| public_error_from_diesel(e, ErrorHandler::Server))?
.into_iter()
.map(|(membership, group)| {
(membership.silo_user_id.into(), group.into())
})
.collect())
}

pub async fn silo_groups_for_self(
&self,
opctx: &OpContext,
Expand Down
59 changes: 32 additions & 27 deletions nexus/db-queries/src/db/datastore/silo_user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,12 +167,14 @@ impl From<SiloUser> for model::SiloUser {
}
}

impl From<SiloUser> for user::User {
fn from(u: SiloUser) -> user::User {
match u {
SiloUser::ApiOnly(u) => u.into(),
SiloUser::Jit(u) => u.into(),
SiloUser::Scim(u) => u.into(),
impl SiloUser {
/// Convert to the external API view, embedding the user's group
/// memberships.
pub fn into_view(self, groups: Vec<user::UserGroup>) -> user::User {
match self {
SiloUser::ApiOnly(u) => u.into_view(groups),
SiloUser::Jit(u) => u.into_view(groups),
SiloUser::Scim(u) => u.into_view(groups),
}
}
}
Expand Down Expand Up @@ -226,15 +228,16 @@ impl From<SiloUserApiOnly> for SiloUser {
}
}

impl From<SiloUserApiOnly> for user::User {
fn from(u: SiloUserApiOnly) -> user::User {
impl SiloUserApiOnly {
fn into_view(self, groups: Vec<user::UserGroup>) -> user::User {
user::User {
id: u.id,
id: self.id,
// TODO the use of external_id as display_name is temporary
display_name: u.external_id,
silo_id: u.silo_id,
time_created: u.time_created,
time_modified: u.time_modified,
display_name: self.external_id,
silo_id: self.silo_id,
time_created: self.time_created,
time_modified: self.time_modified,
groups,
}
}
}
Expand Down Expand Up @@ -288,15 +291,16 @@ impl From<SiloUserJit> for SiloUser {
}
}

impl From<SiloUserJit> for user::User {
fn from(u: SiloUserJit) -> user::User {
impl SiloUserJit {
fn into_view(self, groups: Vec<user::UserGroup>) -> user::User {
user::User {
id: u.id,
id: self.id,
// TODO the use of external_id as display_name is temporary
display_name: u.external_id,
silo_id: u.silo_id,
time_created: u.time_created,
time_modified: u.time_modified,
display_name: self.external_id,
silo_id: self.silo_id,
time_created: self.time_created,
time_modified: self.time_modified,
groups,
}
}
}
Expand Down Expand Up @@ -361,15 +365,16 @@ impl From<SiloUserScim> for SiloUser {
}
}

impl From<SiloUserScim> for user::User {
fn from(u: SiloUserScim) -> user::User {
impl SiloUserScim {
fn into_view(self, groups: Vec<user::UserGroup>) -> user::User {
user::User {
id: u.id,
id: self.id,
// TODO the use of user_name as display_name is temporary
display_name: u.user_name,
silo_id: u.silo_id,
time_created: u.time_created,
time_modified: u.time_modified,
display_name: self.user_name,
silo_id: self.silo_id,
time_created: self.time_created,
time_modified: self.time_modified,
groups,
}
}
}
Expand Down
Loading
Loading