binaryninja/collaboration/
user.rs

1use super::Remote;
2use binaryninjacore_sys::*;
3use std::ptr::NonNull;
4
5use crate::rc::{CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable};
6use crate::string::{BnString, IntoCStr};
7
8#[repr(transparent)]
9pub struct RemoteUser {
10    pub(crate) handle: NonNull<BNCollaborationUser>,
11}
12
13impl RemoteUser {
14    pub(crate) unsafe fn from_raw(handle: NonNull<BNCollaborationUser>) -> Self {
15        Self { handle }
16    }
17
18    pub(crate) unsafe fn ref_from_raw(handle: NonNull<BNCollaborationUser>) -> Ref<Self> {
19        Ref::new(Self { handle })
20    }
21
22    /// Owning Remote
23    pub fn remote(&self) -> Result<Ref<Remote>, ()> {
24        let value = unsafe { BNCollaborationUserGetRemote(self.handle.as_ptr()) };
25        let handle = NonNull::new(value).ok_or(())?;
26        Ok(unsafe { Remote::ref_from_raw(handle) })
27    }
28
29    /// Web api endpoint url
30    pub fn url(&self) -> String {
31        let value = unsafe { BNCollaborationUserGetUrl(self.handle.as_ptr()) };
32        assert!(!value.is_null());
33        unsafe { BnString::into_string(value) }
34    }
35
36    /// Unique id
37    pub fn id(&self) -> String {
38        let value = unsafe { BNCollaborationUserGetId(self.handle.as_ptr()) };
39        assert!(!value.is_null());
40        unsafe { BnString::into_string(value) }
41    }
42
43    /// User's login username
44    pub fn username(&self) -> String {
45        let value = unsafe { BNCollaborationUserGetUsername(self.handle.as_ptr()) };
46        assert!(!value.is_null());
47        unsafe { BnString::into_string(value) }
48    }
49
50    /// Set user's username. You will need to push the user to update the Remote
51    pub fn set_username(&self, username: &str) -> Result<(), ()> {
52        let username = username.to_cstr();
53        let result =
54            unsafe { BNCollaborationUserSetUsername(self.handle.as_ptr(), username.as_ptr()) };
55        if result {
56            Ok(())
57        } else {
58            Err(())
59        }
60    }
61
62    /// User's email address
63    pub fn email(&self) -> String {
64        let value = unsafe { BNCollaborationUserGetEmail(self.handle.as_ptr()) };
65        assert!(!value.is_null());
66        unsafe { BnString::into_string(value) }
67    }
68
69    /// Set user's email. You will need to push the user to update the Remote
70    pub fn set_email(&self, email: &str) -> Result<(), ()> {
71        let username = email.to_cstr();
72        let result =
73            unsafe { BNCollaborationUserSetEmail(self.handle.as_ptr(), username.as_ptr()) };
74        if result {
75            Ok(())
76        } else {
77            Err(())
78        }
79    }
80
81    /// String representing the last date the user logged in
82    pub fn last_login(&self) -> String {
83        let value = unsafe { BNCollaborationUserGetLastLogin(self.handle.as_ptr()) };
84        assert!(!value.is_null());
85        unsafe { BnString::into_string(value) }
86    }
87
88    /// If the user account is active and can log in
89    pub fn is_active(&self) -> bool {
90        unsafe { BNCollaborationUserIsActive(self.handle.as_ptr()) }
91    }
92
93    /// Enable/disable a user account. You will need to push the user to update the Remote
94    pub fn set_is_active(&self, value: bool) -> Result<(), ()> {
95        if unsafe { BNCollaborationUserSetIsActive(self.handle.as_ptr(), value) } {
96            Ok(())
97        } else {
98            Err(())
99        }
100    }
101}
102
103impl PartialEq for RemoteUser {
104    fn eq(&self, other: &Self) -> bool {
105        self.id() == other.id()
106    }
107}
108impl Eq for RemoteUser {}
109
110impl ToOwned for RemoteUser {
111    type Owned = Ref<Self>;
112
113    fn to_owned(&self) -> Self::Owned {
114        unsafe { RefCountable::inc_ref(self) }
115    }
116}
117
118unsafe impl RefCountable for RemoteUser {
119    unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
120        Ref::new(Self {
121            handle: NonNull::new(BNNewCollaborationUserReference(handle.handle.as_ptr())).unwrap(),
122        })
123    }
124
125    unsafe fn dec_ref(handle: &Self) {
126        BNFreeCollaborationUser(handle.handle.as_ptr());
127    }
128}
129
130impl CoreArrayProvider for RemoteUser {
131    type Raw = *mut BNCollaborationUser;
132    type Context = ();
133    type Wrapped<'a> = Guard<'a, RemoteUser>;
134}
135
136unsafe impl CoreArrayProviderInner for RemoteUser {
137    unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
138        BNFreeCollaborationUserList(raw, count)
139    }
140
141    unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, context: &'a Self::Context) -> Self::Wrapped<'a> {
142        let raw_ptr = NonNull::new(*raw).unwrap();
143        Guard::new(Self::from_raw(raw_ptr), context)
144    }
145}