-
Notifications
You must be signed in to change notification settings - Fork 299
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
Add FieldIsZero, validate non-zero fields in middleware #3647
Add FieldIsZero, validate non-zero fields in middleware #3647
Conversation
}); ok { | ||
isZero = v.FieldIsZero | ||
} else { | ||
// TODO: Use reflection to validate a (sub-)field by path |
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.
Do we want to do this?
If so, I will file an issue and add a reference according to the guidelines, otherwise I will remove this else
Ideally these methods should be generated, but that should be done after #2798 is solved
36f79a2
to
973a717
Compare
// TODO: Use reflection to validate a subfield by path | ||
break |
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.
So if msg
is of type EndDevice
, and FieldIsZero
is implemented on MACState
, it doesn't get called unless EndDevice
implements some umbrella FieldIsZero
? I think it makes sense to check the nearest FieldIsZero
of sp
here.
If we don't do this, this FieldIsZero
support on msg
should be done before the loop.
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 think it makes sense to check the nearest FieldIsZero of sp here.
- Since these methods will be auto-generated(see Add FieldIsZero, validate non-zero fields in middleware #3647 (comment)), all relevant messages will have this implemented
- We do not have a generic way to access value of type
T
under arbitrary patha.b.c
, so that is not possible unless we loop over all field tree in the struct using reflection and I don't think we should do that for all RPCs on each call. FieldIsZero
check is done inside the loop to avoid unnecessary type-assert on each RPC. This check is only performed when there's a path, which needs to be zero - there's no reason to checkFieldIsZero
, if we don't need to call it.
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 @johanstokking also wrote, hand-writing those FieldIsZero
funcs is not going to be very maintainable. Can we perhaps generate those funcs?
@htdvisser @johanstokking please see #3647 (comment) I already wrote when opening the PR
|
967afd2
to
033d8bf
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.
In general I'm okay with the current state.
I'm assuming that as long as the struct is part of the test table and the list of all fields is up to date, there's a guard against forgetting the zero checks per field. Right?
Just out of curiosity; why can't we do this with reflection? We would have to look at the request type, traverse the fields recursively, and once the field is found, see which type it is and check if the value is zero.
Yes
|
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.
OK I'm fine with this, thanks for clarifying @rvolosatovs
Summary
In it's current state field mask validation only partially restricts the fields that can be set.
For example if RPC supports paths
A
andA.B
, sending value withA.C
non-empty and field maskA
should result in an error - the RPC implementations currently must perform such checks, but that is error-prone and hard to maintain (in case of NSSet
RPC this is several hundreds lines of checks)- this PR addresses that.An example of real-word case where this is very relevant is key envelopes or MAC state.
Changes
FieldIsZero
onEndDevice
and related messagesFieldIsZero
is implemented for a message and fieldmask is specified - ensure that disallowed fields are zero in the interceptor.Testing
Tested creating a new class C device and sending a bunch of uplinks. Could not test downlink flow, because application downlink is broken cc @adriansmares
Regressions
All clients, which are currently sending invalid messages will be broken - that is expected and desired.
That probably means that CLI should also ensure only the allowed fields are sent. cc @htdvisser
Checklist
README.md
for the chosen target branch.CHANGELOG.md
.CONTRIBUTING.md
, there are no fixup commits left.