lorawan-stack
lorawan-stack copied to clipboard
EUI with `null` value converted to zeros on gateway update
Summary
Error found internally where trying to update a gateway's EUI with a body that explicitly passes null
as its EUI value yields a EUI filled with zeros instead of generating an empty string.
This causes trouble as when unsetting a gateway EUI via a http request with this specific value, it either returns a 409 conflict or sets its value to "0000000000000000"
(depending if a gateway with that EUI already exists).
{
"gateway": {
"ids": {
"eui": null
}
},
"field_mask": {
"paths": [
"ids.eui"
]
}
}
Could not generate this error attempting to do this via a gRPC request.
Steps to Reproduce
- Login
- Create a gtw with an EUI containing only zeros
- Create a gtw with an EUI
- Update the second gateway and pass
null
in theids.eui
field
Examples done with CLI And curl:
# first gateway
ttn-lw-cli gtw create gtw-0 --user-id admin --gateway-eui "0000000000000000" --frequency-plan-id "EU_863_870_TTN"
# second gateway
ttn-lw-cli gtw create gtw-1 --user-id admin --gateway-eui "0000000000000001" --frequency-plan-id "EU_863_870_TTN"
# use curl to provide the body with `gateways.ids.eui` as `null`
curl -X PUT \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <token>" \
-d '{ "gateway": { "ids": { "eui": null }}, "field_mask": { "paths": [ "ids.eui" ] } }' \
"http://localhost:1885/api/v3/gateways/gtw-1"
# Returns
{"code":6,"message":"error:pkg/util/store:eui_taken (EUI already taken)","details":[{"@type":"type.googleapis.com/ttn.lorawan.v3.ErrorDetails","namespace":"pkg/util/store","name":"eui_taken","message_format":"EUI already taken","correlation_id":"e792040de0f64cb3b150c2d167d5eaff","cause":{"namespace":"pkg/util/store","name":"already_exists","message_format":"already exists","correlation_id":"8485628b99cf4cf2890e1b02f36487e8","code":6},"code":6}]}%
Current Result
It works only if not providing null
as the value of the field.
curl -X PUT \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <token>" \
-d '{ "field_mask": { "paths": [ "ids.eui" ] } }' \
"http://localhost:1885/api/v3/gateways/gtw-1"
# response
{"ids":{"gateway_id":"gtw-1"},"created_at":"2024-05-17T14:17:00.408035Z","updated_at":"2024-05-17T14:24:24.632342Z"}%
Expected Result
It should set the EUI to an empty value when passing the null
as a value.
Relevant Logs
No response
URL
No response
Deployment
The Things Stack Open Source (self-hosted)
The Things Stack Version
v3.30-dev
Client Name and Version
No response
Other Information
No response
Proposed Fix
Investigate the unmarshalNBytes
in pkg/types/types.go
to validate why this conversion happens.
Contributing
- [X] I can help by doing more research.
- [X] I can help by implementing a fix after the proposal above is approved.
- [X] I can help by testing the fix before it's released.
Validation
- [X] The fix is tested in a staging environment.
- [X] The fix is documented in The Things Stack Documentation
Code of Conduct
- [X] I agree to follow TTN's Community Code of Conduct.