tests: Delete unnecessary `describe()` wrapper

pull/4452/head
Richard Hansen 2020-10-29 18:48:16 -04:00
parent dbe9151d89
commit 4829bb8962
1 changed files with 247 additions and 249 deletions

View File

@ -93,265 +93,263 @@ describe(__filename, function() {
let agent; let agent;
before(async function() { agent = await common.init(); }); before(async function() { agent = await common.init(); });
describe('socket.io access checks', function() { let authorize;
let authorize; let authorizeHooksBackup;
let authorizeHooksBackup; const cleanUpPads = async () => {
const cleanUpPads = async () => { const padIds = ['pad', 'other-pad', 'päd'];
const padIds = ['pad', 'other-pad', 'päd']; await Promise.all(padIds.map(async (padId) => {
await Promise.all(padIds.map(async (padId) => { if (await padManager.doesPadExist(padId)) {
if (await padManager.doesPadExist(padId)) { const pad = await padManager.getPad(padId);
const pad = await padManager.getPad(padId); await pad.remove();
await pad.remove(); }
} }));
})); };
const settingsBackup = {};
let socket;
beforeEach(async function() {
Object.assign(settingsBackup, settings);
assert(socket == null);
settings.editOnly = false;
settings.requireAuthentication = false;
settings.requireAuthorization = false;
settings.users = {
admin: {password: 'admin-password', is_admin: true},
user: {password: 'user-password'},
}; };
const settingsBackup = {}; authorize = () => true;
let socket; authorizeHooksBackup = plugins.hooks.authorize;
plugins.hooks.authorize = [{hook_fn: (hookName, {req}, cb) => {
return cb([authorize(req)]);
}}];
await cleanUpPads();
});
afterEach(async function() {
Object.assign(settings, settingsBackup);
if (socket) socket.close();
socket = null;
plugins.hooks.authorize = authorizeHooksBackup;
await cleanUpPads();
});
describe('Normal accesses', function() {
it('!authn anonymous cookie /p/pad -> 200, ok', async function() {
const res = await agent.get('/p/pad').expect(200);
socket = await connect(res);
const clientVars = await handshake(socket, 'pad');
assert.equal(clientVars.type, 'CLIENT_VARS');
});
it('!authn !cookie -> ok', async function() {
socket = await connect(null);
const clientVars = await handshake(socket, 'pad');
assert.equal(clientVars.type, 'CLIENT_VARS');
});
it('!authn user /p/pad -> 200, ok', async function() {
const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200);
socket = await connect(res);
const clientVars = await handshake(socket, 'pad');
assert.equal(clientVars.type, 'CLIENT_VARS');
});
it('authn user /p/pad -> 200, ok', async function() {
settings.requireAuthentication = true;
const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200);
socket = await connect(res);
const clientVars = await handshake(socket, 'pad');
assert.equal(clientVars.type, 'CLIENT_VARS');
});
it('authz user /p/pad -> 200, ok', async function() {
settings.requireAuthentication = true;
settings.requireAuthorization = true;
const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200);
socket = await connect(res);
const clientVars = await handshake(socket, 'pad');
assert.equal(clientVars.type, 'CLIENT_VARS');
});
it('supports pad names with characters that must be percent-encoded', async function() {
settings.requireAuthentication = true;
// requireAuthorization is set to true here to guarantee that the user's padAuthorizations
// object is populated. Technically this isn't necessary because the user's padAuthorizations
// is currently populated even if requireAuthorization is false, but setting this to true
// ensures the test remains useful if the implementation ever changes.
settings.requireAuthorization = true;
const encodedPadId = encodeURIComponent('päd');
const res = await agent.get(`/p/${encodedPadId}`).auth('user', 'user-password').expect(200);
socket = await connect(res);
const clientVars = await handshake(socket, 'päd');
assert.equal(clientVars.type, 'CLIENT_VARS');
});
});
describe('Abnormal access attempts', function() {
it('authn anonymous /p/pad -> 401, error', async function() {
settings.requireAuthentication = true;
const res = await agent.get('/p/pad').expect(401);
// Despite the 401, try to create the pad via a socket.io connection anyway.
socket = await connect(res);
const message = await handshake(socket, 'pad');
assert.equal(message.accessStatus, 'deny');
});
it('authn !cookie -> error', async function() {
settings.requireAuthentication = true;
socket = await connect(null);
const message = await handshake(socket, 'pad');
assert.equal(message.accessStatus, 'deny');
});
it('authorization bypass attempt -> error', async function() {
// Only allowed to access /p/pad.
authorize = (req) => req.path === '/p/pad';
settings.requireAuthentication = true;
settings.requireAuthorization = true;
// First authenticate and establish a session.
const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200);
socket = await connect(res);
// Accessing /p/other-pad should fail, despite the successful fetch of /p/pad.
const message = await handshake(socket, 'other-pad');
assert.equal(message.accessStatus, 'deny');
});
});
describe('Authorization levels via authorize hook', function() {
beforeEach(async function() { beforeEach(async function() {
Object.assign(settingsBackup, settings); settings.requireAuthentication = true;
assert(socket == null); settings.requireAuthorization = true;
settings.editOnly = false; });
settings.requireAuthentication = false;
settings.requireAuthorization = false; it("level='create' -> can create", async function() {
settings.users = { authorize = () => 'create';
admin: {password: 'admin-password', is_admin: true}, const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200);
user: {password: 'user-password'}, socket = await connect(res);
}; const clientVars = await handshake(socket, 'pad');
assert.equal(clientVars.type, 'CLIENT_VARS');
assert.equal(clientVars.data.readonly, false);
});
it('level=true -> can create', async function() {
authorize = () => true; authorize = () => true;
authorizeHooksBackup = plugins.hooks.authorize; const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200);
plugins.hooks.authorize = [{hook_fn: (hookName, {req}, cb) => { socket = await connect(res);
return cb([authorize(req)]); const clientVars = await handshake(socket, 'pad');
}}]; assert.equal(clientVars.type, 'CLIENT_VARS');
await cleanUpPads(); assert.equal(clientVars.data.readonly, false);
}); });
afterEach(async function() { it("level='modify' -> can modify", async function() {
Object.assign(settings, settingsBackup); await padManager.getPad('pad'); // Create the pad.
if (socket) socket.close(); authorize = () => 'modify';
socket = null; const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200);
plugins.hooks.authorize = authorizeHooksBackup; socket = await connect(res);
await cleanUpPads(); const clientVars = await handshake(socket, 'pad');
assert.equal(clientVars.type, 'CLIENT_VARS');
assert.equal(clientVars.data.readonly, false);
});
it("level='create' settings.editOnly=true -> unable to create", async function() {
authorize = () => 'create';
settings.editOnly = true;
const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200);
socket = await connect(res);
const message = await handshake(socket, 'pad');
assert.equal(message.accessStatus, 'deny');
});
it("level='modify' settings.editOnly=false -> unable to create", async function() {
authorize = () => 'modify';
settings.editOnly = false;
const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200);
socket = await connect(res);
const message = await handshake(socket, 'pad');
assert.equal(message.accessStatus, 'deny');
});
it("level='readOnly' -> unable to create", async function() {
authorize = () => 'readOnly';
const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200);
socket = await connect(res);
const message = await handshake(socket, 'pad');
assert.equal(message.accessStatus, 'deny');
});
it("level='readOnly' -> unable to modify", async function() {
await padManager.getPad('pad'); // Create the pad.
authorize = () => 'readOnly';
const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200);
socket = await connect(res);
const clientVars = await handshake(socket, 'pad');
assert.equal(clientVars.type, 'CLIENT_VARS');
assert.equal(clientVars.data.readonly, true);
});
});
describe('Authorization levels via user settings', function() {
beforeEach(async function() {
settings.requireAuthentication = true;
}); });
describe('Normal accesses', function() { it('user.canCreate = true -> can create and modify', async function() {
it('!authn anonymous cookie /p/pad -> 200, ok', async function() { settings.users.user.canCreate = true;
const res = await agent.get('/p/pad').expect(200); const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200);
socket = await connect(res); socket = await connect(res);
const clientVars = await handshake(socket, 'pad'); const clientVars = await handshake(socket, 'pad');
assert.equal(clientVars.type, 'CLIENT_VARS'); assert.equal(clientVars.type, 'CLIENT_VARS');
}); assert.equal(clientVars.data.readonly, false);
it('!authn !cookie -> ok', async function() { });
socket = await connect(null); it('user.canCreate = false -> unable to create', async function() {
const clientVars = await handshake(socket, 'pad'); settings.users.user.canCreate = false;
assert.equal(clientVars.type, 'CLIENT_VARS'); const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200);
}); socket = await connect(res);
it('!authn user /p/pad -> 200, ok', async function() { const message = await handshake(socket, 'pad');
const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200); assert.equal(message.accessStatus, 'deny');
socket = await connect(res); });
const clientVars = await handshake(socket, 'pad'); it('user.readOnly = true -> unable to create', async function() {
assert.equal(clientVars.type, 'CLIENT_VARS'); settings.users.user.readOnly = true;
}); const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200);
it('authn user /p/pad -> 200, ok', async function() { socket = await connect(res);
settings.requireAuthentication = true; const message = await handshake(socket, 'pad');
const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200); assert.equal(message.accessStatus, 'deny');
socket = await connect(res); });
const clientVars = await handshake(socket, 'pad'); it('user.readOnly = true -> unable to modify', async function() {
assert.equal(clientVars.type, 'CLIENT_VARS'); await padManager.getPad('pad'); // Create the pad.
}); settings.users.user.readOnly = true;
it('authz user /p/pad -> 200, ok', async function() { const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200);
settings.requireAuthentication = true; socket = await connect(res);
settings.requireAuthorization = true; const clientVars = await handshake(socket, 'pad');
const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200); assert.equal(clientVars.type, 'CLIENT_VARS');
socket = await connect(res); assert.equal(clientVars.data.readonly, true);
const clientVars = await handshake(socket, 'pad'); });
assert.equal(clientVars.type, 'CLIENT_VARS'); it('user.readOnly = false -> can create and modify', async function() {
}); settings.users.user.readOnly = false;
it('supports pad names with characters that must be percent-encoded', async function() { const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200);
settings.requireAuthentication = true; socket = await connect(res);
// requireAuthorization is set to true here to guarantee that the user's padAuthorizations const clientVars = await handshake(socket, 'pad');
// object is populated. Technically this isn't necessary because the user's padAuthorizations assert.equal(clientVars.type, 'CLIENT_VARS');
// is currently populated even if requireAuthorization is false, but setting this to true assert.equal(clientVars.data.readonly, false);
// ensures the test remains useful if the implementation ever changes. });
settings.requireAuthorization = true; it('user.readOnly = true, user.canCreate = true -> unable to create', async function() {
const encodedPadId = encodeURIComponent('päd'); settings.users.user.canCreate = true;
const res = await agent.get(`/p/${encodedPadId}`).auth('user', 'user-password').expect(200); settings.users.user.readOnly = true;
socket = await connect(res); const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200);
const clientVars = await handshake(socket, 'päd'); socket = await connect(res);
assert.equal(clientVars.type, 'CLIENT_VARS'); const message = await handshake(socket, 'pad');
}); assert.equal(message.accessStatus, 'deny');
});
});
describe('Authorization level interaction between authorize hook and user settings', function() {
beforeEach(async function() {
settings.requireAuthentication = true;
settings.requireAuthorization = true;
}); });
describe('Abnormal access attempts', function() { it('authorize hook does not elevate level from user settings', async function() {
it('authn anonymous /p/pad -> 401, error', async function() { settings.users.user.readOnly = true;
settings.requireAuthentication = true; authorize = () => 'create';
const res = await agent.get('/p/pad').expect(401); const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200);
// Despite the 401, try to create the pad via a socket.io connection anyway. socket = await connect(res);
socket = await connect(res); const message = await handshake(socket, 'pad');
const message = await handshake(socket, 'pad'); assert.equal(message.accessStatus, 'deny');
assert.equal(message.accessStatus, 'deny');
});
it('authn !cookie -> error', async function() {
settings.requireAuthentication = true;
socket = await connect(null);
const message = await handshake(socket, 'pad');
assert.equal(message.accessStatus, 'deny');
});
it('authorization bypass attempt -> error', async function() {
// Only allowed to access /p/pad.
authorize = (req) => req.path === '/p/pad';
settings.requireAuthentication = true;
settings.requireAuthorization = true;
// First authenticate and establish a session.
const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200);
socket = await connect(res);
// Accessing /p/other-pad should fail, despite the successful fetch of /p/pad.
const message = await handshake(socket, 'other-pad');
assert.equal(message.accessStatus, 'deny');
});
}); });
it('user settings does not elevate level from authorize hook', async function() {
describe('Authorization levels via authorize hook', function() { settings.users.user.readOnly = false;
beforeEach(async function() { settings.users.user.canCreate = true;
settings.requireAuthentication = true; authorize = () => 'readOnly';
settings.requireAuthorization = true; const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200);
}); socket = await connect(res);
const message = await handshake(socket, 'pad');
it("level='create' -> can create", async function() { assert.equal(message.accessStatus, 'deny');
authorize = () => 'create';
const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200);
socket = await connect(res);
const clientVars = await handshake(socket, 'pad');
assert.equal(clientVars.type, 'CLIENT_VARS');
assert.equal(clientVars.data.readonly, false);
});
it('level=true -> can create', async function() {
authorize = () => true;
const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200);
socket = await connect(res);
const clientVars = await handshake(socket, 'pad');
assert.equal(clientVars.type, 'CLIENT_VARS');
assert.equal(clientVars.data.readonly, false);
});
it("level='modify' -> can modify", async function() {
await padManager.getPad('pad'); // Create the pad.
authorize = () => 'modify';
const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200);
socket = await connect(res);
const clientVars = await handshake(socket, 'pad');
assert.equal(clientVars.type, 'CLIENT_VARS');
assert.equal(clientVars.data.readonly, false);
});
it("level='create' settings.editOnly=true -> unable to create", async function() {
authorize = () => 'create';
settings.editOnly = true;
const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200);
socket = await connect(res);
const message = await handshake(socket, 'pad');
assert.equal(message.accessStatus, 'deny');
});
it("level='modify' settings.editOnly=false -> unable to create", async function() {
authorize = () => 'modify';
settings.editOnly = false;
const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200);
socket = await connect(res);
const message = await handshake(socket, 'pad');
assert.equal(message.accessStatus, 'deny');
});
it("level='readOnly' -> unable to create", async function() {
authorize = () => 'readOnly';
const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200);
socket = await connect(res);
const message = await handshake(socket, 'pad');
assert.equal(message.accessStatus, 'deny');
});
it("level='readOnly' -> unable to modify", async function() {
await padManager.getPad('pad'); // Create the pad.
authorize = () => 'readOnly';
const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200);
socket = await connect(res);
const clientVars = await handshake(socket, 'pad');
assert.equal(clientVars.type, 'CLIENT_VARS');
assert.equal(clientVars.data.readonly, true);
});
});
describe('Authorization levels via user settings', function() {
beforeEach(async function() {
settings.requireAuthentication = true;
});
it('user.canCreate = true -> can create and modify', async function() {
settings.users.user.canCreate = true;
const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200);
socket = await connect(res);
const clientVars = await handshake(socket, 'pad');
assert.equal(clientVars.type, 'CLIENT_VARS');
assert.equal(clientVars.data.readonly, false);
});
it('user.canCreate = false -> unable to create', async function() {
settings.users.user.canCreate = false;
const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200);
socket = await connect(res);
const message = await handshake(socket, 'pad');
assert.equal(message.accessStatus, 'deny');
});
it('user.readOnly = true -> unable to create', async function() {
settings.users.user.readOnly = true;
const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200);
socket = await connect(res);
const message = await handshake(socket, 'pad');
assert.equal(message.accessStatus, 'deny');
});
it('user.readOnly = true -> unable to modify', async function() {
await padManager.getPad('pad'); // Create the pad.
settings.users.user.readOnly = true;
const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200);
socket = await connect(res);
const clientVars = await handshake(socket, 'pad');
assert.equal(clientVars.type, 'CLIENT_VARS');
assert.equal(clientVars.data.readonly, true);
});
it('user.readOnly = false -> can create and modify', async function() {
settings.users.user.readOnly = false;
const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200);
socket = await connect(res);
const clientVars = await handshake(socket, 'pad');
assert.equal(clientVars.type, 'CLIENT_VARS');
assert.equal(clientVars.data.readonly, false);
});
it('user.readOnly = true, user.canCreate = true -> unable to create', async function() {
settings.users.user.canCreate = true;
settings.users.user.readOnly = true;
const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200);
socket = await connect(res);
const message = await handshake(socket, 'pad');
assert.equal(message.accessStatus, 'deny');
});
});
describe('Authorization level interaction between authorize hook and user settings', function() {
beforeEach(async function() {
settings.requireAuthentication = true;
settings.requireAuthorization = true;
});
it('authorize hook does not elevate level from user settings', async function() {
settings.users.user.readOnly = true;
authorize = () => 'create';
const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200);
socket = await connect(res);
const message = await handshake(socket, 'pad');
assert.equal(message.accessStatus, 'deny');
});
it('user settings does not elevate level from authorize hook', async function() {
settings.users.user.readOnly = false;
settings.users.user.canCreate = true;
authorize = () => 'readOnly';
const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200);
socket = await connect(res);
const message = await handshake(socket, 'pad');
assert.equal(message.accessStatus, 'deny');
});
}); });
}); });
}); });