Skip to main content

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}