server_watchdog/infrastructure/config/
auth.rs1use std::error::Error;
2use std::sync::Arc;
3use async_trait::async_trait;
4use crate::application::config::AuthUseCase;
5use crate::domain::chat::{Chat, ChatList, ChatMap};
6use crate::domain::config::Config;
7use crate::domain::file_accessor::FileAccessor;
8
9pub struct AuthAdapter {
10 password: Option<String>,
11 chat_map: Option<ChatMap>,
12 config_file_accessor: Arc<dyn FileAccessor<Config> + Send + Sync>,
13 chat_list_file_accessor: Arc<dyn FileAccessor<ChatList> + Send + Sync>
14}
15
16impl AuthAdapter {
17 pub fn new(
18 config_file_accessor: Arc<dyn FileAccessor<Config> + Send + Sync>,
19 chat_list_file_accessor: Arc<dyn FileAccessor<ChatList> + Send + Sync>
20 ) -> Self {
21 Self {
22 password: None,
23 chat_map: None,
24 config_file_accessor,
25 chat_list_file_accessor
26 }
27 }
28
29 pub async fn init(&mut self) {
30 let config = self.config_file_accessor.read().await
31 .unwrap();
32 self.password = config.password;
33 }
34
35 async fn get_chat_map(&mut self) -> Result<&ChatMap, Box<dyn Error + Send + Sync>> {
36 if self.chat_map.is_none() {
37 let list = self.chat_list_file_accessor.read().await?;
38 self.chat_map = Some(ChatMap::from(list));
39 }
40
41 Ok(self.chat_map.as_ref().unwrap())
42 }
43}
44
45#[async_trait]
46impl AuthUseCase for AuthAdapter {
47 async fn set_password(&self, password: Option<String>) -> Result<(), Box<dyn Error + Send + Sync>> {
48 let mut config = self.config_file_accessor.read().await?;
49 config.password = password;
50 self.config_file_accessor.write(&config).await?;
51 Ok(())
52 }
53
54 async fn validate_password(&mut self, password: String) -> bool {
55 let config_password = self.password.as_ref().expect("Password is not defined").as_str();
56 config_password.eq(password.as_str())
57 }
58
59 async fn register(&mut self, client_name: String, identity: String) -> Result<(), Box<dyn Error + Send + Sync>> {
60 let mut chat_list = self.chat_list_file_accessor.read()
61 .await?;
62
63 let already_exists = chat_list.chats.iter().any(|chat| {
65 chat.client_name == client_name && chat.identity == identity
66 });
67
68 if !already_exists {
69 chat_list.chats.push(Chat::new(client_name, identity));
70 self.chat_list_file_accessor.write(&chat_list).await?;
71 self.chat_map = None;
72 }
73
74 Ok(())
75 }
76
77 async fn authenticate(&mut self, client_name: String, identity: String) -> Option<String> {
78 let chat_map = match self.get_chat_map().await {
79 Ok(value) => value,
80 Err(_) => return None
81 };
82
83 let id = chat_map.get_id(client_name.as_str(), identity.as_str())?;
84 Some(String::from(id))
85 }
86
87 fn password_required(&self) -> bool {
88 self.password.is_some()
89 }
90}