-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinit.rs
134 lines (113 loc) · 4.33 KB
/
init.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//! Handle initialization mode
//!
//! This mode adds the first user to the DB in case none has been registered before. This is required to register the first administrator which then has access to the Hive backend for any further customization.
//!
//! Additionally this mode is used to set the OS users and groups required to run the application
use std::sync::Arc;
use comm_types::auth::{DbUser, Role};
use dialoguer::{theme::ColorfulTheme, Input, Password};
use hive_db::BincodeDb;
use nix::unistd::{Group, User};
use crate::{
config::AppConfig,
database::{
hasher,
keys::{self, config::APP_CONFIG},
MonitorDb,
},
};
pub fn run_init_mode(db: Arc<MonitorDb>) {
let users = db
.credentials_tree
.b_get::<Vec<DbUser>>(&keys::credentials::USERS)
.unwrap();
if users.is_none() || users.unwrap().is_empty() {
// No user found, ask user to register first hive user
add_first_user_prompt(&db);
}
println!("Please provide the system user name used for running Hive");
let hive_user = system_user_prompt();
println!("Please provide the system group name used for running Hive");
let hive_group = system_group_prompt();
println!("Please provide the system user name used for running the Hive runner");
let runner_user = system_user_prompt();
let new_app_config = AppConfig {
hive_user,
hive_group,
runner_user,
};
db.config_tree
.b_insert(&APP_CONFIG, &new_app_config)
.expect("Failed to save value to DB");
println!("Initial Hive setup successful. You can now run the monitor binary in a productive mode: 'monitor standalone' (example)");
}
/// Prompts the user to register the inial user
///
/// Automatically creates the user with the provided username & password in the Hive database
fn add_first_user_prompt(db: &MonitorDb) {
println!(
"In order to initialize the Hive application, please register the initial admin user:"
);
let username_input = Input::with_theme(&ColorfulTheme::default())
.with_prompt("Username")
.validate_with(|input: &String| -> Result<(), &str> {
if input.contains(' ') {
return Err("Whitespaces are not allowed");
}
if input.len() < 4 {
return Err("Username too short, minimum 4 characters are required");
}
Ok(())
})
.interact_text()
.unwrap();
let password_input = Password::with_theme(&ColorfulTheme::default())
.with_prompt("Password")
.with_confirmation("Repeat password", "Error: The passwords don't match.")
.interact()
.unwrap();
let hash = hasher::hash_password(&password_input);
let users = vec![DbUser {
username: username_input.clone(),
hash,
role: Role::ADMIN,
}];
db.credentials_tree
.b_insert(&keys::credentials::USERS, &users)
.unwrap();
println!("Successfully added user '{}', with admin role.\nYou can now restart the application in a non init-mode.", username_input);
}
/// Prompts the user for a system user
///
/// This prompt verifies if the user exists on the system OS
fn system_user_prompt() -> String {
Input::with_theme(&ColorfulTheme::default())
.with_prompt("Username")
.validate_with(|input: &String| -> Result<(), String> {
match User::from_name(input).expect(
"Failed to search system users. This is likely a system configuration issue.",
) {
Some(_) => Ok(()),
None => Err(format!("User with name {} could not be found", input)),
}
})
.interact_text()
.unwrap()
}
/// Prompts the user for a system group
///
/// This prompt verifies if the group exists on the system OS
fn system_group_prompt() -> String {
Input::with_theme(&ColorfulTheme::default())
.with_prompt("Group name")
.validate_with(|input: &String| -> Result<(), String> {
match Group::from_name(input).expect(
"Failed to search system groups. This is likely a system configuration issue.",
) {
Some(_) => Ok(()),
None => Err(format!("Group with name {} could not be found", input)),
}
})
.interact_text()
.unwrap()
}