bitwarden_emergency_access/
emergency_access.rs1use bitwarden_api_api::models::{
2 EmergencyAccessGranteeDetailsResponseModel, EmergencyAccessGrantorDetailsResponseModel,
3 EmergencyAccessStatusType as ApiEmergencyAccessStatus,
4 EmergencyAccessType as ApiEmergencyAccessType,
5};
6use bitwarden_core::{MissingFieldError, UserId, require};
7use bitwarden_uuid::uuid_newtype;
8use serde::{Deserialize, Serialize};
9use serde_repr::{Deserialize_repr, Serialize_repr};
10
11uuid_newtype!(pub EmergencyAccessId);
12
13#[derive(Serialize_repr, Deserialize_repr, Debug, Clone, Copy, PartialEq, Eq)]
15#[bitwarden_ffi::wasm_object]
16#[repr(u8)]
17pub enum EmergencyAccessType {
18 View = 0,
20 Takeover = 1,
22}
23
24#[derive(Serialize_repr, Deserialize_repr, Debug, Clone, Copy, PartialEq, Eq)]
26#[bitwarden_ffi::wasm_object]
27#[repr(u8)]
28pub enum EmergencyAccessStatus {
29 Invited = 0,
31 Accepted = 1,
33 Confirmed = 2,
35 RecoveryInitiated = 3,
37 RecoveryApproved = 4,
39}
40
41#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
43#[serde(rename_all = "camelCase")]
44#[bitwarden_ffi::wasm_record]
45pub struct GranteeEmergencyAccess {
46 pub id: EmergencyAccessId,
48 pub grantee_id: Option<UserId>,
50 pub name: Option<String>,
52 pub email: Option<String>,
54 pub r#type: EmergencyAccessType,
56 pub status: EmergencyAccessStatus,
58 pub wait_time_days: i32,
60 pub avatar_color: Option<String>,
62}
63
64#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
66#[serde(rename_all = "camelCase")]
67#[bitwarden_ffi::wasm_record]
68pub struct GrantorEmergencyAccess {
69 pub id: EmergencyAccessId,
71 pub grantor_id: UserId,
73 pub name: Option<String>,
75 pub email: Option<String>,
77 pub r#type: EmergencyAccessType,
79 pub status: EmergencyAccessStatus,
81 pub wait_time_days: i32,
83 pub avatar_color: Option<String>,
85}
86
87impl TryFrom<ApiEmergencyAccessType> for EmergencyAccessType {
88 type Error = MissingFieldError;
89
90 fn try_from(value: ApiEmergencyAccessType) -> Result<Self, Self::Error> {
91 Ok(match value {
92 ApiEmergencyAccessType::View => Self::View,
93 ApiEmergencyAccessType::Takeover => Self::Takeover,
94 ApiEmergencyAccessType::__Unknown(_) => return Err(MissingFieldError("type")),
95 })
96 }
97}
98
99impl From<EmergencyAccessType> for ApiEmergencyAccessType {
100 fn from(value: EmergencyAccessType) -> Self {
101 match value {
102 EmergencyAccessType::View => Self::View,
103 EmergencyAccessType::Takeover => Self::Takeover,
104 }
105 }
106}
107
108impl TryFrom<ApiEmergencyAccessStatus> for EmergencyAccessStatus {
109 type Error = MissingFieldError;
110
111 fn try_from(value: ApiEmergencyAccessStatus) -> Result<Self, Self::Error> {
112 Ok(match value {
113 ApiEmergencyAccessStatus::Invited => Self::Invited,
114 ApiEmergencyAccessStatus::Accepted => Self::Accepted,
115 ApiEmergencyAccessStatus::Confirmed => Self::Confirmed,
116 ApiEmergencyAccessStatus::RecoveryInitiated => Self::RecoveryInitiated,
117 ApiEmergencyAccessStatus::RecoveryApproved => Self::RecoveryApproved,
118 ApiEmergencyAccessStatus::__Unknown(_) => return Err(MissingFieldError("status")),
119 })
120 }
121}
122
123impl TryFrom<EmergencyAccessGranteeDetailsResponseModel> for GranteeEmergencyAccess {
124 type Error = MissingFieldError;
125
126 fn try_from(response: EmergencyAccessGranteeDetailsResponseModel) -> Result<Self, Self::Error> {
127 Ok(Self {
128 id: EmergencyAccessId::new(require!(response.id)),
129 grantee_id: response.grantee_id.map(UserId::new),
130 name: response.name,
131 email: response.email,
132 r#type: require!(response.r#type).try_into()?,
133 status: require!(response.status).try_into()?,
134 wait_time_days: require!(response.wait_time_days),
135 avatar_color: response.avatar_color,
136 })
137 }
138}
139
140impl TryFrom<EmergencyAccessGrantorDetailsResponseModel> for GrantorEmergencyAccess {
141 type Error = MissingFieldError;
142
143 fn try_from(response: EmergencyAccessGrantorDetailsResponseModel) -> Result<Self, Self::Error> {
144 Ok(Self {
145 id: EmergencyAccessId::new(require!(response.id)),
146 grantor_id: UserId::new(require!(response.grantor_id)),
147 name: response.name,
148 email: response.email,
149 r#type: require!(response.r#type).try_into()?,
150 status: require!(response.status).try_into()?,
151 wait_time_days: require!(response.wait_time_days),
152 avatar_color: response.avatar_color,
153 })
154 }
155}