Skip to content
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

Increase strictness / correctness of URI micro form validation #18

Conversation

PLeVasseur
Copy link
Contributor

@PLeVasseur PLeVasseur commented Dec 25, 2023

Added helper functions on UResource and UEntity

During serialization of UURI to micro form, perform checks on

  1. existence of UResource/UEntity
  2. existence of id
  3. id not overflowing allotted bits
  4. existence of major version
  5. major version not overflowing allotted bits

Also updated is_micro_form() to account for being false in the case that the ids are outside of expected range of 16 bits or UEntity major version it outside of expected range of 8 bits.

Note: Based on an issue I raised over here.

@PLeVasseur PLeVasseur changed the title Add check on UResource and UEntity IDs not overflowing the 16 bits allotted Add check on UResource and UEntity IDs not overflowing the 16 bits allotted, UEntity major version not overflowing 8 bits allotted Dec 25, 2023
@PLeVasseur PLeVasseur changed the title Add check on UResource and UEntity IDs not overflowing the 16 bits allotted, UEntity major version not overflowing 8 bits allotted Increase strictness / correctness of URI micro form validation Dec 26, 2023
@stevenhartley
Copy link

@AnotherDaniel & @sophokles73 please comment on this PR

@PLeVasseur PLeVasseur force-pushed the feature/protobuf_id_u32_to_micro_serializer_u16_checks branch from d1fec48 to ca15f01 Compare January 9, 2024 02:57
Copy link
Contributor

@sophokles73 sophokles73 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not go through all of your changes. In general, I do not like the overall idea of having all the serialization and validation logic in different modules. FMPOV all of this functionality should be in the corresponding structs (thus improving cohesion) and the constraints on the fields should then be checked during creation (or deserialization) and serialization of the entities.

src/proto/uprotocol/uauthority.rs Outdated Show resolved Hide resolved
src/proto/uprotocol/uauthority.rs Outdated Show resolved Hide resolved
src/proto/uprotocol/uauthority.rs Outdated Show resolved Hide resolved
src/proto/uprotocol/uauthority.rs Outdated Show resolved Hide resolved
@PLeVasseur
Copy link
Contributor Author

PLeVasseur commented Jan 11, 2024

I did not go through all of your changes. In general, I do not like the overall idea of having all the serialization and validation logic in different modules. FMPOV all of this functionality should be in the corresponding structs (thus improving cohesion) and the constraints on the fields should then be checked during creation (or deserialization) and serialization of the entities.

First off, thanks for the review! My first Rust code review 😄 Gonna have to get this framed.

Lemme try to break the review down to make sure I'm groking it.

In general, I do not like the overall idea of having all the serialization and validation logic in different modules. FMPOV all of this functionality should be in the corresponding structs (thus improving cohesion)

Let me try to reword it to see if I get it:

UriValidator::validate_micro_form() will continue to exist (since it has to get called by uP-L1 and uP-L2 APIs to validate the UURIs prior to their use), however...

its form will change to from the currently, quite large function to a much smaller one along the lines of...

    #[allow(clippy::missing_panics_doc)]
    pub fn validate_micro_form(uri: &UUri) -> Result<(), ValidationError> {
        if Self::is_empty(uri) {
            Err(ValidationError::new("URI is empty"))?;
        }

       if !UEntity::validate_micro_form(uri) {
            Err(ValidationError::new("UEntity invalid for micro form"))?;
       }

       if !UAuthority::validate_micro_form(uri) {
            Err(ValidationError::new("UAuthority invalid for micro form"))?;
       }

       if !UResource::validate_micro_form(uri) {
            Err(ValidationError::new("UResource invalid for micro form"))?;
       }

       Ok(())
    }

Keep in mind I'm just riffing here, so I'd probably have the validate_micro_form() function on each of UEntity, UResource, and UAuthority return a ValidationError so that I can bubble up / concatenate the reason for the error like I mentioned wanting to do over in this comment.

and the constraints on the fields should then be checked during creation (or deserialization) and serialization of the entities.

Agree on the serialization bit -- the MicroUriSerializer::serialize() function would call UriValidator::validate_micro_form(), as would any implementer of uTransport if e.g. calling send().

As for on creation, I honestly went back and forth in my mind about it. Because the structs are exposed thru the .proto files with the fields as pub, they could be arbitrarily constructed in any way by a user of the SDK which would not pass validation. There's really no way with our current APIs to prevent that from happening (I have thoughts on this for another day that this is not great, but this is already getting long).

I do like the idea of having builders which can help create the individual pieces in a known good fashion. I began work on, but put down for now, some work on that over in this branch. If you think the idea has some legs, I'll work on it a bit more.

TL;DR: Your suggestion is to move the logic for validation of whether the UURI satisfies micro form for a particular struct (e.g. UEntity), into that struct's impl and clean up validate_micro_form() to be the shorter version I wrote above.

@AnotherDaniel
Copy link
Contributor

I do like the idea of having builders which can help create the individual pieces in a known good fashion. I began work on, but put down for now, some work on that over in this branch. If you think the idea has some legs, I'll work on it a bit more.

This ties in with this discussion, about reintroducing Builders for the core .proto objects. I'd be for that... and then the protoc-generated rust code could be made non-public. Thus we would hide the dependency to that code, and potential vagaries of protoc etc from the SDK users.
Thoughts?

