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
Fix function_clause exception on invalid DB security objects #1770
Fix function_clause exception on invalid DB security objects #1770
Conversation
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.
Your tests are broken. You can easily check this by changing any assertion to invalid and see that tests still pass. In general it's a good practice to start writing tests from a fallen state to be sure you actually have them testing something.
The issue here is that all ?_
macro return test objects, i.e. functions and you are overwrapping your tests with ?_test
, so you have functions, that return function that return functions. Naturally that tests nothing.
- Remove all
?_test
wrappers from your tests. - Don't mix
?_
and?
macro in a same test, as your are doing inshould_return_error_for_security_object_with_incorrect_roles
for example, this is incorrect by definition. - Change all the assertion to
?_
ones and return them as a list at the end of your function Instantiators where you have multiple assertions.
Also the test names are exceeding 80 chars. We are usually more relaxed on that in the tests, but it'd be good if you can rename security_object
to sec_obj
, that doesn't change clarity of the test naming much, but making code length more reasonable.
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.
A good fix for a real issue. Requires a bit different approach, but overall - good job. Really appreciate the added tests.
{ok, Status, _, RespBody} = test_request:put(SecurityUrl, [?CONTENT_JSON, ?AUTH], Body), | ||
?_assertEqual(500, Status), | ||
ResultJson = ?JSON_DECODE(RespBody), | ||
?assertMatch({[ |
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.
Use ?_ assertEqual
here, you are not checking guarded pattern, but objects equality.
{ok, Status, _, RespBody} = test_request:put(SecurityUrl, [?CONTENT_JSON, ?AUTH], Body), | ||
?_assertEqual(500, Status), | ||
ResultJson = ?JSON_DECODE(RespBody), | ||
?assertMatch({[ |
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.
Same as above
{ok, Status, _, RespBody} = test_request:put(SecurityUrl, [?CONTENT_JSON, ?AUTH], Body), | ||
?_assertEqual(500, Status), | ||
ResultJson = ?JSON_DECODE(RespBody), | ||
?assertMatch({[ |
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.
Same as above
src/couch/src/couch_db.erl
Outdated
@@ -730,12 +730,22 @@ validate_security_object(SecProps) -> | |||
% we fallback to readers here for backwards compatibility | |||
Members = couch_util:get_value(<<"members">>, SecProps, | |||
couch_util:get_value(<<"readers">>, SecProps, {[]})), | |||
ok = validate_names_and_roles(Admins), | |||
ok = validate_names_and_roles(Members), | |||
case Admins of |
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 inefficient way to go about this, you are essentially splitting validation logic in two places instead of fixing it in the dedicated validator.
Better (and shorter) approach would be to add a "catch all" validator function to raise errors, like this:
@@ -759,6 +749,8 @@ validate_names_and_roles(Props) when is_list(Props) ->
_ -> throw("roles must be a JSON list of strings")
end,
ok.
+validate_names_and_roles(_) ->
+ throw("members must be a JSON list of strings").
One more thing - can you please change your commit message (and PR titile) to something more descriptive? It'll read really cryptic to people out of context when merged. Something like a title of the original issue - "Fix function_clause exception on invalid DB security objects" or similar? |
Hi @eiri Could you help me review again if you have a free time, I updated the codes according to your comments, thank you for your time. |
generally, looks better after adding @eiri 's comments. Just minor comments, there are still some lines longer than 80 characters. |
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.
Almost there, but some tests still need fixing for return of multiple assertion and usage of Equal
vs Match
Hi @eiri could you help review again? thanks. |
3b10fc8
to
fa45642
Compare
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.
Looks good now. Needs squashing before merging, obviously.
@wenli200133 Please edit the description so it says "Closes #1384" so the ticket auto-closes when this merges. Thank you for a great PR! @jiangphcn You can go ahead and merge this on @wenli200133 's behalf. Be sure #1384 gets closed. |
fa45642
to
2e52cb5
Compare
- fix function_clause error on invalid DB security objects when the request body of PUT db/_security endpoint is not a correct json format Closes apache#1384
2e52cb5
to
fcb272e
Compare
@wohali sure, just rebased and merged this PR. Looks that #1384 is auto-closed. @wenli200133 thanks for your great work. |
Overview
This PR will fix function_clause error on invalid DB security objects.
for example when the request body of PUT db/_security endpoint is not a correct json format, if you check the log file you will find the function_clause error.
after fix it,
function_clause
error full stack trace will disappeared instead ofTesting recommendations
case
curl -i -X PUT http://localhost:5984/test/_security -u "adm:pass" -H 'accept: application/json' -d '{"members":["foo"]}'
check logs:
return
{"error":"error","reason":"no_majority"}
curl -i -X PUT http://localhost:15984/test/_security -u "adm:pass" -H 'accept: application/json' -d '{"members":{"names": ["user1","user2"],"roles": "developers"}}'
check log:
return
{"error":"error","reason":"no_majority"}
curl -i -X PUT http://localhost:5984/test/_security -u "adm:pass" -H 'accept: application/json' -d '{"members":{"names": ["user1","user2"],"roles": ["developers"]}}'
return
{"ok":true}
curl -i -X PUT http://localhost:5984/test/_security -u "adm:pass" -H 'accept: application/json' -d '{"admins":{"roles":["admins"],"names":["foo"]},"members":{"names": ["user1","user2"],"roles": ["developers"]}}'
return
{"ok":true}
Related Issues or Pull Requests
#1384
Checklist