binaryninja/collaboration/
user.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
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)
    }
}