1use crate::libs::messages::Message;
12use crate::libs::{data_storage::DataStorage, secret::Secret};
13use crate::msg_error_anyhow;
14use anyhow::Result;
15use std::fs;
16use std::io::Write;
17
18pub mod gitlab;
19pub mod jira;
20pub mod si;
21
22pub use gitlab::GitLabConfig;
23pub use jira::JiraConfig;
24pub use si::SiConfig;
25
26const MAX_RETRY_COUNT: i32 = 3;
28
29#[allow(async_fn_in_trait)]
36pub trait Session {
37 async fn login(&self) -> Result<String>;
39
40 fn set_credentials(&mut self, password: &str) -> Result<()>;
42
43 fn session_id_file(&self) -> &str;
45
46 fn secret(&self) -> Secret;
48
49 fn retry(&self) -> i32;
51
52 fn inc_retry(&mut self);
54
55 fn reset_retry(&mut self);
57
58 async fn get_session_id(&mut self) -> Result<String> {
62 let session_id_file_path = DataStorage::new().get_path(self.session_id_file())?;
63 let session_id_file_path_str = session_id_file_path.to_str().unwrap();
64
65 if let Ok(session_id) = Self::read_session_id(session_id_file_path_str) {
66 Ok(session_id)
67 } else {
68 loop {
69 let password: String = match self.retry() > 0 {
70 true => self.secret().prompt()?, false => self.secret().get_or_prompt()?, };
73
74 self.set_credentials(&password)?;
75
76 let session_id = self.login().await;
77 match session_id {
78 Ok(session_id) => {
79 let _ = Self::write_session_id(session_id_file_path_str, &session_id);
80 self.reset_retry();
81 return Ok(session_id);
82 }
83 Err(_) => {
84 if self.retry() < MAX_RETRY_COUNT {
85 self.inc_retry();
86 continue;
87 }
88 break Err(msg_error_anyhow!(Message::WrongPassword(MAX_RETRY_COUNT)));
89 }
90 }
91 }
92 }
93 }
94
95 fn read_session_id(file_name: &str) -> Result<String> {
97 Ok(fs::read_to_string(file_name)?)
98 }
99
100 fn write_session_id(file_name: &str, session_id: &str) -> Result<()> {
102 let mut file = fs::OpenOptions::new().write(true).create(true).truncate(true).open(file_name)?;
103 file.write_all(session_id.as_bytes())?;
104 Ok(())
105 }
106
107 fn delete_session_id(&self) -> Result<()> {
109 let session_id_file_path = DataStorage::new().get_path(self.session_id_file())?;
110 fs::remove_file(session_id_file_path)?;
111 Ok(())
112 }
113}