-
Notifications
You must be signed in to change notification settings - Fork 0
/
api.js
115 lines (98 loc) · 3.47 KB
/
api.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
var api = exports;
var _ = require('underscore')._;
var config = require('./config.js').config;
var db = require('./db.js');
var userModel = require('./model/user.js');
var XML = require('./xml.js');
var apiDataDefault = {
'version': 1,
'responseFormat': 'json', // possible values: json, jsonp, xml
'jsonpCallback': false, // only used with jsonp response format
'appId': 0 // invalid!!!
};
api.appId = function(req) { return req.apiData.appId; };
api.authenticate = function(req, callback) {
req.apiData = _.clone(apiDataDefault);
var apiData = req.apiData; // shorthand
// validate the response format
if (req.param('_responseFormat')) {
apiData.responseFormat = req.param('_responseFormat');
} else if (req.accepts('json')) {
apiData.responseFormat = 'json';
} else if (req.accepts('xml')) {
apiData.responseFormat = 'xml';
}
if (apiData.responseFormat == 'json' && req.param('callback')) {
apiData.responseFormat = 'jsonp';
apiData.jsonpCallback = req.param('callback');
}
// authorization...
if (req.headers['authorization']) {
var parts = req.headers['authorization'].split(' ');
if (parts.length == 2) {
if (parts[0] == 'Basic') {
// basic authentication...
var decoded = (new Buffer(parts[1], 'base64').toString('ascii'));
parts = decoded.split(':');
if (parts.length == 2) {
// we now have username and password
// trigger a database query, notice the extra else branch with callback()?
userModel.getUserByUserName(parts[0], function(err, user) {
if (!err && user) {
if (user.password == api.hashPassword(parts[1])) {
apiData.appId = user.app_id;
}
}
callback();
});
// prevent calling callback() at the end of this method
// it will be called in the anonymous method above...
return;
}
}
}
}
callback();
};
api.response = function(req, res, data) {
switch (req.apiData.responseFormat) {
case 'xml':
res.header('Content-Type', 'text/xml');
res.write(XML.stringify(data));
res.end();
break;
case 'json':
// simplest format, just output it
res.json(data);
break;
case 'jsonp':
res.header('Content-Type', 'application/javascript');
res.write(apiData.jsonpCallback + '(');
res.write(JSON.stringify(data));
res.write(');');
res.end();
break;
}
};
api.responseError = function(req, res, errMessage, httpStatusCode) {
if (httpStatusCode) {
res.statusCode = httpStatusCode;
}
api.response(req, res, { 'error': errMessage });
}
api.responseNoPermission = function(req, res) {
api.responseError(req, res, 'You don\'t have permission to access this resource', 403);
}
api.hashPassword = function(raw) {
return require('crypto').createHash('md5').update(raw).digest('hex');
}
api.now = function() {
return Math.round(Date.now() / 1000);
}
api.time = function() {
// ugly I now, sorry
return Date.now();
}
api.timeDiff = function(timestamp) {
return api.time() - timestamp;
}