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.
|
|
|
|
*/
|
|
|
|
|
2012-02-28 21:19:10 +01:00
|
|
|
|
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");
|
2011-12-16 21:41:11 +01:00
|
|
|
var padManager = require("../db/PadManager");
|
2012-02-26 17:48:17 +01:00
|
|
|
var randomString = require('ep_etherpad-lite/static/js/pad_utils').randomString;
|
2011-08-03 20:31:25 +02:00
|
|
|
|
|
|
|
//ensure we have an apikey
|
|
|
|
var apikey = null;
|
|
|
|
try
|
|
|
|
{
|
2012-05-12 23:34:26 +02:00
|
|
|
apikey = fs.readFileSync("./APIKEY.txt","utf8");
|
2011-08-03 20:31:25 +02:00
|
|
|
}
|
|
|
|
catch(e)
|
|
|
|
{
|
|
|
|
apikey = randomString(32);
|
2012-05-12 23:34:26 +02:00
|
|
|
fs.writeFileSync("./APIKEY.txt",apikey,"utf8");
|
2011-08-03 20:31:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//a list of all functions
|
2012-09-09 18:20:16 +02:00
|
|
|
var version =
|
|
|
|
{ "1":
|
|
|
|
{ "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
|
|
|
}
|
|
|
|
, "1.1":
|
2012-09-17 23:03:56 +02:00
|
|
|
{ "createGroup" : []
|
|
|
|
, "createGroupIfNotExistsFor" : ["groupMapper"]
|
|
|
|
, "deleteGroup" : ["groupID"]
|
|
|
|
, "listPads" : ["groupID"]
|
|
|
|
, "createPad" : ["padID", "text"]
|
|
|
|
, "createGroupPad" : ["groupID", "padName", "text"]
|
|
|
|
, "createAuthor" : ["name"]
|
2012-12-27 22:09:22 +01:00
|
|
|
, "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"]
|
|
|
|
, "getAuthorName" : ["authorID"]
|
|
|
|
, "padUsers" : ["padID"]
|
|
|
|
, "sendClientsMessage" : ["padID", "msg"]
|
|
|
|
, "listAllGroups" : []
|
|
|
|
}
|
|
|
|
, "1.2":
|
|
|
|
{ "createGroup" : []
|
|
|
|
, "createGroupIfNotExistsFor" : ["groupMapper"]
|
|
|
|
, "deleteGroup" : ["groupID"]
|
|
|
|
, "listPads" : ["groupID"]
|
|
|
|
, "createPad" : ["padID", "text"]
|
|
|
|
, "createGroupPad" : ["groupID", "padName", "text"]
|
|
|
|
, "createAuthor" : ["name"]
|
2013-01-08 20:14:01 +01:00
|
|
|
, "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"]
|
|
|
|
, "getAuthorName" : ["authorID"]
|
|
|
|
, "padUsers" : ["padID"]
|
|
|
|
, "sendClientsMessage" : ["padID", "msg"]
|
|
|
|
, "listAllGroups" : []
|
|
|
|
, "checkToken" : []
|
|
|
|
}
|
|
|
|
, "1.2.1":
|
|
|
|
{ "createGroup" : []
|
|
|
|
, "createGroupIfNotExistsFor" : ["groupMapper"]
|
|
|
|
, "deleteGroup" : ["groupID"]
|
|
|
|
, "listPads" : ["groupID"]
|
|
|
|
, "listAllPads" : []
|
|
|
|
, "createPad" : ["padID", "text"]
|
|
|
|
, "createGroupPad" : ["groupID", "padName", "text"]
|
|
|
|
, "createAuthor" : ["name"]
|
2013-01-22 23:33:51 +01:00
|
|
|
, "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"]
|
|
|
|
, "getAuthorName" : ["authorID"]
|
|
|
|
, "padUsers" : ["padID"]
|
|
|
|
, "sendClientsMessage" : ["padID", "msg"]
|
|
|
|
, "listAllGroups" : []
|
|
|
|
, "checkToken" : []
|
|
|
|
}
|
|
|
|
, "1.2.2":
|
|
|
|
{ "createGroup" : []
|
|
|
|
, "createGroupIfNotExistsFor" : ["groupMapper"]
|
|
|
|
, "deleteGroup" : ["groupID"]
|
|
|
|
, "listPads" : ["groupID"]
|
|
|
|
, "listAllPads" : []
|
2013-01-27 16:40:05 +01:00
|
|
|
, "createDiff" : ["padID", "startRev", "endRev"]
|
2013-01-22 23:33:51 +01:00
|
|
|
, "createPad" : ["padID", "text"]
|
|
|
|
, "createGroupPad" : ["groupID", "padName", "text"]
|
|
|
|
, "createAuthor" : ["name"]
|
2012-09-17 23:03:56 +02:00
|
|
|
, "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"]
|
|
|
|
, "getAuthorName" : ["authorID"]
|
2012-09-09 18:20:16 +02:00
|
|
|
, "padUsers" : ["padID"]
|
|
|
|
, "sendClientsMessage" : ["padID", "msg"]
|
2012-09-17 23:03:56 +02:00
|
|
|
, "listAllGroups" : []
|
2012-12-06 21:06:09 +01:00
|
|
|
, "checkToken" : []
|
2012-09-09 18:20:16 +02:00
|
|
|
}
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//say goodbye if this is an unkown API version
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
//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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//say goodbye if this is a unkown function
|
|
|
|
if(!isKnownFunctionname)
|
|
|
|
{
|
|
|
|
res.send({code: 3, message: "no such function", data: null});
|
|
|
|
return;
|
|
|
|
}
|
2012-09-09 18:20:16 +02:00
|
|
|
|
|
|
|
//check the api key!
|
|
|
|
if(fields["apikey"] != apikey.trim())
|
|
|
|
{
|
|
|
|
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
|
|
|
|
var functionParams = [];
|
2012-09-09 18:20:16 +02:00
|
|
|
for(var i=0;i<version[apiVersion][functionName].length;i++)
|
2011-08-03 20:31:25 +02:00
|
|
|
{
|
2012-09-09 18:20:16 +02:00
|
|
|
functionParams.push(fields[ version[apiVersion][functionName][i] ]);
|
2011-08-03 20:31:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//add a callback function to handle the response
|
|
|
|
functionParams.push(function(err, data)
|
|
|
|
{
|
|
|
|
// no error happend, everything is fine
|
|
|
|
if(err == null)
|
|
|
|
{
|
2011-08-04 20:22:46 +02:00
|
|
|
if(!data)
|
|
|
|
data = null;
|
|
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
//an unkown error happend
|
|
|
|
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
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
//call the api function
|
|
|
|
api[functionName](functionParams[0],functionParams[1],functionParams[2],functionParams[3],functionParams[4]);
|
|
|
|
}
|