Skip to content
This repository has been archived by the owner on Nov 17, 2020. It is now read-only.

Commit

Permalink
Implement check_topic_access callback
Browse files Browse the repository at this point in the history
  • Loading branch information
acogoluegnes committed Dec 29, 2016
1 parent d61e40a commit 151122b
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 14 deletions.
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ define PROJECT_ENV
{http_method, get},
{user_path, "http://localhost:8000/auth/user"},
{vhost_path, "http://localhost:8000/auth/vhost"},
{resource_path, "http://localhost:8000/auth/resource"}
{resource_path, "http://localhost:8000/auth/resource"},
{topic_path, "http://localhost:8000/auth/topic"}
]
endef

Expand Down
22 changes: 16 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ In `rabbitmq.conf` (currently RabbitMQ master):
rabbitmq_auth_backend_http.user_path = http://some-server/auth/user
rabbitmq_auth_backend_http.vhost_path = http://some-server/auth/vhost
rabbitmq_auth_backend_http.resource_path = http://some-server/auth/resource
rabbitmq_auth_backend_http.topic_path = http://some-server/auth/topic

In the classic config format (`rabbitmq.config` prior to 3.7.0 or `advanced.config`):

Expand All @@ -65,7 +66,8 @@ In the classic config format (`rabbitmq.config` prior to 3.7.0 or `advanced.conf
[{http_method, post},
{user_path, "http(s)://some-server/auth/user"},
{vhost_path, "http(s)://some-server/auth/vhost"},
{resource_path, "http(s)://some-server/auth/resource"}]}
{resource_path, "http(s)://some-server/auth/resource"},
{topic_path, "http(s)://some-server/auth/topic"}]}
].

By default `http_method` configuration is `GET` for backwards compatibility. It's recommended
Expand Down Expand Up @@ -98,8 +100,18 @@ Note that you cannot create arbitrary virtual hosts using this plugin; you can o
* `resource` - the type of resource (`exchange`, `queue`, `topic`)
* `name` - the name of the resource
* `permission` - the access level to the resource (`configure`, `write`, `read`) - see [the Access Control guide](http://www.rabbitmq.com/access-control.html) for their meaning
* `routing_key` - the routing key (optional). This parameter is present only when publishing a message on a topic exchange
(to enforce topic authorisation). `resource` then equals to `topic` and `permission` to `write` - see [topic authorisation](http://www.rabbitmq.com/access-control.html#topic-authorisation)

### topic_path

* `username` - the name of the user
* `vhost` - the name of the virtual host containing the resource
* `resource` - the type of resource (`topic` in this case)
* `name` - the name of the resource
* `permission` - the access level to the resource (`write` in this case)
* `routing_key` - the routing key of the published message

See [topic authorisation](http://www.rabbitmq.com/access-control.html#topic-authorisation) for more information
about topic authorisation.

Your web server should always return HTTP 200 OK, with a body
containing:
Expand All @@ -108,9 +120,6 @@ containing:
* `allow` - allow access to the user / vhost / resource
* `allow [list of tags]` - (for `user_path` only) - allow access, and mark the user as an having the tags listed

If you don't want your web server to enforce topic authorisation, it should `allow` all requests with
`resource = topic`.

## Using TLS/HTTPS

If your Web server uses HTTPS and certificate verification, you need to
Expand All @@ -123,6 +132,7 @@ configure the plugin to use a CA and client certificate/key pair using the `rabb
{user_path, "https://some-server/auth/user"},
{vhost_path, "https://some-server/auth/vhost"},
{resource_path, "https://some-server/auth/resource"},
{topic_path, "https://some-server/auth/topic"},
{ssl_options,
[{cacertfile, "/path/to/cacert.pem"},
{certfile, "/path/to/client/cert.pem"},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@ def vhost(request):

def resource(request):
return HttpResponse("allow")

def topic(request):
return HttpResponse("allow")
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
(r'^auth/user', 'rabbitmq_auth_backend_django.auth.views.user'),
(r'^auth/vhost', 'rabbitmq_auth_backend_django.auth.views.vhost'),
(r'^auth/resource', 'rabbitmq_auth_backend_django.auth.views.resource'),
(r'^auth/topic', 'rabbitmq_auth_backend_django.auth.views.topic'),
(r'^admin/doc/', include('django.contrib.admindocs.urls')),
(r'^admin/', include(admin.site.urls)),
)
3 changes: 3 additions & 0 deletions priv/schema/rabbitmq_auth_backend_http.schema
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@

{mapping, "rabbitmq_auth_backend_http.resource_path", "rabbitmq_auth_backend_http.resource_path",
[{datatype, string}, {validators, ["uri"]}]}.

{mapping, "rabbitmq_auth_backend_http.topic_path", "rabbitmq_auth_backend_http.topic_path",
[{datatype, string}, {validators, ["uri"]}]}.
24 changes: 17 additions & 7 deletions src/rabbit_auth_backend_http.erl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

-export([description/0, p/1, q/1]).
-export([user_login_authentication/2, user_login_authorization/1,
check_vhost_access/3, check_resource_access/3]).
check_vhost_access/3, check_resource_access/3, check_topic_access/4]).

%% If keepalive connection is closed, retry N times before failing.
-define(RETRY_ON_KEEPALIVE_CLOSED, 3).
Expand Down Expand Up @@ -62,25 +62,35 @@ check_vhost_access(#auth_user{username = Username}, VHost, Sock) ->
{ip, extract_address(Sock)}]).

check_resource_access(#auth_user{username = Username},
#resource{virtual_host = VHost, kind = Type, name = Name, options = Options},
#resource{virtual_host = VHost, kind = Type, name = Name},
Permission) ->
OptionsParameters = resource_options_as_parameters(Options),
bool_req(resource_path, [{username, Username},
{vhost, VHost},
{resource, Type},
{name, Name},
{permission, Permission}] ++ OptionsParameters).
{permission, Permission}]).

check_topic_access(#auth_user{username = Username},
#resource{virtual_host = VHost, kind = topic = Type, name = Name},
Permission,
Context) ->
OptionsParameters = context_as_parameters(Context),
bool_req(topic_path, [{username, Username},
{vhost, VHost},
{resource, Type},
{name, Name},
{permission, Permission}] ++ OptionsParameters).

%%--------------------------------------------------------------------

resource_options_as_parameters(Options) when is_map(Options) ->
% filter options that would erase fixed parameters
context_as_parameters(Options) when is_map(Options) ->
% filter keys that would erase fixed parameters
[{rabbit_data_coercion:to_atom(Key), maps:get(Key, Options)}
|| Key <- maps:keys(Options),
lists:member(
rabbit_data_coercion:to_atom(Key),
?RESOURCE_REQUEST_PARAMETERS) =:= false];
resource_options_as_parameters(_) ->
context_as_parameters(_) ->
[].

bool_req(PathName, Props) ->
Expand Down

0 comments on commit 151122b

Please sign in to comment.