Merge branch 'list_local_users' into 'next'

Implement list_local_users command

See merge request famedly/conduit!260
merge-requests/261/merge
Timo Kösters 2 years ago
commit f50bdb6010

@ -14,6 +14,7 @@ pub enum AdminCommand {
RegisterAppservice(serde_yaml::Value),
UnregisterAppservice(String),
ListAppservices,
ListLocalUsers,
ShowMemoryUsage,
SendMessage(RoomMessageEventContent),
}
@ -95,6 +96,18 @@ impl Admin {
let state_lock = mutex_state.lock().await;
match event {
AdminCommand::ListLocalUsers => {
match guard.users.list_local_users() {
Ok(users) => {
let mut msg: String = format!("Found {} local user account(s):\n", users.len());
msg += &users.join("\n");
send_message(RoomMessageEventContent::text_plain(&msg), guard, &state_lock);
}
Err(e) => {
send_message(RoomMessageEventContent::text_plain(e.to_string()), guard, &state_lock);
}
}
}
AdminCommand::RegisterAppservice(yaml) => {
guard.appservice.register_appservice(yaml).unwrap(); // TODO handle error
}

@ -1548,6 +1548,9 @@ impl Rooms {
"list_appservices" => {
db.admin.send(AdminCommand::ListAppservices);
}
"list_local_users" => {
db.admin.send(AdminCommand::ListLocalUsers);
}
"get_auth_chain" => {
if args.len() == 1 {
if let Ok(event_id) = EventId::parse_arc(args[0]) {

@ -131,6 +131,42 @@ impl Users {
})
}
/// Returns a list of local users as list of usernames.
///
/// A user account is considered `local` if the length of it's password is greater then zero.
#[tracing::instrument(skip(self))]
pub fn list_local_users(&self) -> Result<Vec<String>> {
let users: Vec<String> = self
.userid_password
.iter()
.filter_map(|(username, pw)| self.get_username_with_valid_password(&username, &pw))
.collect();
Ok(users)
}
/// Will only return with Some(username) if the password was not empty and the
/// username could be successfully parsed.
/// If utils::string_from_bytes(...) returns an error that username will be skipped
/// and the error will be logged.
#[tracing::instrument(skip(self))]
fn get_username_with_valid_password(&self, username: &[u8], password: &[u8]) -> Option<String> {
// A valid password is not empty
if password.is_empty() {
None
} else {
match utils::string_from_bytes(username) {
Ok(u) => Some(u),
Err(e) => {
warn!(
"Failed to parse username while calling get_local_users(): {}",
e.to_string()
);
None
}
}
}
}
/// Returns the password hash for the given user.
#[tracing::instrument(skip(self, user_id))]
pub fn password_hash(&self, user_id: &UserId) -> Result<Option<String>> {

Loading…
Cancel
Save