Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
cc3bd54
wip - begin security object
Feb 3, 2016
44bf989
add functions signature security
Feb 3, 2016
f4e7013
improve comments in security
Feb 3, 2016
e2c93da
nitpick security/user
Feb 3, 2016
5527125
fix problem implement new security
Feb 3, 2016
f2c4c2a
add queryArgs function in KuzzleSecurity
Feb 3, 2016
addddc3
nitpick security
Feb 3, 2016
548472f
fix passing kuzzle to KuzzleSecurity and KuzzleRole
Feb 4, 2016
f72430b
change KuzzleSecurity enumerable
Feb 4, 2016
b04be8f
Merge remote-tracking branch 'origin/master' into kuz-343-security-ob…
Feb 4, 2016
dcc0d92
add comment in searchRoles
Feb 4, 2016
9d127c3
remove option from searchRoles
Feb 4, 2016
155d322
add comments for functions in kuzzlesecurity
Feb 4, 2016
35c48cb
rename getProfiles getRoles in hydrate
Feb 4, 2016
b9ec616
Merge remote-tracking branch 'origin/master' into kuz-343-security-ob…
Feb 4, 2016
5efdf31
remove return this from hydrate functions
Feb 4, 2016
c318d1b
add KuzzleRole KuzzleProfile KuzzleUser constructors
Feb 4, 2016
d15a4f8
add inherit KuzzleDocumentSecurity
Feb 4, 2016
39236f5
add searchProfile in security
Feb 4, 2016
99c1f8f
add fetchRole
Feb 5, 2016
8cc0f27
Merge branch 'kuz-343-security-object' of github.com:kuzzleio/sdk-jav…
Feb 5, 2016
1d1b843
rename fetch to get in security + blacklist factory security
Feb 5, 2016
7def213
add getProfile into kuzzleSecurity
Feb 5, 2016
b864a9f
Merge branch 'kuz-343-security-object' of https://github.com/kuzzleio…
Feb 5, 2016
9a3397a
add createRole function
Feb 5, 2016
411f8d9
Merge branch 'kuz-343-security-object' of github.com:kuzzleio/sdk-jav…
Feb 5, 2016
f4cb75e
Change getProfile doc
Feb 5, 2016
e1e6943
Merge branch 'kuz-343-security-object' of https://github.com/kuzzleio…
Feb 5, 2016
b57e064
remove version from createRole
Feb 5, 2016
f9ef1bc
change updateIfExist into replaceIfExist in security
Feb 5, 2016
3145499
add kuzzleSecurityDocument:toJSON method & update createProfile & upd…
Feb 5, 2016
e68631f
Merge branch 'kuz-343-security-object' of https://github.com/kuzzleio…
Feb 5, 2016
90a0666
add method save for role
Feb 5, 2016
0146a2f
Merge branch 'kuz-343-security-object' of github.com:kuzzleio/sdk-jav…
Feb 5, 2016
bfe60a6
add tojson to user
Feb 5, 2016
648fc1d
mandatory id in role
Feb 5, 2016
253ccb0
pass kuzzleSecurity to constructor and add deleteRole
Feb 5, 2016
2e67a1d
add deleteProfile and deleteUser
Feb 5, 2016
b2e2f50
add User.save()
Feb 5, 2016
b8ea4c5
fix kuzzleSecurity in kuzzleSecurityDocument constructor
Feb 5, 2016
035f0ee
move hydrate from getUser and getProfile in constructor
Feb 5, 2016
dde2558
nitpick require
Feb 5, 2016
92f9d37
add searchUsers method
Feb 5, 2016
1a7d5b6
update createProfile & createRole + add save & toJson & hydrate on ku…
Feb 5, 2016
d7b3eb9
Merge branch 'kuz-343-security-object' of https://github.com/kuzzleio…
Feb 5, 2016
472e52b
add User.hydrate()
Feb 5, 2016
cd80b24
Merge branch 'kuz-343-security-object' of github.com:kuzzleio/sdk-jav…
Feb 5, 2016
99e0fc2
fix: deleteProfile
Feb 5, 2016
96be80b
add createUser method
Feb 5, 2016
4947b52
move check id on top of constructor KuzzleSecurityDocument
Feb 5, 2016
ec5db08
unit test kuzzleSecurity wip
Feb 5, 2016
5394ebb
add test in security for roles methods
Feb 8, 2016
4093b7c
add functions addRole setRoles addProfile
Feb 8, 2016
252ac80
add unit test user
Feb 8, 2016
8b19cc2
add kuzzleRole tests
Feb 8, 2016
6bef724
unit tests kuzzleProfile
Feb 9, 2016
ccac8c2
add user tests
Feb 9, 2016
b8b7a73
fix eshint
Feb 9, 2016
3a91c1d
fix unit testing
Feb 10, 2016
eeb0ac5
Merge remote-tracking branch 'origin/master' into kuz-343-security-ob…
Feb 10, 2016
ae30fc1
generate after merge
Feb 10, 2016
972577d
Merge remote-tracking branch 'origin/master' into kuz-343-security-ob…
Feb 10, 2016
f670a31
generate after merge
Feb 10, 2016
31ce3da
increase test coverage security
Feb 10, 2016
fa25009
100% test coverage
Feb 10, 2016
5509245
add hydrate parameter in getter
Feb 10, 2016
1d61126
add unit test getProfile/getUser with hydrate false
Feb 10, 2016
a9fae5f
fix call to auth/checkToken not send token
Feb 10, 2016
07e7e01
nitpick
Feb 11, 2016
89b1c8b
add options in security methods
Feb 11, 2016
a449dc1
whoami return KuzzleUser
Feb 11, 2016
8548ffd
fix eslint
Feb 11, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,155 changes: 1,139 additions & 16 deletions dist/kuzzle.js

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion dist/kuzzle.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/kuzzle.min.map

