我想到的一种方法是在每次创建新用户时调用的服务器上创建一个设计文档。然后,此函数为新创建的用户创建一个新数据库并将用户名添加到 _security 规则中。
有一个名为couch per user 的插件可以让你做到这一点。安装它,对于 _users 数据库中的每个新user,它将自动为该用户创建一个数据库。
您是对的,_security 文档没有版本控制。但普通文件是。因此,如果将 _security 对象存储为常规的 couchdb 文档,则可以解决复制它们的问题。现在我们需要确保的是,当包含 _security 对象的文档被复制时,它会自动添加到目标数据库的 _security 中。
如果您将验证函数视为“更新前”事件处理程序,那么它们可以用于此任务。我们需要做的是
- 创建一个验证函数来查找包含 _security 对象的文档。
- 一旦找到对象,就向数据库的 _security 字段发出 http 请求,并将对象的内容存储在其中。
- “通过”对象包含 _security,因此它保存在本地数据库中。
现在默认的 javascript 验证函数无法进行 http 调用,因此您需要更改您的 query server。我知道至少 erlang 和 python 查询服务器允许您进行 http 调用。但请先尝试使用您最喜欢的语言的那个。
例子:-
{
_id:adsfasf,
_rev:3-bd25f9790db7a8034d9415da7a4d625,
"type":"security",
_security:
{
"admins": {
"names": [
"superuser"
],
"roles": [
"admins"
]
},
"members": {
"names": [
"user1",
"user2"
],
"roles": [
"developers"
]
}
}
}
}
验证函数
function(newDoc,oldDoc,userCtx,secObj){
if(newDoc.type ==="security"){
//make an http call to db/_security and post the _security field there
}
}
您无需以这种方式收听更改提要。只需使用普通 couchdb 文档和验证功能(在不同的查询服务器中)的组合,您就可以做您想做的事。
性能问题
拥有一个 validate 函数肯定会减慢插入时间,因为它会在插入之前对每个 couchdb 文档进行检查。
Erlang 验证功能将是不同查询服务器中速度最快、资源效率最高的。用 erlang 编写它应该不会太难,因为它只是一个 if 块和对 http 的请求。此示例未经测试,但它应该可以帮助您入门。
fun({N_Doc},_Old_Doc,_User,_Sec)->
case proplists:get_value(<<"type">>,N_Doc) of
<<"_serurity">>->
httpc:request(
post,
{"http://localhost:5984/yourdb/_security",
[],
"application/json",
ejson:encode(proplists:get_value(<<"_security">>))},
[],[]),
1;
<<"some_bad_value">>->
{[{<<"forbidden">>, "Nope this won't do"}]};
_->
1
end
end.
上面的函数只是等待一个“安全”类型的文档,然后将它发送到数据库的 _security 端点。 1 回复意味着一切正常。该文档已经过验证,现在可以存储了。禁止响应不允许存储文档。希望这可以帮助。