Users must also linked to their groups.

This commit is contained in:
Julien Fontanet 2015-05-28 20:35:24 +02:00
parent 621e8e89a5
commit cbd0b9db1d
5 changed files with 61 additions and 11 deletions

View File

@ -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) {

View File

@ -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 = []
}
})

View File

@ -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
}
}

View File

@ -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') {

View File

@ -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)
])
}
// -----------------------------------------------------------------