2011-08-03 20:31:25 +02:00
|
|
|
/**
|
|
|
|
* The API Handler handles all API http requests
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2011-08-11 16:26:41 +02:00
|
|
|
* 2011 Peter 'Pita' Martischka (Primary Technology Ltd)
|
2011-08-03 20:31:25 +02:00
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS-IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2018-08-22 01:56:40 +02:00
|
|
|
var absolutePaths = require('../utils/AbsolutePaths');
|
2011-12-04 16:50:02 +01:00
|
|
|
var ERR = require("async-stacktrace");
|
2011-08-03 20:31:25 +02:00
|
|
|
var fs = require("fs");
|
|
|
|
var api = require("../db/API");
|
2018-08-21 00:05:15 +02:00
|
|
|
var log4js = require('log4js');
|
2011-12-16 21:41:11 +01:00
|
|
|
var padManager = require("../db/PadManager");
|
2014-01-15 20:25:47 +01:00
|
|
|
var randomString = require("../utils/randomstring");
|
2017-07-31 14:43:04 +02:00
|
|
|
var argv = require('../utils/Cli').argv;
|
2011-08-03 20:31:25 +02:00
|
|
|
|
2018-08-21 00:05:15 +02:00
|
|
|
var apiHandlerLogger = log4js.getLogger('APIHandler');
|
|
|
|
|
2011-08-03 20:31:25 +02:00
|
|
|
//ensure we have an apikey
|
|
|
|
var apikey = null;
|
2018-08-22 01:56:40 +02:00
|
|
|
var apikeyFilename = absolutePaths.makeAbsolute(argv.apikey || "./APIKEY.txt");
|
2011-08-03 20:31:25 +02:00
|
|
|
try
|
|
|
|
{
|
2017-07-31 14:43:04 +02:00
|
|
|
apikey = fs.readFileSync(apikeyFilename,"utf8");
|
2018-08-21 00:05:15 +02:00
|
|
|
apiHandlerLogger.info(`Api key file read from: "${apikeyFilename}"`);
|
2011-08-03 20:31:25 +02:00
|
|
|
}
|
2013-11-24 21:34:00 +01:00
|
|
|
catch(e)
|
2011-08-03 20:31:25 +02:00
|
|
|
{
|
2018-08-21 00:05:15 +02:00
|
|
|
apiHandlerLogger.info(`Api key file "${apikeyFilename}" not found. Creating with random contents.`);
|
2011-08-03 20:31:25 +02:00
|
|
|
apikey = randomString(32);
|
2017-07-31 14:43:04 +02:00
|
|
|
fs.writeFileSync(apikeyFilename,apikey,"utf8");
|
2011-08-03 20:31:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//a list of all functions
|
2019-01-11 14:13:24 +01:00
|
|
|
var version = {};
|
|
|
|
|
|
|
|
version["1"] = Object.assign({},
|
2012-09-09 18:20:16 +02:00
|
|
|
{ "createGroup" : []
|
|
|
|
, "createGroupIfNotExistsFor" : ["groupMapper"]
|
|
|
|
, "deleteGroup" : ["groupID"]
|
|
|
|
, "listPads" : ["groupID"]
|
|
|
|
, "createPad" : ["padID", "text"]
|
|
|
|
, "createGroupPad" : ["groupID", "padName", "text"]
|
|
|
|
, "createAuthor" : ["name"]
|
|
|
|
, "createAuthorIfNotExistsFor": ["authorMapper" , "name"]
|
|
|
|
, "listPadsOfAuthor" : ["authorID"]
|
|
|
|
, "createSession" : ["groupID", "authorID", "validUntil"]
|
|
|
|
, "deleteSession" : ["sessionID"]
|
|
|
|
, "getSessionInfo" : ["sessionID"]
|
|
|
|
, "listSessionsOfGroup" : ["groupID"]
|
|
|
|
, "listSessionsOfAuthor" : ["authorID"]
|
|
|
|
, "getText" : ["padID", "rev"]
|
|
|
|
, "setText" : ["padID", "text"]
|
|
|
|
, "getHTML" : ["padID", "rev"]
|
|
|
|
, "setHTML" : ["padID", "html"]
|
|
|
|
, "getRevisionsCount" : ["padID"]
|
|
|
|
, "getLastEdited" : ["padID"]
|
|
|
|
, "deletePad" : ["padID"]
|
|
|
|
, "getReadOnlyID" : ["padID"]
|
|
|
|
, "setPublicStatus" : ["padID", "publicStatus"]
|
|
|
|
, "getPublicStatus" : ["padID"]
|
|
|
|
, "setPassword" : ["padID", "password"]
|
|
|
|
, "isPasswordProtected" : ["padID"]
|
|
|
|
, "listAuthorsOfPad" : ["padID"]
|
|
|
|
, "padUsersCount" : ["padID"]
|
2012-09-13 16:13:54 +02:00
|
|
|
}
|
2019-01-11 14:13:24 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
version["1.1"] = Object.assign({}, version["1"],
|
|
|
|
{ "getAuthorName" : ["authorID"]
|
2012-12-27 22:09:22 +01:00
|
|
|
, "padUsers" : ["padID"]
|
|
|
|
, "sendClientsMessage" : ["padID", "msg"]
|
|
|
|
, "listAllGroups" : []
|
|
|
|
}
|
2019-01-11 14:13:24 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
version["1.2"] = Object.assign({}, version["1.1"],
|
|
|
|
{ "checkToken" : []
|
2013-01-08 20:14:01 +01:00
|
|
|
}
|
2019-01-11 14:13:24 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
version["1.2.1"] = Object.assign({}, version["1.2"],
|
|
|
|
{ "listAllPads" : []
|
2013-01-22 23:33:51 +01:00
|
|
|
}
|
2019-01-11 14:13:24 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
version["1.2.7"] = Object.assign({}, version["1.2.1"],
|
|
|
|
{ "createDiffHTML" : ["padID", "startRev", "endRev"]
|
2013-04-01 17:18:45 +02:00
|
|
|
, "getChatHistory" : ["padID", "start", "end"]
|
|
|
|
, "getChatHead" : ["padID"]
|
|
|
|
}
|
2019-01-11 14:13:24 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
version["1.2.8"] = Object.assign({}, version["1.2.7"],
|
|
|
|
{ "getAttributePool" : ["padID"]
|
2013-11-24 21:34:00 +01:00
|
|
|
, "getRevisionChangeset" : ["padID", "rev"]
|
|
|
|
}
|
2019-01-11 14:13:24 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
version["1.2.9"] = Object.assign({}, version["1.2.8"],
|
|
|
|
{ "copyPad" : ["sourceID", "destinationID", "force"]
|
2013-11-18 07:25:46 +01:00
|
|
|
, "movePad" : ["sourceID", "destinationID", "force"]
|
2012-09-09 18:20:16 +02:00
|
|
|
}
|
2019-01-11 14:13:24 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
version["1.2.10"] = Object.assign({}, version["1.2.9"],
|
|
|
|
{ "getPadID" : ["roID"]
|
2014-05-31 00:39:36 +02:00
|
|
|
}
|
2019-01-11 14:13:24 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
version["1.2.11"] = Object.assign({}, version["1.2.10"],
|
|
|
|
{ "getSavedRevisionsCount" : ["padID"]
|
2015-02-24 23:42:35 +01:00
|
|
|
, "listSavedRevisions" : ["padID"]
|
2015-02-25 01:04:27 +01:00
|
|
|
, "saveRevision" : ["padID", "rev"]
|
2014-11-08 01:41:23 +01:00
|
|
|
, "restoreRevision" : ["padID", "rev"]
|
|
|
|
}
|
2019-01-11 14:13:24 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
version["1.2.12"] = Object.assign({}, version["1.2.11"],
|
|
|
|
{ "appendChatMessage" : ["padID", "text", "authorID", "time"]
|
2015-02-09 06:18:12 +01:00
|
|
|
}
|
2019-01-11 14:13:24 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
version["1.2.13"] = Object.assign({}, version["1.2.12"],
|
|
|
|
{ "appendText" : ["padID", "text"]
|
2015-10-19 18:58:47 +02:00
|
|
|
}
|
2019-01-11 14:13:24 +01:00
|
|
|
);
|
2011-08-03 20:31:25 +02:00
|
|
|
|
2013-02-12 21:50:14 +01:00
|
|
|
// set the latest available API version here
|
2015-10-19 18:58:47 +02:00
|
|
|
exports.latestApiVersion = '1.2.13';
|
2013-02-12 21:50:14 +01:00
|
|
|
|
2013-02-13 17:29:01 +01:00
|
|
|
// exports the versions so it can be used by the new Swagger endpoint
|
|
|
|
exports.version = version;
|
|
|
|
|
2011-08-03 20:31:25 +02:00
|
|
|
/**
|
|
|
|
* Handles a HTTP API call
|
|
|
|
* @param functionName the name of the called function
|
|
|
|
* @param fields the params of the called function
|
|
|
|
* @req express request object
|
|
|
|
* @res express response object
|
|
|
|
*/
|
2012-09-09 18:20:16 +02:00
|
|
|
exports.handle = function(apiVersion, functionName, fields, req, res)
|
2011-08-03 20:31:25 +02:00
|
|
|
{
|
2012-09-09 18:20:16 +02:00
|
|
|
//check if this is a valid apiversion
|
|
|
|
var isKnownApiVersion = false;
|
|
|
|
for(var knownApiVersion in version)
|
2011-08-03 20:31:25 +02:00
|
|
|
{
|
2012-09-09 18:20:16 +02:00
|
|
|
if(knownApiVersion == apiVersion)
|
|
|
|
{
|
|
|
|
isKnownApiVersion = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2013-11-24 21:34:00 +01:00
|
|
|
|
2019-01-11 14:13:24 +01:00
|
|
|
//say goodbye if this is an unknown API version
|
2012-09-09 18:20:16 +02:00
|
|
|
if(!isKnownApiVersion)
|
|
|
|
{
|
|
|
|
res.statusCode = 404;
|
|
|
|
res.send({code: 3, message: "no such api version", data: null});
|
2011-08-03 20:31:25 +02:00
|
|
|
return;
|
|
|
|
}
|
2013-11-24 21:34:00 +01:00
|
|
|
|
2011-08-03 20:31:25 +02:00
|
|
|
//check if this is a valid function name
|
|
|
|
var isKnownFunctionname = false;
|
2012-09-09 18:20:16 +02:00
|
|
|
for(var knownFunctionname in version[apiVersion])
|
2011-08-03 20:31:25 +02:00
|
|
|
{
|
|
|
|
if(knownFunctionname == functionName)
|
|
|
|
{
|
|
|
|
isKnownFunctionname = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2013-11-24 21:34:00 +01:00
|
|
|
|
2019-01-11 14:13:24 +01:00
|
|
|
//say goodbye if this is a unknown function
|
2011-08-03 20:31:25 +02:00
|
|
|
if(!isKnownFunctionname)
|
|
|
|
{
|
|
|
|
res.send({code: 3, message: "no such function", data: null});
|
|
|
|
return;
|
|
|
|
}
|
2013-11-24 21:34:00 +01:00
|
|
|
|
2012-09-09 18:20:16 +02:00
|
|
|
//check the api key!
|
2013-02-13 17:29:01 +01:00
|
|
|
fields["apikey"] = fields["apikey"] || fields["api_key"];
|
2013-11-24 21:34:00 +01:00
|
|
|
|
2012-09-09 18:20:16 +02:00
|
|
|
if(fields["apikey"] != apikey.trim())
|
|
|
|
{
|
2014-11-26 18:34:44 +01:00
|
|
|
res.statusCode = 401;
|
2012-09-09 18:20:16 +02:00
|
|
|
res.send({code: 4, message: "no or wrong API Key", data: null});
|
|
|
|
return;
|
|
|
|
}
|
2011-12-16 21:41:11 +01:00
|
|
|
|
|
|
|
//sanitize any pad id's before continuing
|
|
|
|
if(fields["padID"])
|
|
|
|
{
|
|
|
|
padManager.sanitizePadId(fields["padID"], function(padId)
|
|
|
|
{
|
|
|
|
fields["padID"] = padId;
|
2012-09-09 18:20:16 +02:00
|
|
|
callAPI(apiVersion, functionName, fields, req, res);
|
2011-12-16 21:41:11 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
else if(fields["padName"])
|
|
|
|
{
|
|
|
|
padManager.sanitizePadId(fields["padName"], function(padId)
|
|
|
|
{
|
|
|
|
fields["padName"] = padId;
|
2012-09-09 18:20:16 +02:00
|
|
|
callAPI(apiVersion, functionName, fields, req, res);
|
2011-12-16 21:41:11 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-09-09 18:20:16 +02:00
|
|
|
callAPI(apiVersion, functionName, fields, req, res);
|
2011-12-16 21:41:11 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//calls the api function
|
2012-09-09 18:20:16 +02:00
|
|
|
function callAPI(apiVersion, functionName, fields, req, res)
|
2011-12-16 21:41:11 +01:00
|
|
|
{
|
2011-08-03 20:31:25 +02:00
|
|
|
//put the function parameters in an array
|
2013-10-25 00:47:29 +02:00
|
|
|
var functionParams = version[apiVersion][functionName].map(function (field) {
|
|
|
|
return fields[field]
|
|
|
|
})
|
2013-11-24 21:34:00 +01:00
|
|
|
|
2011-08-03 20:31:25 +02:00
|
|
|
//add a callback function to handle the response
|
|
|
|
functionParams.push(function(err, data)
|
2013-11-24 21:34:00 +01:00
|
|
|
{
|
2011-08-03 20:31:25 +02:00
|
|
|
// no error happend, everything is fine
|
|
|
|
if(err == null)
|
|
|
|
{
|
2011-08-04 20:22:46 +02:00
|
|
|
if(!data)
|
|
|
|
data = null;
|
2013-11-24 21:34:00 +01:00
|
|
|
|
2011-08-04 20:22:46 +02:00
|
|
|
res.send({code: 0, message: "ok", data: data});
|
2011-08-03 20:31:25 +02:00
|
|
|
}
|
|
|
|
// parameters were wrong and the api stopped execution, pass the error
|
2011-12-10 16:46:47 +01:00
|
|
|
else if(err.name == "apierror")
|
2011-08-03 20:31:25 +02:00
|
|
|
{
|
2011-12-10 16:46:47 +01:00
|
|
|
res.send({code: 1, message: err.message, data: null});
|
2011-08-03 20:31:25 +02:00
|
|
|
}
|
2019-01-11 14:13:24 +01:00
|
|
|
//an unknown error happend
|
2011-08-03 20:31:25 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
res.send({code: 2, message: "internal error", data: null});
|
2011-12-04 16:50:02 +01:00
|
|
|
ERR(err);
|
2011-08-03 20:31:25 +02:00
|
|
|
}
|
|
|
|
});
|
2013-11-24 21:34:00 +01:00
|
|
|
|
2011-08-03 20:31:25 +02:00
|
|
|
//call the api function
|
2013-10-25 00:47:29 +02:00
|
|
|
api[functionName].apply(this, functionParams);
|
2011-08-03 20:31:25 +02:00
|
|
|
}
|