diff options
| author | Josh Ferrell <josh@vector35.com> | 2026-04-14 16:22:40 -0400 |
|---|---|---|
| committer | Josh Ferrell <josh@vector35.com> | 2026-05-05 14:46:15 -0400 |
| commit | af50b06082044fcbbf730deda985d0133ca98b88 (patch) | |
| tree | 6b1ae5a4678d8a39a88af4de2cd150663e1a9c8e /rust | |
| parent | e4db4f0704ea6e6b381e9322a336661dc23c3b5f (diff) | |
Switch collaboration permission checks to using User objects
Diffstat (limited to 'rust')
| -rw-r--r-- | rust/src/collaboration/group.rs | 44 | ||||
| -rw-r--r-- | rust/src/collaboration/project.rs | 28 | ||||
| -rw-r--r-- | rust/src/collaboration/remote.rs | 13 |
3 files changed, 34 insertions, 51 deletions
diff --git a/rust/src/collaboration/group.rs b/rust/src/collaboration/group.rs index 01f92169..e3ee82d0 100644 --- a/rust/src/collaboration/group.rs +++ b/rust/src/collaboration/group.rs @@ -1,4 +1,5 @@ use super::Remote; +use crate::collaboration::RemoteUser; use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable}; use crate::string::{BnString, IntoCStr}; use binaryninjacore_sys::*; @@ -55,55 +56,40 @@ impl RemoteGroup { } /// Get list of users in the group - pub fn users(&self) -> Result<(Array<BnString>, Array<BnString>), ()> { - let mut usernames = std::ptr::null_mut(); - let mut user_ids = std::ptr::null_mut(); + pub fn users(&self) -> Result<Array<RemoteUser>, ()> { let mut count = 0; // TODO: This should only fail if collaboration is not supported. // TODO: Because you should not have a RemoteGroup at that point we can ignore? - let success = unsafe { - BNCollaborationGroupGetUsers( - self.handle.as_ptr(), - &mut user_ids, - &mut usernames, - &mut count, - ) - }; - success - .then(|| unsafe { - let ids = Array::new(user_ids, count, ()); - let users = Array::new(usernames, count, ()); - (ids, users) - }) + let result = unsafe { BNCollaborationGroupGetUsers(self.handle.as_ptr(), &mut count) }; + (!result.is_null()) + .then(|| unsafe { Array::new(result, count, ()) }) .ok_or(()) } // TODO: Are any permissions required to the set the remote group users? - /// Set the list of users in a group by their usernames. + /// Set the list of users in a group. /// You will need to push the group to update the Remote. - pub fn set_users<I>(&self, usernames: I) -> Result<(), ()> + pub fn set_users<I>(&self, users: I) -> Result<(), ()> where - I: IntoIterator<Item = String>, + I: IntoIterator<Item = Ref<RemoteUser>>, { - let usernames: Vec<_> = usernames.into_iter().map(|u| u.to_cstr()).collect(); - let mut usernames_raw: Vec<_> = usernames.iter().map(|s| s.as_ptr()).collect(); + let mut users_raw: Vec<_> = users.into_iter().map(|s| s.handle.as_ptr()).collect(); // TODO: This should only fail if collaboration is not supported. // TODO: Because you should not have a RemoteGroup at that point we can ignore? // TODO: Do you need any permissions to do this? let success = unsafe { - BNCollaborationGroupSetUsernames( + BNCollaborationGroupSetUsers( self.handle.as_ptr(), - usernames_raw.as_mut_ptr(), - usernames_raw.len(), + users_raw.as_mut_ptr(), + users_raw.len(), ) }; success.then_some(()).ok_or(()) } - /// Test if a group has a user with the given username - pub fn contains_user(&self, username: &str) -> bool { - let username = username.to_cstr(); - unsafe { BNCollaborationGroupContainsUser(self.handle.as_ptr(), username.as_ptr()) } + /// Test if a group contains a user + pub fn contains_user(&self, user: Ref<RemoteUser>) -> bool { + unsafe { BNCollaborationGroupContainsUser(self.handle.as_ptr(), user.handle.as_ptr()) } } } diff --git a/rust/src/collaboration/project.rs b/rust/src/collaboration/project.rs index cfcc1db4..3a24ea8b 100644 --- a/rust/src/collaboration/project.rs +++ b/rust/src/collaboration/project.rs @@ -12,6 +12,7 @@ use super::{ }; use crate::binary_view::{BinaryView, BinaryViewExt}; +use crate::collaboration::RemoteUser; use crate::database::Database; use crate::file_metadata::FileMetadata; use crate::progress::{NoProgressCallback, ProgressCallback}; @@ -761,34 +762,31 @@ impl RemoteProject { success.then_some(()).ok_or(()) } - /// Determine if a user is in any of the view/edit/admin groups. + /// Determine if a user has view permission (either directly or from a group) /// /// # Arguments /// - /// * `username` - Username of user to check - pub fn can_user_view(&self, username: &str) -> bool { - let username = username.to_cstr(); - unsafe { BNRemoteProjectCanUserView(self.handle.as_ptr(), username.as_ptr()) } + /// * `user` - User to check + pub fn can_user_view(&self, user: Ref<RemoteUser>) -> bool { + unsafe { BNRemoteProjectCanUserView(self.handle.as_ptr(), user.handle.as_ptr()) } } - /// Determine if a user is in any of the edit/admin groups. + /// Determine if a user has edit permission (either directly or from a group) /// /// # Arguments /// - /// * `username` - Username of user to check - pub fn can_user_edit(&self, username: &str) -> bool { - let username = username.to_cstr(); - unsafe { BNRemoteProjectCanUserEdit(self.handle.as_ptr(), username.as_ptr()) } + /// * `user` - User to check + pub fn can_user_edit(&self, user: Ref<RemoteUser>) -> bool { + unsafe { BNRemoteProjectCanUserEdit(self.handle.as_ptr(), user.handle.as_ptr()) } } - /// Determine if a user is in the admin group. + /// Determine if a user has admin permission (either directly or from a group) /// /// # Arguments /// - /// * `username` - Username of user to check - pub fn can_user_admin(&self, username: &str) -> bool { - let username = username.to_cstr(); - unsafe { BNRemoteProjectCanUserAdmin(self.handle.as_ptr(), username.as_ptr()) } + /// * `user` - User to check + pub fn can_user_admin(&self, user: Ref<RemoteUser>) -> bool { + unsafe { BNRemoteProjectCanUserAdmin(self.handle.as_ptr(), user.handle.as_ptr()) } } /// Get the default directory path for a remote Project. This is based off diff --git a/rust/src/collaboration/remote.rs b/rust/src/collaboration/remote.rs index 03c808bc..22e65245 100644 --- a/rust/src/collaboration/remote.rs +++ b/rust/src/collaboration/remote.rs @@ -515,21 +515,20 @@ impl Remote { /// # Arguments /// /// * `name` - Group name - /// * `usernames` - List of usernames of users in the group - pub fn create_group<I>(&self, name: &str, usernames: I) -> Result<Ref<RemoteGroup>, ()> + /// * `users` - List of users in the group + pub fn create_group<I>(&self, name: &str, users: I) -> Result<Ref<RemoteGroup>, ()> where - I: IntoIterator<Item = String>, + I: IntoIterator<Item = Ref<RemoteUser>>, { let name = name.to_cstr(); - let usernames: Vec<_> = usernames.into_iter().map(|s| s.to_cstr()).collect(); - let mut username_ptrs: Vec<_> = usernames.iter().map(|s| s.as_ptr()).collect(); + let mut user_ptrs: Vec<_> = users.into_iter().map(|s| s.handle.as_ptr()).collect(); let value = unsafe { BNRemoteCreateGroup( self.handle.as_ptr(), name.as_ptr(), - username_ptrs.as_mut_ptr(), - username_ptrs.len(), + user_ptrs.as_mut_ptr(), + user_ptrs.len(), ) }; NonNull::new(value) |
