api: fix access to private Xo properties.

This commit is contained in:
Julien Fontanet 2016-02-17 11:02:55 +01:00
parent 6f0cda34b4
commit c2f7a2620c
5 changed files with 53 additions and 44 deletions

View File

@ -21,6 +21,17 @@ import {
// ===================================================================
const PERMISSIONS = {
none: 0,
read: 1,
write: 2,
admin: 3
}
const hasPermission = (user, permission) => (
PERMISSIONS[user.permission] >= PERMISSIONS[permission]
)
// FIXME: this function is specific to XO and should not be defined in
// this file.
function checkPermission (method) {
@ -43,7 +54,7 @@ function checkPermission (method) {
return
}
if (!user.hasPermission(permission)) {
if (!hasPermission(user, permission)) {
throw new Unauthorized()
}
}
@ -79,7 +90,7 @@ function resolveParams (method, params) {
throw new Unauthorized()
}
const userId = user.get('id')
const userId = user.id
// Do not alter the original object.
params = { ...params }
@ -240,9 +251,9 @@ export default class Api {
// FIXME: too coupled with XO.
// Fetch and inject the current user.
const userId = session.get('user_id', undefined)
context.user = userId && await context._getUser(userId)
context.user = userId && await context.getUser(userId)
const userName = context.user
? context.user.get('email')
? context.user.email
: '(unknown user)'
try {

View File

@ -27,7 +27,7 @@ delete_.params = {
// -------------------------------------------------------------------
export async function getAll () {
return await this._groups.get()
return await this.getAllGroups()
}
getAll.description = 'returns all the existing group'

View File

@ -45,7 +45,7 @@ delete_.params = {
// collection.
export async function getAll () {
// Retrieves the users.
const users = await this._users.get()
const users = await this.getAllUsers()
// Filters out private properties.
return mapToArray(users, this.getUserPublicProperties)

View File

@ -1,31 +1,10 @@
import { hash } from 'hashy'
import Collection from '../collection/redis'
import Model from '../model'
import { forEach } from '../utils'
// ===================================================================
const PERMISSIONS = {
none: 0,
read: 1,
write: 2,
admin: 3
}
// ===================================================================
export default class User extends Model {
hasPermission (permission) {
return PERMISSIONS[this.get('permission')] >= PERMISSIONS[permission]
}
setPassword (password) {
return hash(password).then(hash => {
return this.set('pw_hash', hash)
})
}
}
export default class User extends Model {}
User.prototype.default = {
permission: 'none'
@ -44,21 +23,12 @@ export class Users extends Collection {
throw new Error(`the user ${email} already exists`)
}
// Password is a special case.
const password = properties.password
delete properties.password
// Adds the email to the user's properties.
properties.email = email
// Create the user object.
const user = new User(properties)
// Sets the password if any.
if (password != null) {
await user.setPassword(password)
}
// Adds the user to the collection.
return await this.add(user)
}

View File

@ -1,6 +1,7 @@
import filter from 'lodash.filter'
import includes from 'lodash.includes'
import {
hash,
needsRehash,
verify
} from 'hashy'
@ -65,7 +66,11 @@ export default class {
// -----------------------------------------------------------------
async createUser (email, properties) {
async createUser (email, { password, ...properties }) {
if (password) {
properties.pw_hash = await hash(password)
}
// TODO: use plain objects
const user = await this._users.create(email, properties)
@ -95,16 +100,31 @@ export default class {
})
}
async updateUser (id, {email, password, permission}) {
const user = await this._getUser(id)
async updateUser (id, {
// TODO: remove
email,
if (email) user.set('email', email)
if (permission) user.set('permission', permission)
name = email,
password,
permission
}) {
const user = await this.getUser(id)
if (name) {
user.name = name
}
if (permission) {
user.permission = permission
}
if (password) {
await user.setPassword(password)
user.pw_hash = await hash(password)
}
await this._users.save(user.properties)
// TODO: remove
user.email = user.name
delete user.name
await this._users.save(user)
}
// Merge this method in getUser() when plain objects.
@ -129,6 +149,10 @@ export default class {
return user
}
async getAllUsers () {
return this._users.get()
}
async getUserByName (username, returnNullIfMissing) {
// TODO: change `email` by `username`.
const user = await this._users.first({ email: username })
@ -227,6 +251,10 @@ export default class {
return group.properties
}
async getAllGroups () {
return this._groups.get()
}
async addUserToGroup (userId, groupId) {
const [user, group] = await Promise.all([
this.getUser(userId),