patch up rebase

This commit is contained in:
ToxicMushroom 2025-02-13 23:46:35 +01:00
parent 4e4fd8dfa7
commit 91307dc62e
No known key found for this signature in database
GPG key ID: 4F381DAA6E8379CB
4 changed files with 74 additions and 44 deletions

14
Cargo.lock generated
View file

@ -391,6 +391,7 @@ dependencies = [
"multer",
"pin-project-lite",
"serde",
"serde_html_form",
"tower 0.5.2",
"tower-layer",
"tower-service",
@ -5064,6 +5065,19 @@ dependencies = [
"syn 2.0.98",
]
[[package]]
name = "serde_html_form"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d2de91cf02bbc07cde38891769ccd5d4f073d22a40683aa4bc7a95781aaa2c4"
dependencies = [
"form_urlencoded",
"indexmap 2.7.1",
"itoa",
"ryu",
"serde",
]
[[package]]
name = "serde_json"
version = "1.0.138"

View file

@ -9,17 +9,17 @@ pub(crate) enum ProfileMenuItems {
UnixPassword,
}
pub(crate) enum UiMessage {
UnlockEdit,
}
impl std::fmt::Display for UiMessage {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
UiMessage::UnlockEdit => write!(f, "Unlock Edit 🔒"),
}
}
}
// pub(crate) enum UiMessage {
// UnlockEdit,
// }
//
// impl std::fmt::Display for UiMessage {
// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// match self {
// UiMessage::UnlockEdit => write!(f, "Unlock Edit 🔒"),
// }
// }
// }
pub(crate) enum Urls {
Apps,

View file

@ -1,20 +1,34 @@
use super::constants::{ProfileMenuItems, Urls};
use super::errors::HtmxError;
use super::login::{LoginDisplayCtx, Reauth, ReauthPurpose};
use super::navbar::NavbarCtx;
use crate::https::errors::WebError;
use crate::https::extractors::{DomainInfo, VerifiedClientInformation};
use crate::https::middleware::KOpId;
use crate::https::ServerState;
use askama::Template;
use askama_axum::IntoResponse;
use axum::extract::State;
use axum::http::Uri;
use axum::response::Response;
use axum::Extension;
use axum_extra::extract::cookie::CookieJar;
use axum_htmx::{HxPushUrl, HxRequest};
use axum_extra::extract::Form;
use axum_htmx::{HxEvent, HxPushUrl, HxResponseTrigger};
use futures_util::TryFutureExt;
use kanidm_proto::attribute::Attribute;
use kanidm_proto::constants::{ATTR_DISPLAYNAME, ATTR_LEGALNAME, ATTR_MAIL};
use kanidm_proto::internal::UserAuthToken;
use super::constants::{ProfileMenuItems, UiMessage, Urls};
use super::errors::HtmxError;
use super::login::{LoginDisplayCtx, Reauth, ReauthPurpose};
use super::navbar::NavbarCtx;
use kanidm_proto::v1::Entry;
use kanidmd_lib::filter::{f_eq, f_id, Filter};
use kanidmd_lib::prelude::f_and;
use kanidmd_lib::prelude::PartialValue;
use kanidmd_lib::prelude::FC;
use serde::Deserialize;
use serde::Serialize;
use std::fmt;
use std::fmt::Display;
use std::fmt::Formatter;
#[derive(Template)]
#[template(path = "user_settings.html")]
@ -28,8 +42,7 @@ pub(crate) struct ProfileView {
struct ProfilePartialView {
menu_active_item: ProfileMenuItems,
can_rw: bool,
attrs: ProfileAttributes,
posix_enabled: bool,
attrs: ProfileAttributes
}
#[derive(Clone, Debug, Serialize, Deserialize)]
@ -45,9 +58,10 @@ pub(crate) struct ProfileAttributes {
#[derive(Template, Clone)]
#[template(path = "user_settings/profile_changes_partial.html")]
struct ProfileChangesPartialView {
menu_active_item: ProfileMenuItems,
can_rw: bool,
attrs: ProfileAttributes,
new_attrs: ProfileAttributes
new_attrs: ProfileAttributes,
}
#[derive(Template, Clone)]
@ -75,7 +89,7 @@ pub(crate) async fn view_profile_get(
) -> Result<ProfileView, WebError> {
let uat: UserAuthToken = state
.qe_r_ref
.handle_whoami_uat(client_auth_info, kopid.eventid)
.handle_whoami_uat(client_auth_info.clone(), kopid.eventid)
.await?;
let filter = filter_all!(f_and!([f_eq(
@ -85,7 +99,6 @@ pub(crate) async fn view_profile_get(
let base: Vec<Entry> = state
.qe_r_ref
.handle_internalsearch(client_auth_info.clone(), filter, None, kopid.eventid)
.map_err(|op_err| HtmxError::new(&kopid, op_err))
.await?;
let self_entry = base.first().expect("Self no longer exists");
@ -108,22 +121,23 @@ pub(crate) async fn view_profile_get(
legal_name: "hardcoded".to_string(),
emails,
primary_email,
},
},
})
}
pub(crate) async fn view_profile_diff_start_save_post(
State(state): State<ServerState>,
Extension(kopid): Extension<KOpId>,
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
DomainInfo(domain_info): DomainInfo,
// Form must be the last parameter because it consumes the request body
Form(new_attrs): Form<ProfileAttributes>,
) -> axum::response::Result<Response> {
let uat: UserAuthToken = state
.qe_r_ref
.handle_whoami_uat(client_auth_info.clone(), kopid.eventid)
.map_err(|op_err| HtmxError::new(&kopid, op_err))
.map_err(|op_err| HtmxError::new(&kopid, op_err, domain_info.clone()))
.await?;
let time = time::OffsetDateTime::now_utc() + time::Duration::new(60, 0);
@ -136,7 +150,7 @@ pub(crate) async fn view_profile_diff_start_save_post(
let base: Vec<Entry> = state
.qe_r_ref
.handle_internalsearch(client_auth_info.clone(), filter, None, kopid.eventid)
.map_err(|op_err| HtmxError::new(&kopid, op_err))
.map_err(|op_err| HtmxError::new(&kopid, op_err, domain_info))
.await?;
let self_entry = base.first().expect("Self no longer exists");
@ -145,6 +159,7 @@ pub(crate) async fn view_profile_diff_start_save_post(
let primary_email = emails.first().cloned();
let profile_view = ProfileChangesPartialView {
menu_active_item: ProfileMenuItems::UserProfile,
can_rw,
attrs: ProfileAttributes {
account_name: uat.name().to_string(),
@ -153,13 +168,12 @@ pub(crate) async fn view_profile_diff_start_save_post(
emails,
primary_email,
},
new_attrs,
posix_enabled: true,
new_attrs
};
Ok((
HxPushUrl(Uri::from_static("/ui/profile/diff")),
HtmlTemplate(profile_view),
profile_view,
)
.into_response())
}
@ -167,14 +181,15 @@ pub(crate) async fn view_profile_diff_start_save_post(
pub(crate) async fn view_profile_diff_confirm_save_post(
State(state): State<ServerState>,
Extension(kopid): Extension<KOpId>,
HxRequest(hx_request): HxRequest,
VerifiedClientInformation(client_auth_info): VerifiedClientInformation,
DomainInfo(domain_info): DomainInfo,
// Form must be the last parameter because it consumes the request body
Form(new_attrs): Form<ProfileAttributes>,
) -> axum::response::Result<Response> {
let uat: UserAuthToken = state
.qe_r_ref
.handle_whoami_uat(client_auth_info.clone(), kopid.eventid)
.map_err(|op_err| HtmxError::new(&kopid, op_err))
.map_err(|op_err| HtmxError::new(&kopid, op_err, domain_info.clone()))
.await?;
dbg!(&new_attrs);
@ -190,7 +205,7 @@ pub(crate) async fn view_profile_diff_confirm_save_post(
filter.clone(),
kopid.eventid,
)
.map_err(|op_err| HtmxError::new(&kopid, op_err))
.map_err(|op_err| HtmxError::new(&kopid, op_err, domain_info.clone()))
.await?;
state
@ -203,7 +218,7 @@ pub(crate) async fn view_profile_diff_confirm_save_post(
filter.clone(),
kopid.eventid,
)
.map_err(|op_err| HtmxError::new(&kopid, op_err))
.map_err(|op_err| HtmxError::new(&kopid, op_err, domain_info.clone()))
.await?;
state
@ -216,7 +231,7 @@ pub(crate) async fn view_profile_diff_confirm_save_post(
filter.clone(),
kopid.eventid,
)
.map_err(|op_err| HtmxError::new(&kopid, op_err))
.map_err(|op_err| HtmxError::new(&kopid, op_err, domain_info.clone()))
.await?;
// TODO: These are normally not permitted, user should be prevented from changing non modifiable fields in the UI though
@ -247,13 +262,15 @@ pub(crate) async fn view_profile_diff_confirm_save_post(
// .await?;
// TODO: Calling this here returns the old attributes
view_profile_get(
match view_profile_get(
State(state),
Extension(kopid),
HxRequest(hx_request),
VerifiedClientInformation(client_auth_info),
)
.await
DomainInfo(domain_info)
).await {
Ok(pv) => Ok(pv.into_response()),
Err(e) => Ok(e.into_response()),
}
}
// Sends the user a new email input to fill in :)
@ -266,14 +283,13 @@ pub(crate) async fn view_new_email_entry_partial(
HxResponseTrigger::after_swap([HxEvent::new("addEmailSwapped".to_string())]);
Ok((
passkey_init_trigger,
HtmlTemplate(FormModEntryModListPartial {
FormModEntryModListPartial {
can_rw: true,
r#type: "email".to_string(),
name: "emails[]".to_string(),
value: "".to_string(),
invalid_feedback: "Please enter a valid email address.".to_string(),
})
.into_response(),
},
)
.into_response())
}

View file

@ -10,21 +10,21 @@ Profile
<div class="mb-2 row">
<label for="profileUserName" class="col-12 col-md-3 col-lg-2 col-form-label">User name</label>
<div class="col-12 col-md-6 col-lg-5">
<input type="text" readonly class="form-control-plaintext" id="profileUserName" value="(( account_name ))">
<input type="text" readonly class="form-control-plaintext" id="profileUserName" value="(( attrs.account_name ))">
</div>
</div>
<div class="mb-2 row">
<label for="profileDisplayName" class="col-12 col-md-3 col-lg-2 col-form-label">Display name</label>
<div class="col-12 col-md-6 col-lg-5">
<input type="text" class="form-control-plaintext" id="profileDisplayName" value="(( display_name ))">
<input type="text" class="form-control-plaintext" id="profileDisplayName" value="(( attrs.display_name ))">
</div>
</div>
<div class="mb-2 row">
<label for="profileLegalName" class="col-12 col-md-3 col-lg-2 col-form-label">Legal name</label>
<div class="col-12 col-md-6 col-lg-5">
<input type="text" class="form-control-plaintext" id="profileLegalName" value="(( legal_name ))">
<input type="text" class="form-control-plaintext" id="profileLegalName" value="(( attrs.legal_name ))">
</div>
</div>