darkwing/server/dtos/entities/
settings_dto.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
135
136
137
138
139
140
141
142
143
144
145
//! Data transfer objects for handling application settings
//!
//! This module provides types and implementations for working with application
//! settings, including encryption/decryption of sensitive setting values and
//! convenient querying of setting states. It defines constants for common
//! settings and structures for representing both individual settings and
//! collections of settings.

use tracing::debug;

use crate::{
  database::team::Setting,
  server::{
    error::Error, services::database_encryption_services::DynDatabaseEncryption,
  },
};

/// Constant for the setting that controls profile image loading
pub const DISABLE_IMAGES: &str = "disableLoadProfileImages";
/// Constant for the setting that controls GPU usage
pub const DISABLE_GPU: &str = "addArgDisableGpu";

/// Represents a single decrypted setting with its full configuration.
#[derive(Debug, Clone)]
#[allow(unused)]
pub struct SettingsFullData {
  /// The hierarchical level at which this setting applies (e.g. "user",
  /// "team", "global")
  pub level: String,
  /// The category or grouping this setting belongs to
  pub category: String,
  /// The name/identifier of the specific setting parameter
  pub param: String,
  /// The decrypted value of the setting
  pub value: String,
}

impl SettingsFullData {
  /// Creates a new `SettingsFullData` instance from an encrypted setting record
  ///
  /// # Arguments
  ///
  /// * `settings` - The encrypted setting record from the database
  /// * `database_encryption` - Service for decrypting sensitive setting data
  ///
  /// # Returns
  ///
  /// Returns `Result<Self, Error>` which is Ok if decryption succeeds
  ///
  /// # Errors
  ///
  /// Returns an error if the decryption operation fails
  pub async fn new(
    settings: Setting,
    database_encryption: DynDatabaseEncryption,
  ) -> Result<Self, Error> {
    let value = match settings.valueCrypt {
      Some(value) => database_encryption
        .decrypt_data(settings.cryptoKeyId as usize, value)
        .await
        .map_err(|err| {
          Error::DatabaseDecoding("settings value".to_string(), err.to_string())
        })?,
      None => settings.deletedValue,
    };

    Ok(SettingsFullData {
      level: settings.level,
      category: settings.category,
      param: settings.param,
      value,
    })
  }
}

/// A collection of settings that provides convenient query methods
///
/// Wraps a vector of `SettingsFullData` and provides methods to check
/// setting states across categories.
#[derive(Debug, Clone)]
pub struct SettingsList {
  inner: Vec<SettingsFullData>,
}

impl SettingsList {
  /// Creates a new `SettingsList` from a vector of settings
  ///
  /// # Arguments
  ///
  /// * `settings` - Vector of `SettingsFullData` to be managed
  pub fn new(settings: Vec<SettingsFullData>) -> Self {
    SettingsList { inner: settings }
  }

  /// Checks if any setting in the specified category is enabled
  ///
  /// A setting is considered enabled if its param value is "1"
  ///
  /// # Arguments
  ///
  /// * `category` - The category to check for enabled settings
  ///
  /// # Returns
  ///
  /// Returns `true` if any setting in the category is enabled, `false`
  /// otherwise
  ///
  /// # Examples
  ///
  /// ```
  /// use crate::server::dtos::entities::settings_dto::{SettingsList, SettingsFullData};
  ///
  /// let settings = vec![
  ///     SettingsFullData {
  ///         level: "user".to_string(),
  ///         category: "performance".to_string(),
  ///         param: "1".to_string(),  // enabled
  ///         value: "true".to_string(),
  ///     },
  ///     SettingsFullData {
  ///         level: "user".to_string(),
  ///         category: "display".to_string(),
  ///         param: "0".to_string(),  // disabled
  ///         value: "false".to_string(),
  ///     },
  /// ];
  ///
  /// let settings_list = SettingsList::new(settings);
  ///
  /// assert!(settings_list.any("performance"));  // returns true
  /// assert!(!settings_list.any("display"));     // returns false
  /// assert!(!settings_list.any("nonexistent")); // returns false
  /// ```
  pub fn any(&self, category: &str) -> bool {
    debug!(
      "checking if any setting is enabled for category: {} in settings: {:?}",
      category, self.inner
    );

    self
      .inner
      .iter()
      .any(|setting| setting.category == category && setting.param == "1")
  }
}