diff --git a/api/controllers/list.js b/api/controllers/list.js index 1992f25..297a71a 100644 --- a/api/controllers/list.js +++ b/api/controllers/list.js @@ -11,13 +11,9 @@ module.exports = function(store) { const query = _.merge({}, req.query, { roles: req.identity.user.roles, }); - let result = await store.list(query); - - if (req.query.role) { - const requiredUserRoles = mercutio(req.query.role); - result = result.filter(user => mercutio(user.roles).isAny(requiredUserRoles)); - } + const requiredUserRoles = mercutio(req.identity.user.roles); + result = result.filter(user => mercutio(requiredUserRoles).isAny(user.roles)); return res.success(result); } catch (e) { diff --git a/store/query/list.js b/store/query/list.js index 78c9e53..baab94b 100644 --- a/store/query/list.js +++ b/store/query/list.js @@ -30,24 +30,23 @@ function gteQuery(gteObject = {}) { return _.mapValues(gteObject, value => ({ $gte: value })); } -function roleQuery(roles) { - if (!roles) return {}; - - const m = mercutio(roles); - - if (m.is('member@/')) return {}; - +function roleQuery(requestingUserRoles, explicitRoles) { + if (!requestingUserRoles) return {}; + const m = mercutio(requestingUserRoles); const scopeQuery = m .rationalize() .toArray() - .filter(role => ['*', 'admin', 'member'].includes(role.role)) - .map(role => ({ scope: new RegExp(`^${role.scope}`, 'i') })); - + .filter(role => ['*', 'member'].includes(role.role)) + .map(role => ({ scope: new RegExp(`${role.scope}`, 'i') })); const publicQuery = [{ scope: 'public' }]; - const fullOrQuery = publicQuery.concat(scopeQuery); - const query = { roles: { $elemMatch: { $or: fullOrQuery } } }; - return query; + const explicitQuery = (Array.isArray(explicitRoles) ? explicitRoles : ((explicitRoles && [explicitRoles]) || [])) + .map(r => (r.indexOf('@') === -1 ? ({ role: r }) : ({ role: r.split('@')[0], scope: r.split('@')[1] }))); + + const fullOrQuery = { $or: publicQuery.concat(scopeQuery) }; + const elementQuery = explicitQuery.length > 0 ? { $and: [explicitQuery[0]] } : fullOrQuery; + + return { roles: { $elemMatch: elementQuery } }; } function findQuery(query) { @@ -57,7 +56,7 @@ function findQuery(query) { inQuery(query.in), lteQuery(query.lte), gteQuery(query.gte), - roleQuery(query.roles) + roleQuery(query.roles, query.role) ); } @@ -75,7 +74,6 @@ function limitQuery(query) { module.exports = function(query = {}) { const q = this.find(findQuery(query)); - if ('sort' in query) q.sort(sortQuery(query)); if ('limit' in query) q.limit(limitQuery(query)); if ('skip' in query) q.skip(skipQuery(query));