haste_server/auth_n/oidc/
utilities.rs1use haste_fhir_model::r4::generated::{resources::ClientApplication, terminology::IssueType};
2use haste_fhir_operation_error::OperationOutcomeError;
3use haste_jwt::TenantId;
4use haste_repository::{
5 Repository,
6 admin::TenantModelAdmin,
7 types::user::{CreateUser, UpdateUser},
8};
9use regex::Regex;
10
11pub fn is_valid_redirect_url(redirect_url: &str, client: &ClientApplication) -> bool {
12 let k = client.redirectUri.as_ref().and_then(|redirect_uris| {
13 redirect_uris.iter().find(|redirect_pattern| {
14 if let Some(redirect_pattern) = redirect_pattern.value.as_ref()
15 && let Ok(pattern) = Regex::new(&redirect_pattern.replace("*", "(.+)"))
16 {
17 pattern.is_match(redirect_url)
18 } else {
19 false
20 }
21 })
22 });
23
24 k.is_some() && !redirect_url.is_empty()
25}
26
27pub async fn set_user_password<Repo: Repository>(
28 repo: &Repo,
29 tenant: &TenantId,
30 user_email: &str,
31 user_id: &str,
32 password: &str,
33) -> Result<(), OperationOutcomeError> {
34 let password_strength = zxcvbn::zxcvbn(password, &[user_email]);
35
36 if u8::from(password_strength.score()) < 3 {
37 let feedback = password_strength
38 .feedback()
39 .map(|f| format!("{}", f))
40 .unwrap_or_default();
41
42 return Err(OperationOutcomeError::fatal(
43 IssueType::security(),
44 feedback,
45 ));
46 }
47
48 TenantModelAdmin::<CreateUser, _, _, _, String>::update(
49 repo,
50 tenant,
51 UpdateUser {
52 id: user_id.to_string(),
53 password: Some(password.to_string()),
54 email: None,
55 role: None,
56 method: None,
57 provider_id: None,
58 },
59 )
60 .await?;
61
62 Ok(())
63}