Compare commits
	
		
			2 Commits
		
	
	
		
			5903ec2e8c
			...
			3add7a5d37
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 3add7a5d37 | |||
| 9ff4392afb | 
@@ -81,10 +81,9 @@ pub async fn users_route(user: CurrentUser, users: web::Data<Addr<UsersActor>>,
 | 
			
		||||
        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::<Vec<_>>();
 | 
			
		||||
            factors.retain(|f| factors_to_keep.contains(&f.id.0.as_str()));
 | 
			
		||||
        }
 | 
			
		||||
        let factors_to_keep = update.0.two_factor.split(';').collect::<Vec<_>>();
 | 
			
		||||
        user.two_factor.retain(|f| factors_to_keep.contains(&f.id.0.as_str()));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        user.authorized_clients = match update.0.grant_type.as_str() {
 | 
			
		||||
            "all_clients" => None,
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@ use crate::actors::users_actor;
 | 
			
		||||
use crate::actors::users_actor::UsersActor;
 | 
			
		||||
use crate::data::current_user::CurrentUser;
 | 
			
		||||
use crate::data::totp_key::TotpKey;
 | 
			
		||||
use crate::data::user::{FactorID, SecondFactor, SecondFactorType, User};
 | 
			
		||||
use crate::data::user::{FactorID, TwoFactor, TwoFactorType, User};
 | 
			
		||||
 | 
			
		||||
#[derive(serde::Deserialize)]
 | 
			
		||||
pub struct AddTOTPRequest {
 | 
			
		||||
@@ -31,10 +31,10 @@ pub async fn save_totp_factor(user: CurrentUser, form: web::Json<AddTOTPRequest>
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let mut user = User::from(user);
 | 
			
		||||
    user.add_factor(SecondFactor {
 | 
			
		||||
    user.add_factor(TwoFactor {
 | 
			
		||||
        id: FactorID(Uuid::new_v4().to_string()),
 | 
			
		||||
        name: form.0.factor_name,
 | 
			
		||||
        kind: SecondFactorType::TOTP(key),
 | 
			
		||||
        kind: TwoFactorType::TOTP(key),
 | 
			
		||||
    });
 | 
			
		||||
    let res = users.send(users_actor::UpdateUserRequest(user)).await.unwrap().0;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -9,21 +9,21 @@ pub type UserID = String;
 | 
			
		||||
pub struct FactorID(pub String);
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
 | 
			
		||||
pub enum SecondFactorType {
 | 
			
		||||
pub enum TwoFactorType {
 | 
			
		||||
    TOTP(TotpKey)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
 | 
			
		||||
pub struct SecondFactor {
 | 
			
		||||
pub struct TwoFactor {
 | 
			
		||||
    pub id: FactorID,
 | 
			
		||||
    pub name: String,
 | 
			
		||||
    pub kind: SecondFactorType,
 | 
			
		||||
    pub kind: TwoFactorType,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl SecondFactor {
 | 
			
		||||
impl TwoFactor {
 | 
			
		||||
    pub fn type_str(&self) -> &'static str {
 | 
			
		||||
        match self.kind {
 | 
			
		||||
            SecondFactorType::TOTP(_) => "Authenticator app"
 | 
			
		||||
            TwoFactorType::TOTP(_) => "Authenticator app"
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -41,7 +41,8 @@ pub struct User {
 | 
			
		||||
    pub admin: bool,
 | 
			
		||||
 | 
			
		||||
    /// 2FA
 | 
			
		||||
    pub two_factor: Option<Vec<SecondFactor>>,
 | 
			
		||||
    #[serde(default)]
 | 
			
		||||
    pub two_factor: Vec<TwoFactor>,
 | 
			
		||||
 | 
			
		||||
    /// None = all services
 | 
			
		||||
    /// Some([]) = no service
 | 
			
		||||
@@ -65,21 +66,15 @@ impl User {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn has_two_factor(&self) -> bool {
 | 
			
		||||
        self.two_factor.as_ref().map(|f| !f.is_empty()).unwrap_or(false)
 | 
			
		||||
        !self.two_factor.is_empty()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn add_factor(&mut self, factor: SecondFactor) {
 | 
			
		||||
        if self.two_factor.is_none() {
 | 
			
		||||
            self.two_factor = Some(vec![]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        self.two_factor.as_mut().unwrap().push(factor);
 | 
			
		||||
    pub fn add_factor(&mut self, factor: TwoFactor) {
 | 
			
		||||
        self.two_factor.push(factor);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn remove_factor(&mut self, factor_id: FactorID) {
 | 
			
		||||
        if let Some(f) = self.two_factor.as_mut() {
 | 
			
		||||
            f.retain(|f| f.id != factor_id);
 | 
			
		||||
        }
 | 
			
		||||
        self.two_factor.retain(|f| f.id != factor_id);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -103,7 +98,7 @@ impl Default for User {
 | 
			
		||||
            need_reset_password: false,
 | 
			
		||||
            enabled: true,
 | 
			
		||||
            admin: false,
 | 
			
		||||
            two_factor: Some(vec![]),
 | 
			
		||||
            two_factor: vec![],
 | 
			
		||||
            authorized_clients: Some(Vec::new()),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -74,7 +74,7 @@
 | 
			
		||||
    <fieldset class="form-group">
 | 
			
		||||
        <legend class="mt-4">Two factor authentication</legend>
 | 
			
		||||
        <strong>If you uncheck a factor, it will be DELETED</strong>
 | 
			
		||||
        {% for f in u.two_factor.as_deref().unwrap_or_default() %}
 | 
			
		||||
        {% for f in u.two_factor %}
 | 
			
		||||
        <div class="form-check">
 | 
			
		||||
            <label class="form-check-label">
 | 
			
		||||
                <input type="checkbox" class="form-check-input two-fact-checkbox"
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,7 @@
 | 
			
		||||
    </tr>
 | 
			
		||||
    </thead>
 | 
			
		||||
    <tbody>
 | 
			
		||||
    {% for f in user.two_factor.as_deref().unwrap_or_default() %}
 | 
			
		||||
    {% for f in user.two_factor %}
 | 
			
		||||
    <tr id="factor-{{ f.id.0 }}">
 | 
			
		||||
        <td>{{ f.type_str() }}</td>
 | 
			
		||||
        <td>{{ f.name }}</td>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user