import: Use the correct author ID when using sessions

There are two different ways an author ID becomes associated with a
user: either bound to a token or bound to a session ID. (The token and
session ID come from the `token` and `sessionID` cookies, or, in the
case of socket.io messages, from the `token` and `sessionID` message
properties.) When `settings.requireSession` is true or the user is
accessing a group pad, the session ID should be used. Otherwise the
token should be used.

Before this change, the `/p/:pad/import` handler was always using the
token, even when `settings.requireSession` was true. This caused the
following error because a different author ID was bound to the token
versus the session ID:

> Unable to import file into ${pad}. Author ${authorID} exists but he
> never contributed to this pad

This bug was reported in issue #4006. PR #4012 worked around the
problem by binding the same author ID to the token as well as the
session ID.

This change does the following:
  * Modifies the import handler to use the session ID to obtain the
    author ID (when appropriate).
  * Expands the documentation for the SecurityManager checkAccess
    function.
  * Removes the workaround from PR #4012.
  * Cleans up the `bin/createUserSession.js` test script.
This commit is contained in:
Richard Hansen 2020-09-02 17:16:02 -04:00 committed by John McLear
parent db0bcb524e
commit 6c2a361935
5 changed files with 92 additions and 160 deletions

View file

@ -2,77 +2,46 @@
* A tool for generating a test user session which can be used for debugging configs
* that require sessions.
*/
const m = (f) => __dirname + '/../' + f;
const request = require('../src/node_modules/request');
const settings = require(__dirname+'/../tests/container/loadSettings').loadSettings();
const supertest = require(__dirname+'/../src/node_modules/supertest');
const api = supertest('http://'+settings.ip+":"+settings.port);
const path = require('path');
const fs = require('fs');
const path = require('path');
const querystring = require('querystring');
const request = require(m('src/node_modules/request'));
const settings = require(m('src/node/utils/Settings'));
const supertest = require(m('src/node_modules/supertest'));
// get the API Key
var filePath = path.join(__dirname, '../APIKEY.txt');
var apikey = fs.readFileSync(filePath, {encoding: 'utf-8'});
(async () => {
const api = supertest('http://'+settings.ip+':'+settings.port);
// Set apiVersion to base value, we change this later.
var apiVersion = 1;
const filePath = path.join(__dirname, '../APIKEY.txt');
const apikey = fs.readFileSync(filePath, {encoding: 'utf-8'});
// Update the apiVersion
api.get('/api/')
.expect(function(res){
apiVersion = res.body.currentVersion;
if (!res.body.currentVersion) throw new Error("No version set in API");
return;
})
.end(function(err, res){
// Now we know the latest API version, let's create a group
var uri = '/api/'+apiVersion+'/createGroup?apikey='+apikey;
api.post(uri)
.expect(function(res){
if (res.body.code === 1){
console.error("Error creating group", res.body);
}else{
var groupID = res.body.data.groupID;
console.log("groupID", groupID);
let res;
// creating a group pad
api.post('/api/'+apiVersion+'/createGroupPad?apikey='+apikey+'&groupID='+groupID)
.expect(function(res){
if (res.body.code === 1){
console.error("Error creating author", res.body);
}else{
console.log("Test Pad ID ====> ", res.body.data.padID)
}
}).end(function(){})
res = await api.get('/api/');
const apiVersion = res.body.currentVersion;
if (!apiVersion) throw new Error('No version set in API');
const uri = (cmd, args) => `/api/${apiVersion}/${cmd}?${querystring.stringify(args)}`;
// create an author
api.post('/api/'+apiVersion+'/createAuthor?apikey='+apikey)
.expect(function(res){
if (res.body.code === 1){
console.error("Error creating author", res.body);
}else{
console.log("authorID", res.body.data.authorID)
var authorID = res.body.data.authorID;
// create a session for this authorID
var validUntil = Math.floor(new Date() / 1000) + 60000;
console.log("validUntil", validUntil)
api.post('/api/'+apiVersion+'/createSession?apikey='+apikey + '&groupID='+groupID+'&authorID='+authorID+'&validUntil='+validUntil)
.expect(function(res){
if (res.body.code === 1){
console.error("Error creating author", res.body);
}else{
console.log("Session made: ====> create a cookie named sessionID and set it's value to ", res.body.data.sessionID);
}
})
.end(function(){}) // I shouldn't have nested but here we are.. it's not too ugly :P
res = await api.post(uri('createGroup', {apikey}));
if (res.body.code === 1) throw new Error(`Error creating group: ${res.body}`);
const groupID = res.body.data.groupID;
console.log('groupID', groupID);
}
})
.end(function(){})
res = await api.post(uri('createGroupPad', {apikey, groupID}));
if (res.body.code === 1) throw new Error(`Error creating group pad: ${res.body}`);
console.log('Test Pad ID ====> ', res.body.data.padID);
}
return;
})
.end(function(){})
});
// end
res = await api.post(uri('createAuthor', {apikey}));
if (res.body.code === 1) throw new Error(`Error creating author: ${res.body}`);
const authorID = res.body.data.authorID;
console.log('authorID', authorID);
const validUntil = Math.floor(new Date() / 1000) + 60000;
console.log('validUntil', validUntil);
res = await api.post(uri('createSession', {apikey, groupID, authorID, validUntil}));
if (res.body.code === 1) throw new Error(`Error creating session: ${res.body}`);
console.log('Session made: ====> create a cookie named sessionID and set the value to',
res.body.data.sessionID);
})();