bitwarden_importers/importers/onepassword/access/sso/ui.rs
1//! Public callback contracts the SSO login flow drives.
2
3use async_trait::async_trait;
4
5/// The outcome of the identity provider step of an SSO login.
6pub enum SsoLoginResult {
7 /// The full URL the identity provider redirected to. It carries the authorization code.
8 RedirectedTo(String),
9 /// The user gave up on the login.
10 Cancel,
11}
12
13/// Callbacks that take the user through an SSO login.
14#[async_trait]
15pub trait SsoUi: Send + Sync {
16 /// Opens `sso_login_url`, usually in a browser, and waits for the identity provider to
17 /// redirect to `redirect_to`.
18 async fn perform_sso_login(&self, sso_login_url: &str, redirect_to: &str) -> SsoLoginResult;
19
20 /// Shows the device enrollment UI, which the login then drives through the returned context.
21 /// Called once per login: every import is a new device.
22 async fn begin_sso_enrollment(&self) -> Box<dyn SsoEnrollmentContext>;
23}
24
25/// The stage a device enrollment is in, for the UI to show.
26#[derive(Debug, Clone, Copy, PartialEq, Eq)]
27#[cfg_attr(feature = "wasm", derive(serde::Serialize, serde::Deserialize))]
28#[bitwarden_ffi::wasm_record]
29#[cfg_attr(feature = "wasm", tsify(type_prefix = "OnePasswordSso"))]
30pub enum EnrollmentStatus {
31 /// Waiting for the user to approve this device on one that is already enrolled.
32 WaitingForApproval,
33 /// Receiving the credentials from the approving device.
34 ExchangingCredentials,
35 /// Finishing the enrollment.
36 Completing,
37}
38
39/// How a device enrollment ended.
40#[derive(Debug, Clone, Copy, PartialEq, Eq)]
41#[cfg_attr(feature = "wasm", derive(serde::Serialize, serde::Deserialize))]
42#[bitwarden_ffi::wasm_record]
43#[cfg_attr(feature = "wasm", tsify(type_prefix = "OnePassword"))]
44pub enum SsoEnrollmentResult {
45 /// The approving device handed over the credentials.
46 Success,
47 /// The user canceled.
48 Canceled,
49 /// The user denied the request on the approving device.
50 Denied,
51 /// Anything else went wrong.
52 Failed,
53}
54
55/// The answer to the verification code prompt.
56pub enum VerificationCodeResult {
57 /// The code the approving device shows.
58 Code(String),
59 /// The user canceled.
60 Cancel,
61}
62
63/// A device enrollment in progress: the UI shows its stage, asks for the verification code, and
64/// lets the user cancel.
65#[async_trait]
66pub trait SsoEnrollmentContext: Send + Sync {
67 /// Resolves when the user cancels the enrollment. An implementation that cannot cancel never
68 /// resolves.
69 async fn cancelled(&self);
70
71 /// Shows the stage the enrollment has reached.
72 async fn update_status(&self, status: EnrollmentStatus, message: &str);
73
74 /// Asks for the verification code the approving device shows.
75 async fn provide_verification_code(&self) -> VerificationCodeResult;
76
77 /// Closes the enrollment UI. Called exactly once when the enrollment ends, unless the login is
78 /// dropped halfway.
79 async fn end_enrollment(&self, result: SsoEnrollmentResult);
80}