Skip to content

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 e0695ee commit 8701beb
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 17 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ Or, in the classic config format (`rabbitmq.config`, prior to 3.7.0) or `advance
].

Authentication requests will be packed into the headers of incoming
messages. There are three types of request: `login`, `check_vhost` and
`check_resource`. Responses should be returned in the message
messages. There are four types of request: `login`, `check_vhost`,
`check_resource` and `check_topic`. Responses should be returned in the message
body. Responses to `login` requests should be "refused" if login is
unsuccessful or a comma-separated list of tags for the user if login
is successful. Responses to the other types should be the words
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ boolean checkVhost(String username,
String vhost);

boolean checkResource(String username,
String vhost,
String resourceName,
ResourceType resourceType,
ResourcePermission permission);

boolean checkTopic(String username,
String vhost,
String resourceName,
ResourceType resourceType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,16 @@ else if (action.equals("check_resource")) {
get("vhost", headers),
get("name", headers),
ResourceType.valueOf(getU("resource", headers)),
ResourcePermission.valueOf(getU("permission", headers)),
get("routing_key", headers)));
ResourcePermission.valueOf(getU("permission", headers))));
}
else if (action.equals("check_topic")) {
return bool(authBackend.checkTopic(
get("username", headers),
get("vhost", headers),
get("name", headers),
ResourceType.valueOf(getU("resource", headers)),
ResourcePermission.valueOf(getU("permission", headers)),
get("routing_key", headers)));
}

throw new RuntimeException("Unexpected action " + action);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,16 @@ public boolean checkResource(String username,
String vhost,
String resourceName,
ResourceType resourceType,
ResourcePermission permission,
String routingKey) {
if(resourceType == ResourceType.TOPIC) {
return routingKey.startsWith("a");
} else {
return true;
}
ResourcePermission permission) {
return true;
}

public boolean checkTopic(String username,
String vhost,
String resourceName,
ResourceType resourceType,
ResourcePermission permission,
String routingKey) {
return routingKey.startsWith("a");
}
}
26 changes: 20 additions & 6 deletions src/rabbit_auth_backend_amqp.erl
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
-export([description/0]).

-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]).

-behaviour(gen_server).

Expand Down Expand Up @@ -64,26 +64,37 @@ check_vhost_access(#auth_user{username = Username}, VHost, _Sock) ->
infinity).

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) ->
OptionsHeaders = resource_options_as_headers(Options),
gen_server:call(?SERVER, {check_resource, [{username, Username},
{vhost, VHost},
{resource, Type},
{name, Name},
{permission, Permission}] ++ OptionsHeaders},
{permission, Permission}]},
infinity).

check_topic_access(#auth_user{username = Username},
#resource{virtual_host = VHost, kind = topic = Type, name = Name},
Permission,
Context) ->
OptionsHeaders = context_as_headers(Context),
gen_server:call(?SERVER, {check_topic, [{username, Username},
{vhost, VHost},
{resource, Type},
{name, Name},
{permission, Permission}] ++ OptionsHeaders},
infinity).

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

resource_options_as_headers(Options) when is_map(Options) ->
context_as_headers(Options) when is_map(Options) ->
% filter options 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),
?CHECK_RESOURCE_ACCESS_HEADERS) =:= false];
resource_options_as_headers(_) ->
context_as_headers(_) ->
[].

init([]) ->
Expand Down Expand Up @@ -134,6 +145,9 @@ handle_call({check_vhost, Args}, _From, State) ->
handle_call({check_resource, Args}, _From, State) ->
{reply, bool_rpc([{action, check_resource} | Args], State), State};

handle_call({check_topic, Args}, _From, State) ->
{reply, bool_rpc([{action, check_topic} | Args], State), State};

handle_call(_Req, _From, State) ->
{reply, unknown_request, State}.

Expand Down

0 comments on commit 8701beb

Please sign in to comment.