Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
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
510 changes: 187 additions & 323 deletions dist/kuzzle.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions 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.

112 changes: 26 additions & 86 deletions src/security/kuzzleProfile.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
var
KuzzleSecurityDocument = require('./kuzzleSecurityDocument'),
KuzzleRole = require('./kuzzleRole');
KuzzleSecurityDocument = require('./kuzzleSecurityDocument');

function KuzzleProfile(kuzzleSecurity, id, content) {

Expand All @@ -17,17 +16,6 @@ function KuzzleProfile(kuzzleSecurity, id, content) {
}
});

// 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, {
Expand Down Expand Up @@ -60,8 +48,8 @@ KuzzleProfile.prototype.save = function (options, cb) {
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 (!this.content.policies) {
throw new Error('Argument "policies" is mandatory in a profile. This argument contains an array of objects.');
}

if (options && cb === undefined && typeof options === 'function') {
Expand All @@ -86,89 +74,49 @@ KuzzleProfile.prototype.save = function (options, cb) {


/**
* Add a role in the roles list
* @param {KuzzleRole|string} role - can be an instance of KuzzleRole or an id in string
* Add a policy in the policies list
* @param {Object} role - must be an object containing at least a "roleId" member which must be a string.
Copy link

@ballinette ballinette Jul 19, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpicking: the param name is "policy" and not "role"

*
* @returns {KuzzleProfile} this
*/
KuzzleProfile.prototype.addRole = function (role) {
KuzzleProfile.prototype.addPolicy = function (policy) {

if (typeof role !== 'string' && !(role instanceof KuzzleRole)) {
throw new Error('Parameter "roles" must be a KuzzleRole or a id string');
if (typeof policy !== 'object' || typeof policy.roleId !== 'string') {
throw new Error('Parameter "policies" must be an object containing at least a "roleId" member which must be a string.');
}

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

this.content.roles.push(role);
this.content.policies.push(policy);

return this;
};

/**
* Set roles list
* @param {Array} roles - can be an array of KuzzleRole or an array of string
* Set policies list
* @param {Array} policies - must be an array of objects containing at least a "roleId" member which must be a string
*
* @returns {KuzzleProfile} this
*/
KuzzleProfile.prototype.setRoles = function (roles) {
KuzzleProfile.prototype.setPolicies = function (policies) {

if (!Array.isArray(roles)) {
throw new Error('Parameter "roles" must be an array of KuzzleRole or an array of string');
if (!Array.isArray(policies)) {
throw new Error('Parameter "policies" must be an array of objects containing at least a "roleId" member which must be a 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');
policies.map(function (policy) {
if (typeof policy !== 'object' || typeof policy.roleId !== 'string') {
throw new Error('Parameter "policies" must be an array of objects containing at least a "roleId" member which must be a string');
}
});

this.content.roles = roles;
this.content.policies = policies;

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, self.id, {roles: response.result.hits}));
});
};

/**
* Serialize this object into a JSON object
*
Expand All @@ -183,29 +131,21 @@ KuzzleProfile.prototype.serialize = function () {
}

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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

condition useless, because in any case, we return the same data ;)

return data;
}

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

return role;
});

return data;
};

/**
* Returns the list of roles associated to this profile.
* Each role element can be either a string or a KuzzleRole object
* Returns the list of policies associated to this profile.
* Each policy element is an array of objects containing at least a "roleId" member which must be a string
*
* @return {object} an array of roles
* @return {object} an array of policies
*/
KuzzleProfile.prototype.getRoles = function () {
return this.content.roles;
KuzzleProfile.prototype.getPolicies = function () {
return this.content.policies;
};

module.exports = KuzzleProfile;
103 changes: 12 additions & 91 deletions src/security/kuzzleSecurity.js
Original file line number Diff line number Diff line change
Expand Up @@ -252,92 +252,51 @@ KuzzleSecurity.prototype.roleFactory = function(id, content) {
/**
* Get a specific profile from kuzzle
*
* Takes an optional argument object with the following property:
* - hydrate (boolean, default: true):
* if is set to false, return a list id in role instead of KuzzleRole.
*
* @param {string} id
* @param {object} [options] - (optional) arguments
* @param {responseCallback} cb - returns Kuzzle's response
*/
KuzzleSecurity.prototype.getProfile = function (id, options, cb) {
KuzzleSecurity.prototype.getProfile = function (id, cb) {
var
data,
self = this,
hydrate = true;
self = this;

if (!id || typeof id !== 'string') {
throw new Error('Id parameter is mandatory for getProfile function');
}

if (!cb && typeof options === 'function') {
cb = options;
options = null;
}
else if (options.hydrate !== undefined) {
hydrate = options.hydrate;
}

data = {_id: id};

self.kuzzle.callbackRequired('KuzzleSecurity.getProfile', cb);

self.kuzzle.query(this.buildQueryArgs('getProfile'), data, options, function (error, response) {
self.kuzzle.query(this.buildQueryArgs('getProfile'), data, {}, function (error, response) {
if (error) {
return cb(error);
}

if (!hydrate) {
response.result._source.roles = response.result._source.roles.map(function (role) {
var formattedRole = {_id: role._id};
if (role._source.restrictedTo !== undefined) {
formattedRole.restrictedTo = role._source.restrictedTo;
}
if (role._source.allowInternalIndex !== undefined) {
formattedRole.allowInternalIndex = role._source.allowInternalIndex;
}

return formattedRole;
});
}

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

/**
* Executes a search on profiles according to a filter
*
* Takes an optional argument object with the following property:
* - hydrate (boolean, default: true):
* if is set to false, return a list id in role instead of KuzzleRole.
* Because hydrate need to fetch all related KuzzleRole object, leave hydrate to true will have a performance cost
*
* /!\ There is a small delay between profile creation and their existence in our persistent search layer,
* usually a couple of seconds.
* That means that a profile that was just been created won’t be returned by this function.
*
* @param {Object} filters - this object can contains an array `roles` with a list of roles id, a integer `from` and a integer `size`
* @param {object} [options] - (optional) arguments
* @param {responseCallback} [cb] - returns Kuzzle's response
*/
KuzzleSecurity.prototype.searchProfiles = function (filters, options, cb) {
KuzzleSecurity.prototype.searchProfiles = function (filters, cb) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here: please reintroduce the options argument.

var
self = this;

filters.hydrate = true;

if (!cb && typeof options === 'function') {
cb = options;
options = null;
}
else if (options.hydrate !== undefined) {
filters.hydrate = options.hydrate;
}

self.kuzzle.callbackRequired('KuzzleSecurity.searchProfiles', cb);

self.kuzzle.query(this.buildQueryArgs('searchProfiles'), {body: filters}, options, function (error, response) {
self.kuzzle.query(this.buildQueryArgs('searchProfiles'), {body: filters}, {}, function (error, response) {
var documents;

if (error) {
Expand Down Expand Up @@ -439,13 +398,7 @@ KuzzleSecurity.prototype.updateProfile = function (id, content, options, cb) {
}

Object.keys(res.result._source).forEach(function (property) {
if (property !== 'roles') {
updatedContent[property] = res.result._source[property];
}
});

updatedContent.roles = res.result._source.roles.map(function (role) {
return role._id;
updatedContent[property] = res.result._source[property];
});

cb(null, new KuzzleProfile(self, res.result._id, updatedContent));
Expand Down Expand Up @@ -503,82 +456,50 @@ KuzzleSecurity.prototype.profileFactory = function(id, content) {
/**
* Get a specific user from kuzzle using its unique ID
*
* Takes an optional argument object with the following property:
* - hydrate (boolean, default: true):
* if is set to false, return a list id in role instead of KuzzleRole.
*
* @param {string} id
* @param {object} [options] - (optional) arguments
* @param {responseCallback} cb - returns Kuzzle's response
*/
KuzzleSecurity.prototype.getUser = function (id, options, cb) {
KuzzleSecurity.prototype.getUser = function (id, cb) {
Copy link
Contributor

@scottinet scottinet Jul 19, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The options parameter should stay: it may contain a queued option, handling offline mode.
See: http://kuzzle.io/sdk-documentation/#getuser

var
data,
self = this,
hydrate = true;
self = this;

if (!id || typeof id !== 'string') {
throw new Error('Id parameter is mandatory for getUser function');
}

if (!cb && typeof options === 'function') {
cb = options;
options = null;
}
else if (options.hydrate !== undefined) {
hydrate = options.hydrate;
}

data = {_id: id};

self.kuzzle.callbackRequired('KuzzleSecurity.getUser', cb);

self.kuzzle.query(this.buildQueryArgs('getUser'), data, options, function (err, response) {
self.kuzzle.query(this.buildQueryArgs('getUser'), data, {}, function (err, response) {
if (err) {
return cb(err);
}

if (!hydrate) {
response.result._source.profile = response.result._source.profile._id;
}

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

/**
* Executes a search on user according to a filter
*
* Takes an optional argument object with the following property:
* - hydrate (boolean, default: true):
* if is set to false, return a list id in role instead of KuzzleRole.
* Because hydrate need to fetch all related KuzzleRole object, leave hydrate to true will have a performance cost
*
* /!\ There is a small delay between user creation and their existence in our persistent search layer,
* usually a couple of seconds.
* That means that a user that was just been created won’t be returned by this function.
*
* @param {Object} filters - same filters as documents filters
* @param {object} [options] - (optional) arguments
* @param {responseCallback} [cb] - returns Kuzzle's response
*/
KuzzleSecurity.prototype.searchUsers = function (filters, options, cb) {
KuzzleSecurity.prototype.searchUsers = function (filters, cb) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here: please reintroduce the options argument.

var
self = this;

filters.hydrate = true;

if (!cb && typeof options === 'function') {
cb = options;
options = null;
}
else if (options.hydrate !== undefined) {
filters.hydrate = options.hydrate;
}

self.kuzzle.callbackRequired('KuzzleSecurity.searchUsers', cb);

self.kuzzle.query(this.buildQueryArgs('searchUsers'), {body: filters}, options, function (error, response) {
self.kuzzle.query(this.buildQueryArgs('searchUsers'), {body: filters}, {}, function (error, response) {
var documents;

if (error) {
Expand Down Expand Up @@ -797,7 +718,7 @@ KuzzleSecurity.prototype.getUserRights = function (userId, options, cb) {
self = this;

if (!userId || typeof userId !== 'string') {
throw new Error('userId parameter is mandatory for isActionAllowed function');
throw new Error('userId parameter is mandatory for getUserRights function');
}

if (!cb && typeof options === 'function') {
Expand Down
Loading