smbcloud_cli/account/logout/
mod.rs

1use anyhow::{anyhow, Result};
2use console::style;
3use dialoguer::{theme::ColorfulTheme, Confirm};
4use reqwest::{Client, StatusCode};
5use smbcloud_networking::{
6    constants::PATH_USERS_SIGN_OUT, environment::Environment, get_smb_token, smb_base_url_builder,
7    smb_token_file_path,
8};
9use spinners::Spinner;
10use std::fs;
11
12use crate::{
13    cli::CommandResult,
14    ui::{fail_message, fail_symbol, succeed_message, succeed_symbol},
15};
16
17pub async fn process_logout(env: Environment) -> Result<CommandResult> {
18    // Logout if user confirms
19    if let Some(token_path) = smb_token_file_path(env) {
20        let confirm = match Confirm::with_theme(&ColorfulTheme::default())
21            .with_prompt("Do you want to logout? y/n")
22            .interact()
23        {
24            Ok(confirm) => confirm,
25            Err(_) => {
26                let error = anyhow!("Invalid input.");
27                return Err(error);
28            }
29        };
30        if !confirm {
31            return Ok(CommandResult {
32                spinner: Spinner::new(
33                    spinners::Spinners::SimpleDotsScrolling,
34                    style("Cancel operation.").green().bold().to_string(),
35                ),
36                symbol: succeed_symbol(),
37                msg: "Doing nothing.".to_owned(),
38            });
39        }
40
41        let spinner = Spinner::new(
42            spinners::Spinners::SimpleDotsScrolling,
43            style("Logging you out...").green().bold().to_string(),
44        );
45
46        // Call backend
47        match do_process_logout(env).await {
48            Ok(_) => {
49                fs::remove_file(token_path)?;
50                Ok(CommandResult {
51                    spinner,
52                    symbol: succeed_symbol(),
53                    msg: succeed_message("You are logged out!"),
54                })
55            }
56            Err(e) => Err(anyhow!("{e}")),
57        }
58    } else {
59        Ok(CommandResult {
60            spinner: Spinner::new(
61                spinners::Spinners::SimpleDotsScrolling,
62                style("Loading...").green().bold().to_string(),
63            ),
64            symbol: fail_symbol(),
65            msg: fail_message("You are not logged in. Please login first."),
66        })
67    }
68}
69
70async fn do_process_logout(env: Environment) -> Result<()> {
71    let token = get_smb_token(env).await?;
72
73    let response = Client::new()
74        .delete(build_smb_logout_url(env))
75        .header("Authorization", token)
76        .header("Accept", "application/json")
77        .header("Content-Type", "application/x-www-form-urlencoded")
78        .send()
79        .await?;
80
81    match response.status() {
82        StatusCode::OK => Ok(()),
83        _ => Err(anyhow!("Failed to logout.")),
84    }
85}
86
87fn build_smb_logout_url(env: Environment) -> String {
88    let mut url_builder = smb_base_url_builder(env);
89    url_builder.add_route(PATH_USERS_SIGN_OUT);
90    url_builder.build()
91}