-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Per document access control #4673
base: main
Are you sure you want to change the base?
Conversation
3b15aae
to
c51a1eb
Compare
9e26c53
to
5ec411a
Compare
src/chttpd/src/chttpd_view.erl
Outdated
% {ok, Resp} = fabric:query_view(Db, Options, DDoc, ViewName, | ||
% fun view_cb/2, VAcc, Args), | ||
% {ok, Resp#vacc.resp}. | ||
% % TODO: This might just be a debugging leftover, we might be able | ||
% % to undo this by just returning {ok, Resp#vacc.resp} | ||
% % However, this *might* be here because we need to handle | ||
% % errors here now, because access might tell us to. | ||
% case fabric:query_view(Db, Options, DDoc, ViewName, | ||
% fun view_cb/2, VAcc, Args) of | ||
% {ok, Resp} -> | ||
% {ok, Resp#vacc.resp}; | ||
% {error, Error} -> | ||
% throw(Error) | ||
% end. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this be removed, or is more work needed here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I pointed out some compiler warnings that I saw when poking around.
I also noticed a few TODO and other comments that I'm guessing need to still be addressed or removed?
Currently this PR has no description, and I wonder if you could add some high level documentation of how this works, or maybe link to an architectural document?
sorry for not making this explicit, but if you follow the superseded PRs backwards, you should find more commentary that I didn’t think was necessary to repeat here. The main design is outlined here: apache/couchdb-documentation#424 |
thanks and yes, these are all minor or already resolved, but not cleaned up yet. None of these should be major changes. I wanted to get a review on the general shape before getting everything into perfect shape. Also thanks for the compiler warnings pass, I’ll get to those. |
This reverts commit 576c90f.
b1e1899
to
072d467
Compare
latest push fixes compiler warnings noted by Jay |
@@ -1034,6 +1034,8 @@ error_info({bad_request, Error, Reason}) -> | |||
{400, couch_util:to_binary(Error), couch_util:to_binary(Reason)}; | |||
error_info({query_parse_error, Reason}) -> | |||
{400, <<"query_parse_error">>, Reason}; | |||
error_info(access) -> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is too generic for me, per_doc_access_denied
or something similarly descriptive please.
Roles = couch_util:get_value(<<"roles">>, UserProps, []), | ||
case lists:member(<<"_admin">>, Roles) of | ||
true -> Roles; | ||
_ -> Roles ++ [<<"_users">>] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[<<"_users">> | Roles]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we’ve been over. this before, I want to explicitly append the new role to the array so any tests and code that expect their existing roles in the beginning just keep working and you OK’d that reasoning on an older PR :)
@@ -199,7 +206,7 @@ proxy_auth_user(Req) -> | |||
Roles = | |||
case header_value(Req, XHeaderRoles) of | |||
undefined -> []; | |||
Else -> re:split(Else, "\\s*,\\s*", [trim, {return, binary}]) | |||
Else -> re:split(Else, "\\s*,\\s*", [trim, {return, binary}]) ++ [<<"_users">>] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[<<"_users">> | re:split ...]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
c.f. #4673 (comment)
@@ -248,7 +255,7 @@ jwt_authentication_handler(Req) -> | |||
Req#httpd{ | |||
user_ctx = #user_ctx{ | |||
name = User, | |||
roles = Roles | |||
roles = Roles ++ [<<"_users">>] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[<<"_users">> | Roles]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
c.f. #4673 (comment)
{Body} -> | ||
Access = couch_util:get_value(<<"_access">>, Body), | ||
apply_open_options(Db, {ok, Doc#doc{access = Access}}, Options); | ||
_Else -> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will do a full review tomorrow but I am uncomfortable with a giant _Else
here. what else would we get except a body? undefined
or nil
? let's be specific in couch_db.erl.
I am coming back to couchdb updating an old application that has already implemented the above (per-document access, with linux-like permissions like owner/read/write access, even per-field protection on the doc). I personally don't like this feature and wouldn't like to see it merged:
I would be in favour of document lifecycle plugins/hooks, where we can implement this feature and many others. |
I think secondary indexes would need to be updated to support this for it to have the desired effect (restricting a user's visibility of a database to a subset). I'm sure we've not done that work for dreyfus/clouseau (and I definitely haven't for nouveau). I share your concern that this implementation might not meet everyone's needs, but that's not necessarily a blocker. It just needs to meet a significant number of people's needs. I don't find "I believe CouchDB should stick to being a database." compelling. Other databases have richer permissions and access controls that we currently do, they're not off-topic. The PR changes a number of internal records which prevents a smooth upgrade of existing CouchDB clusters and is blocked from merging until that is fixed imo, so there's time to think. We currently have |
We implemented a fork of CouchDB with exactly that (a Perhaps the requirement to present a subset of the database needs to be revisited? If this requirement were to be dropped, things might become easier. |
@arturog thank you for your comments, practical experience with variants of the same idea here are invaluable.
I’m 100% on board with you here. That’s why this is designed as an opt-in feature. If you have a system on top of CouchSB that works for you, that will just continue to work. To avoid confusion, let me restate the design goal of this PR: “make the db-per-user pattern obsolete”. It is specifically not “support arbitrary ACLs inside a database”. With that out of the way, the scope of the potential work for a complete solution here is very big. In accordance with common wisdom: to built a complex system that works, one first has to build a simple system that works. The current PR reflects the simplest system that I could think of to get the minimal functionality working that satisfies the design goal. To this end, per-user design docs (and all associated indexes of any form, JS, Mango, Search/Nouveau) are not supported. A future version of this PR however can use the new
Maybe you want a different feature? You are stating the explicit design goal of this PR that should be dropped. |
first draft implementation of apache/couchdb-documentation#424 (which is itself a little out of date, but it paints the big picture).