Skip to content

Commit

Permalink
Merge pull request #226 from adlnet/authHeaderFix
Browse files Browse the repository at this point in the history
Rejection possibilities when encountering invalid Authorization credentials
  • Loading branch information
vbhayden authored Mar 14, 2018
2 parents 8216d3b + 18058c4 commit 85bc752
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 69 deletions.
36 changes: 32 additions & 4 deletions test/v1_0_2/non_templating.js
Original file line number Diff line number Diff line change
Expand Up @@ -3718,14 +3718,42 @@ console.log('nonT test3 blah blah blah blah:', attachment, typeof(attachment), '
.expect(400, done)
});

if(!global.OAUTH)
{
if (!global.OAUTH) {
//This test appears to only make sense in the case of http basic Auth. Should we have additional tests for bad OAUTH, which is more complicated?
it('An LRS rejects a Statement of bad authorization (either authentication needed or failed credentials) with error code 401 Unauthorized (7.1)', function (done) {

// This test was not allowing for different, non-standardized prioritizations of request statuses
// when rejecting Requests based on Authentication. An LRS may receive a request with bad credentials,
// but place higher priority on an improper header -- returning 400 for that header violation. This test
// has been updated to first check that bad credentials receive a 401 and then check that bad credentials
// AND invalid headers receive either 400 or 401.
//
// Identical changes were made to the 1.0.3 tests for Authentication.
//
// If authorization is bad and everything else is fine, we'll expect a 401
let badAuthHeaders = helper.addAllHeaders({}, true);

request(helper.getEndpointAndAuth())
.get(helper.getEndpointStatements())
.headers(headers)
.expect(401)
.end();

// In the case of BOTH a bad header situation AND bad auth, the LRS can return either 401 or 400
badAuthHeaders["X-Experience-API-Version"] = "BAD";

request(helper.getEndpointAndAuth())
.get(helper.getEndpointStatements())
.headers(helper.addAllHeaders({}, true))
.expect(401, done);
.headers(headers)
.end(function (err, res) {

if (res.statusCode === 400 || res.statusCode === 401) {
done();
} else {
done("Response should have been either 401 or 400.");
}

});
});
}

Expand Down
169 changes: 104 additions & 65 deletions test/v1_0_3/H.Communication4.0-Authentication.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,71 +13,110 @@
* An LRS rejects a Statement of bad authorization (either authentication needed or failed credentials) with error code 401 Unauthorized
*/
describe('An LRS rejects a Statement of bad authorization, either authentication needed or failed credentials, with error code 401 Unauthorized (Authentication, Communication 4.0, XAPI-00334)', function()
{
it("fails when given a random name pass pair", function(done)
{
if (global.OAUTH)
{
done();
}
else
{
var templates = [
{
statement: '{{statements.default}}'
}];
var data = helper.createFromTemplate(templates);
data = data.statement;
data.id = helper.generateUUID();
var headers = helper.addAllHeaders(
{});

//warning: this ".\\" is super important. Node caches the modules, and the superrequest module has been modified to work correctly
//with oauth already. We get a new verions by appending some other characters to defeat the cache.
if (global.OAUTH)
request = require('.\\super-request');
else
headers["Authorization"] = 'Basic ' + new Buffer('RobCIsNot:AUserOnThisLRS').toString('base64');
request(helper.getEndpointAndAuth())
.put(helper.getEndpointStatements() + '?statementId=' + data.id)
.headers(headers)
.json(data)
.expect(401, done);
}
});

it('fails with a malformed header', function(done)
{
if (global.OAUTH)
{
done();
}
else
{
var templates = [
{
statement: '{{statements.default}}'
}];
var data = helper.createFromTemplate(templates);
data = data.statement;
data.id = helper.generateUUID();
var headers = helper.addAllHeaders(
{});

//warning: this ".\\" is super important. Node caches the modules, and the superrequest module has been modified to work correctly
//with oauth already. We get a new verions by appending some other characters to defeat the cache.
if (global.OAUTH)
request = require('.\\super-request');
else
headers["Authorization"] = 'Basic:' + new Buffer('RobCIsNot:AUserOnThisLRS').toString('base64'); //note bad encoding here.
request(helper.getEndpointAndAuth())
.put(helper.getEndpointStatements() + '?statementId=' + data.id)
.headers(headers)
.json(data)
.expect(401, done);
}
});
});
{
// This test was not allowing for different, non-standardized prioritizations of request statuses
// when rejecting Requests based on Authentication. An LRS may receive a request with bad credentials,
// but place higher priority on an improper header -- returning 400 for that header violation. This test
// has been updated to first check that bad credentials receive a 401 and then check that bad credentials
// AND invalid headers receive either 400 or 401.
//
// Identical changes were made to the 1.0.2 test for Authentication in v1_0_2/non_templating.js.

it("fails when given a random name pass pair", function (done) {
if (global.OAUTH) {
done();
}
else {
var templates = [
{
statement: '{{statements.default}}'
}];
var data = helper.createFromTemplate(templates);
data = data.statement;
data.id = helper.generateUUID();
var headers = helper.addAllHeaders({});

//warning: this ".\\" is super important. Node caches the modules, and the superrequest module has been modified to work correctly
//with oauth already. We get a new verions by appending some other characters to defeat the cache.
if (global.OAUTH)
request = require('.\\super-request');
else
headers["Authorization"] = 'Basic ' + new Buffer('RobCIsNot:AUserOnThisLRS').toString('base64');

// Assuming everything is fine, minus the auth credentials
request(helper.getEndpointAndAuth())
.put(helper.getEndpointStatements() + '?statementId=' + data.id)
.headers(headers)
.json(data)
.expect(401)
.end();

// In the case of BOTH a bad header situation AND bad auth, the LRS can return either 401 or 400
headers["X-Experience-API-Version"] = "BAD";

request(helper.getEndpointAndAuth())
.get(helper.getEndpointStatements())
.headers(headers)
.end(function (err, res) {

if (res.statusCode === 400 || res.statusCode === 401) {
done();
} else {
done("Response should have been either 401 or 400.");
}

});
}
});

it('fails with a malformed header', function (done) {
if (global.OAUTH) {
done();
}
else {
var templates = [
{
statement: '{{statements.default}}'
}];
var data = helper.createFromTemplate(templates);
data = data.statement;
data.id = helper.generateUUID();
var headers = helper.addAllHeaders(
{});

//warning: this ".\\" is super important. Node caches the modules, and the superrequest module has been modified to work correctly
//with oauth already. We get a new verions by appending some other characters to defeat the cache.
if (global.OAUTH)
request = require('.\\super-request');
else
headers["Authorization"] = 'Basic:' + new Buffer('RobCIsNot:AUserOnThisLRS').toString('base64'); //note bad encoding here.

request(helper.getEndpointAndAuth())
.put(helper.getEndpointStatements() + '?statementId=' + data.id)
.headers(headers)
.json(data)
.expect(401)
.end();

// Same as above
headers["X-Experience-API-Version"] = "BAD";

request(helper.getEndpointAndAuth())
.get(helper.getEndpointStatements())
.headers(headers)
.end(function (err, res) {

if (res.statusCode === 400 || res.statusCode === 401) {
done();
} else {
done("Response should have been either 401 or 400.");
}

});
}
});
});


/** XAPI-00335, Communication 2.1.3 GET Statements
* An LRS must support HTTP Basic Authentication
Expand Down

0 comments on commit 85bc752

Please sign in to comment.