Large diffs are not rendered by default.

38 changes: 25 additions & 13 deletions src/kuzzle.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
var
uuid = require('node-uuid'),
KuzzleDataCollection = require('./kuzzleDataCollection');
KuzzleDataCollection = require('./kuzzleDataCollection'),
KuzzleSecurity = require('./security/kuzzleSecurity'),
KuzzleUser = require('./security/kuzzleUser');

/**
* This is a global callback pattern, called by all asynchronous functions of the Kuzzle object.
Expand All @@ -18,6 +20,7 @@ var
* @param {responseCallback} [cb] - Handles connection response
* @constructor
*/

module.exports = Kuzzle = function (url, options, cb) {
var self = this;

Expand Down Expand Up @@ -111,7 +114,6 @@ module.exports = Kuzzle = function (url, options, cb) {
value: url,
enumerable: true
},
// writable properties
autoQueue: {
value: false,
enumerable: true,
Expand Down Expand Up @@ -219,7 +221,7 @@ module.exports = Kuzzle = function (url, options, cb) {
}
});

/*
/**
* Some methods (mainly read queries) require a callback function. This function exists to avoid repetition of code,
* and is called by these methods
*/
Expand All @@ -231,7 +233,15 @@ module.exports = Kuzzle = function (url, options, cb) {
}
});

/*
/**
* Create an attribute security that embed all methods to manage Role, Profile and User
*/
Object.defineProperty(this, 'security', {
value: new KuzzleSecurity(this),
enumerable: true
});

/**
* Emit an event to all registered listeners
* An event cannot be emitted multiple times before a timeout has been reached.
*/
Expand Down Expand Up @@ -273,7 +283,6 @@ module.exports = Kuzzle = function (url, options, cb) {
});
}

return this;
};


