use core::str;
use serde::Serialize;
use crate::{
account::Users,
command::{Command, CommandLevel},
error::Result,
permission::PermissionLevel,
redacted::Redacted,
};
#[derive(Debug, Serialize, Clone, PartialEq)]
pub struct SetUserChangePasswd {
pub account: Users,
#[serde(rename = "new")]
pub new_passwd: Redacted<String>,
#[serde(rename = "old")]
pub old_passwd: Redacted<String>,
}
impl SetUserChangePasswd {
pub fn new(
account: Users,
new_passwd: impl Into<Redacted<String>>,
old_passwd: impl Into<Redacted<String>>,
) -> Self {
Self {
account,
new_passwd: new_passwd.into(),
old_passwd: old_passwd.into(),
}
}
}
impl Command for SetUserChangePasswd {
type Response = String;
const CMD_NAME: &'static str = "set.user.change_passwd";
const LEVEL: CommandLevel = CommandLevel::Encrypted;
const MINIMAL_PERMISSIONS: PermissionLevel = PermissionLevel::Advanced;
fn params(&self) -> Result<Option<impl serde::Serialize>> {
Ok(Some(self))
}
}
#[cfg(test)]
mod tests {
use crate::account::Account;
use crate::auth_data::AuthData;
use crate::redacted::Redacted;
use super::*;
const RESPONSE_JSON: &str =
r#"{"code":0,"when":1692685512,"msg":"ok","desc":"set.user.change_passwd"}"#;
#[test]
fn request_has_correct_structure() {
let cmd = SetUserChangePasswd::new(
Users::User1,
Redacted("new_pass".to_string()),
Redacted("old_pass".to_string()),
);
assert!(cmd.is_secured());
assert!(cmd.is_encrypted());
let params = cmd.params().unwrap().unwrap();
let parsed = serde_json::to_value(params).unwrap();
assert_eq!(parsed["account"], "user1");
assert_eq!(parsed["new"], "new_pass");
assert_eq!(parsed["old"], "old_pass");
}
#[test]
fn encode_with_auth_encrypts_params() {
let cmd = SetUserChangePasswd::new(
Users::User1,
Redacted("new_pass".to_string()),
Redacted("old_pass".to_string()),
);
let auth = AuthData::new::<SetUserChangePasswd>(Account::Super, "pass", "salt").unwrap();
let encoded = cmd.encode(Some(auth)).unwrap();
let json: serde_json::Value = serde_json::from_slice(&encoded.0).unwrap();
assert_eq!(json["cmd"], "set.user.change_passwd");
assert_eq!(json["account"], "super");
assert!(json["ts"].as_u64().unwrap() > 0);
assert_eq!(json["token"].as_str().unwrap().len(), 8);
let param = json["param"].as_str().unwrap();
assert!(!param.contains("user1"), "param should be encrypted");
assert!(!param.contains("new_pass"), "param should be encrypted");
}
#[test]
fn deserialize_response_fixture() {
let response = SetUserChangePasswd::parse_response(RESPONSE_JSON.as_bytes()).unwrap();
assert!(response.code.is_success());
assert_eq!(response.desc, "set.user.change_passwd");
assert_eq!(response.when, 1692685512);
assert_eq!(response.msg, "ok");
}
}