From b0b910e4d541dfd218d916e1d03708f74e306150 Mon Sep 17 00:00:00 2001
From: Alexander Olofsson <alexander.olofsson@liu.se>
Date: Mon, 7 Oct 2024 15:28:18 +0200
Subject: [PATCH] Fix a series of invalid access bugs

---
 app/models/passwordstate_server.rb            |  9 ++--
 .../_host_password_choice.html.erb            | 12 +++--
 .../_host_server_selection.html.erb           | 44 +++++++------------
 .../_passwords_tab_pane_content.html.erb      |  2 +-
 4 files changed, 29 insertions(+), 38 deletions(-)

diff --git a/app/models/passwordstate_server.rb b/app/models/passwordstate_server.rb
index 1f45458..a13ad30 100644
--- a/app/models/passwordstate_server.rb
+++ b/app/models/passwordstate_server.rb
@@ -83,12 +83,11 @@ class PasswordstateServer < ApplicationRecord
       # Only handle a single password list if using API keys
       client.password_lists.tap do |list|
         list.instance_eval <<-CODE, __FILE__, __LINE__ + 1
-        # def lazy_load
-        #   load [get('username', { _force: true })]
-        # end
-
         def lazy_load
-          load [get(#{user}, { _force: true })]
+          load [get(#{user}, _force: true)]
+        rescue StandardError => ex
+          client.logger.error "Failed to load entries for password list - \#{ex.class}: \#{ex}"
+          load []
         end
         CODE
       end.map(&:attributes)
diff --git a/app/views/foreman_passwordstate/_host_password_choice.html.erb b/app/views/foreman_passwordstate/_host_password_choice.html.erb
index a9b3b5a..cf4dc41 100644
--- a/app/views/foreman_passwordstate/_host_password_choice.html.erb
+++ b/app/views/foreman_passwordstate/_host_password_choice.html.erb
@@ -2,13 +2,15 @@
   item = %w[hosts discovered_hosts].include?(controller_name) ? @host : @hostgroup
   facet = item&.passwordstate_facet
 
-  if !(item&.persisted?)
+  inherited = false
+  if !item&.persisted?
     hostgroup = @hostgroup || @host&.hostgroup
     inherited = facet.nil?
     inherited ||= true if hostgroup&.inherited_facet_attributes(Facets.registered_facets[:passwordstate_facet])&.any?
 
     facet ||= item&.build_passwordstate_facet(hostgroup.inherited_facet_attributes(Facets.registered_facets[:passwordstate_facet])) if inherited && hostgroup
   end
+  inherited ||= true if facet.nil?
 -%>
 
 <%= fields_for item  do |f| %>
@@ -23,17 +25,19 @@
         lists = server.password_lists&.map do |list|
           [ list.password_list_id, "#{list.password_list} - #{list.full_path(unix: true)}" ]
         end
-        list = facet&.passwordstate_password_list
+        list = facet&.password_list
       rescue StandardError => e
         Rails.logger.error "Failed to get Passwordstate password lists; #{e.class}: #{e}"
+        list = facet&.password_list || Openstruct.new(password_list_id: facet&.password_list_id || -1)
+        lists = [ list.password_list_id, "ERROR! #{e.class}: #{e}" ]
       end
     end
   -%>
   <div id="passwordstate_list_select" style="<%= lists.empty? && 'display:none;' || '' %>">
   <%= select_f f, :password_list_id, lists, :first, :last,
     { selected: list&.password_list_id,
-      # disable_button: _(HostsAndHostgroupsHelper::INHERIT_TEXT),
-      # disable_button_enabled: inherited
+      disable_button: _(HostsAndHostgroupsHelper::INHERIT_TEXT),
+      disable_button_enabled: inherited
     },
     { disabled: lists.empty?,
       help_inline: :indicator,
diff --git a/app/views/foreman_passwordstate/_host_server_selection.html.erb b/app/views/foreman_passwordstate/_host_server_selection.html.erb
index e8fc924..a7fe095 100644
--- a/app/views/foreman_passwordstate/_host_server_selection.html.erb
+++ b/app/views/foreman_passwordstate/_host_server_selection.html.erb
@@ -1,13 +1,21 @@
 <%-
   item = %w[hosts discovered_hosts].include?(controller_name) ? @host : @hostgroup
-  facet = item.try(:passwordstate_facet)
+  facet = item&.passwordstate_facet
 
-  if !(item.persisted? rescue false)
-    hostgroup = @hostgroup || @host.hostgroup
+  inherited = false
+  if !item&.persisted?
+    hostgroup = @hostgroup || @host&.hostgroup
     inherited = facet.nil?
     inherited ||= true if hostgroup&.inherited_facet_attributes(Facets.registered_facets[:passwordstate_facet])&.any?
 
-    facet ||= item.build_passwordstate_facet(hostgroup.inherited_facet_attributes(Facets.registered_facets[:passwordstate_facet])) if inherited && hostgroup
+    facet ||= item&.build_passwordstate_facet(hostgroup.inherited_facet_attributes(Facets.registered_facets[:passwordstate_facet])) if inherited && hostgroup
+  end
+  inherited ||= true if facet.nil?
+
+  servers = PasswordstateServer.all.map do |server|
+    name = "#{server.name} - #{server.url}"
+    name += " (not available)" unless server.test_connection
+    [ server.id, name ]
   end
 -%>
 
@@ -15,33 +23,13 @@
 
 <%= fields_for item do |f| %>
 <%= f.fields_for 'passwordstate_facet_attributes' do |f| %>
-  <%-
-    begin
-      servers = PasswordstateServer.all.map do |server|
-        name = "#{server.name} - #{server.url}"
-        name += " (not available)" unless server.test_connection
-        [ server.id, name ]
-      end
-    rescue StandardError => e
-  -%>
-<!--
-Errors occured during rendering;
-<%= e.class %>: <%= e %>
-<%= e.backtrace.join "\n" %>
--->
-  <%-
-      servers = []
-    end
-    server_id = facet.try :passwordstate_server_id rescue nil
-  -%>
   <%= select_f f, :passwordstate_server_id, servers, :first, :last,
     { include_blank: true,
-      selected: server_id,
-      # disable_button: _(HostsAndHostgroupsHelper::INHERIT_TEXT),
-      # disable_button_enabled: inherited,
+      selected: facet&.server_id,
+      disable_button: _(HostsAndHostgroupsHelper::INHERIT_TEXT),
+      disable_button_enabled: inherited,
     },
-    { disabled: servers.empty?,
-      help_inline: :indicator,
+    { help_inline: :indicator,
       label: _('Passwordstate Server'),
       label_help: _("<b>NB</b>: Selecting a Passwordstate server will replace ALL password handling<br/>Resetting this option will clear ALL passwords"),
       label_help_options: { data: { placement: 'top' } },
diff --git a/app/views/foreman_passwordstate/_passwords_tab_pane_content.html.erb b/app/views/foreman_passwordstate/_passwords_tab_pane_content.html.erb
index bd7ae71..f0fa584 100644
--- a/app/views/foreman_passwordstate/_passwords_tab_pane_content.html.erb
+++ b/app/views/foreman_passwordstate/_passwords_tab_pane_content.html.erb
@@ -20,7 +20,7 @@ groups.each do |id, passwords|
       <td colspan="2" title="<%= pw.expiry_date %>">
 <%-
 expired = Time.now > pw.expiry_date
-diff = Time.now - pw.expiry_date
+diff = (Time.now - pw.expiry_date).abs
 expiry_near = diff < 30 * 24 * 60 * 60
 
 if expiry_near
-- 
GitLab