From 78d70af510d9db17e1891ad430c221e5054f121c Mon Sep 17 00:00:00 2001 From: Pierre Hubert Date: Tue, 19 Apr 2022 17:14:05 +0200 Subject: [PATCH] Administrators can remove two factor authentication --- assets/css/base_settings_page.css | 1 + src/controllers/admin_controller.rs | 6 +++++ src/data/user.rs | 16 ++++++++----- templates/settings/edit_user.html | 29 +++++++++++++++++++++--- templates/settings/two_factors_page.html | 2 +- 5 files changed, 44 insertions(+), 10 deletions(-) diff --git a/assets/css/base_settings_page.css b/assets/css/base_settings_page.css index 7546218..81f58eb 100644 --- a/assets/css/base_settings_page.css +++ b/assets/css/base_settings_page.css @@ -11,4 +11,5 @@ body { .page_body { padding: 3rem; + overflow-y: scroll; } \ No newline at end of file diff --git a/src/controllers/admin_controller.rs b/src/controllers/admin_controller.rs index 4413646..793b73f 100644 --- a/src/controllers/admin_controller.rs +++ b/src/controllers/admin_controller.rs @@ -60,6 +60,7 @@ pub struct UpdateUserQuery { admin: Option, grant_type: String, granted_clients: String, + two_factor: String, } pub async fn users_route(user: CurrentUser, users: web::Data>, update_query: Option>) -> impl Responder { @@ -80,6 +81,11 @@ pub async fn users_route(user: CurrentUser, users: web::Data>, user.enabled = update.0.enabled.is_some(); user.admin = update.0.admin.is_some(); + if let Some(factors) = user.two_factor.as_mut() { + let factors_to_keep = update.0.two_factor.split(';').collect::>(); + factors.retain(|f| factors_to_keep.contains(&f.id.0.as_str())); + } + user.authorized_clients = match update.0.grant_type.as_str() { "all_clients" => None, "custom_clients" => Some(update.0.granted_clients.split(',') diff --git a/src/data/user.rs b/src/data/user.rs index a0f0edf..d965341 100644 --- a/src/data/user.rs +++ b/src/data/user.rs @@ -41,7 +41,7 @@ pub struct User { pub admin: bool, /// 2FA - pub second_factors: Option>, + pub two_factor: Option>, /// None = all services /// Some([]) = no service @@ -64,16 +64,20 @@ impl User { verify_password(pass, &self.password) } + pub fn has_two_factor(&self) -> bool { + self.two_factor.as_ref().map(|f| !f.is_empty()).unwrap_or(false) + } + pub fn add_factor(&mut self, factor: SecondFactor) { - if self.second_factors.is_none() { - self.second_factors = Some(vec![]); + if self.two_factor.is_none() { + self.two_factor = Some(vec![]); } - self.second_factors.as_mut().unwrap().push(factor); + self.two_factor.as_mut().unwrap().push(factor); } pub fn remove_factor(&mut self, factor_id: FactorID) { - if let Some(f) = self.second_factors.as_mut() { + if let Some(f) = self.two_factor.as_mut() { f.retain(|f| f.id != factor_id); } } @@ -99,7 +103,7 @@ impl Default for User { need_reset_password: false, enabled: true, admin: false, - second_factors: Some(vec![]), + two_factor: Some(vec![]), authorized_clients: Some(Vec::new()), } } diff --git a/templates/settings/edit_user.html b/templates/settings/edit_user.html index 261291b..a253e6d 100644 --- a/templates/settings/edit_user.html +++ b/templates/settings/edit_user.html @@ -68,6 +68,25 @@ + + + {% if u.has_two_factor() %} +
+ Two factor authentication + If you uncheck a factor, it will be DELETED + {% for f in u.two_factor.as_deref().unwrap_or_default() %} +
+ +
+ {% endfor %} +
+ {% endif %} +
Granted clients @@ -161,11 +180,15 @@ document.querySelector("input[name=granted_clients]").value = authorized_clients; + const factors_to_keep = [...document.querySelectorAll(".two-fact-checkbox")] + .filter(e => e.checked) + .map(e => e.value) + .join(";") + + document.querySelector("input[name=two_factor]").value = factors_to_keep; + form.submit(); }); - - - {% endblock content %} \ No newline at end of file diff --git a/templates/settings/two_factors_page.html b/templates/settings/two_factors_page.html index 69a6a47..a9257a3 100644 --- a/templates/settings/two_factors_page.html +++ b/templates/settings/two_factors_page.html @@ -23,7 +23,7 @@ - {% for f in user.second_factors.as_deref().unwrap_or_default() %} + {% for f in user.two_factor.as_deref().unwrap_or_default() %} {{ f.type_str() }} {{ f.name }}