|  | 
| 12 | 12 | // See the License for the specific language governing permissions and | 
| 13 | 13 | // limitations under the License. | 
| 14 | 14 | 
 | 
|  | 15 | +use std::collections::HashMap; | 
|  | 16 | + | 
| 15 | 17 | use crate::commons::QueueType; | 
| 16 | 18 | use crate::responses::{ClusterDefinitionSet, Policy, PolicyDefinitionOps}; | 
| 17 | 19 | 
 | 
|  | 20 | +use crate::password_hashing; | 
|  | 21 | + | 
| 18 | 22 | pub trait DefinitionSetTransformer { | 
| 19 | 23 |     fn transform<'a>(&'a self, defs: &'a mut ClusterDefinitionSet) -> &'a mut ClusterDefinitionSet; | 
| 20 | 24 | } | 
| @@ -66,6 +70,44 @@ impl DefinitionSetTransformer for DropEmptyPolicies { | 
| 66 | 70 |     } | 
| 67 | 71 | } | 
| 68 | 72 | 
 | 
|  | 73 | +#[derive(Default, Debug)] | 
|  | 74 | +pub struct ObfuscateUsernames {} | 
|  | 75 | + | 
|  | 76 | +impl DefinitionSetTransformer for ObfuscateUsernames { | 
|  | 77 | +    fn transform<'a>(&'a self, defs: &'a mut ClusterDefinitionSet) -> &'a mut ClusterDefinitionSet { | 
|  | 78 | +        // keeps track of name changes | 
|  | 79 | +        let mut obfuscated = HashMap::<String, String>::new(); | 
|  | 80 | +        let mut i = 1u16; | 
|  | 81 | +        for u in &defs.users { | 
|  | 82 | +            let new_name = format!("obfuscated-user-{}", i); | 
|  | 83 | +            i += 1; | 
|  | 84 | +            obfuscated.insert(u.name.clone(), new_name.clone()); | 
|  | 85 | +        } | 
|  | 86 | +        let obfuscated2 = obfuscated.clone(); | 
|  | 87 | + | 
|  | 88 | +        let updated_users = defs.users.clone().into_iter().map(|u| { | 
|  | 89 | +            let new_name = obfuscated.get(&u.name).unwrap_or(&u.name).as_str(); | 
|  | 90 | +            let salt = password_hashing::salt(); | 
|  | 91 | +            let new_password = format!("password-{}", i); | 
|  | 92 | +            let hash = | 
|  | 93 | +                password_hashing::base64_encoded_salted_password_hash_sha256(&salt, &new_password); | 
|  | 94 | + | 
|  | 95 | +            u.with_name(new_name.to_owned()).with_password_hash(hash) | 
|  | 96 | +        }); | 
|  | 97 | + | 
|  | 98 | +        let updated_permissions = defs.permissions.clone().into_iter().map(|p| { | 
|  | 99 | +            let new_new = obfuscated2.get(&p.user).unwrap_or(&p.user).as_str(); | 
|  | 100 | + | 
|  | 101 | +            p.with_username(new_new) | 
|  | 102 | +        }); | 
|  | 103 | + | 
|  | 104 | +        defs.users = updated_users.collect::<Vec<_>>(); | 
|  | 105 | +        defs.permissions = updated_permissions.collect::<Vec<_>>(); | 
|  | 106 | + | 
|  | 107 | +        defs | 
|  | 108 | +    } | 
|  | 109 | +} | 
|  | 110 | + | 
| 69 | 111 | #[derive(Default, Debug)] | 
| 70 | 112 | pub struct ExcludeUsers {} | 
| 71 | 113 | 
 | 
| @@ -126,6 +168,9 @@ impl From<Vec<&str>> for TransformationChain { | 
| 126 | 168 |                 "drop_empty_policies" => { | 
| 127 | 169 |                     vec.push(Box::new(DropEmptyPolicies::default())); | 
| 128 | 170 |                 } | 
|  | 171 | +                "obfuscate_usernames" => { | 
|  | 172 | +                    vec.push(Box::new(ObfuscateUsernames::default())); | 
|  | 173 | +                } | 
| 129 | 174 |                 "exclude_users" => { | 
| 130 | 175 |                     vec.push(Box::new(ExcludeUsers::default())); | 
| 131 | 176 |                 } | 
|  | 
0 commit comments