[yew-devel] [PATCH proxmox-yew-comp] fix #6787: ui: allow creating PAM users from dashboard

Shannon Sterz s.sterz at proxmox.com
Tue Oct 28 13:46:18 CET 2025


On Tue Oct 28, 2025 at 1:19 PM CET, Shan Shaji wrote:
> When tried to create a user in the PAM realm an error occurs if the user
> doesn't exist on the host. To fix the issue hid the password and confirm
> password fields. Now the user will only be added to the `.cfg` file and
> won't be trying to update the password. The error was originating from
> the invocation of `pam_chauthtok`.
>
> Since the user is not created on the system, if tried to change the
> password the same error will be shown again. Inorder to avoid that
> the "change password" button will only be enabled if the user is
> not a "pam" user.
>
> Signed-off-by: Shan Shaji <s.shaji at proxmox.com>
> ---
>  src/user_panel.rs | 63 ++++++++++++++++++++++++++++++-----------------
>  1 file changed, 41 insertions(+), 22 deletions(-)
>
> diff --git a/src/user_panel.rs b/src/user_panel.rs
> index d983928..fec9b2c 100644
> --- a/src/user_panel.rs
> +++ b/src/user_panel.rs
> @@ -165,8 +165,12 @@ impl LoadableComponent for ProxmoxUserPanel {
>
>      fn toolbar(&self, ctx: &LoadableComponentContext<Self>) -> Option<Html> {
>          let link = ctx.link();
> -
>          let disabled = self.selection.is_empty();
> +        let mut disable_change_password = disabled;
> +
> +        if let Some(user) = self.get_selected_user() {
> +            disable_change_password = user.user.userid.realm().as_str() == "pam";
> +        }
>
>          let toolbar = Toolbar::new()
>              .class("pwt-w-100")
> @@ -190,7 +194,7 @@ impl LoadableComponent for ProxmoxUserPanel {
>              .with_spacer()
>              .with_child(
>                  Button::new(tr!("Change Password"))
> -                    .disabled(disabled)
> +                    .disabled(disable_change_password)
>                      .onclick(link.change_view_callback(|_| Some(ViewState::ChangePassword))),
>              )
>              .with_child(
> @@ -257,6 +261,13 @@ fn check_confirm_password(form_ctx: FormContext) {
>  }
>
>  impl ProxmoxUserPanel {
> +    fn get_selected_user(&self) -> Option<UserWithTokens> {
> +        self.selection
> +            .selected_key()
> +            .map(|key| self.store.read().lookup_record(&key).cloned())
> +            .flatten()

could you use an `and_then` instead of the `map` above and safe on the
flatten here?

> +    }
> +
>      fn create_add_dialog(&self, ctx: &LoadableComponentContext<Self>) -> Html {
>          EditWindow::new(tr!("Add") + ": " + &tr!("User"))
>              .renderer(add_user_input_panel)
> @@ -463,8 +474,10 @@ fn password_change_input_panel(_form_ctx: &FormContext) -> Html {
>          .into()
>  }
>
> -fn add_user_input_panel(_form_ctx: &FormContext) -> Html {
> -    InputPanel::new()
> +fn add_user_input_panel(form_ctx: &FormContext) -> Html {
> +    let is_pam = form_ctx.read().get_field_text("realm") == "pam";
> +
> +    let mut panel = InputPanel::new()
>          .padding(4)
>          .with_field(
>              tr!("User name"),
> @@ -481,24 +494,30 @@ fn add_user_input_panel(_form_ctx: &FormContext) -> Html {
>                  .name("realm")
>                  .required(true)
>                  .submit(false),
> -        )
> -        .with_field(
> -            tr!("Password"),
> -            Field::new()
> -                .name("password")
> -                .required(true)
> -                .schema(&PASSWORD_SCHEMA)
> -                .input_type(InputType::Password),
> -        )
> -        // fixme: validate confirmation
> -        .with_field(
> -            tr!("Confirm password"),
> -            Field::new()
> -                .name("confirm_password")
> -                .required(true)
> -                .submit(false)
> -                .input_type(InputType::Password),
> -        )
> +        );
> +
> +    if !is_pam {
> +        panel = panel
> +            .with_field(
> +                tr!("Password"),
> +                Field::new()
> +                    .name("password")
> +                    .required(true)
> +                    .schema(&PASSWORD_SCHEMA)
> +                    .input_type(InputType::Password),
> +            )
> +            // fixme: validate confirmation
> +            .with_field(
> +                tr!("Confirm password"),
> +                Field::new()
> +                    .name("confirm_password")
> +                    .required(true)
> +                    .submit(false)
> +                    .input_type(InputType::Password),
> +            );
> +    }
> +
> +    panel
>          .with_field(
>              tr!("Expire"),
>              Field::new()





More information about the yew-devel mailing list