From 4be9bdbc08b3dc94e5cb14505eee63d901d22d0c Mon Sep 17 00:00:00 2001 From: Marcial Rosales Date: Tue, 26 Jul 2022 13:25:55 +0200 Subject: [PATCH] Use wildcard library rather than re for cluster, vhost , queue , exchange, and routing-key patterns --- deps/rabbitmq_auth_backend_oauth2/README.md | 16 ++++++++++---- .../src/rabbit_auth_backend_oauth2.erl | 7 ++---- .../test/unit_SUITE.erl | 22 ++++++------------- 3 files changed, 21 insertions(+), 24 deletions(-) diff --git a/deps/rabbitmq_auth_backend_oauth2/README.md b/deps/rabbitmq_auth_backend_oauth2/README.md index 05afc7af63..aba33914ac 100644 --- a/deps/rabbitmq_auth_backend_oauth2/README.md +++ b/deps/rabbitmq_auth_backend_oauth2/README.md @@ -328,7 +328,9 @@ Both permissions are meant for a RabbitMQ server whose `resource_server_type` is This field is essentially a permission discriminator. The first permission grants `read`, `write` and `configure` permissions to any vhost which matches -the pattern `primary-*` that belongs to a cluster whose `resource_server_id` is equal to `finance`. +the pattern `primary-*` that belongs to a cluster whose `resource_server_id` contains the string `finance`. +The `cluster` attribute is a regular expression like the `vhost`. If we wanted to match exactly the `finance` cluster +we would use instead `^finance$`. The second permission grants the `tag:administrator` user-tag to both clusters, `finance` and `inventory`. @@ -343,10 +345,16 @@ A JWT token may have permissions for resources other than RabbitMQ. The `locations` field can be either a string containing a single location or a Json array containing zero or many locations. -A location consists of a list of key-value pairs separated by forward slash `/` character. The supported keys are: +A location consists of a list of key-value pairs separated by forward slash `/` character. -- `cluster` This is the only mandatory key. It is a regular expression which must match RabbitMQ's `resource_server_id` otherwise the location is ignored. For instance, if we want to match exactly `rabbitmq` we should use `^rabbitmq$`. -- `vhost` This is the virtual host we are granting access to. It can be a fixed value or regular expression. RabbitMQ defaults to `*`. +The location format is `cluster:[/vhost:][/queue:|/exchange:]`. Any string separated by `/` which does not +conform to `:` is ignored. For instance, if your locations start with a prefix, e.g. `vrn/cluster:rabbitmq`, +the `vrn` pattern part is ignored. + +The supported location's attributed are: + +- `cluster` This is the only mandatory key. It is a regular expression which must match RabbitMQ's `resource_server_id` otherwise the location is ignored. +- `vhost` This is the virtual host we are granting access to. It also a regular expression. RabbitMQ defaults to `*`. - `queue`|`exchange` This is the queue or exchange we are granting access to. A location can only specify one or the other but not both. However, RabbitMQ under the covers translates these permissions to scopes which means RabbitMQ does not differentiate between queues and exchanges, they are just resources. RabbitMQ defaults to `*`. - `routing-key` this is the routing key we are granted access to. RabbitMQ defaults to `*`. diff --git a/deps/rabbitmq_auth_backend_oauth2/src/rabbit_auth_backend_oauth2.erl b/deps/rabbitmq_auth_backend_oauth2/src/rabbit_auth_backend_oauth2.erl index d26389f7f3..5a46e76e92 100644 --- a/deps/rabbitmq_auth_backend_oauth2/src/rabbit_auth_backend_oauth2.erl +++ b/deps/rabbitmq_auth_backend_oauth2/src/rabbit_auth_backend_oauth2.erl @@ -399,11 +399,8 @@ map_locations_to_permission_resource_paths(ResourceServerId, L) -> FilteredLocations. cluster_matches_resource_server_id(#{?CLUSTER_LOCATION_ATTRIBUTE := Cluster}, - ResourceServerId) -> - case re:run(ResourceServerId, Cluster) of - nomatch -> false; - _ -> true - end; + ResourceServerId) -> + wildcard:match(ResourceServerId, Cluster); cluster_matches_resource_server_id(_,_) -> false. diff --git a/deps/rabbitmq_auth_backend_oauth2/test/unit_SUITE.erl b/deps/rabbitmq_auth_backend_oauth2/test/unit_SUITE.erl index 45ccc43d1b..7087b3ffd1 100644 --- a/deps/rabbitmq_auth_backend_oauth2/test/unit_SUITE.erl +++ b/deps/rabbitmq_auth_backend_oauth2/test/unit_SUITE.erl @@ -204,17 +204,17 @@ test_post_process_payload_rich_auth_request_using_regular_expression_with_cluste { "can use regular expression on any location's attribute ", [ #{<<"type">> => ?RESOURCE_SERVER_TYPE, - <<"locations">> => [<<"cluster:rabbitmq-*/vhost:^finance-.*">> ], + <<"locations">> => [<<"cluster:rabbitmq-*/vhost:^finance-*">> ], <<"actions">> => [<<"read">>] } ], - [<<"rabbitmq-test.read:^finance-.*/*/*">> ] + [<<"rabbitmq-test.read:^finance-*/*/*">> ] }, { "should filter out any location which does not match the cluster's pattern ", [ #{<<"type">> => ?RESOURCE_SERVER_TYPE, - <<"locations">> => [<<"cluster:rabbitmq-t-.*/vhost:^finance-.*">>, - <<"cluster:^rabbitmq$/vhost:^finance-.*">> ], + <<"locations">> => [<<"cluster:rabbitmq-t-*/vhost:^finance-*">>, + <<"cluster:^rabbitmq$/vhost:^finance-*">> ], <<"actions">> => [<<"read">>] } ], @@ -409,21 +409,13 @@ test_post_process_payload_rich_auth_request(_) -> ], [<<"rabbitmq.read:finance-*/*-invoice/r-*">> ] }, - { "can use regular expression on any location's attribute except on the cluster", + { "can use regular expression on any location's attribute", [ #{<<"type">> => ?RESOURCE_SERVER_TYPE, - <<"locations">> => [<<"cluster:rabbitmq/vhost:^finance-.*">> ], + <<"locations">> => [<<"cluster:rabbitmq/vhost:^finance-*">> ], <<"actions">> => [<<"read">>] } ], - [<<"rabbitmq.read:^finance-.*/*/*">> ] - }, - { "can use regular expression on any location's attribute except on the cluster", - [ #{<<"type">> => ?RESOURCE_SERVER_TYPE, - <<"locations">> => [<<"cluster:rabbitmq-*/vhost:^finance-.*">> ], - <<"actions">> => [<<"read">>] - } - ], - [<<"rabbitmq.read:^finance-.*/*/*">> ] + [<<"rabbitmq.read:^finance-*/*/*">> ] }, { "should ignore permissions which are empty",