chimes_rust/utils/
auth.rs1use std::pin::Pin;
2
3use crate::entity::ChimesUserDetailInfo;
4use crate::query::{QueryUserRole, QueryUserRoleParams};
5use actix_web::{HttpRequest, Result};
6use futures::Future;
7use serde::Deserialize;
8
9use crate::entity::ChimesUserInfo;
10use crate::query::{QueryUserPermission, QueryUserPermissionParams};
11use actix_utils::future::{err, ok};
12use actix_web::dev::Payload;
13use actix_web::{FromRequest, HttpMessage};
14use chimes_auth::{ChimesAuthService, ChimesAuthUser};
15use chimes_utils::get_rbatis;
16
17use super::UserClaims;
18
19#[derive(Clone, Default, Deserialize)]
20pub struct SystemUser<ChimesUserInfo> {
21 pub user: ChimesUserInfo,
22 pub roles: Vec<String>,
23 pub open_id: Option<String>,
24 pub union_id: Option<String>,
25}
26
27impl SystemUser<ChimesUserInfo> {
28 #[allow(dead_code)]
29 pub fn has_role(&self, role: &String) -> bool {
30 self.roles.contains(role)
31 }
32}
33
34impl ChimesAuthUser<SystemUser<ChimesUserInfo>> for SystemUser<ChimesUserInfo> {
35 #[allow(dead_code)]
36 fn get_user_name(&self) -> String {
37 self.user.username.clone().unwrap_or_default()
38 }
39
40 #[allow(dead_code)]
41 fn get_creditial(&self) -> String {
42 self.user.phone.clone().unwrap_or_default()
43 }
44
45 #[allow(dead_code)]
46 fn to_detail(self) -> Self {
47 self
48 }
49}
50
51impl FromRequest for SystemUser<ChimesUserInfo> {
52 type Error = actix_web::Error;
53 type Future = actix_utils::future::Ready<Result<Self, Self::Error>>;
54
55 fn from_request(req: &HttpRequest, _payload: &mut Payload) -> Self::Future {
56 let header = req.headers();
57
58 match req.extensions().get::<SystemUser<ChimesUserInfo>>() {
59 Some(user) => {
60 let mut us = user.clone();
61 if header.contains_key("AttachedOpenId") {
62 us.open_id = header
63 .get("AttachedOpenId")
64 .map(|f| f.to_str().ok().map(|g| g.to_string()).unwrap_or_default());
65 us.union_id = header
66 .get("AttachedUnionId")
67 .map(|f| f.to_str().ok().map(|g| g.to_string()).unwrap_or_default());
68 }
69 ok(us)
70 }
71 None => {
72 log::info!("Not found the SystemUser");
73 err(actix_web::error::ErrorBadRequest("ups..."))
74 }
75 }
76 }
77}
78
79#[derive(Clone)]
80pub struct ChimesUserAuthService<SystemUser> {
81 #[allow(unused)]
82 pub system_user: Option<SystemUser>,
83}
84
85impl ChimesAuthService<SystemUser<ChimesUserInfo>>
86 for ChimesUserAuthService<SystemUser<ChimesUserInfo>>
87{
88 type Future = Pin<Box<dyn Future<Output = Option<SystemUser<ChimesUserInfo>>>>>;
89
90 fn permit(
91 &self,
92 ust: &Option<SystemUser<ChimesUserInfo>>,
93 req_method: &String,
94 url_pattern: &String,
95 ) -> Self::Future {
96 let up = url_pattern.clone();
97 let mth = req_method.clone();
98 let mtusr = ust.clone();
99 let username = match ust {
100 Some(st) => st.get_user_name(),
101 None => "ANNOYMOUS".to_string(),
102 };
103
104 Box::pin(async move {
105 let param = QueryUserPermissionParams {
106 api_method: mth.clone(),
107 api_pattern: up.clone(),
108 username: username.clone(),
109 };
110
111 let rb = get_rbatis();
112 match QueryUserPermission::query(rb, ¶m).await {
113 Ok(rs) => {
114 if !rs.is_empty() {
115 let rp = rs[0].clone();
116 if rp.api_bypass == Some("ANONYMOUS".to_string())
117 || rp.api_bypass == Some("anonymous".to_string())
118 {
119 Some(SystemUser::default())
121 } else if rp.api_bypass == Some("USER".to_string())
122 || rp.api_bypass == Some("user".to_string())
123 {
124 if mtusr.is_none() {
125 return None;
126 } else {
127 return mtusr;
128 }
129 } else {
130 let mut find_username = None;
131 for rx in rs.clone() {
132 if rx.username.is_some() {
133 find_username = rx.username.clone();
134 break;
135 }
136 }
137 if find_username.is_none() {
138 return None;
139 } else {
140 return mtusr;
141 }
142 }
143 } else if up.is_empty() {
144 mtusr
145 } else {
146 None
147 }
148 }
149 Err(err) => {
150 log::warn!(
151 "Query the permission for user with an error: {}",
152 err.to_string()
153 );
154 None
155 }
156 }
157 })
158 }
159
160 fn authenticate(&self, token: &String) -> Self::Future {
161 let rb = get_rbatis();
162 let tk = token.clone();
163 Box::pin(async move {
164 match UserClaims::decode(&tk) {
165 Some(uc) => match ChimesUserInfo::load_username(rb, &uc.aud).await {
166 Ok(r) => match r {
167 Some(u) => {
168 let param = QueryUserRoleParams {
169 user_id: u.user_id,
170 username: u.username.clone(),
171 company_code: u.company_code.clone(),
172 role_codes: u.parse_simulate_roles(),
173 };
174
175 let roles: Vec<String> = match QueryUserRole::query(rb, ¶m).await {
176 Ok(rs) => rs
177 .into_iter()
178 .map(|f| f.role_code.unwrap_or_default())
179 .collect(),
180 Err(_) => {
181 vec![]
182 }
183 };
184 Some(SystemUser {
185 user: u,
186 roles,
187 open_id: None,
188 union_id: None,
189 })
190 }
191 None => None,
192 },
193 Err(_) => None,
194 },
195 None => None,
196 }
197 })
198 }
199
200 fn nojwt_authenticate(&self, token: &String) -> Self::Future {
201 let rb = get_rbatis();
202 let tk = token.clone();
203 Box::pin(async move {
204 match ChimesUserInfo::load_username(rb, &tk.clone()).await {
205 Ok(r) => match r {
206 Some(u) => {
207 let param = QueryUserRoleParams {
208 user_id: u.user_id,
209 username: u.username.clone(),
210 company_code: u.company_code.clone(),
211 role_codes: u.parse_simulate_roles(),
212 };
213
214 let roles = match QueryUserRole::query(rb, ¶m).await {
215 Ok(rs) => rs
216 .into_iter()
217 .map(|f| f.role_code.unwrap_or_default())
218 .collect(),
219 Err(_) => {
220 vec![]
221 }
222 };
223 Some(SystemUser {
224 user: u,
225 roles,
226 open_id: None,
227 union_id: None,
228 })
229 }
230 None => {
231 log::warn!("For NoJWT mode, to load by openid with: {}, ", tk.clone());
232 match ChimesUserDetailInfo::load_openid(rb, &tk.clone()).await {
233 Ok(cdinfo) => {
234 if cdinfo.is_none() {
235 None
236 } else {
237 let cdu = cdinfo.unwrap();
238 let mu = cdu.to_user();
239 let roles = cdu
240 .roles
241 .into_iter()
242 .map(|f| f.role_code.unwrap_or_default())
243 .collect::<Vec<String>>();
244 Some(SystemUser {
245 user: mu.clone(),
246 roles,
247 open_id: mu.open_id.clone(),
248 union_id: mu.union_id.clone(),
249 })
250 }
251 }
252 Err(_err) => None,
253 }
254 }
255 },
256 Err(_) => None,
257 }
258 })
259 }
260}