Let validator take signatures
This commit is contained in:
Родитель
639e1fd43c
Коммит
8da980742e
|
@ -6,6 +6,7 @@ const website = require('./website');
|
|||
const examples = require('./examples');
|
||||
const logger = require('./logger');
|
||||
const filters = require('./filters');
|
||||
const keys = require('./keys');
|
||||
|
||||
exports.build = function(options) {
|
||||
options = options || {};
|
||||
|
@ -37,6 +38,7 @@ exports.build = function(options) {
|
|||
app.get('/assertion.valid.json', host(examples.validAssertion));
|
||||
app.get('/badge.valid.json', host(examples.validBadge));
|
||||
app.get('/issuer.valid.json', host(examples.validIssuer));
|
||||
app.get('/public-key', function(req, res, next){ res.send(keys.public) });
|
||||
|
||||
return app;
|
||||
};
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
var jws = require('jws');
|
||||
var keys = require('./keys');
|
||||
|
||||
function makeUrl(host, path) {
|
||||
return 'http://' + host + path;
|
||||
}
|
||||
|
@ -26,6 +29,21 @@ exports.validAssertion = function validAssertion(host) {
|
|||
};
|
||||
};
|
||||
|
||||
exports.validSignature = function validSignature(host) {
|
||||
var assertion = exports.validAssertion(host);
|
||||
assertion.verify.type = 'signed';
|
||||
assertion.verify.url = makeUrl(host, '/public-key');
|
||||
return exports.sign(assertion);
|
||||
};
|
||||
|
||||
exports.sign = function sign(assertion) {
|
||||
return jws.sign({
|
||||
header: { alg: 'rs256' },
|
||||
privateKey: keys.private,
|
||||
payload: assertion
|
||||
});
|
||||
};
|
||||
|
||||
exports.validBadge = function validBadge(host) {
|
||||
return {
|
||||
name: 'Pizza Badge',
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
const fs = require('fs');
|
||||
module.exports = {
|
||||
'private': fs.readFileSync(__dirname + '/rsa-private.pem'),
|
||||
'public': fs.readFileSync(__dirname + '/rsa-public.pem'),
|
||||
//'wrongPublic': fs.readFileSync(__dirname + '/rsa-wrong-public.pem'),
|
||||
};
|
|
@ -3,3 +3,4 @@ exports.website = require('./website');
|
|||
exports.examples = require('./examples');
|
||||
exports.logger = require('./logger');
|
||||
exports.filters = require('./filters');
|
||||
exports.keys = require('./keys');
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAxN373P43npgsCdIs4NKpGiREvyWFIob5gVULymtQQY3ktj95
|
||||
jwzyX+Jhnjq4vC16hU48yoVccyVbgQ0ksMwiFhOMOkVTAPmQ24lWFTb+AO4/noqQ
|
||||
lK6KXPJMbRrYMOBrYjhJF+BAsXbHpaqCDGj36Dw+WXh+WMytrOgfP/dUuLiNLdUX
|
||||
903jnHadbPC5XwJSm+PEoXCiXhWL+iXqq/8XcJeE9eHitpP76Y4cR/lf7wzKpJ/f
|
||||
UXAhIk34li7ioV0yEfBbRmuL8aEExN4NJr06/EkHXYBZGzERNMxMCLO0bcFssF/7
|
||||
jE8rLCA2gsE10vOcBxeBrkwpo5MtDCWWo0Dl3QIDAQABAoIBAQCD20aRavfn0nZU
|
||||
kaAbaR138+jTuhak3JCKzmKaTiwv7BDO/E63wG0qSZ8mcqA+8ZsJZDCVWKNmQBQ8
|
||||
qIf1npQKA0e906bXlVAvqpmsleukxe54ishxvUHRJTyJKxy4B+gEnjxesIXEFxF7
|
||||
ZWu7UicRNiBwnqLJaTW+BK7Bki/9k/m767WyMf73pGbPQOlVw0lFi3iWdV5F7N8H
|
||||
Uzzz7UmgLdsqSfIvMuOaaNT5y10CC8QJgjOm2OarB0qyo9bUF9El8n6ClqW1hopS
|
||||
dqf5pDg2r2xv8TfWIX2e0u0TOux5ZcVREQSe5zEXk/9aqAoYMrJhx5OHbgPoaM5h
|
||||
eoUzzvRBAoGBAOS3bVZLEM/t728uA8N3OaMLkOXW/Xmfv2Q7JRqDJ0Sg7beuKVne
|
||||
WlawljR6eO8bixoYpbY9dHAjycSzN9Ad2+x5SyKyd0tvGmjrsdK21EcQvMFLr3Ks
|
||||
Xyn9bKU4mH8VwqBVwlxisFSvIkRGBMFCR5gzWTygHT9rqe4VAxKrsjtNAoGBANxZ
|
||||
760EHNSLqV8h6Z2HFYeCiESpFypJjEQH2DPdOQAisqonD3iMhK0v/AJP0ublCIt2
|
||||
9nZD/uDnwoIzThQkKHWRENUNfQHUzzgkioZhid369V4PiyNJ75KRP7ovrUlkgnKp
|
||||
vmHok36Tl0FJnHNB4ak6f85gwzqj/Mdk3ck7omzRAoGAJD0sBdA/CbMZjPQthHsP
|
||||
ltXuT3yRDQRSvv7gEiNVxXn6MHBX/PVOOw4fvpDpOHmUwL3HA+kY2evRvGjpHwCc
|
||||
KAvP6997J2ijNpyhwFFXsSrlvXrQgcruCSkuXb9p6jj4bY8pDJpWdhSJyWeOuVBX
|
||||
J7Z7HTABclsMwbxykDLEOsECgYB/y6VGqeDyoEFNzERKOUMSQXE4qPynaNpxxj7s
|
||||
7XuWiYknR9ogJxb3vqGg0ZzWjrSi9g7AznSvCZr0mj7JTaMtdEHX3qfGfR7lR8QT
|
||||
ZdRoqpjNwaQHhmTsk1Lrb6VHsIQ7bhjdfd61BXIuyjtzWR1AYY4oKlRv2RXMqsI6
|
||||
aFyuUQKBgQCbDOTqjwduNGSlRbHOEwrC84RKE0e3iEm0wffvEkZMOjv86ZOjnMkg
|
||||
lw1K6+pxeB2sfX+87ETNBx2MecBVuEIYZJoUGFxZcVxpgm+yRGW8GNsBC+rjBYwY
|
||||
dj8SBn4KFEOxkihKRXMG/eMZPKApoVuPG+Ma6p/7y0dPER6wXBL3Sg==
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -0,0 +1,9 @@
|
|||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxN373P43npgsCdIs4NKp
|
||||
GiREvyWFIob5gVULymtQQY3ktj95jwzyX+Jhnjq4vC16hU48yoVccyVbgQ0ksMwi
|
||||
FhOMOkVTAPmQ24lWFTb+AO4/noqQlK6KXPJMbRrYMOBrYjhJF+BAsXbHpaqCDGj3
|
||||
6Dw+WXh+WMytrOgfP/dUuLiNLdUX903jnHadbPC5XwJSm+PEoXCiXhWL+iXqq/8X
|
||||
cJeE9eHitpP76Y4cR/lf7wzKpJ/fUXAhIk34li7ioV0yEfBbRmuL8aEExN4NJr06
|
||||
/EkHXYBZGzERNMxMCLO0bcFssF/7jE8rLCA2gsE10vOcBxeBrkwpo5MtDCWWo0Dl
|
||||
3QIDAQAB
|
||||
-----END PUBLIC KEY-----
|
|
@ -36,13 +36,16 @@ exports.validate = function validate(req, res, next) {
|
|||
res.locals.assertionString = assertionString;
|
||||
|
||||
try {
|
||||
assertion = JSON.parse(assertionString);
|
||||
var assertion = JSON.parse(assertionString);
|
||||
} catch(e) {
|
||||
/* Assume signature and move on
|
||||
return respond({
|
||||
status: 'invalid',
|
||||
reason: 'Could not parse string as JSON',
|
||||
error: e.message
|
||||
});
|
||||
*/
|
||||
assertion = assertionString;
|
||||
}
|
||||
|
||||
res.locals.assertion = assertion;
|
||||
|
|
|
@ -11,7 +11,8 @@
|
|||
"bunyan": "~0.21.4",
|
||||
"nunjucks": "~0.1.9",
|
||||
"gelf-stream": "~0.2.2",
|
||||
"newrelic": "~0.9.22"
|
||||
"newrelic": "~0.9.22",
|
||||
"jws": "~0.2.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha": "~1.9.0",
|
||||
|
|
|
@ -4,10 +4,25 @@ var validator = require('openbadges-validator');
|
|||
|
||||
var utils = require('./utils');
|
||||
var examples = require('../').examples;
|
||||
var keys = require('../').keys;
|
||||
|
||||
describe('Examples', function() {
|
||||
var app = utils.buildApp();
|
||||
|
||||
describe('at /public-key', function() {
|
||||
it('should return public key', function(done) {
|
||||
request(app)
|
||||
.get('/public-key')
|
||||
.expect(200)
|
||||
.end(function(err, res){
|
||||
if (err)
|
||||
return done(err);
|
||||
res.text.should.equal(keys.public.toString());
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('at /assertion.valid.json', function() {
|
||||
var url = '/assertion.valid.json';
|
||||
|
||||
|
|
|
@ -55,6 +55,30 @@ describe('Website', function() {
|
|||
});
|
||||
});
|
||||
|
||||
describe('with good signature', function() {
|
||||
function goodString(post) {
|
||||
var host = url.parse(post.url).host;
|
||||
return examples.validSignature(host);
|
||||
}
|
||||
|
||||
it('should render index.html with info', function(done) {
|
||||
sinon.spy(app, "render");
|
||||
|
||||
var post = request(app).post('/');
|
||||
post.send({ assertion: goodString(post) })
|
||||
.expect(200, function(err, res) {
|
||||
app.render.calledOnce.should.be.true;
|
||||
app.render.firstCall.args[0].should.equal('index.html');
|
||||
app.render.firstCall.args[1].should.have.property('valid', true);
|
||||
app.render.firstCall.args[1].should.have.property('response');
|
||||
app.render.firstCall.args[1].response.should.have.property('status', 'valid');
|
||||
app.render.firstCall.args[1].response.should.have.property('info');
|
||||
app.render.restore();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('with bad assertion', function() {
|
||||
var badString = JSON.stringify(examples.validAssertion('NOPESORRY'));
|
||||
|
||||
|
|
|
@ -24,9 +24,9 @@
|
|||
<div class="large-12 columns">
|
||||
<form id="js-assertion-form" method="post" action="/">
|
||||
{% if assertion %}
|
||||
<textarea class="assertion" name="assertion" placeholder="paste your assertion here">{{ assertion|pprint }}</textarea>
|
||||
<textarea class="assertion" name="assertion" placeholder="paste your assertion or signature here">{{ assertion|pprint }}</textarea>
|
||||
{% else %}
|
||||
<textarea class="assertion" name="assertion" placeholder="paste your assertion here">{{ assertionString }}</textarea>
|
||||
<textarea class="assertion" name="assertion" placeholder="paste your assertion or signature here">{{ assertionString }}</textarea>
|
||||
{% endif %}
|
||||
<input class="button radius" type="submit" value="Check Validity">
|
||||
<img class="spinner" src="/img/loader.gif" />
|
||||
|
|
Загрузка…
Ссылка в новой задаче