Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
6 changes: 6 additions & 0 deletions docs/development/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand All @@ -86,13 +87,18 @@ 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

If you haven't already, install [Cargo-Nextest](https://nexte.st/docs/installation/pre-built-binaries/).

- 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 OpenPolicyAgent 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

Expand Down
4 changes: 2 additions & 2 deletions policies/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Copy link
Member

Choose a reason for hiding this comment

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

did that change in podman or did this never work?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't know, but it only has one opts field now

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
Expand Down
26 changes: 26 additions & 0 deletions policies/authorization_grant/authorization_grant.rego
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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
Expand Down
38 changes: 26 additions & 12 deletions policies/authorization_grant/authorization_grant_test.rego
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Loading