mirror of
https://github.com/mclueppers/xo-server.git
synced 2025-07-29 17:04:44 +02:00
Major bug fixes. MySQL authentication and user creation works now...
This commit is contained in:
parent
cf10d2341d
commit
7bc47a5ab9
19
config/db.mysql.sql
Normal file
19
config/db.mysql.sql
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
DROP TABLE IF EXISTS `users`;
|
||||||
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!40101 SET character_set_client = utf8 */;
|
||||||
|
|
||||||
|
CREATE TABLE `users` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`username` varchar(45) DEFAULT NULL,
|
||||||
|
`password` varchar(80) DEFAULT NULL,
|
||||||
|
`permissions` smallint(1) DEFAULT NULL,
|
||||||
|
`created` datetime DEFAULT NULL,
|
||||||
|
`lastlogin` datetime DEFAULT NULL,
|
||||||
|
`email` varchar(254) DEFAULT NULL,
|
||||||
|
`active` smallint(1) DEFAULT '0',
|
||||||
|
`activationtoken` varchar(45) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE KEY `email_UNIQUE` (`email`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
|
13
package.json
13
package.json
@ -4,6 +4,12 @@
|
|||||||
"email": "julien.fontanet@vates.fr",
|
"email": "julien.fontanet@vates.fr",
|
||||||
"url": "http://vates.fr/"
|
"url": "http://vates.fr/"
|
||||||
},
|
},
|
||||||
|
"contributors": [
|
||||||
|
{
|
||||||
|
"name": "Martin Dobrev",
|
||||||
|
"email": "martin.dobrev@unixsol.co.uk"
|
||||||
|
}
|
||||||
|
],
|
||||||
"name": "xo-server",
|
"name": "xo-server",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"homepage": "http://github.com/vatesfr/xo-server/",
|
"homepage": "http://github.com/vatesfr/xo-server/",
|
||||||
@ -23,7 +29,12 @@
|
|||||||
"underscore": ">=1.5.2",
|
"underscore": ">=1.5.2",
|
||||||
"validator": ">=1.2.1",
|
"validator": ">=1.2.1",
|
||||||
"ws": ">=0.4.27",
|
"ws": ">=0.4.27",
|
||||||
"xmlrpc": ">=1.1.0"
|
"xmlrpc": ">=1.1.0",
|
||||||
|
"knex": ">=0.4.11",
|
||||||
|
"mysql": ">=2.0.0-alpha9",
|
||||||
|
"bignumber": ">=1.1.0",
|
||||||
|
"ldapjs": ">=0.6.3",
|
||||||
|
"require-all": ">=0.0.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {},
|
"devDependencies": {},
|
||||||
"optionalDependencies": {},
|
"optionalDependencies": {},
|
||||||
|
@ -136,7 +136,6 @@ Api.err = {
|
|||||||
Api.prototype.checkPermission = function (session, permission)
|
Api.prototype.checkPermission = function (session, permission)
|
||||||
{
|
{
|
||||||
// @todo Handle token permission.
|
// @todo Handle token permission.
|
||||||
|
|
||||||
var user_id = session.get('user_id');
|
var user_id = session.get('user_id');
|
||||||
|
|
||||||
if (undefined === user_id)
|
if (undefined === user_id)
|
||||||
@ -151,6 +150,9 @@ Api.prototype.checkPermission = function (session, permission)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return this.xo.users.first(user_id).then(function (user) {
|
return this.xo.users.first(user_id).then(function (user) {
|
||||||
|
if (!user) {
|
||||||
|
console.log("Api.checkPermission: XO.users.first returned empty result. user_id: %s", user_id);
|
||||||
|
} else
|
||||||
if (!user.hasPermission(permission))
|
if (!user.hasPermission(permission))
|
||||||
{
|
{
|
||||||
throw Api.err.UNAUTHORIZED;
|
throw Api.err.UNAUTHORIZED;
|
||||||
|
223
src/collection/mysql.js
Normal file
223
src/collection/mysql.js
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
/*
|
||||||
|
* MySQL collection
|
||||||
|
* Copyright (C) 2013 Martin Dobrev <martin.dobrev@unixsol.co.uk>
|
||||||
|
* UNIXSOL LTD, registered company in UK and Wales
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @autor: Martin Dobrev <martin.dobrev@unixsol.co.uk>
|
||||||
|
**/
|
||||||
|
|
||||||
|
var _ = require('underscore');
|
||||||
|
var Q = require('q');
|
||||||
|
|
||||||
|
function MySQL(options, models)
|
||||||
|
{
|
||||||
|
if (!options)
|
||||||
|
{
|
||||||
|
options = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!options.uri)
|
||||||
|
{
|
||||||
|
throw 'MySQL missing option: uri';
|
||||||
|
}
|
||||||
|
|
||||||
|
_.defaults(options, {
|
||||||
|
'indexes': [],
|
||||||
|
});
|
||||||
|
|
||||||
|
MySQL.super_.call(this, models);
|
||||||
|
|
||||||
|
this.uri = options.uri;
|
||||||
|
this.indexes = options.indexes;
|
||||||
|
this.prefix = options.prefix;
|
||||||
|
}
|
||||||
|
require('util').inherits(MySQL, require('../collection'));
|
||||||
|
|
||||||
|
// Private methods
|
||||||
|
MySQL.prototype._extract = function (ids)
|
||||||
|
{
|
||||||
|
var knex = require('knex').knex;
|
||||||
|
|
||||||
|
// @todo make it global
|
||||||
|
var perms = {
|
||||||
|
0: 'none',
|
||||||
|
1: 'read',
|
||||||
|
2: 'write',
|
||||||
|
3: 'admin',
|
||||||
|
};
|
||||||
|
|
||||||
|
var promises = [];
|
||||||
|
|
||||||
|
_.each(ids, function (id) {
|
||||||
|
promises.push(knex('users').where('email', id).andWhere('active', 1).select('password', 'email', 'permissions').then(function (model)
|
||||||
|
{
|
||||||
|
if (_.isEmpty(model))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// Return the model
|
||||||
|
var result =
|
||||||
|
{
|
||||||
|
id: id,
|
||||||
|
email: model[0].email,
|
||||||
|
pw_hash: model[0].password,
|
||||||
|
permission: perms[model[0].permissions],
|
||||||
|
};
|
||||||
|
return result;
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
return Q.all(promises).then(function (models) {
|
||||||
|
return _.filter(models, function (model) {
|
||||||
|
return (null !== model);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
MySQL.prototype._get = function (properties)
|
||||||
|
{
|
||||||
|
var knex = require('knex').knex;
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
if (_.isEmpty(properties))
|
||||||
|
{
|
||||||
|
return knex('users').select('email').then(function (ids) {
|
||||||
|
var result = [];
|
||||||
|
for (var i=0, n=ids.length; i<n; i++)
|
||||||
|
{
|
||||||
|
result.push(ids[i].email);
|
||||||
|
}
|
||||||
|
return self._extract(result);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Special treatment for 'id'.
|
||||||
|
var id = properties.id;
|
||||||
|
delete properties.id;
|
||||||
|
|
||||||
|
// Special case where we only match against id.
|
||||||
|
if (_.isEmpty(properties))
|
||||||
|
{
|
||||||
|
return this._extract([id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
var indexes = this.indexes;
|
||||||
|
var unfit = _.difference(_.keys(properties), indexes);
|
||||||
|
if (0 !== unfit.length)
|
||||||
|
{
|
||||||
|
throw 'not indexed fields: '+ unfit.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
var keys = _.map(properties, function (value, index) {
|
||||||
|
return [value];
|
||||||
|
});
|
||||||
|
|
||||||
|
return knex('users').where('email', keys).andWhere('active', 1).select('email').then(function (ids) {
|
||||||
|
if (undefined !== id)
|
||||||
|
{
|
||||||
|
if (!_.contains(ids, id.email))
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
ids = [id];
|
||||||
|
}
|
||||||
|
|
||||||
|
return self._extract([ids[0].email]);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
MySQL.prototype._add = function (models, options)
|
||||||
|
{
|
||||||
|
// @todo Temporary mesure, implement “set()” instead.
|
||||||
|
var replace = !!(options && options.replace);
|
||||||
|
|
||||||
|
var knex = require('knex').knex;
|
||||||
|
var indexes = this.indexes;
|
||||||
|
|
||||||
|
var promises = [];
|
||||||
|
|
||||||
|
// @todo dirty
|
||||||
|
var perms = {
|
||||||
|
'none': 0,
|
||||||
|
'read': 1,
|
||||||
|
'write': 2,
|
||||||
|
'admin': 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
_.each(models, function (model) {
|
||||||
|
var promise;
|
||||||
|
|
||||||
|
// Extend the schema adding missing values
|
||||||
|
var tday = new Date().toISOString().replace(/T/, ' ').replace(/\..+/, ''); // @todo: use of nodejs library maybe?!
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
email: model.email,
|
||||||
|
password: model.pw_hash,
|
||||||
|
permissions: perms[model.permission],
|
||||||
|
username: model.email,
|
||||||
|
created: tday,
|
||||||
|
lastlogin: '0000-00-00 00:00:00',
|
||||||
|
active: 1,
|
||||||
|
activationtoken: null
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log(data);
|
||||||
|
|
||||||
|
if (!replace) {
|
||||||
|
promises.push(knex('users').insert(data));
|
||||||
|
} else {
|
||||||
|
promises.push(knex('users').where('email', model.email).update(data));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return Q.all(promises);
|
||||||
|
};
|
||||||
|
|
||||||
|
MySQL.prototype._remove = function (ids)
|
||||||
|
{
|
||||||
|
var knex = require('knex').knex;
|
||||||
|
var prefix = this.prefix;
|
||||||
|
|
||||||
|
var promises = [];
|
||||||
|
|
||||||
|
var keys = [];
|
||||||
|
for (var i = 0, n = ids.length; i < n; ++i)
|
||||||
|
{
|
||||||
|
keys.push(ids[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(keys);
|
||||||
|
console.log(ids);
|
||||||
|
|
||||||
|
// @todo Handle indexes.
|
||||||
|
//promises.push(knex('users').whereIn('email', keys).del());
|
||||||
|
|
||||||
|
promises.push(true);
|
||||||
|
|
||||||
|
return Q.all(promises);
|
||||||
|
};
|
||||||
|
|
||||||
|
MySQL.prototype._update = function (models)
|
||||||
|
{
|
||||||
|
console.info('Not yet implemented: _update');
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
MySQL.extend = require('extendable');
|
||||||
|
module.exports = MySQL;
|
@ -68,7 +68,6 @@ Redis.prototype._extract = function (ids) {
|
|||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mix the identifier in.
|
// Mix the identifier in.
|
||||||
model.id = id;
|
model.id = id;
|
||||||
return model;
|
return model;
|
||||||
@ -92,6 +91,8 @@ Redis.prototype._add = function (models, options) {
|
|||||||
|
|
||||||
var promises = [];
|
var promises = [];
|
||||||
|
|
||||||
|
console.log(models);
|
||||||
|
|
||||||
_.each(models, function (model) {
|
_.each(models, function (model) {
|
||||||
var promise;
|
var promise;
|
||||||
|
|
||||||
@ -194,7 +195,7 @@ Redis.prototype._get = function (properties) {
|
|||||||
|
|
||||||
ids = [id];
|
ids = [id];
|
||||||
}
|
}
|
||||||
|
console.log(ids);
|
||||||
return self._extract(ids);
|
return self._extract(ids);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -16,7 +16,6 @@ var http_servers = [];
|
|||||||
|
|
||||||
|
|
||||||
// Modified by Martin Dobrev @ 2013-10-22
|
// Modified by Martin Dobrev @ 2013-10-22
|
||||||
var mysql = require('mysql');
|
|
||||||
var ldap = require('ldapjs');
|
var ldap = require('ldapjs');
|
||||||
var Knex = require('knex');
|
var Knex = require('knex');
|
||||||
ldap.Attribute.settings.guid_format = ldap.GUID_FORMAT_B;
|
ldap.Attribute.settings.guid_format = ldap.GUID_FORMAT_B;
|
||||||
@ -475,6 +474,6 @@ xo.on('started', function () {
|
|||||||
|
|
||||||
console.warn('[Warning] No users, creating “admin@admin.net” with password “admin”');
|
console.warn('[Warning] No users, creating “admin@admin.net” with password “admin”');
|
||||||
|
|
||||||
//return xo.users.create('admin@admin.net', 'admin', 'admin');
|
return xo.users.create('admin@admin.net', 'admin', 'admin');
|
||||||
}).done();
|
}).done();
|
||||||
});
|
});
|
||||||
|
@ -245,7 +245,7 @@ Xo.prototype.start = function (cfg) {
|
|||||||
'indexes': ['user_id'],
|
'indexes': ['user_id'],
|
||||||
});
|
});
|
||||||
xo.users = new Users({
|
xo.users = new Users({
|
||||||
//'connection': redis,
|
'connection': redis,
|
||||||
'prefix' : 'xo:user',
|
'prefix' : 'xo:user',
|
||||||
'uri' : cfg.get('mysql', 'uri'),
|
'uri' : cfg.get('mysql', 'uri'),
|
||||||
'indexes' : ['email'],
|
'indexes' : ['email'],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user