-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Mango match_failures/2 function
#6080
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
base: main
Are you sure you want to change the base?
Changes from all commits
483b24c
9a8a10c
a9656d6
8fed785
2f37649
6f2dbab
0542d23
44e17fa
c7d7aa0
734dc8d
91b2a0b
4fdeb7e
9e15759
e908e68
c2d56e2
910ee4a
200cbda
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -46,7 +46,12 @@ set_timeout(Pid, TimeOut) when is_integer(TimeOut), TimeOut > 0 -> | |
| gen_server:call(Pid, {set_timeout, TimeOut}). | ||
|
|
||
| prompt(Pid, Data) -> | ||
| gen_server:call(Pid, {prompt, Data}). | ||
| case gen_server:call(Pid, {prompt, Data}) of | ||
| {error, Error} -> | ||
| throw(Error); | ||
| Other -> | ||
| Other | ||
| end. | ||
|
|
||
| init(_) -> | ||
| {ok, #st{}}. | ||
|
|
@@ -95,6 +100,21 @@ handle_call({prompt, [<<"nouveau_index_doc">>, Doc]}, _From, St) -> | |
| Else | ||
| end, | ||
| {reply, Vals, St}; | ||
| handle_call({prompt, [<<"validate_fun">>, Selector0 | _Rest]}, _From, St) -> | ||
| try mango_selector:normalize(Selector0) of | ||
| Selector -> | ||
| case validate_vdu(Selector) of | ||
| ok -> {reply, true, St}; | ||
| Error -> {reply, {error, Error}, St} | ||
| end | ||
| catch | ||
| throw:{mango_error, mango_selector, {invalid_operator, Op}} -> | ||
| Msg = io_lib:format("invalid operator: ~p", [Op]), | ||
| {reply, {error, {compilation_error, Msg}}, St}; | ||
| throw:{mango_error, mango_util, {invalid_field_name, Field}} -> | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wonder if this will catch all possible mango_error errors. What about So we don't have to worry about every single corner case here
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This results in responses containing literal Erlang values, which I'd rather avoid. I'm not sure how else to write a generic error formatting block that does not have this problem. |
||
| Msg = io_lib:format("invalid field name: ~p", [Field]), | ||
| {reply, {error, {compilation_error, Msg}}, St} | ||
| end; | ||
| handle_call({prompt, [<<"ddoc">>, <<"new">>, DDocId, {DDoc}]}, _From, St) -> | ||
| NewSt = | ||
| case couch_util:get_value(<<"validate_doc_update">>, DDoc) of | ||
|
|
@@ -112,18 +132,39 @@ handle_call({prompt, [<<"ddoc">>, DDocId, [<<"validate_doc_update">>], Args]}, _ | |
| Msg = [<<"validate_doc_update">>, DDocId], | ||
| {stop, {invalid_call, Msg}, {invalid_call, Msg}, St}; | ||
| Selector -> | ||
| [NewDoc, OldDoc, _Ctx, _SecObj] = Args, | ||
| Struct = {[{<<"newDoc">>, NewDoc}, {<<"oldDoc">>, OldDoc}]}, | ||
| Reply = | ||
| case mango_selector:match(Selector, Struct) of | ||
| true -> true; | ||
| _ -> {[{<<"forbidden">>, <<"document is not valid">>}]} | ||
| end, | ||
| {reply, Reply, St} | ||
| case validate_vdu(Selector) of | ||
| {_, Error} -> | ||
| {stop, {invalid_call, Error}, {invalid_call, Error}, St}; | ||
| ok -> | ||
| [NewDoc, OldDoc, _Ctx, _SecObj] = Args, | ||
| Struct = | ||
| case OldDoc of | ||
| null -> {[{<<"newDoc">>, NewDoc}]}; | ||
| Doc -> {[{<<"newDoc">>, NewDoc}, {<<"oldDoc">>, Doc}]} | ||
| end, | ||
| Reply = | ||
| case mango_selector:match_failures(Selector, Struct) of | ||
| [] -> | ||
| true; | ||
| Failures -> | ||
| {[{<<"forbidden">>, {[{<<"failures">>, Failures}]}}]} | ||
| end, | ||
| {reply, Reply, St} | ||
| end | ||
| end; | ||
| handle_call(Msg, _From, St) -> | ||
| {stop, {invalid_call, Msg}, {invalid_call, Msg}, St}. | ||
|
|
||
| validate_vdu(VDU) -> | ||
| case mango_selector:has_allowed_fields(VDU, [<<"newDoc">>, <<"oldDoc">>]) of | ||
| true -> | ||
| ok; | ||
| false -> | ||
| Msg = | ||
| <<"'validate_doc_update' may only contain 'newDoc' and 'oldDoc' as top-level fields">>, | ||
| {compilation_error, Msg} | ||
| end. | ||
|
|
||
| handle_cast(garbage_collect, St) -> | ||
| garbage_collect(), | ||
| {noreply, St}; | ||
|
|
||
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.
As discussed in slack let's always validate mango VDUs to remove a footgun from the 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.
I've just amended things so that Mango VDUs are always validated.