From 07d12e30baea5d904a9ccd1052e48e92c437d3a5 Mon Sep 17 00:00:00 2001 From: Basil Crow Date: Fri, 11 Oct 2024 11:53:04 -0700 Subject: [PATCH] [JENKINS-69651] CSP compatibility for `ScriptApproval` --- ...cated-approvedClasspaths-clear-btn-hide.js | 2 + ...cated-approvedClasspaths-clear-btn-show.js | 2 + .../scripts/ScriptApproval/index.jelly | 182 +----------------- .../ScriptApproval/render-classpaths.js | 152 +++++++++++++++ 4 files changed, 160 insertions(+), 178 deletions(-) create mode 100644 src/main/resources/org/jenkinsci/plugins/scriptsecurity/scripts/ScriptApproval/deprecated-approvedClasspaths-clear-btn-hide.js create mode 100644 src/main/resources/org/jenkinsci/plugins/scriptsecurity/scripts/ScriptApproval/deprecated-approvedClasspaths-clear-btn-show.js create mode 100644 src/main/resources/org/jenkinsci/plugins/scriptsecurity/scripts/ScriptApproval/render-classpaths.js diff --git a/src/main/resources/org/jenkinsci/plugins/scriptsecurity/scripts/ScriptApproval/deprecated-approvedClasspaths-clear-btn-hide.js b/src/main/resources/org/jenkinsci/plugins/scriptsecurity/scripts/ScriptApproval/deprecated-approvedClasspaths-clear-btn-hide.js new file mode 100644 index 000000000..777b5b8f6 --- /dev/null +++ b/src/main/resources/org/jenkinsci/plugins/scriptsecurity/scripts/ScriptApproval/deprecated-approvedClasspaths-clear-btn-hide.js @@ -0,0 +1,2 @@ +document.getElementById('deprecated-approvedClasspaths-clear-btn').style.display = 'none'; +document.getElementById('deprecated-approvedClasspaths-clear-spinner').style.display = ''; diff --git a/src/main/resources/org/jenkinsci/plugins/scriptsecurity/scripts/ScriptApproval/deprecated-approvedClasspaths-clear-btn-show.js b/src/main/resources/org/jenkinsci/plugins/scriptsecurity/scripts/ScriptApproval/deprecated-approvedClasspaths-clear-btn-show.js new file mode 100644 index 000000000..d7d39bd5c --- /dev/null +++ b/src/main/resources/org/jenkinsci/plugins/scriptsecurity/scripts/ScriptApproval/deprecated-approvedClasspaths-clear-btn-show.js @@ -0,0 +1,2 @@ +document.getElementById('deprecated-approvedClasspaths-clear-btn').style.display = ''; +document.getElementById('deprecated-approvedClasspaths-clear-spinner').style.display = 'none'; diff --git a/src/main/resources/org/jenkinsci/plugins/scriptsecurity/scripts/ScriptApproval/index.jelly b/src/main/resources/org/jenkinsci/plugins/scriptsecurity/scripts/ScriptApproval/index.jelly index cb2ca82a3..70104f5e5 100644 --- a/src/main/resources/org/jenkinsci/plugins/scriptsecurity/scripts/ScriptApproval/index.jelly +++ b/src/main/resources/org/jenkinsci/plugins/scriptsecurity/scripts/ScriptApproval/index.jelly @@ -27,176 +27,8 @@ THE SOFTWARE. - + +

@@ -312,16 +144,10 @@ THE SOFTWARE.