Expand Down Expand Up @@ -504,13 +513,18 @@ Kuzzle.prototype.checkToken = function (token, callback) {
Kuzzle.prototype.whoAmI = function (callback) {
var self = this;

this.callbackRequired('Kuzzle.whoAmI', callback);
self.callbackRequired('Kuzzle.whoAmI', callback);

this.query({controller: 'auth', action: 'getCurrentUser'}, {}, {}, callback);
self.query({controller: 'auth', action: 'getCurrentUser'}, {}, {}, function (err, response) {
if (err) {
return callback(err);
}

callback(null, new KuzzleUser(self.security, response.result._id, response.result._source));
});

return self;
};

/**
* Clean up the queue, ensuring the queryTTL and queryMaxSize properties are respected
*/
Expand Down Expand Up @@ -724,10 +738,9 @@ Kuzzle.prototype.getStatistics = function (timestamp, options, cb) {
*
* @param {string} [index] - The name of the data index containing the data collection
* @param {string} collection - The name of the data collection you want to manipulate
* @param headers {object} [headers] - Common properties for all future write documents queries
* @returns {object} A KuzzleDataCollection instance
*/
Kuzzle.prototype.dataCollectionFactory = function(index, collection, headers) {
Kuzzle.prototype.dataCollectionFactory = function(index, collection) {
this.isValid();

if (arguments.length === 1) {
Expand All @@ -749,7 +762,7 @@ Kuzzle.prototype.dataCollectionFactory = function(index, collection, headers) {
}

if (!this.collections[index][collection]) {
this.collections[index][collection] = new KuzzleDataCollection(this, index, collection, headers);
this.collections[index][collection] = new KuzzleDataCollection(this, index, collection);
}

return this.collections[index][collection];
Expand Down Expand Up @@ -976,7 +989,7 @@ Kuzzle.prototype.query = function (queryArgs, query, options, cb) {
* Do not add the token for the checkToken route, to avoid getting a token error when
* a developer simply wish to verify his token
*/
if (self.jwtToken !== undefined && object.controller !== 'auth' && object.action !== 'checkToken') {
if (self.jwtToken !== undefined && !(object.controller === 'auth' && object.action === 'checkToken')) {
object.headers = object.headers || {};
object.headers.authorization = 'Bearer ' + self.jwtToken;
}
Expand Down Expand Up @@ -1126,7 +1139,6 @@ Kuzzle.prototype.startQueuing = function () {
if (this.state === 'offline' && !this.autoQueue) {
this.queuing = true;
}

return this;
};

Expand Down
1 change: 0 additions & 1 deletion src/kuzzleDataCollection.js
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,6 @@ KuzzleDataCollection.prototype.createDocument = function (id, document, options,
data._id = id;
}

data.persist = true;
data = self.kuzzle.addHeaders(data, self.headers);

if (cb) {
Expand Down
199 changes: 199 additions & 0 deletions src/security/kuzzleProfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
var
KuzzleSecurityDocument = require('./kuzzleSecurityDocument'),
KuzzleRole = require('./kuzzleRole');

function KuzzleProfile(kuzzleSecurity, id, content) {

KuzzleSecurityDocument.call(this, kuzzleSecurity, id, content);

// Define properties
Object.defineProperties(this, {
// private properties
deleteActionName: {
value: 'deleteProfile'
}
});

// Hydrate profile with roles if roles are not only string but objects with `_id` and `_source`
if (content && content.roles) {
content.roles = content.roles.map(function (role) {
if (!role._id || !role._source) {
return role;
}

return new KuzzleRole(kuzzleSecurity, role._id, role._source);
});
}

// promisifying
if (kuzzleSecurity.kuzzle.bluebird) {
return kuzzleSecurity.kuzzle.bluebird.promisifyAll(this, {
suffix: 'Promise',
filter: function (name, func, target, passes) {
var whitelist = ['hydrate', 'save'];

return passes && whitelist.indexOf(name) !== -1;
}
});
}

}

KuzzleProfile.prototype = Object.create(KuzzleSecurityDocument.prototype, {
constructor: {
value: KuzzleProfile
}
});

/**
* Persist to the persistent layer the current profile
*
* @param {object} [options] - Optional parameters
* @param {responseCallback} [cb] - Handles the query response
* @returns {Object} this
*/
KuzzleProfile.prototype.save = function (options, cb) {
var
data,
self = this;

if (!this.content.roles) {
throw new Error('Argument "roles" is mandatory in a profile. This argument contains an array of KuzzleRole or an array of id string');
}

if (options && cb === undefined && typeof options === 'function') {
cb = options;
options = null;
}

data = this.serialize();

self.kuzzle.query(self.kuzzleSecurity.buildQueryArgs('createOrReplaceProfile'), data, options, function (error) {
if (error) {
return cb ? cb(error) : false;
}

if (cb) {
cb(null, self);
}
});

return self;
};


/**
* Add a role in the roles list
* @param {KuzzleRole|string} role - can be an instance of KuzzleRole or an id in string
*
* @returns {KuzzleProfile} this
*/
KuzzleProfile.prototype.addRole = function (role) {

if (typeof role !== 'string' && !(role instanceof KuzzleRole)) {
throw new Error('Parameter "roles" must be a KuzzleRole or a id string');
}

if (!this.content.roles) {
this.content.roles = [];
}

this.content.roles.push(role);

return this;
};

/**
* Set roles list
* @param {Array} roles - can be an array of KuzzleRole or an array of string
*
* @returns {KuzzleProfile} this
*/
KuzzleProfile.prototype.setRoles = function (roles) {

if (!Array.isArray(roles)) {
throw new Error('Parameter "roles" must be an array of KuzzleRole or an array of string');
}

roles.map(function (role) {
if (typeof role !== 'string' && !(role instanceof KuzzleRole)) {
throw new Error('Parameter "roles" must be an array of KuzzleRole or an array of string');
}
});

this.content.roles = roles;

return this;
};


/**
* Hydrate the profile - get real KuzzleRole and not just ids
* Warning: do not try to hydrate a profile with newly added role which is not created in kuzzle
*
* @param {object} [options] - Optional parameters
* @param {responseCallback} [cb] - Handles the query response
*/
KuzzleProfile.prototype.hydrate = function (options, cb) {

var
self = this,
data = {ids: []};

data.ids = this.content.roles.map(function (role) {
if (typeof role === 'string') {
return role;
}

if (role instanceof KuzzleRole) {
return role.id;
}
});

if (options && cb === undefined && typeof options === 'function') {
cb = options;
options = null;
}

self.kuzzle.callbackRequired('KuzzleProfile.hydrate', cb);

self.kuzzle.query(self.kuzzleSecurity.buildQueryArgs('mGetRoles'), {body: data}, options, function (error, response) {
if (error) {
return cb(error);
}

cb(null, new KuzzleProfile(self, response.result._id, response.result._source));
});
};

/**
* Serialize this object into a JSON object
*
* @return {object} JSON object representing this securityDocument
*/
KuzzleProfile.prototype.serialize = function () {
var
data = {};

if (this.id) {
data._id = this.id;
}

data.body = this.content;
if (!data.body.roles || !Array.isArray(data.body.roles)) {
return data;
}

data.body.roles = data.body.roles.map(function(role) {
if (role instanceof KuzzleRole) {
return role.id;
}

return role;
});

return data;
};


module.exports = KuzzleProfile;
66 changes: 66 additions & 0 deletions src/security/kuzzleRole.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
var KuzzleSecurityDocument = require('./kuzzleSecurityDocument');

function KuzzleRole(kuzzleSecurity, id, content) {

KuzzleSecurityDocument.call(this, kuzzleSecurity, id, content);

// Define properties
Object.defineProperties(this, {
// private properties
deleteActionName: {
value: 'deleteRole'
}
});

// promisifying
if (kuzzleSecurity.kuzzle.bluebird) {
return kuzzleSecurity.kuzzle.bluebird.promisifyAll(this, {
suffix: 'Promise',
filter: function (name, func, target, passes) {
var whitelist = ['save'];

return passes && whitelist.indexOf(name) !== -1;
}
});
}

}

KuzzleRole.prototype = Object.create(KuzzleSecurityDocument.prototype, {
constructor: {
value: KuzzleRole
}
});

/**
* Saves this role into Kuzzle.
*
* If this is a new role, this function will create it in Kuzzle.
* Otherwise, this method will replace the latest version of this role in Kuzzle by the current content
* of this object.
*
* @param {object} [options] - Optional parameters
* @param {responseCallback} [cb] - Handles the query response
*/
KuzzleRole.prototype.save = function (options, cb) {
var
data = this.serialize(),
self = this;

if (options && cb === undefined && typeof options === 'function') {
cb = options;
options = null;
}

self.kuzzle.query(this.kuzzleSecurity.buildQueryArgs('createOrReplaceRole'), data, options, function (error) {
if (error) {
return cb ? cb(error) : false;
}

if (cb) {
cb(null, self);
}
});
};

module.exports = KuzzleRole;
Loading