Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 16 additions & 36 deletions .github/workflows/check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,7 @@ on:
outputs:
test_results_url:
description: "URL of the test results artifact"
value: ${{ jobs.nextest.outputs.test_results_url }}
doctest_results_url:
description: "URL of the doctest results artifact"
value: ${{ jobs.doctest.outputs.test_results_url }}
value: ${{ jobs.test.outputs.test_results_url }}
workflow_dispatch:

concurrency:
Expand Down Expand Up @@ -120,51 +117,34 @@ jobs:
with:
args: "--cache --max-cache-age 1d --verbose --no-progress --exclude-path './target/' --exclude-path './up-spec/' -- './**/*.md' './**/*.rs' './**/*.adoc'"

nextest:
test:
# Subset of feature-combos, on only one OS - more complete testing in test-featurematrix.yaml
outputs:
test_results_url: ${{ steps.test_results.outputs.artifact-url }}
runs-on: ubuntu-latest
env:
NEXTEST_EXPERIMENTAL_LIBTEST_JSON: 1
strategy:
matrix:
feature-flags: ["", "--no-default-features", "--all-features"]
steps:
- uses: actions/checkout@v4
with:
submodules: "recursive"
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ env.RUST_TOOLCHAIN }}
- uses: Swatinem/rust-cache@v2
# Using nextest because it's faster than built-in test
- uses: taiki-e/install-action@nextest
- name: Run cargo nextest
- name: Run lib tests
run: |
cargo nextest run --message-format libtest-json-plus > testresults.json
mkdir -p ${GITHUB_WORKSPACE}/target
RUSTC_BOOTSTRAP=1 cargo test --no-fail-fast --all-targets ${{ matrix.feature-flags }} -- -Z unstable-options --format junit --report-time > ${GITHUB_WORKSPACE}/target/lib-test-results.xml
- name: Run doc tests
run: |
RUSTC_BOOTSTRAP=1 cargo test --no-fail-fast --doc ${{ matrix.feature-flags }} -- -Z unstable-options --format junit --report-time > ${GITHUB_WORKSPACE}/target/doc-test-results.xml

- name: Upload all-features test results artifact
id: test_results
if: matrix.feature-flags == '--all-features'
uses: actions/upload-artifact@v4
with:
name: test-results
path: testresults.json

doctest:
# Run doctests separately, as nextest doesn't yet (https://github.com/nextest-rs/nextest/issues/16)
outputs:
test_results_url: ${{ steps.doctest_results.outputs.artifact-url }}
runs-on: ubuntu-latest
env:
RUSTDOCFLAGS: -Dwarnings
steps:
- uses: actions/checkout@v4
with:
submodules: "recursive"
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ env.RUST_TOOLCHAIN }}
- name: Run doc tests
run: |
RUSTC_BOOTSTRAP=1 cargo test --doc --all-features -- -Z unstable-options --format json --report-time > doctestresults--all-features.json
- name: Upload doctest results artifact
uses: actions/upload-artifact@v4
with:
name: doctest-results
path: doctestresults--all-features.json
# include all test result files
path: target/*-results.xml
6 changes: 1 addition & 5 deletions .github/workflows/latest-up-spec-compatibility.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,9 @@ jobs:
with:
toolchain: ${{ env.RUST_TOOLCHAIN }}
- uses: Swatinem/rust-cache@v2
- uses: taiki-e/install-action@nextest
- name: Run tests
run: |
# Using nextest because it's faster than built-in test
cargo nextest run --all-features
# but it cannot execute doc tests
cargo test --doc --all-features
cargo test --all-features

# This step will only be run if the tests in the previous step have succeeded.
# In that case, we use the exit code produced by the OFT run as the job's
Expand Down
77 changes: 75 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ zenoh = { version = "1.5.0" }
chrono = "0.4.41"
clap = { version = "4.5.40", features = ["derive"] }
serde_json = "1.0.128"
serial_test = { version = "3.2.0" }
test-case = { version = "3.3" }
tokio = { version = "1.45.1", default-features = false, features = ["rt-multi-thread", "signal"] }
tracing-subscriber = "0.3.19"
Expand Down
15 changes: 9 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,14 @@ Covers:
### Authentication & Authorization
`uman~auth-configuration~1`

The transport provided by this crate can be configured with credentials that the transport will provide to the Zenoh router during connection establishment. A [_username_ and _password_](https://zenoh.io/docs/manual/user-password/) can be specified in the Zenoh config file that is passed into the `UPTransportZenoh::new` function to create a new transport instance.
The transport provided by this crate can be configured with credentials that the transport will provide to the Zenoh router during connection establishment. A [_username_ and _password_](https://zenoh.io/docs/manual/user-password/) can be specified in the Zenoh config file that is passed into the `UPTransportZenohBuilder::with_config_file` function.

Access to resources can be configured in the Zenoh config file by means of [Access Control Lists](https://zenoh.io/docs/manual/access-control/).
Access to resources can be configured in the Zenoh (peer's or router's) config file by means of [Access Control Lists](https://zenoh.io/docs/manual/access-control/).
The [authorization integration tests](./tests/authorization.rs) illustrate, how ACLs can be used to restrict a client's authority to put and subscribe to messages using corresponding rule sets.

Covers:
- `req~utransport-send-error-permission-denied~2`
- `req~utransport-send-prevent-address-spoofing~1`
- `req~utransport-registerlistener-prevent-unauthorized-access~1`

### Maximum number of listeners
`uman~max-listeners-configuration~1`
Expand Down Expand Up @@ -116,15 +118,16 @@ Needs: impl, itest

In general, uProtocol entities are only allowed to send messages on their own behalf. Certain specific uEntities acting as a uProtocol Streamer also need to send messages _on behalf of_ other uEntities in order to fulfill their original purpose of routing messages hence and forth between different transports. Making these authoritzation decisions requires the (proven) establishment of an _identity_ and its _authorities_.

The Zenoh transport delegates all authorization decisions to the Zenoh router that the transport is configured to connect to. For this purpose, the transport supports configuration of credentials which are being used during connection establishment. The Zenoh router uses the provided credentials to establish the client's identity and its associated authorities. Whenever the uEntity sends a message via the router or registers a subscriber for a key pattern, the router verifies, if the client is authorized to publish using the key or receive messages matching the key pattern.
The Zenoh transport delegates all authorization decisions to the Zenoh router (or peer) that the transport is configured to connect to. For this purpose, the transport supports configuration of credentials which are being used during connection establishment. The Zenoh router uses the provided credentials to establish the client's identity and its associated authorities. Whenever the uEntity sends a message via the router or registers a subscriber for a key pattern, the router verifies that the client is authorized to publish using the key or receive messages matching the key pattern.

Rationale:
The Zenoh transport is implemented as a library that is linked to the (custom) code that implements a uEntity's functionality. It is therefore not feasible to perform the authentication and authoritzation within the transport library code, because uEntities can not be forced to actually utilize one of uProtocol's transport libraries but may instead chooose to implement the binding to the transport protocol themselves.

Covers:
- `req~utransport-send-error-permission-denied~2`
- `req~utransport-send-prevent-address-spoofing~1`
- `req~utransport-registerlistener-prevent-unauthorized-access~1`

Needs: impl, utest
Needs: itest

## Change Log

Expand Down
3 changes: 2 additions & 1 deletion src/utransport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use async_trait::async_trait;
use bytes::Bytes;
use protobuf::Message;
use std::sync::Arc;
use tracing::{debug, error};
use tracing::{debug, error, trace};
use up_rust::{
ComparableListener, UAttributes, UAttributesValidators, UCode, UListener, UMessage, UPriority,
UStatus, UTransport, UUri,
Expand Down Expand Up @@ -125,6 +125,7 @@ impl UPTransportZenoh {
// [impl->dsn~up-transport-zenoh-attributes-mapping~1]
.attachment(attachment)
.await
.inspect(|()| trace!("putting message with key: {zenoh_key}"))
.map_err(|e| {
UStatus::fail_with_code(
UCode::INTERNAL,
Expand Down
Loading