Implements groups.

This commit is contained in:
Julien Fontanet 2015-05-28 19:26:16 +02:00
parent c9eca5ec7e
commit 621e8e89a5
3 changed files with 124 additions and 20 deletions

View File

@ -1,7 +1,5 @@
// FIXME All methods are to implement
export async function create ({name}) {
return Date.now() // Dummy id
return (await this.createGroup({name})).id
}
create.description = 'creates a new group'
@ -14,7 +12,7 @@ create.params = {
// Deletes an existing group.
async function delete_ ({id}) {
return true
await this.deleteGroup(id)
}
// delete is not a valid identifier.
@ -29,18 +27,7 @@ delete_.params = {
// -------------------------------------------------------------------
export async function getAll () {
return [
{
id: 'G1',
name: 'Groupe 1',
users: []
},
{
id: 'G2',
name: 'Groupe 2',
users: []
}
]
return await this._groups.get()
}
delete_.description = 'returns all the existing group'
@ -53,7 +40,7 @@ delete_.params = {
// sets group.users with an array of user ids
export async function setUsers ({id, userIds}) {
return true
await this.setGroupUsers(id, userIds)
}
setUsers.description = 'sets the users belonging to a group'
@ -67,7 +54,7 @@ setUsers.params = {
// adds the user id to group.users
export async function addUser ({id, userId}) {
return true
await this.addUserToGroup(userId, id)
}
addUser.description = 'adds a user to a group'
@ -81,7 +68,7 @@ addUser.params = {
// remove the user id from group.users
export async function removeUser ({id, userId}) {
return true
await this.removeUserFromGroup(userId, id)
}
// -------------------------------------------------------------------
@ -96,7 +83,7 @@ removeUser.params = {
// -------------------------------------------------------------------
export async function set ({id, name}) {
return true
await this.updateGroup(id, {name})
}
set.description = 'changes the properties of an existing group'

47
src/models/group.js Normal file
View File

@ -0,0 +1,47 @@
import forEach from 'lodash.foreach'
import Collection from '../collection/redis'
import Model from '../model'
// ===================================================================
export default class Group extends Model {}
// ===================================================================
export class Groups extends Collection {
get Model () {
return Group
}
create (name) {
return this.add(new Group({
name,
users: '[]'
}))
}
async save (group) {
// Serializes.
group.users = JSON.stringify(group.users)
return await this.update(group)
}
async get (properties) {
const groups = await super.get(properties)
// Deserializes.
forEach(groups, group => {
const {users} = group
try {
group.users = JSON.parse(users)
} catch (error) {
console.warn('cannot parse group.user:', users)
group.users = []
}
})
return groups
}
}

View File

@ -1,4 +1,5 @@
import Bluebird from 'bluebird'
import filter from 'lodash.filter'
import forEach from 'lodash.foreach'
import includes from 'lodash.includes'
import isEmpty from 'lodash.isempty'
@ -18,6 +19,7 @@ import Xapi from './xapi'
import {Acls} from './models/acl'
import {autobind} from './decorators'
import {generateToken} from './utils'
import {Groups} from './models/group'
import {JsonRpcError, NoSuchObject, Unauthorized} from './api-errors'
import {ModelAlreadyExists} from './collection'
import {Servers} from './models/server'
@ -31,6 +33,12 @@ class NoSuchAuthenticationToken extends NoSuchObject {
}
}
class NoSuchGroup extends NoSuchObject {
constructor (id) {
super(id, 'group')
}
}
class NoSuchUser extends NoSuchObject {
constructor (id) {
super(id, 'user')
@ -56,6 +64,7 @@ export default class Xo extends EventEmitter {
//
// TODO: remove and put everything in the `_objects` collection.
this._acls = null
this._groups = null
this._servers = null
this._tokens = null
this._users = null
@ -90,6 +99,10 @@ export default class Xo extends EventEmitter {
prefix: 'xo:acl',
indexes: ['subject', 'object']
})
this._groups = new Groups({
connection: redis,
prefix: 'xo:group'
})
this._servers = new Servers({
connection: redis,
prefix: 'xo:server',
@ -211,6 +224,63 @@ export default class Xo extends EventEmitter {
// -----------------------------------------------------------------
async createGroup ({name}) {
// TODO: use plain objects.
const group = (await this._groups.create(name)).properties
group.users = JSON.parse(group.users)
return group
}
async deleteGroup (id) {
if (!await this._groups.remove(id)) {
throw new NoSuchGroup(id)
}
}
async updateGroup (id, {name}) {
const group = await this.getGroup(id)
if (name) group.name = name
await this._groups.save(group)
}
async getGroup (id) {
const group = (await this._groups.first(id)).properties
if (!group) {
throw new NoSuchGroup(id)
}
return group
}
async addUserToGroup (userId, groupId) {
const group = await this.getGroup(groupId)
group.users.push(userId)
await this._groupss.save(group)
}
async removeUserFromGroup (userId, groupId) {
const group = await this.getGroup(groupId)
group.users = filter(group.users, id => id !== userId)
await this._groups.save(group)
}
async setGroupUsers (groupId, userIds) {
const group = await this.getGroup(groupId)
group.users = userIds
await this._groups.save(group)
}
// -----------------------------------------------------------------
async createAuthenticationToken ({userId}) {
// TODO: use plain objects
const token = await this._tokens.generate(userId)