Use wildcard library rather than re

for cluster, vhost , queue , exchange,
and routing-key patterns
This commit is contained in:
Marcial Rosales 2022-07-26 13:25:55 +02:00 committed by Michael Klishin
parent 7cea128a48
commit 4be9bdbc08
No known key found for this signature in database
GPG Key ID: E80EDCFA0CDB21EE
3 changed files with 21 additions and 24 deletions

View File

@ -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:<resource_server_id_pattern>[/vhost:<vhostpattern>][/queue:<queue_name_pattern>|/exchange:<exchange_name_pattern][/routing-key:<routing_key_pattern>]`. Any string separated by `/` which does not
conform to `<key>:<value>` 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 `*`.

View File

@ -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.

View File

@ -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",