From cbd0b9db1d7a7effbef1600163337b3852069614 Mon Sep 17 00:00:00 2001 From: Julien Fontanet Date: Thu, 28 May 2015 20:35:24 +0200 Subject: [PATCH] Users must also linked to their groups. --- src/index.js | 2 +- src/models/group.js | 2 +- src/models/user.js | 25 +++++++++++++++++++++++++ src/utils.js | 1 + src/xo.js | 42 +++++++++++++++++++++++++++++++++--------- 5 files changed, 61 insertions(+), 11 deletions(-) diff --git a/src/index.js b/src/index.js index e31b3ebe1..f89213417 100644 --- a/src/index.js +++ b/src/index.js @@ -210,7 +210,7 @@ const apiHelpers = { // Handles both properties and wrapped models. const properties = user.properties || user - return pick(properties, 'id', 'email', 'permission') + return pick(properties, 'id', 'email', 'groups', 'permission') }, getServerPublicProperties (server) { diff --git a/src/models/group.js b/src/models/group.js index 8a7467104..372cb6ce7 100644 --- a/src/models/group.js +++ b/src/models/group.js @@ -37,7 +37,7 @@ export class Groups extends Collection { try { group.users = JSON.parse(users) } catch (error) { - console.warn('cannot parse group.user:', users) + console.warn('cannot parse group.users:', users) group.users = [] } }) diff --git a/src/models/user.js b/src/models/user.js index 207ad1c39..c74631155 100644 --- a/src/models/user.js +++ b/src/models/user.js @@ -1,3 +1,4 @@ +import forEach from 'lodash.foreach' import {hash, needsRehash, verify} from 'hashy' import Collection from '../collection/redis' @@ -65,4 +66,28 @@ export class Users extends Collection { return this.add(user) } + + async save (user) { + // Serializes. + user.groups = JSON.stringify(user.groups) + + return await this.update(user) + } + + async get (properties) { + const users = await super.get(properties) + + // Deserializes + forEach(users, user => { + const {groups} = user + try { + user.groups = groups ? JSON.parse(groups) : [] + } catch (_) { + console.warn('cannot parse user.groups:', groups) + user.groups = [] + } + }) + + return users + } } diff --git a/src/utils.js b/src/utils.js index 07171b690..031e54ee0 100644 --- a/src/utils.js +++ b/src/utils.js @@ -95,6 +95,7 @@ export const pFinally = (promise, cb) => { } // ------------------------------------------------------------------- + export function parseSize (size) { let bytes = humanFormat.parse.raw(size, { scale: 'binary' }) if (bytes.unit && bytes.unit !== 'B') { diff --git a/src/xo.js b/src/xo.js index 5c0e724bd..737855875 100644 --- a/src/xo.js +++ b/src/xo.js @@ -4,6 +4,7 @@ import forEach from 'lodash.foreach' import includes from 'lodash.includes' import isEmpty from 'lodash.isempty' import isString from 'lodash.isstring' +import map from 'lodash.map' import proxyRequest from 'proxy-http-request' import XoCollection from 'xo-collection' import XoUniqueIndex from 'xo-collection/unique-index' @@ -203,7 +204,7 @@ export default class Xo extends EventEmitter { if (password) user.setPassword(password) if (permission) user.set('permission', permission) - await this._users.update(user) + await this._users.save(user.properties) } // Merge this method in getUser() when plain objects. @@ -247,36 +248,59 @@ export default class Xo extends EventEmitter { } async getGroup (id) { - const group = (await this._groups.first(id)).properties + const group = (await this._groups.first(id)) if (!group) { throw new NoSuchGroup(id) } - return group + return group.properties } async addUserToGroup (userId, groupId) { - const group = await this.getGroup(groupId) + const [user, group] = await Promise.all([ + this.getUser(userId), + this.getGroup(groupId) + ]) + user.groups.push(groupId) group.users.push(userId) - await this._groupss.save(group) + await Promise.all([ + this._users.save(user), + this._groups.save(group) + ]) } async removeUserFromGroup (userId, groupId) { - const group = await this.getGroup(groupId) + const [user, group] = await Promise.all([ + this.getUser(userId), + this.getGroup(groupId) + ]) + user.groups = filter(user.groups, id => id !== groupId) group.users = filter(group.users, id => id !== userId) - await this._groups.save(group) + await Promise.all([ + this._users.save(user), + this._groups.save(group) + ]) } async setGroupUsers (groupId, userIds) { - const group = await this.getGroup(groupId) + const [users, group] = await Promise.all([ + Promise.all(map(userIds, this.getUser, this)), + this.getGroup(groupId) + ]) + forEach(users, user => { + user.groups.push(groupId) + }) group.users = userIds - await this._groups.save(group) + await Promise.all([ + Promise.all(map(users, this._users.save, this._users)), + this._groups.save(group) + ]) } // -----------------------------------------------------------------