This commit is contained in:
Mike Larsson 2013-07-31 09:58:09 -04:00
Родитель 639e1fd43c
Коммит 8da980742e
11 изменённых файлов: 110 добавлений и 4 удалений

Просмотреть файл

@ -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',

6
lib/keys.js Normal file
Просмотреть файл

@ -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');

27
lib/rsa-private.pem Normal file
Просмотреть файл

@ -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-----

9
lib/rsa-public.pem Normal file
Просмотреть файл

@ -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" />