From a61c80c4140564b1a4daf19d9086c05a8f276c20 Mon Sep 17 00:00:00 2001 From: cel Date: Fri, 30 Nov 2018 14:57:12 -1000 Subject: Show git signatures - Add /git/signature page to verify signatures using gpg - Show link to signature pages for tag and commit objects --- lib/serve.js | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) (limited to 'lib/serve.js') diff --git a/lib/serve.js b/lib/serve.js index a28f758..fc8aa7b 100644 --- a/lib/serve.js +++ b/lib/serve.js @@ -1870,6 +1870,7 @@ Serve.prototype.git = function (url) { case 'blob': return this.gitBlob(m[2]) case 'raw': return this.gitRaw(m[2]) case 'diff': return this.gitDiff(m[2]) + case 'signature': return this.gitSignature(m[2]) case 'line-comment': return this.gitLineComment(m[2]) default: return this.respond(404, 'Not found') } @@ -1985,6 +1986,67 @@ Serve.prototype.gitObject = function (rev) { }) } +Serve.prototype.gitSignature = function (id) { + var self = this + if (!/[0-9a-f]{24}/.test(id)) { + return pull( + ph('div.error', 'not a git object id'), + self.wrapPage('git'), + self.respondSink(400) + ) + } + if (!u.isRef(self.query.msg)) return pull( + ph('div.error', 'missing message id'), + self.wrapPage('git signature for ' + id), + self.respondSink(400) + ) + + self.app.git.openObject({ + obj: id, + msg: self.query.msg, + type: self.query.type, + }, function (err, obj) { + if (err) return handleError(err) + var msgDate = new Date(obj.msg.value.timestamp) + self.app.verifyGitObjectSignature(obj, function (err, verification) { + if (err) return handleError(err) + var objPath = '/git/object/' + id + '?msg=' + encodeURIComponent(obj.msg.key) + pull( + ph('section', [ + ph('h3', [ + ph('a', {href: self.app.render.toUrl(objPath)}, id), ': ', + ph('a', {href: ''}, 'signature') + ]), + ph('div', [ + self.phIdLink(obj.msg.value.author), ' pushed ', + ph('a', { + href: self.app.render.toUrl(obj.msg.key), + title: msgDate.toLocaleString(), + }, htime(msgDate)) + ]), + ph('pre', u.escapeHTML(verification.output)) + /* + verification.goodsig ? 'good' : 'bad', + ph('pre', u.escapeHTML(verification.status)) + */ + ]), + self.wrapPage('git signature for ' + id), + self.respondSink(200) + ) + }) + }) + + function handleError(err) { + if (err && err.name === 'BlobNotFoundError') + return self.askWantBlobs(err.links) + if (err) return pull( + pull.once(u.renderError(err).outerHTML), + self.wrapPage('git signature for ' + id), + self.respondSink(400) + ) + } +} + Serve.prototype.gitCommit = function (rev) { var self = this if (!/[0-9a-f]{24}/.test(rev)) { @@ -2073,6 +2135,12 @@ Serve.prototype.gitCommit = function (rev) { pull.once(commit.tree), self.gitObjectLinks(obj.msg.key, 'tree') )]) : '', + commit.gpgsig ? ph('div', [ + ph('a', {href: self.app.render.toUrl( + '/git/signature/' + rev + '?msg=' + encodeURIComponent(self.query.msg) + )}, 'signature'), + commit.signatureVersion ? [' from ', ph('code', u.escapeHTML(commit.signatureVersion))] : '' + ]) : '', h('blockquote', self.app.render.gitCommitBody(commit.body)).outerHTML, ph('h4', 'files'), @@ -2203,6 +2271,12 @@ Serve.prototype.gitTag = function (rev) { self.gitObjectLinks(obj.msg.key, tag.type) ), ' ', ph('code', u.escapeHTML(tag.tag)), + tag.gpgsig ? ph('div', [ + ph('a', {href: self.app.render.toUrl( + '/git/signature/' + rev + '?msg=' + encodeURIComponent(self.query.msg) + )}, 'signature'), + tag.signatureVersion ? [' from ', ph('code', u.escapeHTML(tag.signatureVersion))] : '' + ]) : '', h('pre', self.app.render.linkify(tag.body)).outerHTML, ] ]), -- cgit v1.2.3