Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[JENKINS-22834] Render classpaths with ajax.
  • Loading branch information
ikedam committed Aug 2, 2014
1 parent 780459f commit 662cab3
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 35 deletions.
Expand Up @@ -767,36 +767,48 @@ public List<PendingClasspath> getPendingClasspaths() {
return new ArrayList<PendingClasspath>(getPendingClasspathMap().values());
}

@Restricted(NoExternalUse.class) // for use from Ajax
@JavaScriptMethod
public Object getClasspathRenderInfo() {
return new Object[]{
getPendingClasspaths(),
getApprovedClasspaths(),
};
}

@Restricted(NoExternalUse.class) // for use from AJAX
@JavaScriptMethod public List<ApprovedClasspath> approveClasspath(String hash, String classpath) throws IOException {
@JavaScriptMethod
public Object approveClasspath(String hash, String classpath) throws IOException {
Jenkins.getInstance().checkPermission(Jenkins.RUN_SCRIPTS);
PendingClasspath cp = getPendingClasspath(hash);
if (cp != null && cp.getPath().equals(classpath)) {
removePendingClasspath(hash);
addApprovedClasspath(new ApprovedClasspath(cp.getHash(), cp.getPath()));
save();
}
return getApprovedClasspaths();
return getClasspathRenderInfo();
}

@Restricted(NoExternalUse.class) // for use from AJAX
@JavaScriptMethod public List<ApprovedClasspath> denyClasspath(String hash, String classpath) throws IOException {
@JavaScriptMethod
public Object denyClasspath(String hash, String classpath) throws IOException {
Jenkins.getInstance().checkPermission(Jenkins.RUN_SCRIPTS);
PendingClasspath cp = getPendingClasspath(hash);
if (cp != null && cp.getPath().equals(classpath)) {
removePendingClasspath(hash);
save();
}
return getApprovedClasspaths();
return getClasspathRenderInfo();
}

// TODO nicer would be to allow the user to actually edit the list directly (with syntax checks)
@Restricted(NoExternalUse.class) // for use from AJAX
@JavaScriptMethod public synchronized List<ApprovedClasspath> clearApprovedClasspaths() throws IOException {
@JavaScriptMethod
public synchronized Object clearApprovedClasspaths() throws IOException {
Jenkins.getInstance().checkPermission(Jenkins.RUN_SCRIPTS);
removeAllApprovedClasspath();
save();
return getApprovedClasspaths();
return getClasspathRenderInfo();
}

}
Expand Up @@ -69,29 +69,68 @@ THE SOFTWARE.
updateApprovedSignatures(r);
});
}
function hideClasspath(hash) {
$('pcp-' + hash).style.display = 'none';
}
function updateApprovedClasspaths(r) {
$('approvedClasspaths').value = r.responseObject().map(function(e){return e.hash + "(" + e.path + ")";}).join('\n');

function renderClasspaths(r) {
var pendingClasspaths = r.responseObject()[0];
var approvedClasspaths = r.responseObject()[1];
if (pendingClasspaths.length == 0) {
$('pendingClasspaths-none').show();
$('pendingClasspaths').childElements().each(function(e){e.remove()});
$('pendingClasspaths').hide();
} else {
$('pendingClasspaths-none').hide();
$('pendingClasspaths').childElements().each(function(e){e.remove()});
/*
Create a list like:
<p id="pcp-${pcp.hash}">
<button onclick="approveClasspath('${pcp.hash}', '${pcp.path}')">Approve</button> /
<button onclick="denyClasspath('${pcp.hash}', '${pcp.path}')">Deny</button>
${pcp.hash} (${pcp.path})
</p>
*/
pendingClasspaths.each(function(e) {
var block = new Element('p', { 'id': 'pcp-' + e.hash });
var approveButton = new Element('button', { 'hash': e.hash, 'path': e.path });
approveButton.insert('Approve');
approveButton.observe('click', function() {
approveClasspath(this.readAttribute('hash'), this.readAttribute('path'));
});
var denyButton = new Element('button', { 'hash': e.hash, 'path': e.path });
denyButton.insert('Deny');
denyButton.observe('click', function() {
denyClasspath(this.readAttribute('hash'), this.readAttribute('path'));
});
block.insert(approveButton);
block.insert(denyButton);
block.insert(e.hash + "(" + e.path + ")");

$('pendingClasspaths').insert(block);
});
$('pendingClasspaths').show();
}
$('approvedClasspaths').value = approvedClasspaths.map(function(e){return e.hash + "(" + e.path + ")";}).join('\n');
}
function approveClasspath(hash, path) {
mgr.approveClasspath(hash, path, function(r) {
updateApprovedClasspaths(r);
hideClasspath(hash);
renderClasspaths(r);
});
}
function denyClasspath(hash, path) {
mgr.denyClasspath(hash, path, function(r) {
updateApprovedClasspaths(r);
hideClasspath(hash);
renderClasspaths(r);
});
}
function clearApprovedClasspaths() {
mgr.clearApprovedClasspaths(function(r) {
updateApprovedClasspaths(r);
renderClasspaths(r);
});
}

Event.observe(window, "load", function(){
mgr.getClasspathRenderInfo(function(r) {
renderClasspaths(r);
});
});
</script>
<j:choose>
<j:when test="${it.pendingScripts.isEmpty()}">
Expand Down Expand Up @@ -151,27 +190,13 @@ THE SOFTWARE.
<button onclick="if (confirm('Really delete all approvals? Any existing scripts will need to be rerun and signatures reapproved.')) {clearApprovedSignatures()}">Clear Approvals</button>
</p>
<hr/>
<j:choose>
<j:when test="${it.pendingClasspaths.isEmpty()}">
<p>
No pending classpath approvals.
</p>
</j:when>
<j:otherwise>
<j:forEach var="pcp" items="${it.pendingClasspaths}">
<div id="pcp-${pcp.hash}">
<p>
<button onclick="approveClasspath('${pcp.hash}', '${pcp.path}')">Approve</button> /
<button onclick="denyClasspath('${pcp.hash}', '${pcp.path}')">Deny</button>
${pcp.hash} (${pcp.path})
</p>
</div>
</j:forEach>
</j:otherwise>
</j:choose>
<p id="pendingClasspaths-none">
No pending classpath approvals.
</p>
<div id="pendingClasspaths">
</div>
<p>Classpaths already approved:</p>
<textarea readonly="readonly" id="approvedClasspaths" rows="10" cols="80">
<j:forEach var="acp" items="${it.approvedClasspaths}">${acp.hash} (${acp.path})<st:out value="&#10;"/></j:forEach>
</textarea>
<p>
You can also remove all previous classpaths approvals:
Expand Down

0 comments on commit 662cab3

Please sign in to comment.