Various updates.
This commit is contained in:
parent
22ce37c0cd
commit
ddf259f8b7
|
@ -13,7 +13,7 @@
|
|||
},
|
||||
"main": "src/main.js",
|
||||
"dependencies": {
|
||||
"backbone": ">=1.0.0",
|
||||
"extendable": ">=0.0.3",
|
||||
"hashy": ">=0.1.0",
|
||||
"underscore": ">=1.4.4"
|
||||
},
|
||||
|
|
103
src/api.js
103
src/api.js
|
@ -2,6 +2,17 @@ var _ = require('underscore');
|
|||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
function deprecated(fn)
|
||||
{
|
||||
return function (session, req, res) {
|
||||
console.warn(req.method +' is deprecated!');
|
||||
|
||||
return fn.call(this, session, req, res);
|
||||
};
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
function Api(xo)
|
||||
{
|
||||
this.xo = xo;
|
||||
|
@ -41,9 +52,19 @@ Api.prototype.get = function (name) {
|
|||
)
|
||||
{}
|
||||
|
||||
return _.isFunction(current)
|
||||
? current
|
||||
: undefined
|
||||
// Method found.
|
||||
if (_.isFunction(current))
|
||||
{
|
||||
return current;
|
||||
}
|
||||
|
||||
// It's a (deprecated) alias.
|
||||
if (_.isString(current))
|
||||
{
|
||||
return deprecated(this.get(current));
|
||||
}
|
||||
|
||||
return undefined;
|
||||
;
|
||||
};
|
||||
|
||||
|
@ -64,14 +85,14 @@ function err(code, message)
|
|||
Api.err = {
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// JSON errors.
|
||||
// JSON-RPC errors.
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
'INVALID_JSON': err(-32700, 'invalid JSON'),
|
||||
|
||||
'INVALID_REQUEST': err(-32600, 'invalid JSON-RPC request'),
|
||||
|
||||
'INVALID_METHOD': err(-326001, 'method not found'),
|
||||
'INVALID_METHOD': err(-32601, 'method not found'),
|
||||
|
||||
'INVALID_PARAMS': err(-32602, 'invalid parameter(s)'),
|
||||
|
||||
|
@ -100,6 +121,7 @@ Api.fn.api = {
|
|||
},
|
||||
};
|
||||
|
||||
// Session management
|
||||
Api.fn.session = {
|
||||
'signInWithPassword': function (session, req, res) {
|
||||
var p_email = req.params.email;
|
||||
|
@ -161,7 +183,7 @@ Api.fn.session = {
|
|||
return true;
|
||||
},
|
||||
|
||||
'getUser': function (session, req, res) {
|
||||
'getUser': deprecated(function (session, req, res) {
|
||||
var user_id = session.get('user_id');
|
||||
if (undefined === user_id)
|
||||
{
|
||||
|
@ -169,36 +191,18 @@ Api.fn.session = {
|
|||
}
|
||||
|
||||
return _.pick(users.get(user_id), 'id', 'email');
|
||||
});
|
||||
|
||||
'getUserId': function (session, req, res) {
|
||||
return session.get('user_id', null);
|
||||
};
|
||||
|
||||
'createToken': function (session, req, res) {
|
||||
var user_id = session.get('user_id');
|
||||
if ((undefined === user_id)
|
||||
|| session.has('token_id'))
|
||||
{
|
||||
throw Api.err.UNAUTHORIZED;
|
||||
}
|
||||
'createToken': 'token.create'
|
||||
|
||||
// @todo Ugly.
|
||||
var token = this.tokens.model.generate(user_id);
|
||||
this.tokens.add(token);
|
||||
|
||||
return token.id;
|
||||
},
|
||||
|
||||
'destroyToken': function (session, req, res) {
|
||||
var p_token = req.params.token;
|
||||
|
||||
if (!this.tokens.get(p_token))
|
||||
{
|
||||
throw Api.err.INVALID_PARAMS;
|
||||
}
|
||||
|
||||
this.tokens.remove(p_token);
|
||||
return true;
|
||||
},
|
||||
'destroyToken': 'token.delete',
|
||||
};
|
||||
|
||||
// User management.
|
||||
Api.fn.user = {
|
||||
'create': function (session, req, res) {
|
||||
var p_email = req.params.email;
|
||||
|
@ -220,7 +224,9 @@ Api.fn.user = {
|
|||
},
|
||||
|
||||
'delete': function (session, req, res) {
|
||||
var p_id = req.params.id;
|
||||
|
||||
var user
|
||||
},
|
||||
|
||||
'changePassword': function (session, req, res) {
|
||||
|
@ -235,3 +241,38 @@ Api.fn.user = {
|
|||
|
||||
},
|
||||
};
|
||||
|
||||
// Token management.
|
||||
Api.fn.token = {
|
||||
'create': function (session, req, res) {
|
||||
var user_id = session.get('user_id');
|
||||
if ((undefined === user_id)
|
||||
|| session.has('token_id'))
|
||||
{
|
||||
throw Api.err.UNAUTHORIZED;
|
||||
}
|
||||
|
||||
// @todo Ugly.
|
||||
var token = this.tokens.model.generate(user_id);
|
||||
this.tokens.add(token);
|
||||
|
||||
return token.id;
|
||||
},
|
||||
|
||||
'delete': function (session, req, res) {
|
||||
var p_token = req.params.token;
|
||||
|
||||
if (!this.tokens.get(p_token))
|
||||
{
|
||||
throw Api.err.INVALID_PARAMS;
|
||||
}
|
||||
|
||||
this.tokens.remove(p_token);
|
||||
return true;
|
||||
},
|
||||
};
|
||||
|
||||
// VM
|
||||
Api.fn.vm = {
|
||||
|
||||
};
|
||||
|
|
112
src/main.js
112
src/main.js
|
@ -1,5 +1,6 @@
|
|||
var events = require('events');
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
var util = require('util');
|
||||
var Session = require('session');
|
||||
|
||||
//--------------------------------------
|
||||
|
||||
|
@ -8,34 +9,6 @@ var api = require('./api')(xo);
|
|||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
function Session()
|
||||
{
|
||||
this.data = {};
|
||||
}
|
||||
|
||||
util.inherits(Session, events.EventEmitter);
|
||||
|
||||
Session.prototype.close = function () {
|
||||
session.emit('close');
|
||||
};
|
||||
|
||||
Session.prototype.get = function (name, def) {
|
||||
if (undefined !== this.data[name])
|
||||
{
|
||||
return this.data[name];
|
||||
}
|
||||
|
||||
return def;
|
||||
};
|
||||
|
||||
Session.prototype.has = function (name) {
|
||||
return (undefined !== this.data[name]);
|
||||
};
|
||||
|
||||
Session.prototype.set = function (name, value) {
|
||||
this.data[name] = value;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
function Response(transport, id)
|
||||
|
@ -70,22 +43,8 @@ Response.prototype.sendError = function (error)
|
|||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
require('socket.io')
|
||||
.listen(8080)
|
||||
.sockets.on('connection', function (socket) {
|
||||
|
||||
// @todo comment
|
||||
var transport = function (message) {
|
||||
socket.send(data);
|
||||
};
|
||||
|
||||
var session = new Session();
|
||||
session.on('close', function () {
|
||||
socket.disconnect();
|
||||
});
|
||||
|
||||
// When a message is received.
|
||||
socket.on('message', function (message) {
|
||||
function json_api_call(session, transport, message)
|
||||
{
|
||||
try
|
||||
{
|
||||
var req = JSON.parse(message.toString());
|
||||
|
@ -117,6 +76,65 @@ require('socket.io')
|
|||
},
|
||||
new Response(transport, req.id)
|
||||
);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// JSON-RPC over WebSocket.
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
require('socket.io').listen(8080).sockets.on('connection', function (socket) {
|
||||
var transport = function (message) {
|
||||
socket.send(data);
|
||||
};
|
||||
|
||||
var session = new Session();
|
||||
session.on('close', function () {
|
||||
socket.disconnect();
|
||||
});
|
||||
})
|
||||
;
|
||||
|
||||
socket.on('message', function (message) {
|
||||
json_api_call(session, transport, message);
|
||||
});
|
||||
});
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// JSON-RPC over TCP.
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
require('net').createServer(function (socket) {
|
||||
var transport = function (message) {
|
||||
socket.write(message); // @todo Handle long messages.
|
||||
};
|
||||
|
||||
var session = new Session();
|
||||
session.on('close', function () {
|
||||
socket.end(); // @todo Check it is enough.
|
||||
});
|
||||
|
||||
var length = null; // Expected message length.
|
||||
var buffer = new Buffer();
|
||||
socket.on('data', function (data) {
|
||||
data.copy(buffer);
|
||||
|
||||
// Read the message length.
|
||||
if (!length)
|
||||
{
|
||||
var i = _.indexOf(buffer, 10);
|
||||
if (-1 === i)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
length = +buffer.toString('ascii', 0, i); // @todo Handle NaN.
|
||||
buffer = buffer.slice(i + 1);
|
||||
}
|
||||
|
||||
// We do not have received everything.
|
||||
if (buffer.length < length)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
json_api_call(session, transport, buffer.toString());
|
||||
});
|
||||
}).listen('<path>'); // @todo
|
||||
|
|
13
src/xo.js
13
src/xo.js
|
@ -1,8 +1,9 @@
|
|||
var _ = require('underscore');
|
||||
var Backbone = require('backbone');
|
||||
var crypto = require('crypto');
|
||||
var hashy = require('hashy');
|
||||
var Q = require('q');
|
||||
var Collection = require('collection');
|
||||
var Model = require('model');
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -33,7 +34,7 @@ var check = function () {
|
|||
|
||||
// @todo We could also give a permission level to tokens (<=
|
||||
// user.permission).
|
||||
var Token = Backbone.Model.extend({
|
||||
var Token = Model.extend({
|
||||
// Validates model attributes.
|
||||
'validate': function (attr) {
|
||||
check(attr.id).len(10);
|
||||
|
@ -52,7 +53,9 @@ var Token = Backbone.Model.extend({
|
|||
},
|
||||
});
|
||||
|
||||
var User = Backbone.Model.extend({
|
||||
user.set('password', '123');
|
||||
|
||||
var User = Model.extend({
|
||||
'default': {
|
||||
'permission': 'none',
|
||||
},
|
||||
|
@ -102,11 +105,11 @@ var User = Backbone.Model.extend({
|
|||
// Collections
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
var Tokens = Backbone.Collection.extend({
|
||||
var Tokens = Collection.extend({
|
||||
'model': Token,
|
||||
});
|
||||
|
||||
var Users = Backbone.Collection.extend({
|
||||
var Users = Collection.extend({
|
||||
'model': User,
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue