Only allow C-S device scopes when the C-S API scope has been requested (#5215)
This commit is contained in:
@@ -72,6 +72,7 @@ Make sure your code adheres to our Rust and TypeScript code style by running:
|
||||
|
||||
- `cargo +nightly fmt` (with the nightly toolchain installed)
|
||||
- `npm run format` in the `frontend` directory
|
||||
- `make fmt` in the `policies` directory (if changed)
|
||||
|
||||
When updating SQL queries in the `crates/storage-pg/` crate, you may need to update the `sqlx` introspection data. To do this, make sure to install `cargo-sqlx` (`cargo install sqlx-cli`) and:
|
||||
|
||||
@@ -86,6 +87,7 @@ While you're developing and before submitting a patch, you'll want to test your
|
||||
|
||||
- Run `cargo clippy --workspace` to lint the Rust code.
|
||||
- Run `npm run lint` in the `frontend` directory to lint the frontend code.
|
||||
- Run `make fmt` and `make lint` in the `policies` directory to format and lint the included policy.
|
||||
|
||||
### Run the tests
|
||||
|
||||
@@ -93,6 +95,10 @@ If you haven't already, install [Cargo-Nextest](https://nexte.st/docs/installati
|
||||
|
||||
- Run the tests to the backend by running `cargo nextest run --workspace`. This requires a connection to a PostgreSQL database, set via the `DATABASE_URL` environment variable.
|
||||
- Run the tests to the frontend by running `npm run test` in the `frontend` directory.
|
||||
- To run the tests for the included policy, change to the `policies` directory and run one of:
|
||||
- `make test` (needs Open Policy Agent installed)
|
||||
- `make PODMAN=1 test` (runs inside a container; needs Podman installed)
|
||||
- `make DOCKER=1 test` (runs inside a container; needs Docker installed)
|
||||
|
||||
## 8. Submit a pull request
|
||||
|
||||
|
||||
@@ -24,9 +24,9 @@ ifeq ($(DOCKER), 1)
|
||||
REGAL := docker run -i -v $(shell pwd):/policies:ro -w /policies --rm $(REGAL_DOCKER_IMAGE)
|
||||
else ifeq ($(PODMAN), 1)
|
||||
# When running rootless, the volume directory may need to be given global write permissions on the host
|
||||
OPA := podman run -i -v $(shell pwd):/policies:ro:Z -w /policies --rm $(OPA_DOCKER_IMAGE)
|
||||
OPA := podman run -i -v $(shell pwd):/policies:ro,Z -w /policies --rm $(OPA_DOCKER_IMAGE)
|
||||
OPA_RW := podman run -i -v $(shell pwd):/policies:Z -w /policies --rm $(OPA_DOCKER_IMAGE)
|
||||
REGAL := podman run -i -v $(shell pwd):/policies:ro:Z -w /policies --rm $(REGAL_DOCKER_IMAGE)
|
||||
REGAL := podman run -i -v $(shell pwd):/policies:ro,Z -w /policies --rm $(REGAL_DOCKER_IMAGE)
|
||||
else
|
||||
OPA := opa
|
||||
OPA_RW := opa
|
||||
|
||||
@@ -98,6 +98,26 @@ uses_stable_scopes if {
|
||||
count({scope | some scope in scope_list; startswith(scope, "urn:matrix:client:")}) > 0
|
||||
}
|
||||
|
||||
has_device_scope if {
|
||||
scope_list := split(input.scope, " ")
|
||||
count({scope | some scope in scope_list; startswith(scope, "urn:matrix:client:device:")}) > 0
|
||||
}
|
||||
|
||||
has_device_scope if {
|
||||
scope_list := split(input.scope, " ")
|
||||
count({scope | some scope in scope_list; startswith(scope, "urn:matrix:org.matrix.msc2967.client:device:")}) > 0
|
||||
}
|
||||
|
||||
has_cs_api_scope if {
|
||||
scope_list := split(input.scope, " ")
|
||||
count({scope | some scope in scope_list; startswith(scope, "urn:matrix:client:api:")}) > 0
|
||||
}
|
||||
|
||||
has_cs_api_scope if {
|
||||
scope_list := split(input.scope, " ")
|
||||
count({scope | some scope in scope_list; startswith(scope, "urn:matrix:org.matrix.msc2967.client:api:")}) > 0
|
||||
}
|
||||
|
||||
# METADATA
|
||||
# entrypoint: true
|
||||
violation contains {"msg": msg} if {
|
||||
@@ -116,6 +136,12 @@ violation contains {"msg": "only one device scope is allowed at a time"} if {
|
||||
count({scope | some scope in scope_list; startswith(scope, "urn:matrix:client:device:")}) > 1
|
||||
}
|
||||
|
||||
# Prevent the creation of C-S API devices for sessions that don't have C-S API access.
|
||||
violation contains {"msg": "device scopes are only allowed when the client-server API scope is requested"} if {
|
||||
has_device_scope
|
||||
not has_cs_api_scope
|
||||
}
|
||||
|
||||
violation contains {"msg": "request cannot mix unstable and stable scopes"} if {
|
||||
uses_stable_scopes
|
||||
uses_unstable_scopes
|
||||
|
||||
@@ -78,70 +78,84 @@ test_unstable_device_scopes if {
|
||||
authorization_grant.allow with input.user as user
|
||||
with input.client as client
|
||||
with input.grant_type as "authorization_code"
|
||||
with input.scope as "urn:matrix:org.matrix.msc2967.client:device:AAbbCCdd01"
|
||||
with input.scope as "urn:matrix:org.matrix.msc2967.client:api:* urn:matrix:org.matrix.msc2967.client:device:AAbbCCdd01"
|
||||
|
||||
authorization_grant.allow with input.user as user
|
||||
with input.client as client
|
||||
with input.grant_type as "authorization_code"
|
||||
with input.scope as "urn:matrix:org.matrix.msc2967.client:device:AAbbCCdd01-asdasdsa1-2313"
|
||||
with input.scope as "urn:matrix:org.matrix.msc2967.client:api:* urn:matrix:org.matrix.msc2967.client:device:AAbbCCdd01-asdasdsa1-2313"
|
||||
|
||||
# Too short
|
||||
not authorization_grant.allow with input.user as user
|
||||
with input.client as client
|
||||
with input.grant_type as "authorization_code"
|
||||
with input.scope as "urn:matrix:org.matrix.msc2967.client:device:abcd"
|
||||
with input.scope as "urn:matrix:org.matrix.msc2967.client:api:* urn:matrix:org.matrix.msc2967.client:device:abcd"
|
||||
|
||||
# Multiple device scope
|
||||
not authorization_grant.allow with input.user as user
|
||||
with input.client as client
|
||||
with input.grant_type as "authorization_code"
|
||||
with input.scope as "urn:matrix:org.matrix.msc2967.client:device:AAbbCCdd01 urn:matrix:org.matrix.msc2967.client:device:AAbbCCdd02"
|
||||
with input.scope as "urn:matrix:org.matrix.msc2967.client:api:* urn:matrix:org.matrix.msc2967.client:device:AAbbCCdd01 urn:matrix:org.matrix.msc2967.client:device:AAbbCCdd02"
|
||||
|
||||
# Allowed with the device code grant
|
||||
authorization_grant.allow with input.user as user
|
||||
with input.client as client
|
||||
with input.grant_type as "urn:ietf:params:oauth:grant-type:device_code"
|
||||
with input.scope as "urn:matrix:org.matrix.msc2967.client:device:AAbbCCdd01"
|
||||
with input.scope as "urn:matrix:org.matrix.msc2967.client:api:* urn:matrix:org.matrix.msc2967.client:device:AAbbCCdd01"
|
||||
|
||||
# Not authorization_grant.allowed for the client credentials grant
|
||||
not authorization_grant.allow with input.client as client
|
||||
with input.grant_type as "client_credentials"
|
||||
with input.scope as "urn:matrix:org.matrix.msc2967.client:device:AAbbCCdd01"
|
||||
with input.scope as "urn:matrix:org.matrix.msc2967.client:api:* urn:matrix:org.matrix.msc2967.client:device:AAbbCCdd01"
|
||||
}
|
||||
|
||||
test_stable_device_scopes if {
|
||||
authorization_grant.allow with input.user as user
|
||||
with input.client as client
|
||||
with input.grant_type as "authorization_code"
|
||||
with input.scope as "urn:matrix:client:device:AAbbCCdd01"
|
||||
with input.scope as "urn:matrix:client:api:* urn:matrix:client:device:AAbbCCdd01"
|
||||
|
||||
authorization_grant.allow with input.user as user
|
||||
with input.client as client
|
||||
with input.grant_type as "authorization_code"
|
||||
with input.scope as "urn:matrix:client:device:AAbbCCdd01-asdasdsa1-2313"
|
||||
with input.scope as "urn:matrix:client:api:* urn:matrix:client:device:AAbbCCdd01-asdasdsa1-2313"
|
||||
|
||||
# Too short
|
||||
not authorization_grant.allow with input.user as user
|
||||
with input.client as client
|
||||
with input.grant_type as "authorization_code"
|
||||
with input.scope as "urn:matrix:client:device:abcd"
|
||||
with input.scope as "urn:matrix:client:api:* urn:matrix:client:device:abcd"
|
||||
|
||||
# Multiple device scope
|
||||
not authorization_grant.allow with input.user as user
|
||||
with input.client as client
|
||||
with input.grant_type as "authorization_code"
|
||||
with input.scope as "urn:matrix:client:device:AAbbCCdd01 urn:matrix:client:device:AAbbCCdd02"
|
||||
with input.scope as "urn:matrix:client:api:* urn:matrix:client:device:AAbbCCdd01 urn:matrix:client:device:AAbbCCdd02"
|
||||
|
||||
# Allowed with the device code grant
|
||||
authorization_grant.allow with input.user as user
|
||||
with input.client as client
|
||||
with input.grant_type as "urn:ietf:params:oauth:grant-type:device_code"
|
||||
with input.scope as "urn:matrix:client:device:AAbbCCdd01"
|
||||
with input.scope as "urn:matrix:client:api:* urn:matrix:client:device:AAbbCCdd01"
|
||||
|
||||
# Not authorization_grant.allowed for the client credentials grant
|
||||
not authorization_grant.allow with input.client as client
|
||||
with input.grant_type as "client_credentials"
|
||||
with input.scope as "urn:matrix:client:device:AAbbCCdd01"
|
||||
with input.scope as "urn:matrix:client:api:* urn:matrix:client:device:AAbbCCdd01"
|
||||
}
|
||||
|
||||
test_device_scope_only_with_cs_api_scope if {
|
||||
not authorization_grant.allow with input.user as user
|
||||
with input.client as client
|
||||
with input.grant_type as "authorization_code"
|
||||
# Requested a device scope but no C-S API scope:
|
||||
with input.scope as "urn:matrix:client:device:AAbbCCdd01"
|
||||
|
||||
not authorization_grant.allow with input.user as user
|
||||
with input.client as client
|
||||
with input.grant_type as "authorization_code"
|
||||
# Requested a device scope but no C-S API scope:
|
||||
with input.scope as "urn:matrix:org.matrix.msc2967.client:device:AAbbCCdd01"
|
||||
}
|
||||
|
||||
test_mix_stable_and_unstable_scopes if {
|
||||
|
||||
Reference in New Issue
Block a user