kanidmd_core/https/views/
profile.rs

1use crate::https::errors::WebError;
2use crate::https::extractors::{DomainInfo, VerifiedClientInformation};
3use crate::https::middleware::KOpId;
4use crate::https::ServerState;
5use askama::Template;
6use axum::extract::State;
7use axum::response::Response;
8use axum::Extension;
9use axum_extra::extract::cookie::CookieJar;
10use kanidm_proto::internal::UserAuthToken;
11
12use super::constants::{ProfileMenuItems, UiMessage, Urls};
13use super::errors::HtmxError;
14use super::login::{LoginDisplayCtx, Reauth, ReauthPurpose};
15use super::navbar::NavbarCtx;
16
17#[derive(Template)]
18#[template(path = "user_settings.html")]
19pub(crate) struct ProfileView {
20    navbar_ctx: NavbarCtx,
21    profile_partial: ProfilePartialView,
22}
23
24#[derive(Template, Clone)]
25#[template(path = "user_settings_profile_partial.html")]
26struct ProfilePartialView {
27    menu_active_item: ProfileMenuItems,
28    can_rw: bool,
29    account_name: String,
30    display_name: String,
31    email: Option<String>,
32}
33
34pub(crate) async fn view_profile_get(
35    State(state): State<ServerState>,
36    Extension(kopid): Extension<KOpId>,
37    VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
38    DomainInfo(domain_info): DomainInfo,
39) -> Result<ProfileView, WebError> {
40    let uat: UserAuthToken = state
41        .qe_r_ref
42        .handle_whoami_uat(client_auth_info, kopid.eventid)
43        .await?;
44
45    let time = time::OffsetDateTime::now_utc() + time::Duration::new(60, 0);
46
47    let can_rw = uat.purpose_readwrite_active(time);
48
49    Ok(ProfileView {
50        navbar_ctx: NavbarCtx { domain_info },
51
52        profile_partial: ProfilePartialView {
53            menu_active_item: ProfileMenuItems::UserProfile,
54            can_rw,
55            account_name: uat.name().to_string(),
56            display_name: uat.displayname.clone(),
57            email: uat.mail_primary.clone(),
58        },
59    })
60}
61
62pub(crate) async fn view_profile_unlock_get(
63    State(state): State<ServerState>,
64    VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
65    DomainInfo(domain_info): DomainInfo,
66    Extension(kopid): Extension<KOpId>,
67    jar: CookieJar,
68) -> Result<Response, HtmxError> {
69    let uat: UserAuthToken = state
70        .qe_r_ref
71        .handle_whoami_uat(client_auth_info.clone(), kopid.eventid)
72        .await
73        .map_err(|op_err| HtmxError::new(&kopid, op_err, domain_info.clone()))?;
74
75    let display_ctx = LoginDisplayCtx {
76        domain_info,
77        oauth2: None,
78        reauth: Some(Reauth {
79            username: uat.spn,
80            purpose: ReauthPurpose::ProfileSettings,
81        }),
82        error: None,
83    };
84
85    Ok(super::login::view_reauth_get(
86        state,
87        client_auth_info,
88        kopid,
89        jar,
90        Urls::Profile.as_ref(),
91        display_ctx,
92    )
93    .await)
94}