@PLeVasseur
Copy link
Contributor Author

PLeVasseur commented Jan 12, 2024

I like that idea a lot!

@AnotherDaniel, @sophokles73 -- where would make sense to go from here? Close this PR and pick back up my other PR with this kinda functionality also included?

Or change this PR to kinda do what Kai was suggesting and then tackle the builders in a new PR?

@sophokles73
Copy link
Contributor

@PLeVasseur FMPOV we should start with moving the checks into the corresponding structs.
Then, in an additional PR, you could start adding builders ...

@PLeVasseur PLeVasseur force-pushed the feature/protobuf_id_u32_to_micro_serializer_u16_checks branch from ca15f01 to e7425f9 Compare January 23, 2024 19:05
@PLeVasseur
Copy link
Contributor Author

@sophokles73 -- could you take a look again to see I addressed your concern? I broke the validation logic for micro URI form up into the impls of the constituent members of a UUri.

src/proto/uprotocol/uauthority.rs Outdated Show resolved Hide resolved
src/proto/uprotocol/uentity.rs Outdated Show resolved Hide resolved
src/proto/uprotocol/uresource.rs Outdated Show resolved Hide resolved
@PLeVasseur PLeVasseur force-pushed the feature/protobuf_id_u32_to_micro_serializer_u16_checks branch 2 times, most recently from f298fce to daba0f5 Compare January 29, 2024 18:07
@PLeVasseur
Copy link
Contributor Author

@sophokles73 -- I rebased & updated to bail out of the validate_micro_form() functions on first fail of validation.

Could you take a look again?

@PLeVasseur PLeVasseur force-pushed the feature/protobuf_id_u32_to_micro_serializer_u16_checks branch from a5c0aa6 to 5f2a278 Compare February 7, 2024 21:34
Copy link
Contributor

@sophokles73 sophokles73 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You got the idea 👍
I made some suggestions for improvement. WDYT?

src/uri/serializer/microuriserializer.rs Show resolved Hide resolved
src/uri/serializer/microuriserializer.rs Outdated Show resolved Hide resolved
@PLeVasseur
Copy link
Contributor Author

You got the idea 👍 I made some suggestions for improvement. WDYT?

Alrighty, I updated based on your suggestions. Can you take another look?

Cargo.toml Show resolved Hide resolved
src/uri/validator/urivalidator.rs Outdated Show resolved Hide resolved
src/uri/validator/urivalidator.rs Show resolved Hide resolved
src/uri/serializer/microuriserializer.rs Show resolved Hide resolved
@PLeVasseur
Copy link
Contributor Author

Hey folks -- sorry I missed that the up-core-api change got merged fixing the ambiguity around id/ip. I'll have a go at updating this to unblock #28

cc @sophokles73 @AnotherDaniel

@PLeVasseur PLeVasseur force-pushed the feature/protobuf_id_u32_to_micro_serializer_u16_checks branch from 3d0f30f to 044a3f6 Compare February 14, 2024 16:59
…heir ids set when attempting to serialize to micro UURI. Should add in some unit tests too, to check this path.
PLeVasseur and others added 21 commits February 14, 2024 14:03
… fail, when either of UResource or UEntity ids do not fit within the allotted 16 bits.
…Need to revisit the MicroUriSerializer impl to see if there's any checks I can remove regarding UAuthority IP and ID and UEntity and UResource ID.
…has. Helps Pete be able to build behind corporate proxy :)
…UAuthority, updates to add check on bytes after serialization.
@PLeVasseur PLeVasseur force-pushed the feature/protobuf_id_u32_to_micro_serializer_u16_checks branch from efb53e2 to e02f64c Compare February 14, 2024 19:10
@PLeVasseur
Copy link
Contributor Author

Hey folks -- sorry I missed that the up-core-api change got merged fixing the ambiguity around id/ip. I'll have a go at updating this to unblock #28

Even better, @AnotherDaniel's PR got in first! Makes life easy.

Could you take a look and see if I hit the points we discussed the other day @sophokles73?

.gitignore Outdated
.vscode/
.idea/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe you can add an EOL here?

@@ -268,7 +327,7 @@ mod tests {
assert!(uprotocol_uri.is_err());
assert_eq!(
uprotocol_uri.unwrap_err().to_string(),
"URI is empty or not in micro form"
"Failed to validate micro URI format: URI is empty"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather remove these literal comparisons as they are hard to maintain. In particular, when not using constants for the messages ...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I could go through this file and remove these.

To a degree I was following along with the rest of the unit tests.

You want me to remove them all from this file?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FMPOV we (i.e. you ;-)) should

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, went ahead and did that, could you take another look?

Copy link
Contributor

@sophokles73 sophokles73 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@sophokles73
Copy link
Contributor

@stevenhartley can you approve the workflow run so that we can see that the changes pass all checks? And then merge ...

@stevenhartley stevenhartley merged commit da51048 into eclipse-uprotocol:main Feb 16, 2024
3 checks passed
@PLeVasseur PLeVasseur deleted the feature/protobuf_id_u32_to_micro_serializer_u16_checks branch February 16, 2024 14:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants