summaryrefslogtreecommitdiff
path: root/rust/src/collaboration/user.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rust/src/collaboration/user.rs')
-rw-r--r--rust/src/collaboration/user.rs154
1 files changed, 154 insertions, 0 deletions
diff --git a/rust/src/collaboration/user.rs b/rust/src/collaboration/user.rs
new file mode 100644
index 00000000..0e3433d3
--- /dev/null
+++ b/rust/src/collaboration/user.rs
@@ -0,0 +1,154 @@
+use super::Remote;
+use binaryninjacore_sys::*;
+use std::ffi::c_char;
+use std::ptr::NonNull;
+
+use crate::rc::{CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable};
+use crate::string::{BnStrCompatible, BnString};
+
+#[repr(transparent)]
+pub struct RemoteUser {
+ pub(crate) handle: NonNull<BNCollaborationUser>,
+}
+
+impl RemoteUser {
+ pub(crate) unsafe fn from_raw(handle: NonNull<BNCollaborationUser>) -> Self {
+ Self { handle }
+ }
+
+ pub(crate) unsafe fn ref_from_raw(handle: NonNull<BNCollaborationUser>) -> Ref<Self> {
+ Ref::new(Self { handle })
+ }
+
+ /// Owning Remote
+ pub fn remote(&self) -> Result<Ref<Remote>, ()> {
+ let value = unsafe { BNCollaborationUserGetRemote(self.handle.as_ptr()) };
+ let handle = NonNull::new(value).ok_or(())?;
+ Ok(unsafe { Remote::ref_from_raw(handle) })
+ }
+
+ /// Web api endpoint url
+ pub fn url(&self) -> BnString {
+ let value = unsafe { BNCollaborationUserGetUrl(self.handle.as_ptr()) };
+ assert!(!value.is_null());
+ unsafe { BnString::from_raw(value) }
+ }
+
+ /// Unique id
+ pub fn id(&self) -> BnString {
+ let value = unsafe { BNCollaborationUserGetId(self.handle.as_ptr()) };
+ assert!(!value.is_null());
+ unsafe { BnString::from_raw(value) }
+ }
+
+ /// User's login username
+ pub fn username(&self) -> BnString {
+ let value = unsafe { BNCollaborationUserGetUsername(self.handle.as_ptr()) };
+ assert!(!value.is_null());
+ unsafe { BnString::from_raw(value) }
+ }
+
+ /// Set user's username. You will need to push the user to update the Remote
+ pub fn set_username<U: BnStrCompatible>(&self, username: U) -> Result<(), ()> {
+ let username = username.into_bytes_with_nul();
+ let result = unsafe {
+ BNCollaborationUserSetUsername(
+ self.handle.as_ptr(),
+ username.as_ref().as_ptr() as *const c_char,
+ )
+ };
+ if result {
+ Ok(())
+ } else {
+ Err(())
+ }
+ }
+
+ /// User's email address
+ pub fn email(&self) -> BnString {
+ let value = unsafe { BNCollaborationUserGetEmail(self.handle.as_ptr()) };
+ assert!(!value.is_null());
+ unsafe { BnString::from_raw(value) }
+ }
+
+ /// Set user's email. You will need to push the user to update the Remote
+ pub fn set_email<U: BnStrCompatible>(&self, email: U) -> Result<(), ()> {
+ let username = email.into_bytes_with_nul();
+ let result = unsafe {
+ BNCollaborationUserSetEmail(
+ self.handle.as_ptr(),
+ username.as_ref().as_ptr() as *const c_char,
+ )
+ };
+ if result {
+ Ok(())
+ } else {
+ Err(())
+ }
+ }
+
+ /// String representing the last date the user logged in
+ pub fn last_login(&self) -> BnString {
+ let value = unsafe { BNCollaborationUserGetLastLogin(self.handle.as_ptr()) };
+ assert!(!value.is_null());
+ unsafe { BnString::from_raw(value) }
+ }
+
+ /// If the user account is active and can log in
+ pub fn is_active(&self) -> bool {
+ unsafe { BNCollaborationUserIsActive(self.handle.as_ptr()) }
+ }
+
+ /// Enable/disable a user account. You will need to push the user to update the Remote
+ pub fn set_is_active(&self, value: bool) -> Result<(), ()> {
+ if unsafe { BNCollaborationUserSetIsActive(self.handle.as_ptr(), value) } {
+ Ok(())
+ } else {
+ Err(())
+ }
+ }
+}
+
+impl PartialEq for RemoteUser {
+ fn eq(&self, other: &Self) -> bool {
+ self.id() == other.id()
+ }
+}
+impl Eq for RemoteUser {}
+
+impl ToOwned for RemoteUser {
+ type Owned = Ref<Self>;
+
+ fn to_owned(&self) -> Self::Owned {
+ unsafe { RefCountable::inc_ref(self) }
+ }
+}
+
+unsafe impl RefCountable for RemoteUser {
+ unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
+ Ref::new(Self {
+ handle: NonNull::new(BNNewCollaborationUserReference(handle.handle.as_ptr())).unwrap(),
+ })
+ }
+
+ unsafe fn dec_ref(handle: &Self) {
+ BNFreeCollaborationUser(handle.handle.as_ptr());
+ }
+}
+
+impl CoreArrayProvider for RemoteUser {
+ type Raw = *mut BNCollaborationUser;
+ type Context = ();
+ type Wrapped<'a> = Guard<'a, RemoteUser>;
+}
+
+unsafe impl CoreArrayProviderInner for RemoteUser {
+ unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
+ BNFreeCollaborationUserList(raw, count)
+ }
+
+ unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, context: &'a Self::Context) -> Self::Wrapped<'a> {
+ let raw_ptr = NonNull::new(*raw).unwrap();
+ Guard::new(Self::from_raw(raw_ptr), context)
+ }
+}