rocketmq_auth/authentication/model/
user.rs1use std::sync::OnceLock;
15
16use cheetah_string::CheetahString;
17use serde::Deserialize;
18use serde::Serialize;
19
20use crate::authentication::enums::subject_type::SubjectType;
21use crate::authentication::enums::user_status::UserStatus;
22use crate::authentication::enums::user_type::UserType;
23use crate::authentication::model::subject::Subject;
24
25#[derive(Debug, Clone, Serialize, Deserialize)]
26pub struct User {
27 username: CheetahString,
28 password: Option<CheetahString>,
29 #[serde(rename = "userType")]
30 user_type: Option<UserType>,
31 #[serde(rename = "userStatus")]
32 user_status: Option<UserStatus>,
33 #[serde(skip)]
34 subject_key_cache: OnceLock<String>,
35}
36
37impl User {
38 pub fn of(username: impl Into<CheetahString>) -> Self {
39 User {
40 username: username.into(),
41 password: None,
42 user_type: None,
43 user_status: None,
44 subject_key_cache: OnceLock::new(),
45 }
46 }
47
48 pub fn of_with_password(username: impl Into<CheetahString>, password: impl Into<CheetahString>) -> Self {
49 User {
50 username: username.into(),
51 password: Some(password.into()),
52 user_type: None,
53 user_status: None,
54 subject_key_cache: OnceLock::new(),
55 }
56 }
57
58 pub fn of_with_type(
59 username: impl Into<CheetahString>,
60 password: impl Into<CheetahString>,
61 user_type: UserType,
62 ) -> Self {
63 User {
64 username: username.into(),
65 password: Some(password.into()),
66 user_type: Some(user_type),
67 user_status: None,
68 subject_key_cache: OnceLock::new(),
69 }
70 }
71}
72
73impl User {
74 pub fn username(&self) -> &CheetahString {
75 &self.username
76 }
77
78 pub fn password(&self) -> Option<&CheetahString> {
79 self.password.as_ref()
80 }
81
82 pub fn user_type(&self) -> Option<UserType> {
83 self.user_type
84 }
85
86 pub fn user_status(&self) -> Option<UserStatus> {
87 self.user_status
88 }
89
90 pub fn set_user_status(&mut self, status: UserStatus) {
91 self.user_status = Some(status);
92 }
93
94 pub fn set_password(&mut self, password: impl Into<CheetahString>) {
95 self.password = Some(password.into());
96 }
97
98 pub fn set_user_type(&mut self, user_type: UserType) {
99 self.user_type = Some(user_type);
100 }
101
102 pub fn username_from_subject_key(subject_key: &str) -> &str {
103 subject_key
104 .split_once(':')
105 .map(|(_, username)| username)
106 .unwrap_or(subject_key)
107 }
108}
109
110impl Subject for User {
111 fn subject_key(&self) -> &str {
112 self.subject_key_cache
113 .get_or_init(|| format!("{}:{}", SubjectType::User.name(), self.username))
114 .as_str()
115 }
116
117 fn subject_type(&self) -> SubjectType {
118 SubjectType::User
119 }
120}
121
122#[cfg(test)]
123mod tests {
124 use super::*;
125
126 #[test]
127 fn test_user_of() {
128 let username = "test_user";
129 let user = User::of(username);
130 assert_eq!(user.username(), &CheetahString::from(username));
131 assert!(user.password().is_none());
132 assert!(user.user_type().is_none());
133 assert!(user.user_status().is_none());
134 }
135
136 #[test]
137 fn test_user_of_with_password() {
138 let username = "test_user";
139 let password = "test_password";
140 let user = User::of_with_password(username, password);
141 assert_eq!(user.username(), &CheetahString::from(username));
142 assert_eq!(user.password(), Some(&CheetahString::from(password)));
143 assert!(user.user_type().is_none());
144 assert!(user.user_status().is_none());
145 }
146
147 #[test]
148 fn test_user_of_with_type() {
149 let username = "test_user";
150 let password = "test_password";
151 let user_type = UserType::Normal;
152 let user = User::of_with_type(username, password, user_type);
153 assert_eq!(user.username(), &CheetahString::from(username));
154 assert_eq!(user.password(), Some(&CheetahString::from(password)));
155 assert_eq!(user.user_type(), Some(user_type));
156 assert!(user.user_status().is_none());
157 }
158
159 #[test]
160 fn test_user_set_user_status() {
161 let mut user = User::of("test_user");
162 user.set_user_status(UserStatus::Enable);
163 assert_eq!(user.user_status(), Some(UserStatus::Enable));
164 }
165
166 #[test]
167 fn test_user_subject_trait() {
168 let username = "test_user";
169 let user = User::of(username);
170 assert_eq!(user.subject_key(), "User:test_user");
171 assert_eq!(user.subject_type(), SubjectType::User);
172 }
173}