bug23578 merged into default (ssl info)
This commit is contained in:
commit
6970cde1aa
|
|
@ -109,7 +109,7 @@ where cmd is one of:
|
|||
|
||||
def fmt_usage_stanza(root, verb):
|
||||
def fmt_args(args):
|
||||
res = " ".join(["<{0}>".format(a) for a in args['mandatory']])
|
||||
res = " ".join(["{0}=...".format(a) for a in args['mandatory']])
|
||||
opts = " ".join("{0}=...".format(o) for o in args['optional'].keys())
|
||||
if opts != "":
|
||||
res += " [{0}]".format(opts)
|
||||
|
|
|
|||
|
|
@ -18,4 +18,4 @@
|
|||
%%
|
||||
%% Contributor(s): ______________________________________.
|
||||
%%
|
||||
-record(context, {username, password, is_admin}).
|
||||
-record(context, {user, password}).
|
||||
|
|
|
|||
|
|
@ -31,8 +31,9 @@
|
|||
will need to be encoded as "<code>%2f</code>".</p>
|
||||
|
||||
<p>PUTing a resource creates it. The JSON object you upload must
|
||||
have certain keys (documented below). Other keys are
|
||||
ignored. Missing keys consitute an error.</p>
|
||||
have certain mandatory keys (documented below) and may have
|
||||
optional keys. Other keys are ignored. Missing mandatory keys
|
||||
constitute an error.</p>
|
||||
|
||||
<p>Since bindings do not have names or IDs in AMQP we synthesise
|
||||
one based on all its properties. Since predicting this name is
|
||||
|
|
@ -67,7 +68,7 @@ Content-Length: 5
|
|||
</li>
|
||||
<li>
|
||||
Get a list of channels, fast publishers first:
|
||||
<pre>$ curl -i -u guest:guest 'http://localhost:55672/api/channels?sort=message_stats.publish_details.rate&sort_reverse=true'
|
||||
<pre>$ curl -i -u guest:guest 'http://localhost:55672/api/channels?sort=message_stats.publish_details.rate&sort_reverse=true'
|
||||
HTTP/1.1 200 OK
|
||||
Server: MochiWeb/1.1 WebMachine/1.7 (participate in the frantic)
|
||||
Date: Tue, 12 Oct 2010 10:03:21 GMT
|
||||
|
|
@ -96,7 +97,7 @@ Content-Length: 0</pre>
|
|||
<li>
|
||||
Create a new exchange in the default virtual host:
|
||||
<pre>$ curl -i -u guest:guest -H "content-type:application/json" \
|
||||
-XPUT -d'{"type":"direct","auto_delete":false,"durable":true,"internal":false,"arguments":[]}' \
|
||||
-XPUT -d'{"type":"direct","durable":true}' \
|
||||
http://localhost:55672/api/exchanges/%2f/my-new-exchange
|
||||
HTTP/1.1 204 No Content
|
||||
Server: MochiWeb/1.1 WebMachine/1.7 (participate in the frantic)
|
||||
|
|
@ -234,7 +235,8 @@ Content-Length: 0</pre>
|
|||
<td></td>
|
||||
<td class="path">/api/exchanges/<i>vhost</i>/<i>name</i></td>
|
||||
<td>An individual exchange. To PUT an exchange, you will need a body looking something like this:
|
||||
<pre>{"type":"direct","auto_delete":false,"durable":true,"internal":false,"arguments":[]}</pre></td>
|
||||
<pre>{"type":"direct","auto_delete":false,"durable":true,"internal":false,"arguments":[]}</pre>
|
||||
The <code>type</code> key is mandatory; other keys are optional.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>X</td>
|
||||
|
|
@ -275,7 +277,8 @@ Content-Length: 0</pre>
|
|||
<td></td>
|
||||
<td class="path">/api/queues/<i>vhost</i>/<i>name</i></td>
|
||||
<td>An individual queue. To PUT a queue, you will need a body looking something like this:
|
||||
<pre>{"auto_delete":false,"durable":true,"arguments":[]}</pre></td>
|
||||
<pre>{"auto_delete":false,"durable":true,"arguments":[]}</pre>
|
||||
All keys are optional.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>X</td>
|
||||
|
|
@ -320,6 +323,7 @@ Content-Length: 0</pre>
|
|||
together many times! To create a new binding, POST to this
|
||||
URI. You will need a body looking something like this:
|
||||
<pre>{"routing_key":"my_routing_key","arguments":[]}</pre>
|
||||
All keys are optional.
|
||||
The response will contain a <code>Location</code> header
|
||||
telling you the URI of your new binding.
|
||||
</td>
|
||||
|
|
@ -377,7 +381,8 @@ Content-Length: 0</pre>
|
|||
<td></td>
|
||||
<td class="path">/api/users/<i>name</i></td>
|
||||
<td>An individual user. To PUT a user, you will need a body looking something like this:
|
||||
<pre>{"password":"secret", "administrator":true}</pre></td>
|
||||
<pre>{"password":"secret", "administrator":true}</pre>
|
||||
All keys are mandatory.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>X</td>
|
||||
|
|
@ -410,7 +415,8 @@ Content-Length: 0</pre>
|
|||
<td></td>
|
||||
<td class="path">/api/permissions/<i>vhost</i>/<i>user</i></td>
|
||||
<td>An individual permission of a user and virtual host. To PUT a permission, you will need a body looking something like this:
|
||||
<pre>{"configure":".*","write":".*","read":".*"}</pre></td>
|
||||
<pre>{"configure":".*","write":".*","read":".*"}</pre>
|
||||
All keys are mandatory.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>X</td>
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ form.inline-form { float: left; margin-right: 100px; }
|
|||
input, select { padding: 0.2em; }
|
||||
input[type=text] { font: 1.1em Lucidatypewriter, Courier, monospace; }
|
||||
input[type=text].wide { width: 300px; }
|
||||
.mand { color: #f88; padding: 0 5px;}
|
||||
|
||||
table.form { margin-bottom: 0.5em; }
|
||||
table.form th { text-align: right; vertical-align: top; }
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
<td>
|
||||
<input type="hidden" name="destination_type" value="q"/>
|
||||
<input type="text" name="source" value=""/>
|
||||
<span class="mand">*</span>
|
||||
</td>
|
||||
</tr>
|
||||
<% } else { %>
|
||||
|
|
@ -38,6 +39,7 @@
|
|||
</th>
|
||||
<td>
|
||||
<input type="text" name="destination" value=""/>
|
||||
<span class="mand">*</span>
|
||||
</td>
|
||||
</tr>
|
||||
<% } %>
|
||||
|
|
|
|||
|
|
@ -54,11 +54,11 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<th><label>Name:</label></th>
|
||||
<td><input type="text" name="name"/></td>
|
||||
<td><input type="text" name="name"/><span class="mand">*</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><label>Type:</label></th>
|
||||
<td><input type="text" name="type"/></td>
|
||||
<td><input type="text" name="type"/><span class="mand">*</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><label>Durability:</label></th>
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<th><label>Name:</label></th>
|
||||
<td><input type="text" name="name"/></td>
|
||||
<td><input type="text" name="name"/><span class="mand">*</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><label>Durability:</label></th>
|
||||
|
|
|
|||
|
|
@ -28,7 +28,10 @@
|
|||
<table class="form">
|
||||
<tr>
|
||||
<th><label>Username:</label></th>
|
||||
<td><input type="text" name="username"/></td>
|
||||
<td>
|
||||
<input type="text" name="username"/>
|
||||
<span class="mand">*</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
|
|
@ -42,6 +45,7 @@
|
|||
<td>
|
||||
<div id="password">
|
||||
<input type="text" name="password" />
|
||||
<span class="mand">*</span>
|
||||
</div>
|
||||
<div id="no-password">
|
||||
User cannot log in using password.
|
||||
|
|
@ -62,3 +66,5 @@
|
|||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p><sub>Only users within the internal RabbitMQ database are managed here. Other users (e.g. those authenticated over LDAP) will not appear.</sub></p>
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
<table class="form">
|
||||
<tr>
|
||||
<th><label>Name:</label></th>
|
||||
<td><input type="text" name="name"/></td>
|
||||
<td><input type="text" name="name"/><span class="mand">*</span></td>
|
||||
</tr>
|
||||
</table>
|
||||
<input type="submit" value="Add virtual host"/>
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
%% The contents of this file are subject to the Mozilla Public License
|
||||
%% Version 1.1 (the "License"); you may not use this file except in
|
||||
%% compliance with the License. You may obtain a copy of the License at
|
||||
%% http://www.mozilla.org/MPL/
|
||||
%%
|
||||
%% Software distributed under the License is distributed on an "AS IS"
|
||||
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|
||||
%% License for the specific language governing rights and limitations
|
||||
%% under the License.
|
||||
%%
|
||||
%% The Original Code is RabbitMQ Management Plugin.
|
||||
%%
|
||||
%% The Initial Developer of the Original Code is VMware, Inc.
|
||||
%% Copyright (c) 2007-2010 VMware, Inc. All rights reserved.
|
||||
-module(rabbit_mgmt).
|
||||
|
||||
-export([start/0, stop/0]).
|
||||
|
||||
start() ->
|
||||
application:start(rabbit_mgmt).
|
||||
|
||||
stop() ->
|
||||
application:stop(rabbit_mgmt).
|
||||
|
|
@ -241,7 +241,7 @@ handle_call({get_channel, Name}, _From, State = #state{tables = Tables}) ->
|
|||
|
||||
handle_call({get_overview, Username}, _From, State = #state{tables = Tables}) ->
|
||||
VHosts = case Username of
|
||||
all -> rabbit_access_control:list_vhosts();
|
||||
all -> rabbit_vhost:list();
|
||||
_ -> rabbit_mgmt_util:vhosts(Username)
|
||||
end,
|
||||
Qs0 = [rabbit_mgmt_format:queue(Q) || V <- VHosts,
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
-export([format/2, print/2, pid/1, ip/1, amqp_table/1, tuple/1, timestamp/1]).
|
||||
-export([timestamp_ms/1]).
|
||||
-export([node_and_pid/1, protocol/1, resource/1, permissions/1, queue/1]).
|
||||
-export([exchange/1, user/1, binding/1, url/2, application/1]).
|
||||
-export([exchange/1, user/1, internal_user/1, binding/1, url/2, application/1]).
|
||||
-export([pack_binding_props/2, unpack_binding_props/1, tokenise/1]).
|
||||
-export([args_type/1, listener/1, properties/1]).
|
||||
|
||||
|
|
@ -106,10 +106,16 @@ permissions({User, VHost, Conf, Write, Read}) ->
|
|||
{write, Write},
|
||||
{read, Read}].
|
||||
|
||||
internal_user(User) ->
|
||||
[{name, User#internal_user.username},
|
||||
{password_hash, base64:encode(User#internal_user.password_hash)},
|
||||
{administrator, User#internal_user.is_admin}].
|
||||
|
||||
user(User) ->
|
||||
[{name, User#user.username},
|
||||
{password_hash, base64:encode(User#user.password_hash)},
|
||||
{administrator, User#user.is_admin}].
|
||||
{administrator, User#user.is_admin},
|
||||
{auth_backend, User#user.auth_backend}].
|
||||
|
||||
|
||||
listener(#listener{node = Node, protocol = Protocol,
|
||||
host = Host, ip_address = IPAddress, port = Port}) ->
|
||||
|
|
|
|||
|
|
@ -20,13 +20,16 @@
|
|||
-export([is_authorized_vhost/2, is_authorized/3, is_authorized_user/3]).
|
||||
-export([bad_request/3, id/2, parse_bool/1]).
|
||||
-export([with_decode/4, with_decode_opts/4, not_found/3, amqp_request/4]).
|
||||
-export([all_or_one_vhost/2, with_decode_vhost/4, reply/3, filter_vhost/3]).
|
||||
-export([filter_user/3, with_decode/5, redirect/2, args/1, vhosts/1]).
|
||||
-export([props_to_method/2]).
|
||||
-export([all_or_one_vhost/2, http_to_amqp/5, reply/3, filter_vhost/3]).
|
||||
-export([filter_user/3, with_decode/5, redirect/2, args/1]).
|
||||
-export([reply_list/3, reply_list/4, sort_list/4, destination_type/1]).
|
||||
|
||||
-include("rabbit_mgmt.hrl").
|
||||
-include_lib("amqp_client/include/amqp_client.hrl").
|
||||
|
||||
-define(FRAMING, rabbit_framing_amqp_0_9_1).
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
is_authorized(ReqData, Context) ->
|
||||
|
|
@ -37,14 +40,17 @@ is_authorized_admin(ReqData, Context) ->
|
|||
fun(#user{is_admin = IsAdmin}) -> IsAdmin end).
|
||||
|
||||
is_authorized_vhost(ReqData, Context) ->
|
||||
is_authorized(ReqData, Context,
|
||||
fun(#user{username = Username}) ->
|
||||
case vhost(ReqData) of
|
||||
not_found -> true;
|
||||
none -> true;
|
||||
V -> lists:member(V, vhosts(Username))
|
||||
end
|
||||
end).
|
||||
is_authorized(
|
||||
ReqData, Context,
|
||||
fun(User) ->
|
||||
case vhost(ReqData) of
|
||||
not_found -> true;
|
||||
none -> true;
|
||||
V -> lists:member(
|
||||
V,
|
||||
rabbit_access_control:list_vhosts(User, write))
|
||||
end
|
||||
end).
|
||||
|
||||
is_authorized_user(ReqData, Context, Item) ->
|
||||
is_authorized(
|
||||
|
|
@ -62,14 +68,14 @@ is_authorized(ReqData, Context, Fun) ->
|
|||
ReqData, Context},
|
||||
case rabbit_mochiweb_util:parse_auth_header(
|
||||
wrq:get_req_header("authorization", ReqData)) of
|
||||
[User, Pass] ->
|
||||
case rabbit_access_control:check_user_pass_login(User, Pass) of
|
||||
{ok, U = #user{is_admin = IsAdmin}} ->
|
||||
case Fun(U) of
|
||||
[Username, Password] ->
|
||||
case rabbit_access_control:check_user_pass_login(Username,
|
||||
Password) of
|
||||
{ok, User} ->
|
||||
case Fun(User) of
|
||||
true -> {true, ReqData,
|
||||
Context#context{username = User,
|
||||
password = Pass,
|
||||
is_admin = IsAdmin}};
|
||||
Context#context{user = User,
|
||||
password = Password}};
|
||||
false -> Unauthorized
|
||||
end;
|
||||
{refused, _, _} ->
|
||||
|
|
@ -82,7 +88,7 @@ is_authorized(ReqData, Context, Fun) ->
|
|||
vhost(ReqData) ->
|
||||
case id(vhost, ReqData) of
|
||||
none -> none;
|
||||
VHost -> case rabbit_access_control:vhost_exists(VHost) of
|
||||
VHost -> case rabbit_vhost:exists(VHost) of
|
||||
true -> VHost;
|
||||
false -> not_found
|
||||
end
|
||||
|
|
@ -236,39 +242,76 @@ decode(Body) ->
|
|||
catch error:_ -> {error, not_json}
|
||||
end.
|
||||
|
||||
with_decode_vhost(Keys, ReqData, Context, Fun) ->
|
||||
case vhost(ReqData) of
|
||||
not_found -> not_found(vhost_not_found, ReqData, Context);
|
||||
VHost -> with_decode(Keys, ReqData, Context,
|
||||
fun (Vals) -> Fun(VHost, Vals) end)
|
||||
end.
|
||||
|
||||
get_or_missing(K, L) ->
|
||||
case proplists:get_value(K, L) of
|
||||
undefined -> {key_missing, K};
|
||||
V -> V
|
||||
end.
|
||||
|
||||
http_to_amqp(MethodName, ReqData, Context, Transformers, Extra) ->
|
||||
case vhost(ReqData) of
|
||||
not_found ->
|
||||
not_found(vhost_not_found, ReqData, Context);
|
||||
VHost ->
|
||||
case decode(wrq:req_body(ReqData)) of
|
||||
{ok, Props} ->
|
||||
try
|
||||
rabbit_mgmt_util:amqp_request(
|
||||
VHost, ReqData, Context,
|
||||
props_to_method(
|
||||
MethodName, Props, Transformers, Extra))
|
||||
catch {error, Error} ->
|
||||
bad_request(Error, ReqData, Context)
|
||||
end;
|
||||
{error, Reason} ->
|
||||
bad_request(Reason, ReqData, Context)
|
||||
end
|
||||
end.
|
||||
|
||||
props_to_method(MethodName, Props, Transformers, Extra) ->
|
||||
Props1 = [{list_to_atom(binary_to_list(K)), V} || {K, V} <- Props],
|
||||
props_to_method(
|
||||
MethodName, rabbit_mgmt_format:format(Props1 ++ Extra, Transformers)).
|
||||
|
||||
props_to_method(MethodName, Props) ->
|
||||
Props1 = rabbit_mgmt_format:format(
|
||||
Props,
|
||||
[{fun (Args) -> [{arguments, args(Args)}] end, [arguments]}]),
|
||||
FieldNames = ?FRAMING:method_fieldnames(MethodName),
|
||||
{Res, _Idx} = lists:foldl(
|
||||
fun (K, {R, Idx}) ->
|
||||
NewR = case proplists:get_value(K, Props1) of
|
||||
undefined -> R;
|
||||
V -> setelement(Idx, R, V)
|
||||
end,
|
||||
{NewR, Idx + 1}
|
||||
end, {?FRAMING:method_record(MethodName), 2},
|
||||
FieldNames),
|
||||
Res.
|
||||
|
||||
parse_bool(<<"true">>) -> true;
|
||||
parse_bool(<<"false">>) -> false;
|
||||
parse_bool(true) -> true;
|
||||
parse_bool(false) -> false;
|
||||
parse_bool(V) -> throw({error, {not_boolean, V}}).
|
||||
|
||||
amqp_request(VHost, ReqData, Context, Method) ->
|
||||
amqp_request(VHost, ReqData,
|
||||
Context = #context{ user = #user { username = Username },
|
||||
password = Password }, Method) ->
|
||||
try
|
||||
Params = #amqp_params{username = Context#context.username,
|
||||
password = Context#context.password,
|
||||
Params = #amqp_params{username = Username,
|
||||
password = Password,
|
||||
virtual_host = VHost},
|
||||
{ok, Conn} = amqp_connection:start(direct, Params),
|
||||
%% No need to check for {error, {auth_failure_likely...
|
||||
%% since we will weed out failed logins in some webmachine
|
||||
%% is_authorized/2 anyway.
|
||||
{ok, Ch} = amqp_connection:open_channel(Conn),
|
||||
amqp_channel:call(Ch, Method),
|
||||
amqp_channel:close(Ch),
|
||||
amqp_connection:close(Conn),
|
||||
{true, ReqData, Context}
|
||||
case amqp_connection:start(direct, Params) of
|
||||
{ok, Conn} ->
|
||||
{ok, Ch} = amqp_connection:open_channel(Conn),
|
||||
amqp_channel:call(Ch, Method),
|
||||
amqp_channel:close(Ch),
|
||||
amqp_connection:close(Conn),
|
||||
{true, ReqData, Context};
|
||||
{error, auth_failure} ->
|
||||
not_authorised(<<"">>, ReqData, Context)
|
||||
end
|
||||
catch
|
||||
exit:{{server_initiated_close, ?NOT_FOUND, Reason}, _} ->
|
||||
not_found(list_to_binary(Reason), ReqData, Context);
|
||||
|
|
@ -278,28 +321,25 @@ amqp_request(VHost, ReqData, Context, Method) ->
|
|||
when ServerClose =:= server_initiated_close;
|
||||
ServerClose =:= server_initiated_hard_close ->
|
||||
bad_request(list_to_binary(io_lib:format("~p ~s", [Code, Reason])),
|
||||
ReqData, Context)
|
||||
ReqData, Context);
|
||||
E:R -> io:format("~p~n", [{E,R}])
|
||||
end.
|
||||
|
||||
all_or_one_vhost(ReqData, Fun) ->
|
||||
case rabbit_mgmt_util:vhost(ReqData) of
|
||||
none -> lists:append(
|
||||
[Fun(V) || V <- rabbit_access_control:list_vhosts()]);
|
||||
none -> lists:append([Fun(V) || V <- rabbit_vhost:list()]);
|
||||
not_found -> vhost_not_found;
|
||||
VHost -> Fun(VHost)
|
||||
end.
|
||||
|
||||
filter_vhost(List, _ReqData, Context) ->
|
||||
VHosts = vhosts(Context#context.username),
|
||||
VHosts = rabbit_access_control:list_vhosts(Context#context.user, write),
|
||||
[I || I <- List, lists:member(proplists:get_value(vhost, I), VHosts)].
|
||||
|
||||
vhosts(Username) ->
|
||||
[VHost || {VHost, _ConfigurePerm, _WritePerm, _ReadPerm}
|
||||
<- rabbit_access_control:list_user_permissions(Username)].
|
||||
|
||||
filter_user(List, _ReqData, #context{is_admin = true}) ->
|
||||
filter_user(List, _ReqData, #context{user = #user{is_admin = true}}) ->
|
||||
List;
|
||||
filter_user(List, _ReqData, #context{username = Username, is_admin = false}) ->
|
||||
filter_user(List, _ReqData,
|
||||
#context{user = #user{username = Username, is_admin = false}}) ->
|
||||
[I || I <- List, proplists:get_value(user, I) == Username].
|
||||
|
||||
redirect(Location, ReqData) ->
|
||||
|
|
|
|||
|
|
@ -36,9 +36,10 @@ resource_exists(ReqData, Context) ->
|
|||
_ -> true
|
||||
end, ReqData, Context}.
|
||||
|
||||
to_json(ReqData, Context) ->
|
||||
Params = #amqp_params{username = Context#context.username,
|
||||
password = Context#context.password,
|
||||
to_json(ReqData, Context = #context{ user = #user { username = Username },
|
||||
password = Password }) ->
|
||||
Params = #amqp_params{username = Username,
|
||||
password = Password,
|
||||
virtual_host = rabbit_mgmt_util:vhost(ReqData)},
|
||||
%% TODO use network connection (need to check what we're bound to)
|
||||
{ok, Conn} = amqp_connection:start(direct, Params),
|
||||
|
|
|
|||
|
|
@ -22,8 +22,6 @@
|
|||
-include_lib("webmachine/include/webmachine.hrl").
|
||||
-include_lib("amqp_client/include/amqp_client.hrl").
|
||||
|
||||
-define(FRAMING, rabbit_framing_amqp_0_9_1).
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
init(_Config) -> {ok, #context{}}.
|
||||
|
||||
|
|
@ -186,11 +184,11 @@ add_vhost(VHost) ->
|
|||
rabbit_mgmt_wm_vhost:put_vhost(VHostName).
|
||||
|
||||
add_permission(Permission) ->
|
||||
rabbit_access_control:set_permissions(pget(user, Permission),
|
||||
pget(vhost, Permission),
|
||||
pget(configure, Permission),
|
||||
pget(write, Permission),
|
||||
pget(read, Permission)).
|
||||
rabbit_auth_backend_internal:set_permissions(pget(user, Permission),
|
||||
pget(vhost, Permission),
|
||||
pget(configure, Permission),
|
||||
pget(write, Permission),
|
||||
pget(read, Permission)).
|
||||
|
||||
add_queue(Queue) ->
|
||||
rabbit_amqqueue:declare(r(queue, Queue),
|
||||
|
|
@ -222,21 +220,6 @@ add_binding(Binding) ->
|
|||
pget(Key, List) ->
|
||||
proplists:get_value(Key, List).
|
||||
|
||||
%% TODO use this elsewhere
|
||||
%% props_to_method(Method, Props) ->
|
||||
%% Props1 = add_args_types(Props),
|
||||
%% FieldNames = ?FRAMING:method_fieldnames(Method),
|
||||
%% {Res, _Idx} = lists:foldl(
|
||||
%% fun (K, {R, Idx}) ->
|
||||
%% NewR = case proplists:get_value(K, Props1) of
|
||||
%% undefined -> R;
|
||||
%% V -> setelement(Idx, R, V)
|
||||
%% end,
|
||||
%% {NewR, Idx + 1}
|
||||
%% end, {?FRAMING:method_record(Method), 2},
|
||||
%% FieldNames),
|
||||
%% Res.
|
||||
|
||||
r(Type, Props) ->
|
||||
r(Type, name, Props).
|
||||
|
||||
|
|
|
|||
|
|
@ -55,18 +55,18 @@ to_json(ReqData, Context) ->
|
|||
end).
|
||||
|
||||
accept_content(ReqData, Context) ->
|
||||
Fun = case rabbit_mgmt_util:destination_type(ReqData) of
|
||||
exchange -> fun binding_to_exchange_bind/1;
|
||||
queue -> fun binding_to_queue_bind/1
|
||||
end,
|
||||
sync_resource(ReqData, Context, Fun).
|
||||
MethodName = case rabbit_mgmt_util:destination_type(ReqData) of
|
||||
exchange -> 'exchange.bind';
|
||||
queue -> 'queue.bind'
|
||||
end,
|
||||
sync_resource(MethodName, ReqData, Context).
|
||||
|
||||
delete_resource(ReqData, Context) ->
|
||||
Fun = case rabbit_mgmt_util:destination_type(ReqData) of
|
||||
exchange -> fun binding_to_exchange_unbind/1;
|
||||
queue -> fun binding_to_queue_unbind/1
|
||||
end,
|
||||
sync_resource(ReqData, Context, Fun).
|
||||
MethodName = case rabbit_mgmt_util:destination_type(ReqData) of
|
||||
exchange -> 'exchange.unbind';
|
||||
queue -> 'queue.unbind'
|
||||
end,
|
||||
sync_resource(MethodName, ReqData, Context).
|
||||
|
||||
is_authorized(ReqData, Context) ->
|
||||
rabbit_mgmt_util:is_authorized_vhost(ReqData, Context).
|
||||
|
|
@ -101,49 +101,15 @@ with_binding(ReqData, Context, Fun) ->
|
|||
Fun(Binding)
|
||||
end.
|
||||
|
||||
sync_resource(ReqData, Context, BindingToAMQPMethod) ->
|
||||
sync_resource(MethodName, ReqData, Context) ->
|
||||
with_binding(
|
||||
ReqData, Context,
|
||||
fun(Binding) ->
|
||||
Props0 = rabbit_mgmt_format:binding(Binding),
|
||||
Props = Props0 ++
|
||||
[{exchange, proplists:get_value(source, Props0)},
|
||||
{queue, proplists:get_value(destination, Props0)}],
|
||||
rabbit_mgmt_util:amqp_request(
|
||||
rabbit_mgmt_util:vhost(ReqData),
|
||||
ReqData, Context, BindingToAMQPMethod(Binding))
|
||||
rabbit_mgmt_util:vhost(ReqData), ReqData, Context,
|
||||
rabbit_mgmt_util:props_to_method(MethodName, Props))
|
||||
end).
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
binding_to_queue_bind(#binding{destination = Dest,
|
||||
source = Source,
|
||||
key = RoutingKey,
|
||||
args = Arguments}) ->
|
||||
#'queue.bind'{ queue = Dest#resource.name,
|
||||
exchange = Source#resource.name,
|
||||
routing_key = RoutingKey,
|
||||
arguments = Arguments }.
|
||||
|
||||
binding_to_queue_unbind(#binding{destination = Dest,
|
||||
source = Source,
|
||||
key = RoutingKey,
|
||||
args = Arguments}) ->
|
||||
#'queue.unbind'{ queue = Dest#resource.name,
|
||||
exchange = Source#resource.name,
|
||||
routing_key = RoutingKey,
|
||||
arguments = Arguments }.
|
||||
|
||||
binding_to_exchange_bind(#binding{destination = Dest,
|
||||
source = Source,
|
||||
key = RoutingKey,
|
||||
args = Arguments}) ->
|
||||
#'exchange.bind'{ source = Source#resource.name,
|
||||
destination = Dest#resource.name,
|
||||
routing_key = RoutingKey,
|
||||
arguments = Arguments }.
|
||||
|
||||
binding_to_exchange_unbind(#binding{destination = Dest,
|
||||
source = Source,
|
||||
key = RoutingKey,
|
||||
args = Arguments}) ->
|
||||
#'exchange.unbind'{ source = Source#resource.name,
|
||||
destination = Dest#resource.name,
|
||||
routing_key = RoutingKey,
|
||||
arguments = Arguments }.
|
||||
|
|
|
|||
|
|
@ -60,41 +60,38 @@ create_path(ReqData, Context) ->
|
|||
{"dummy", ReqData, Context}.
|
||||
|
||||
accept_content(ReqData, {_Mode, Context}) ->
|
||||
rabbit_mgmt_util:with_decode_vhost(
|
||||
[routing_key, arguments], ReqData, Context,
|
||||
fun(VHost, [Key, Args0]) ->
|
||||
Source = rabbit_mgmt_util:id(source, ReqData),
|
||||
Dest = rabbit_mgmt_util:id(destination, ReqData),
|
||||
DestType = rabbit_mgmt_util:id(dtype, ReqData),
|
||||
Args = rabbit_mgmt_util:args(Args0),
|
||||
Method =
|
||||
case DestType of
|
||||
<<"q">> ->
|
||||
#'queue.bind'{ exchange = Source,
|
||||
queue = Dest,
|
||||
routing_key = Key,
|
||||
arguments = Args };
|
||||
<<"e">> ->
|
||||
#'exchange.bind'{ source = Source,
|
||||
destination = Dest,
|
||||
routing_key = Key,
|
||||
arguments = Args}
|
||||
end,
|
||||
case rabbit_mgmt_util:amqp_request(
|
||||
VHost, ReqData, Context, Method) of
|
||||
{{halt, _}, _, _} = Res ->
|
||||
Res;
|
||||
{true, ReqData, Context2} ->
|
||||
Source = rabbit_mgmt_util:id(source, ReqData),
|
||||
Dest = rabbit_mgmt_util:id(destination, ReqData),
|
||||
DestType = rabbit_mgmt_util:id(dtype, ReqData),
|
||||
VHost = rabbit_mgmt_util:vhost(ReqData),
|
||||
Response =
|
||||
case DestType of
|
||||
<<"q">> ->
|
||||
rabbit_mgmt_util:http_to_amqp(
|
||||
'queue.bind', ReqData, Context,
|
||||
[], [{exchange, Source}, {queue, Dest}]);
|
||||
<<"e">> ->
|
||||
rabbit_mgmt_util:http_to_amqp(
|
||||
'exchange.bind', ReqData, Context,
|
||||
[], [{source, Source}, {destination, Dest}])
|
||||
end,
|
||||
case Response of
|
||||
{{halt, _}, _, _} = Res ->
|
||||
Res;
|
||||
{true, ReqData, Context2} ->
|
||||
rabbit_mgmt_util:with_decode(
|
||||
[routing_key, arguments], ReqData, Context,
|
||||
fun([Key, Args]) ->
|
||||
Loc = binary_to_list(
|
||||
rabbit_mgmt_format:url(
|
||||
"/api/bindings/~s/e/~s/~s/~s/~s",
|
||||
[VHost, Source, DestType, Dest,
|
||||
rabbit_mgmt_format:pack_binding_props(
|
||||
Key, Args)])),
|
||||
Key, rabbit_mgmt_util:args(Args))])),
|
||||
ReqData2 = wrq:set_resp_header("Location", Loc, ReqData),
|
||||
{true, ReqData2, Context2}
|
||||
end
|
||||
end).
|
||||
end)
|
||||
end.
|
||||
|
||||
is_authorized(ReqData, {Mode, Context}) ->
|
||||
{Res, RD2, C2} = rabbit_mgmt_util:is_authorized_vhost(ReqData, Context),
|
||||
|
|
|
|||
|
|
@ -47,22 +47,10 @@ to_json(ReqData, Context) ->
|
|||
rabbit_mgmt_util:reply(X, ReqData, Context).
|
||||
|
||||
accept_content(ReqData, Context) ->
|
||||
Name = rabbit_mgmt_util:id(exchange, ReqData),
|
||||
rabbit_mgmt_util:with_decode_vhost(
|
||||
[type, durable, auto_delete, internal, arguments], ReqData, Context,
|
||||
fun(VHost, [Type, Durable, AutoDelete, Internal, Args]) ->
|
||||
Durable1 = rabbit_mgmt_util:parse_bool(Durable),
|
||||
AutoDelete1 = rabbit_mgmt_util:parse_bool(AutoDelete),
|
||||
Internal1 = rabbit_mgmt_util:parse_bool(Internal),
|
||||
rabbit_mgmt_util:amqp_request(
|
||||
VHost, ReqData, Context,
|
||||
#'exchange.declare'{ exchange = Name,
|
||||
type = Type,
|
||||
durable = Durable1,
|
||||
auto_delete = AutoDelete1,
|
||||
internal = Internal1,
|
||||
arguments = rabbit_mgmt_util:args(Args)})
|
||||
end).
|
||||
rabbit_mgmt_util:http_to_amqp(
|
||||
'exchange.declare', ReqData, Context,
|
||||
[{fun rabbit_mgmt_util:parse_bool/1, [durable, auto_delete, internal]}],
|
||||
[{exchange, rabbit_mgmt_util:id(exchange, ReqData)}]).
|
||||
|
||||
delete_resource(ReqData, Context) ->
|
||||
rabbit_mgmt_util:amqp_request(
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@ init(_Config) -> {ok, #context{}}.
|
|||
content_types_provided(ReqData, Context) ->
|
||||
{[{"application/json", to_json}], ReqData, Context}.
|
||||
|
||||
to_json(ReqData, Context = #context{username = Username, is_admin = IsAdmin}) ->
|
||||
to_json(ReqData, Context = #context{user = #user{username = Username,
|
||||
is_admin = IsAdmin}}) ->
|
||||
{ok, StatsLevel} = application:get_env(rabbit, collect_statistics),
|
||||
%% NB: node and stats level duplicate what's in /nodes but we want
|
||||
%% to (a) know which node we're talking to and (b) use the stats
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ accept_content(ReqData, Context) ->
|
|||
rabbit_mgmt_util:with_decode(
|
||||
[configure, write, read], ReqData, Context,
|
||||
fun([Conf, Write, Read]) ->
|
||||
rabbit_access_control:set_permissions(
|
||||
rabbit_auth_backend_internal:set_permissions(
|
||||
User, VHost, Conf, Write, Read),
|
||||
{true, ReqData, Context}
|
||||
end)
|
||||
|
|
@ -67,7 +67,7 @@ accept_content(ReqData, Context) ->
|
|||
delete_resource(ReqData, Context) ->
|
||||
User = rabbit_mgmt_util:id(user, ReqData),
|
||||
VHost = rabbit_mgmt_util:id(vhost, ReqData),
|
||||
rabbit_access_control:clear_permissions(User, VHost),
|
||||
rabbit_auth_backend_internal:clear_permissions(User, VHost),
|
||||
{true, ReqData, Context}.
|
||||
|
||||
is_authorized(ReqData, Context) ->
|
||||
|
|
@ -77,14 +77,15 @@ is_authorized(ReqData, Context) ->
|
|||
|
||||
perms(ReqData) ->
|
||||
User = rabbit_mgmt_util:id(user, ReqData),
|
||||
case rabbit_access_control:lookup_user(User) of
|
||||
case rabbit_auth_backend_internal:lookup_user(User) of
|
||||
{ok, _} ->
|
||||
case rabbit_mgmt_util:vhost(ReqData) of
|
||||
not_found ->
|
||||
not_found;
|
||||
VHost ->
|
||||
Perms = rabbit_access_control:list_user_vhost_permissions(
|
||||
User, VHost),
|
||||
Perms =
|
||||
rabbit_auth_backend_internal:list_user_vhost_permissions(
|
||||
User, VHost),
|
||||
case Perms of
|
||||
[{Configure, Write, Read}] ->
|
||||
{User, VHost, Configure, Write, Read};
|
||||
|
|
|
|||
|
|
@ -39,4 +39,4 @@ is_authorized(ReqData, Context) ->
|
|||
|
||||
permissions() ->
|
||||
[rabbit_mgmt_format:permissions(P) ||
|
||||
P <- rabbit_access_control:list_permissions()].
|
||||
P <- rabbit_auth_backend_internal:list_permissions()].
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ content_types_provided(ReqData, Context) ->
|
|||
|
||||
to_json(ReqData, Context) ->
|
||||
User = rabbit_mgmt_util:id(user, ReqData),
|
||||
Perms = rabbit_access_control:list_user_permissions(User),
|
||||
Perms = rabbit_auth_backend_internal:list_user_permissions(User),
|
||||
rabbit_mgmt_util:reply_list(
|
||||
[rabbit_mgmt_format:permissions({User, VHost,
|
||||
Conf, Write, Read}) ||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ content_types_provided(ReqData, Context) ->
|
|||
|
||||
to_json(ReqData, Context) ->
|
||||
VHost = rabbit_mgmt_util:id(vhost, ReqData),
|
||||
Perms = rabbit_access_control:list_vhost_permissions(VHost),
|
||||
Perms = rabbit_auth_backend_internal:list_vhost_permissions(VHost),
|
||||
rabbit_mgmt_util:reply_list(
|
||||
[rabbit_mgmt_format:permissions({User, VHost,
|
||||
Conf, Write, Read}) ||
|
||||
|
|
|
|||
|
|
@ -47,19 +47,10 @@ to_json(ReqData, Context) ->
|
|||
rabbit_mgmt_util:reply(Q, ReqData, Context).
|
||||
|
||||
accept_content(ReqData, Context) ->
|
||||
Name = rabbit_mgmt_util:id(queue, ReqData),
|
||||
rabbit_mgmt_util:with_decode_vhost(
|
||||
[durable, auto_delete, arguments], ReqData, Context,
|
||||
fun(VHost, [Durable, AutoDelete, Args]) ->
|
||||
Durable1 = rabbit_mgmt_util:parse_bool(Durable),
|
||||
AutoDelete1 = rabbit_mgmt_util:parse_bool(AutoDelete),
|
||||
rabbit_mgmt_util:amqp_request(
|
||||
VHost, ReqData, Context,
|
||||
#'queue.declare'{ queue = Name,
|
||||
durable = Durable1,
|
||||
auto_delete = AutoDelete1,
|
||||
arguments = rabbit_mgmt_util:args(Args) })
|
||||
end).
|
||||
rabbit_mgmt_util:http_to_amqp(
|
||||
'queue.declare', ReqData, Context,
|
||||
[{fun rabbit_mgmt_util:parse_bool/1, [durable, auto_delete]}],
|
||||
[{queue, rabbit_mgmt_util:id(queue, ReqData)}]).
|
||||
|
||||
delete_resource(ReqData, Context) ->
|
||||
rabbit_mgmt_util:amqp_request(
|
||||
|
|
|
|||
|
|
@ -43,7 +43,8 @@ resource_exists(ReqData, Context) ->
|
|||
|
||||
to_json(ReqData, Context) ->
|
||||
{ok, User} = user(ReqData),
|
||||
rabbit_mgmt_util:reply(rabbit_mgmt_format:user(User), ReqData, Context).
|
||||
rabbit_mgmt_util:reply(rabbit_mgmt_format:internal_user(User),
|
||||
ReqData, Context).
|
||||
|
||||
accept_content(ReqData, Context) ->
|
||||
Username = rabbit_mgmt_util:id(user, ReqData),
|
||||
|
|
@ -56,7 +57,7 @@ accept_content(ReqData, Context) ->
|
|||
|
||||
delete_resource(ReqData, Context) ->
|
||||
User = rabbit_mgmt_util:id(user, ReqData),
|
||||
rabbit_access_control:delete_user(User),
|
||||
rabbit_auth_backend_internal:delete_user(User),
|
||||
{true, ReqData, Context}.
|
||||
|
||||
is_authorized(ReqData, Context) ->
|
||||
|
|
@ -65,35 +66,35 @@ is_authorized(ReqData, Context) ->
|
|||
%%--------------------------------------------------------------------
|
||||
|
||||
user(ReqData) ->
|
||||
rabbit_access_control:lookup_user(rabbit_mgmt_util:id(user, ReqData)).
|
||||
rabbit_auth_backend_internal:lookup_user(rabbit_mgmt_util:id(user, ReqData)).
|
||||
|
||||
put_user(User) ->
|
||||
case {proplists:is_defined(password, User),
|
||||
proplists:is_defined(password_hash, User)} of
|
||||
{true, _} ->
|
||||
Pass = proplists:get_value(password, User),
|
||||
put_user(User, Pass, fun rabbit_access_control:change_password/2);
|
||||
put_user(User, Pass, fun rabbit_auth_backend_internal:change_password/2);
|
||||
{_, true} ->
|
||||
Hash = base64:decode(proplists:get_value(password_hash, User)),
|
||||
put_user(User, Hash,
|
||||
fun rabbit_access_control:change_password_hash/2);
|
||||
fun rabbit_auth_backend_internal:change_password_hash/2);
|
||||
_ ->
|
||||
put_user(User, <<>>,
|
||||
fun rabbit_access_control:change_password_hash/2)
|
||||
fun rabbit_auth_backend_internal:change_password_hash/2)
|
||||
end.
|
||||
|
||||
put_user(User, PWArg, PWFun) ->
|
||||
Username = proplists:get_value(name, User),
|
||||
IsAdmin = proplists:get_value(administrator, User),
|
||||
case rabbit_access_control:lookup_user(Username) of
|
||||
case rabbit_auth_backend_internal:lookup_user(Username) of
|
||||
{error, not_found} ->
|
||||
rabbit_access_control:add_user(
|
||||
rabbit_auth_backend_internal:add_user(
|
||||
Username, rabbit_guid:binstring_guid("tmp_"));
|
||||
_ ->
|
||||
ok
|
||||
end,
|
||||
PWFun(Username, PWArg),
|
||||
case rabbit_mgmt_util:parse_bool(IsAdmin) of
|
||||
true -> rabbit_access_control:set_admin(Username);
|
||||
false -> rabbit_access_control:clear_admin(Username)
|
||||
true -> rabbit_auth_backend_internal:set_admin(Username);
|
||||
false -> rabbit_auth_backend_internal:clear_admin(Username)
|
||||
end.
|
||||
|
|
|
|||
|
|
@ -38,6 +38,6 @@ is_authorized(ReqData, Context) ->
|
|||
|
||||
users() ->
|
||||
[begin
|
||||
{ok, User} = rabbit_access_control:lookup_user(U),
|
||||
rabbit_mgmt_format:user(User)
|
||||
end || {U, _} <- rabbit_access_control:list_users()].
|
||||
{ok, User} = rabbit_auth_backend_internal:lookup_user(U),
|
||||
rabbit_mgmt_format:internal_user(User)
|
||||
end || {U, _} <- rabbit_auth_backend_internal:list_users()].
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ allowed_methods(ReqData, Context) ->
|
|||
{['HEAD', 'GET', 'PUT', 'DELETE'], ReqData, Context}.
|
||||
|
||||
resource_exists(ReqData, Context) ->
|
||||
{rabbit_access_control:vhost_exists(id(ReqData)), ReqData, Context}.
|
||||
{rabbit_vhost:exists(id(ReqData)), ReqData, Context}.
|
||||
|
||||
to_json(ReqData, Context) ->
|
||||
VHost = [{name, id(ReqData)}],
|
||||
|
|
@ -48,7 +48,7 @@ accept_content(ReqData, Context) ->
|
|||
|
||||
delete_resource(ReqData, Context) ->
|
||||
VHost = id(ReqData),
|
||||
rabbit_access_control:delete_vhost(VHost),
|
||||
rabbit_vhost:delete(VHost),
|
||||
{true, ReqData, Context}.
|
||||
|
||||
is_authorized(ReqData, Context) ->
|
||||
|
|
@ -60,7 +60,7 @@ id(ReqData) ->
|
|||
rabbit_mgmt_util:id(vhost, ReqData).
|
||||
|
||||
put_vhost(VHost) ->
|
||||
case rabbit_access_control:vhost_exists(VHost) of
|
||||
case rabbit_vhost:exists(VHost) of
|
||||
true -> ok;
|
||||
false -> rabbit_access_control:add_vhost(VHost)
|
||||
false -> rabbit_vhost:add(VHost)
|
||||
end.
|
||||
|
|
|
|||
|
|
@ -28,12 +28,8 @@ init(_Config) -> {ok, #context{}}.
|
|||
content_types_provided(ReqData, Context) ->
|
||||
{[{"application/json", to_json}], ReqData, Context}.
|
||||
|
||||
to_json(ReqData, Context = #context{username = Username,
|
||||
is_admin = IsAdmin}) ->
|
||||
VHosts = case IsAdmin of
|
||||
true -> vhosts();
|
||||
false -> format(rabbit_mgmt_util:vhosts(Username))
|
||||
end,
|
||||
to_json(ReqData, Context = #context{user = User}) ->
|
||||
VHosts = format(rabbit_access_control:list_vhosts(User, read)),
|
||||
rabbit_mgmt_util:reply_list(VHosts, ReqData, Context).
|
||||
|
||||
is_authorized(ReqData, Context) ->
|
||||
|
|
@ -42,7 +38,7 @@ is_authorized(ReqData, Context) ->
|
|||
%%--------------------------------------------------------------------
|
||||
|
||||
vhosts() ->
|
||||
format(rabbit_access_control:list_vhosts()).
|
||||
format(rabbit_vhost:list()).
|
||||
|
||||
format(Vs) ->
|
||||
[[{name, N}] || N <- Vs].
|
||||
|
|
|
|||
|
|
@ -26,8 +26,7 @@ init(_Config) -> {ok, #context{}}.
|
|||
content_types_provided(ReqData, Context) ->
|
||||
{[{"application/json", to_json}], ReqData, Context}.
|
||||
|
||||
to_json(ReqData, Context = #context{username = Username}) ->
|
||||
{ok, User} = rabbit_access_control:lookup_user(Username),
|
||||
to_json(ReqData, Context = #context{user = User}) ->
|
||||
rabbit_mgmt_util:reply(rabbit_mgmt_format:user(User), ReqData, Context).
|
||||
|
||||
is_authorized(ReqData, Context) ->
|
||||
|
|
|
|||
|
|
@ -178,9 +178,7 @@ test_auth(Code, Headers) ->
|
|||
|
||||
exchanges_test() ->
|
||||
%% Can pass booleans or strings
|
||||
Good = [{type, <<"direct">>}, {durable, <<"true">>},
|
||||
{auto_delete, <<"false">>}, {internal, <<"false">>},
|
||||
{arguments, []}],
|
||||
Good = [{type, <<"direct">>}, {durable, <<"true">>}],
|
||||
http_put("/vhosts/myvhost", [], ?NO_CONTENT),
|
||||
http_get("/exchanges/myvhost/foo", ?NOT_AUTHORISED),
|
||||
http_put("/exchanges/myvhost/foo", Good, ?NOT_AUTHORISED),
|
||||
|
|
@ -201,20 +199,12 @@ exchanges_test() ->
|
|||
http_get("/exchanges/myvhost/foo"),
|
||||
|
||||
http_put("/exchanges/badvhost/bar", Good, ?NOT_FOUND),
|
||||
http_put("/exchanges/myvhost/bar",
|
||||
[{type, <<"bad_exchange_type">>},
|
||||
{durable, true}, {auto_delete, false}, {internal, false},
|
||||
{arguments, []}],
|
||||
http_put("/exchanges/myvhost/bar", [{type, <<"bad_exchange_type">>}],
|
||||
?BAD_REQUEST),
|
||||
http_put("/exchanges/myvhost/bar",
|
||||
[{type, <<"direct">>},
|
||||
{durable, <<"troo">>}, {auto_delete, false}, {internal, false},
|
||||
{arguments, []}],
|
||||
http_put("/exchanges/myvhost/bar", [{type, <<"direct">>},
|
||||
{durable, <<"troo">>}],
|
||||
?BAD_REQUEST),
|
||||
http_put("/exchanges/myvhost/foo",
|
||||
[{type, <<"direct">>},
|
||||
{durable, false}, {auto_delete, false}, {internal, false},
|
||||
{arguments, []}],
|
||||
http_put("/exchanges/myvhost/foo", [{type, <<"direct">>}],
|
||||
?BAD_REQUEST),
|
||||
|
||||
http_delete("/exchanges/myvhost/foo", ?NO_CONTENT),
|
||||
|
|
@ -225,7 +215,7 @@ exchanges_test() ->
|
|||
ok.
|
||||
|
||||
queues_test() ->
|
||||
Good = [{durable, true}, {auto_delete, false}, {arguments, []}],
|
||||
Good = [{durable, true}],
|
||||
http_get("/queues/%2f/foo", ?NOT_FOUND),
|
||||
http_put("/queues/%2f/foo", Good, ?NO_CONTENT),
|
||||
http_put("/queues/%2f/foo", Good, ?NO_CONTENT),
|
||||
|
|
@ -233,10 +223,10 @@ queues_test() ->
|
|||
|
||||
http_put("/queues/badvhost/bar", Good, ?NOT_FOUND),
|
||||
http_put("/queues/%2f/bar",
|
||||
[{durable, <<"troo">>}, {auto_delete, false}, {arguments, []}],
|
||||
[{durable, <<"troo">>}],
|
||||
?BAD_REQUEST),
|
||||
http_put("/queues/%2f/foo",
|
||||
[{durable, false}, {auto_delete, false}, {arguments, []}],
|
||||
[{durable, false}],
|
||||
?BAD_REQUEST),
|
||||
|
||||
http_put("/queues/%2f/baz", Good, ?NO_CONTENT),
|
||||
|
|
@ -266,9 +256,8 @@ queues_test() ->
|
|||
ok.
|
||||
|
||||
bindings_test() ->
|
||||
XArgs = [{type, <<"direct">>}, {durable, false}, {auto_delete, false},
|
||||
{internal, false}, {arguments, []}],
|
||||
QArgs = [{durable, false}, {auto_delete, false}, {arguments, []}],
|
||||
XArgs = [{type, <<"direct">>}],
|
||||
QArgs = [],
|
||||
http_put("/exchanges/%2f/myexchange", XArgs, ?NO_CONTENT),
|
||||
http_put("/queues/%2f/myqueue", QArgs, ?NO_CONTENT),
|
||||
http_put("/bindings/%2f/e/myexchange/q/badqueue/routing", [], ?NOT_FOUND),
|
||||
|
|
@ -310,9 +299,8 @@ bindings_test() ->
|
|||
ok.
|
||||
|
||||
bindings_post_test() ->
|
||||
XArgs = [{type, <<"direct">>}, {durable, false}, {auto_delete, false},
|
||||
{internal, false}, {arguments, []}],
|
||||
QArgs = [{durable, false}, {auto_delete, false}, {arguments, []}],
|
||||
XArgs = [{type, <<"direct">>}],
|
||||
QArgs = [],
|
||||
BArgs = [{routing_key, <<"routing">>}, {arguments, [{foo, <<"bar">>}]}],
|
||||
http_put("/exchanges/%2f/myexchange", XArgs, ?NO_CONTENT),
|
||||
http_put("/queues/%2f/myqueue", QArgs, ?NO_CONTENT),
|
||||
|
|
@ -339,7 +327,6 @@ bindings_e2e_test() ->
|
|||
BArgs = [{routing_key, <<"routing">>}, {arguments, []}],
|
||||
http_post("/bindings/%2f/e/amq.direct/e/badexchange", BArgs, ?NOT_FOUND),
|
||||
http_post("/bindings/%2f/e/badexchange/e/amq.fanout", BArgs, ?NOT_FOUND),
|
||||
http_post("/bindings/%2f/e/amq.direct/e/amq.fanout", [{a, "b"}], ?BAD_REQUEST),
|
||||
Headers = http_post("/bindings/%2f/e/amq.direct/e/amq.fanout", BArgs, ?CREATED),
|
||||
"/api/bindings/%2F/e/amq.direct/e/amq.fanout/routing" =
|
||||
pget("location", Headers),
|
||||
|
|
@ -399,7 +386,7 @@ permissions_administrator_test() ->
|
|||
ok.
|
||||
|
||||
permissions_vhost_test() ->
|
||||
QArgs = [{durable, false}, {auto_delete, false}, {arguments, []}],
|
||||
QArgs = [],
|
||||
PermArgs = [{configure, <<".*">>}, {write, <<".*">>}, {read, <<".*">>}],
|
||||
http_put("/users/myuser", [{password, <<"myuser">>},
|
||||
{administrator, false}], ?NO_CONTENT),
|
||||
|
|
@ -452,14 +439,16 @@ permissions_vhost_test() ->
|
|||
|
||||
permissions_amqp_test() ->
|
||||
%% Just test that it works at all, not that it works in all possible cases.
|
||||
QArgs = [{durable, false}, {auto_delete, false}, {arguments, []}],
|
||||
QArgs = [],
|
||||
PermArgs = [{configure, <<"foo.*">>}, {write, <<"foo.*">>},
|
||||
{read, <<"foo.*">>}],
|
||||
http_put("/users/myuser", [{password, <<"myuser">>},
|
||||
{administrator, false}], ?NO_CONTENT),
|
||||
http_put("/permissions/%2f/myuser", PermArgs, ?NO_CONTENT),
|
||||
http_put("/queues/%2f/bar-queue", QArgs, "myuser", "myuser", ?NOT_AUTHORISED),
|
||||
http_put("/queues/%2f/bar-queue", QArgs, "nonexistent", "nonexistent", ?NOT_AUTHORISED),
|
||||
http_put("/queues/%2f/bar-queue", QArgs, "myuser", "myuser",
|
||||
?NOT_AUTHORISED),
|
||||
http_put("/queues/%2f/bar-queue", QArgs, "nonexistent", "nonexistent",
|
||||
?NOT_AUTHORISED),
|
||||
http_delete("/users/myuser", ?NO_CONTENT),
|
||||
ok.
|
||||
|
||||
|
|
@ -506,16 +495,15 @@ permissions_connection_channel_test() ->
|
|||
ok.
|
||||
|
||||
unicode_test() ->
|
||||
QArgs = [{durable, false}, {auto_delete, false}, {arguments, []}],
|
||||
QArgs = [],
|
||||
http_put("/queues/%2f/♫♪♫♪", QArgs, ?NO_CONTENT),
|
||||
http_get("/queues/%2f/♫♪♫♪", ?OK),
|
||||
http_delete("/queues/%2f/♫♪♫♪", ?NO_CONTENT),
|
||||
ok.
|
||||
|
||||
all_configuration_test() ->
|
||||
XArgs = [{type, <<"direct">>}, {durable, false}, {auto_delete, false},
|
||||
{internal, false}, {arguments, []}],
|
||||
QArgs = [{durable, false}, {auto_delete, false}, {arguments, []}],
|
||||
XArgs = [{type, <<"direct">>}],
|
||||
QArgs = [],
|
||||
http_put("/queues/%2f/my-queue", QArgs, ?NO_CONTENT),
|
||||
http_put("/exchanges/%2f/my-exchange", XArgs, ?NO_CONTENT),
|
||||
http_put("/bindings/%2f/e/my-exchange/q/my-queue/routing", [], ?NO_CONTENT),
|
||||
|
|
@ -601,11 +589,9 @@ aliveness_test() ->
|
|||
ok.
|
||||
|
||||
arguments_test() ->
|
||||
XArgs = [{type, <<"headers">>}, {durable, false}, {auto_delete, false},
|
||||
{internal, false},
|
||||
XArgs = [{type, <<"headers">>},
|
||||
{arguments, [{'alternate-exchange', <<"amq.direct">>}]}],
|
||||
QArgs = [{durable, false}, {auto_delete, false},
|
||||
{arguments, [{'x-expires', 1800000}]}],
|
||||
QArgs = [{arguments, [{'x-expires', 1800000}]}],
|
||||
BArgs = [{routing_key, <<"">>},
|
||||
{arguments, [{'x-match', <<"all">>},
|
||||
{foo, <<"bar">>}]}],
|
||||
|
|
@ -629,7 +615,7 @@ arguments_test() ->
|
|||
ok.
|
||||
|
||||
queue_purge_test() ->
|
||||
QArgs = [{durable, false}, {auto_delete, false}, {arguments, []}],
|
||||
QArgs = [],
|
||||
http_put("/queues/%2f/myqueue", QArgs, ?NO_CONTENT),
|
||||
{ok, Conn} = amqp_connection:start(network, #amqp_params{}),
|
||||
{ok, Ch} = amqp_connection:open_channel(Conn),
|
||||
|
|
@ -657,7 +643,7 @@ queue_purge_test() ->
|
|||
ok.
|
||||
|
||||
sorting_test() ->
|
||||
QArgs = [{durable, false}, {auto_delete, false}, {arguments, []}],
|
||||
QArgs = [],
|
||||
PermArgs = [{configure, <<".*">>}, {write, <<".*">>}, {read, <<".*">>}],
|
||||
http_put("/vhosts/vh1", [], ?NO_CONTENT),
|
||||
http_put("/permissions/vh1/guest", PermArgs, ?NO_CONTENT),
|
||||
|
|
|
|||
Loading…
Reference in New Issue