Я думаю, что вы ставите телегу впереди лошади.
для моделирования данных, вы должны сначала что теперь ваши вопросы к данным есть. Что касается пользователей, ролей и привилегий связи, вопрос очевиден
Для данного пользователя, каковы привилегии?
Пока привилегии на роль не превышают несколько 100k, ваша ролевая модель должна быть достаточно простым
{
_id: "roleName",
description: "a role",
privileges:[
"someService:someAction:someInstance",
]
},
{
_id: "admin",
description: "Administrator",
privileges:[
"adminService:*:*",
]
}
У нас есть данный пользователь с упрощенной моделью
{
_id: "foo",
roles: ["roleName","admin"]
}
Чтобы получить привилегии для данного пользователя "foo" (который вы загрузили до user
), мы делаем что-то вроде
var user_privileges = db.roles.aggregate([
{ $match:{ _id:{ $in: user.roles} } },
{ $unwind: "$privileges" },
{ $group:{ _id: null, $push:{ "forAllRoles": "$privileges" } }
]}
, который должен привести в результирующий документ, как
{ _id: null, forAllRoles:[
"adminService:*:*",
"someService:someAction:someInstance"
]
}
Проверка разрешения теперь становится легко
var permission_needed = "adminService:*:*"
if(user_privileges.forAllRoles.indexOf(permission_needed) > -1){
console.log("Yay, admin!");
doSomeAdminStuff();
} else {
console.log("Don't you dare again, user!");
}
Поскольку мы LookUp привилегии по roles._id
, который индексируется, агрегация должна быть довольно эффективно, потому что мы ограничиваем документы только очень немногими перед обработкой.
Если вы хотите добавить разрешение на роль, это просто
db.roles.update(
{ _id: "roleName" },
{ $addToSet: { privileges: [ "otherService:*:someInstance" ] } }
)
НТН
Если вам нужно, чтобы проверить это, запрос коллекции перед установкой пользователя. –
@Michelem Это работает, но не эффективно. Это делается на стороне приложения. Для двух операций будут две задержки сети. Будет лучше, если мы сможем выполнить проверку на стороне сервера mongodb. –