mirror of
https://github.com/kanidm/kanidm.git
synced 2025-02-23 04:27:02 +01:00
patch up rebase
This commit is contained in:
parent
4e4fd8dfa7
commit
91307dc62e
14
Cargo.lock
generated
14
Cargo.lock
generated
|
@ -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"
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
Loading…
Reference in a new issue