diff --git a/lib/cartodb/signed_maps.js b/lib/cartodb/signed_maps.js index 6c4af8d3..76955a58 100644 --- a/lib/cartodb/signed_maps.js +++ b/lib/cartodb/signed_maps.js @@ -85,28 +85,59 @@ o._redisCmd = function(redisFunc, redisArgs, callback) { ); }; +o._getAuthMethod = function(auth) { + return auth.method || 'open'; +}; + //--------------- PUBLIC API ------------------------------------- -// Check if the given certificate authorizes waiver of "auth" -o.authorizedByCert = function(cert, auth) { +/// Check formal validity of a certificate +// +/// Return an Error instance if invalid, null otherwise +/// +o.checkInvalidCertificate = function(cert) { //console.log("Checking cert: "); console.dir(cert); if ( cert.version !== "0.0.1" ) { - throw new Error("Unsupported certificate version " + cert.version); + return new Error("Unsupported certificate version " + cert.version); } if ( ! cert.auth ) { - throw new Error("No certificate authorization"); +console.log("Cert is : "); console.dir(cert); + return new Error("No certificate authorization"); } - if ( ! cert.auth.method ) { - throw new Error("No certificate authorization method"); + var method = this._getAuthMethod(cert.auth); + + switch ( method ) { + case 'open': + break; + case 'token': + if ( ! _.isArray(cert.auth.valid_tokens) ) + return new Error("Invalid 'token' authentication: missing valid_tokens"); + if ( ! cert.auth.valid_tokens.length ) + return new Error("Invalid 'token' authentication: no valid_tokens"); + break; + default: + return new Error("Unsupported authentication method: " + cert.auth.method); + break; } + return null; // all valid +} + +// Check if the given certificate authorizes waiver of "auth" +o.authorizedByCert = function(cert, auth) { + + var err = this.checkInvalidCertificate(cert); + if ( err ) throw err; + + var method = this._getAuthMethod(cert.auth); + // Open authentication certificates are always authorized - if ( cert.auth.method === 'open' ) return true; + if ( method === 'open' ) return true; // Token based authentication requires valid token - if ( cert.auth.method === 'token' ) { + if ( method === 'token' ) { var found = cert.auth.valid_tokens.indexOf(auth); //if ( found !== -1 ) { //console.log("Token " + auth + " is found at position " + found + " in valid tokens " + cert.auth.valid_tokens); diff --git a/test/unit/cartodb/signed_maps.test.js b/test/unit/cartodb/signed_maps.test.js index cac35cea..8d1ed604 100644 --- a/test/unit/cartodb/signed_maps.test.js +++ b/test/unit/cartodb/signed_maps.test.js @@ -81,5 +81,29 @@ suite('signed_maps', function() { ); }); + test('can validate certificates', function(done) { + var smap = new SignedMaps(redis_pool); + assert.ok(smap); + Step( + function invalidVersion() { + var cert = { version: '-1' }; + var err = smap.checkInvalidCertificate(cert); + assert.ok(err); + assert.equal(err.message, "Unsupported certificate version -1"); + return null; + }, + function invalidTokenAuth() { + var cert = { version: '0.0.1', auth: { method:'token', valid_token:[] } }; + var err = smap.checkInvalidCertificate(cert); + assert.ok(err); + assert.equal(err.message, "Invalid 'token' authentication: missing valid_tokens"); + return null; + }, + function finish(err) { + done(err); + } + ); + }); + });