- + - + diff --git a/src/main/resources/org/jenkinsci/plugins/scriptsecurity/scripts/ScriptApproval/render-classpaths.js b/src/main/resources/org/jenkinsci/plugins/scriptsecurity/scripts/ScriptApproval/render-classpaths.js new file mode 100644 index 000000000..5122e5367 --- /dev/null +++ b/src/main/resources/org/jenkinsci/plugins/scriptsecurity/scripts/ScriptApproval/render-classpaths.js @@ -0,0 +1,152 @@ +function hideScript(hash) { + document.getElementById('ps-' + hash).remove(); +} +function approveScript(hash) { + mgr.approveScript(hash); + hideScript(hash); +} +function denyScript(hash) { + mgr.denyScript(hash); + hideScript(hash); +} +function hideSignature(hash) { + document.getElementById('s-' + hash).style.display = 'none'; +} +function updateApprovedSignatures(r) { + var both = r.responseObject(); + document.getElementById('approvedSignatures').value = both[0].join('\n'); + document.getElementById('aclApprovedSignatures').value = both[1].join('\n'); + if (document.getElementById('dangerousApprovedSignatures')) { + document.getElementById('dangerousApprovedSignatures').value = both[2].join('\n'); + } +} +function approveSignature(signature, hash) { + mgr.approveSignature(signature, function(r) { + updateApprovedSignatures(r); + }); + hideSignature(hash); +} +function aclApproveSignature(signature, hash) { + mgr.aclApproveSignature(signature, function(r) { + updateApprovedSignatures(r); + }); + hideSignature(hash); +} +function denySignature(signature, hash) { + mgr.denySignature(signature); + hideSignature(hash); +} +function clearApprovedSignatures() { + mgr.clearApprovedSignatures(function(r) { + updateApprovedSignatures(r); + }); +} +function clearDangerousApprovedSignatures() { + mgr.clearDangerousApprovedSignatures(function(r) { + updateApprovedSignatures(r); + }); +} + +function renderPendingClasspathEntries(pendingClasspathEntries) { + if (pendingClasspathEntries.length == 0) { + document.getElementById('pendingClasspathEntries-none').style.display = ''; + Array.from(document.getElementById('pendingClasspathEntries').children).forEach(function(e){e.remove()}); + document.getElementById('pendingClasspathEntries').style.display = 'none'; + } else { + document.getElementById('pendingClasspathEntries-none').style.display = 'none'; + Array.from(document.getElementById('pendingClasspathEntries').children).forEach(function(e){e.remove()}); + pendingClasspathEntries.forEach(function(e) { + var block = document.createElement('p'); + block.setAttribute('id', 'pcp-' + e.hash); + var approveButton = document.createElement('button'); + approveButton.setAttribute('class', 'approve'); + approveButton.setAttribute('hash', e.hash); + approveButton.textContent = 'Approve'; + approveButton.addEventListener('click', function() { + approveClasspathEntry(this.getAttribute('hash')); + }); + var denyButton = document.createElement('button'); + denyButton.setAttribute('class', 'deny'); + denyButton.setAttribute('hash', e.hash); + denyButton.textContent = 'Deny'; + denyButton.addEventListener('click', function() { + denyClasspathEntry(this.getAttribute('hash')); + }); + block.appendChild(approveButton); + block.appendChild(denyButton); + var code = document.createElement('code'); + code.setAttribute('title', e.hash); + code.textContent = e.path; + block.appendChild(code); + + document.getElementById('pendingClasspathEntries').appendChild(block); + }); + document.getElementById('pendingClasspathEntries').style.display = ''; + } +} + +function renderApprovedClasspathEntries(approvedClasspathEntries) { + if (approvedClasspathEntries.length == 0) { + document.getElementById('approvedClasspathEntries-none').style.display = ''; + Array.from(document.getElementById('approvedClasspathEntries').children).forEach(function(e){e.remove()}); + document.getElementById('approvedClasspathEntries').style.display = 'none'; + document.getElementById('approvedClasspathEntries-clear').style.display = 'none'; + } else { + document.getElementById('approvedClasspathEntries-none').style.display = 'none'; + Array.from(document.getElementById('approvedClasspathEntries').children).forEach(function(e){e.remove()}); + approvedClasspathEntries.forEach(function(e) { + var block = document.createElement('p'); + block.setAttribute('id', 'acp-' + e.hash); + var deleteButton = document.createElement('button'); + deleteButton.setAttribute('class', 'delete'); + deleteButton.setAttribute('hash', e.hash); + deleteButton.textContent = 'Delete'; + deleteButton.addEventListener('click', function() { + if (confirm('Really delete this approved classpath entry? Any existing scripts using it will need to be rerun and the entry reapproved.')) { + denyApprovedClasspathEntry(this.getAttribute('hash')); + } + }); + block.appendChild(deleteButton); + var code = document.createElement('code'); + code.setAttribute('title', e.hash); + code.textContent = e.path; + block.appendChild(code); + + document.getElementById('approvedClasspathEntries').appendChild(block); + }); + document.getElementById('approvedClasspathEntries').style.display = ''; + document.getElementById('approvedClasspathEntries-clear').style.display = ''; + } +} + +function renderClasspaths(r) { + renderPendingClasspathEntries(r.responseObject()[0]); + renderApprovedClasspathEntries(r.responseObject()[1]); +} + +function approveClasspathEntry(hash) { + mgr.approveClasspathEntry(hash, function(r) { + renderClasspaths(r); + }); +} +function denyClasspathEntry(hash) { + mgr.denyClasspathEntry(hash, function(r) { + renderClasspaths(r); + }); +} +function denyApprovedClasspathEntry(hash) { + mgr.denyApprovedClasspathEntry(hash, function(r) { + renderClasspaths(r); + }); +} +function clearApprovedClasspathEntries() { + mgr.clearApprovedClasspathEntries(function(r) { + renderClasspaths(r); + }); +} + +document.addEventListener('DOMContentLoaded', function() { + mgr.getClasspathRenderInfo(function(r) { + renderClasspaths(r); + }); +});