Merge pull request #722 from rabbitmq/mgmt-oauth
Management UI can obtain an OAuth 2 token from UAA/CF SSO service
This commit is contained in:
commit
f1ade9c9a6
|
|
@ -12,7 +12,6 @@ define PROJECT_ENV
|
|||
|
||||
{cors_allow_origins, []},
|
||||
{cors_max_age, 1800},
|
||||
|
||||
{content_security_policy, "default-src 'self'"}
|
||||
]
|
||||
endef
|
||||
|
|
|
|||
|
|
@ -361,6 +361,18 @@ end}.
|
|||
]}.
|
||||
|
||||
%% ===========================================================================
|
||||
%% Authorization
|
||||
|
||||
{mapping, "management.enable_uaa", "rabbitmq_management.enable_uaa",
|
||||
[{datatype, {enum, [true, false]}}]}.
|
||||
|
||||
{mapping, "management.uaa_client_id", "rabbitmq_management.uaa_client_id",
|
||||
[{datatype, string}]}.
|
||||
|
||||
{mapping, "management.uaa_location", "rabbitmq_management.uaa_location",
|
||||
[{datatype, string}]}.
|
||||
|
||||
%% ===========================================================================
|
||||
|
||||
|
||||
%% One of 'basic', 'detailed' or 'none'. See
|
||||
|
|
|
|||
|
|
@ -975,6 +975,17 @@ or:
|
|||
<pre>curl -4u 'guest:guest' -H 'content-type:application/json' -X PUT localhost:15672/api/vhost-limits/my-vhost/max-connections -d '{"value": 50}'</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>X</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td class="path">/api/auth</td>
|
||||
<td>
|
||||
Details about the OAuth2 configuration. It will return HTTP
|
||||
status 200 with body: <pre>{"enable_uaa":"boolean", "uaa_client_id":"string", "uaa_location":"string"}</pre>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -16,15 +16,52 @@
|
|||
<script src="js/prefs.js" type="text/javascript"></script>
|
||||
<script src="js/formatters.js" type="text/javascript"></script>
|
||||
<script src="js/charts.js" type="text/javascript"></script>
|
||||
|
||||
<script src="js/singular/singular.js" type="application/javascript"></script>
|
||||
|
||||
<link href="css/main.css" rel="stylesheet" type="text/css"/>
|
||||
<link href="favicon.ico" rel="shortcut icon" type="image/x-icon"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
var uaa_logged_in = false;
|
||||
var uaa_invalid = false;
|
||||
var auth = JSON.parse(sync_get('/auth'));
|
||||
enable_uaa = auth.enable_uaa;
|
||||
uaa_client_id = auth.uaa_client_id;
|
||||
uaa_location = auth.uaa_location;
|
||||
if (enable_uaa) {
|
||||
Singular.init({
|
||||
singularLocation: './js/singular/',
|
||||
uaaLocation: uaa_location,
|
||||
clientId: uaa_client_id,
|
||||
onIdentityChange: function (identity) {
|
||||
uaa_logged_in = true;
|
||||
start_app_login();
|
||||
},
|
||||
onLogout: function () {
|
||||
uaa_logged_in = false;
|
||||
var hash = window.location.hash.substring(1);
|
||||
var params = {}
|
||||
hash.split('&').map(hk => {
|
||||
let temp = hk.split('=');
|
||||
params[temp[0]] = temp[1]
|
||||
});
|
||||
if (params.error) {
|
||||
uaa_invalid = true;
|
||||
replace_content('login-status', '<p class="warning">' + decodeURIComponent(params.error) + ':' + decodeURIComponent(params.error_description) + '</p> <button id="loginWindow" onclick="uaa_login_window()">Click here to log out</button>');
|
||||
} else {
|
||||
replace_content('login-status', '<button id="loginWindow" onclick="uaa_login_window()">Click here to log in</button>');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<!--[if lte IE 8]>
|
||||
<script src="js/excanvas.min.js" type="text/javascript"></script>
|
||||
<link href="css/evil.css" rel="stylesheet" type="text/css"/>
|
||||
<![endif]-->
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="outer"></div>
|
||||
<div id="debug"></div>
|
||||
|
|
|
|||
|
|
@ -261,11 +261,23 @@ dispatcher_add(function(sammy) {
|
|||
});
|
||||
|
||||
sammy.put('#/logout', function() {
|
||||
// clear a local storage value used by earlier versions
|
||||
clear_pref('auth');
|
||||
clear_cookie_value('auth');
|
||||
location.reload();
|
||||
});
|
||||
// clear a local storage value used by earlier versions
|
||||
clear_pref('auth');
|
||||
clear_cookie_value('auth');
|
||||
if (uaa_logged_in) {
|
||||
clear_pref('uaa_token');
|
||||
var redirect;
|
||||
if (window.location.hash != "") {
|
||||
redirect = window.location.href.split(window.location.hash)[0];
|
||||
} else {
|
||||
redirect = window.location.href
|
||||
};
|
||||
uaa_logged_in = false;
|
||||
var logoutRedirectUrl = Singular.properties.uaaLocation + '/logout.do?client_id=' + Singular.properties.clientId + '&redirect=' + redirect;
|
||||
get(logoutRedirectUrl, "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", function(req) { });
|
||||
}
|
||||
location.reload();
|
||||
});
|
||||
|
||||
sammy.put('#/rate-options', function() {
|
||||
update_rate_options(this);
|
||||
|
|
|
|||
|
|
@ -764,3 +764,7 @@ var chart_data = {};
|
|||
// whenever a UI requests a page that doesn't exist
|
||||
// because things were deleted between refreshes
|
||||
var last_page_out_of_range_error = 0;
|
||||
|
||||
var enable_uaa;
|
||||
var uaa_client_id;
|
||||
var uaa_location;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,17 @@
|
|||
$(document).ready(function() {
|
||||
replace_content('outer', format('login', {}));
|
||||
start_app_login();
|
||||
if (enable_uaa) {
|
||||
get(uaa_location + "/info", "application/json", function(req) {
|
||||
if (req.status !== 200) {
|
||||
replace_content('outer', format('login_uaa', {}));
|
||||
replace_content('login-status', '<p class="warning">' + uaa_location + " does not appear to be a running UAA instance or may not have a trusted SSL certificate" + '</p> <button id="loginWindow" onclick="uaa_login_window()">Single Sign On</button>');
|
||||
} else {
|
||||
replace_content('outer', format('login_uaa', {}));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
replace_content('outer', format('login', {}));
|
||||
start_app_login();
|
||||
}
|
||||
});
|
||||
|
||||
function dispatcher_add(fun) {
|
||||
|
|
@ -58,6 +69,15 @@ function login_route_with_path() {
|
|||
window.location.replace(location);
|
||||
}
|
||||
|
||||
function getParameterByName(name) {
|
||||
var match = RegExp('[#&]' + name + '=([^&]*)').exec(window.location.hash);
|
||||
return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
|
||||
}
|
||||
|
||||
function getAccessToken() {
|
||||
return getParameterByName('access_token');
|
||||
}
|
||||
|
||||
function start_app_login() {
|
||||
app = new Sammy.Application(function () {
|
||||
this.get('#/', function() {});
|
||||
|
|
@ -70,19 +90,58 @@ function start_app_login() {
|
|||
this.get('#/login/:username/:password', login_route);
|
||||
this.get(/\#\/login\/(.*)/, login_route_with_path);
|
||||
});
|
||||
app.run();
|
||||
if (get_cookie_value('auth') != null) {
|
||||
check_login();
|
||||
if (enable_uaa) {
|
||||
var token = getAccessToken();
|
||||
if (token != null) {
|
||||
set_auth_pref(uaa_client_id + ':' + token);
|
||||
store_pref('uaa_token', token);
|
||||
check_login();
|
||||
} else if(has_auth_cookie_value()) {
|
||||
check_login();
|
||||
};
|
||||
} else {
|
||||
app.run();
|
||||
if (get_cookie_value('auth') != null) {
|
||||
check_login();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function uaa_logout_window() {
|
||||
uaa_invalid = true;
|
||||
uaa_login_window();
|
||||
}
|
||||
|
||||
function uaa_login_window() {
|
||||
var redirect;
|
||||
if (window.location.hash != "") {
|
||||
redirect = window.location.href.split(window.location.hash)[0];
|
||||
} else {
|
||||
redirect = window.location.href
|
||||
};
|
||||
var loginRedirectUrl;
|
||||
if (uaa_invalid) {
|
||||
loginRedirectUrl = Singular.properties.uaaLocation + '/logout.do?client_id=' + Singular.properties.clientId + '&redirect=' + redirect;
|
||||
} else {
|
||||
loginRedirectUrl = Singular.properties.uaaLocation + '/oauth/authorize?response_type=token&client_id=' + Singular.properties.clientId + '&redirect_uri=' + redirect;
|
||||
};
|
||||
window.open(loginRedirectUrl, "LOGIN_WINDOW");
|
||||
}
|
||||
|
||||
function check_login() {
|
||||
user = JSON.parse(sync_get('/whoami'));
|
||||
if (user == false) {
|
||||
// clear a local storage value used by earlier versions
|
||||
clear_pref('auth');
|
||||
clear_pref('uaa_token');
|
||||
clear_cookie_value('auth');
|
||||
replace_content('login-status', '<p>Login failed</p>');
|
||||
if (enable_uaa) {
|
||||
uaa_invalid = true;
|
||||
replace_content('login-status', '<button id="loginWindow" onclick="uaa_login_window()">Log out</button>');
|
||||
} else {
|
||||
replace_content('login-status', '<p>Login failed</p>');
|
||||
}
|
||||
}
|
||||
else {
|
||||
hide_popup_warn();
|
||||
|
|
@ -138,12 +197,20 @@ function start_app() {
|
|||
// just leave the history here.
|
||||
//Sammy.HashLocationProxy._interval = null;
|
||||
|
||||
|
||||
app = new Sammy.Application(dispatcher);
|
||||
app.run();
|
||||
|
||||
var url = this.location.toString();
|
||||
var hash = this.location.hash;
|
||||
var pathname = this.location.pathname;
|
||||
if (url.indexOf('#') == -1) {
|
||||
this.location = url + '#/';
|
||||
} else if (hash.indexOf('#token_type') != - 1 && pathname == '/') {
|
||||
// This is equivalent to previous `if` clause when uaa authorisation is used.
|
||||
// Tokens are passed in the url hash, so the url always contains a #.
|
||||
// We need to check the current path is `/` and token is present,
|
||||
// so we can redirect to `/#/`
|
||||
this.location = url.replace(/#token_type.+/gi, "#/");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -560,7 +627,11 @@ function submit_import(form) {
|
|||
vhost_part = '/' + esc(vhost_name);
|
||||
}
|
||||
|
||||
var form_action = "/definitions" + vhost_part + '?auth=' + get_cookie_value('auth');
|
||||
if (enable_uaa) {
|
||||
var form_action = "/definitions" + vhost_part + '?token=' + get_pref('uaa_token');
|
||||
} else {
|
||||
var form_action = "/definitions" + vhost_part + '?auth=' + get_cookie_value('auth');
|
||||
};
|
||||
var fd = new FormData();
|
||||
fd.append('file', file);
|
||||
with_req('POST', form_action, fd, function(resp) {
|
||||
|
|
@ -600,9 +671,15 @@ function postprocess() {
|
|||
$('#download-definitions').on('click', function() {
|
||||
var idx = $("select[name='vhost-download'] option:selected").index();
|
||||
var vhost = ((idx <=0 ) ? "" : "/" + esc($("select[name='vhost-download'] option:selected").val()));
|
||||
if (enable_uaa) {
|
||||
var path = 'api/definitions' + vhost + '?download=' +
|
||||
esc($('#download-filename').val()) +
|
||||
'&auth=' + get_cookie_value('auth');
|
||||
'&token=' + get_pref('uaa_token');
|
||||
} else {
|
||||
var path = 'api/definitions' + vhost + '?download=' +
|
||||
esc($('#download-filename').val()) +
|
||||
'&auth=' + get_cookie_value('auth');
|
||||
};
|
||||
window.location = path;
|
||||
setTimeout('app.run()');
|
||||
return false;
|
||||
|
|
@ -1114,10 +1191,14 @@ function has_auth_cookie_value() {
|
|||
}
|
||||
|
||||
function auth_header() {
|
||||
if(has_auth_cookie_value()) {
|
||||
return "Basic " + decodeURIComponent(get_cookie_value('auth'));
|
||||
if(has_auth_cookie_value() && enable_uaa) {
|
||||
return "Bearer " + decodeURIComponent(get_pref('uaa_token'));
|
||||
} else {
|
||||
return null;
|
||||
if(has_auth_cookie_value()) {
|
||||
return "Basic " + decodeURIComponent(get_cookie_value('auth'));
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1149,6 +1230,19 @@ function with_req(method, path, body, fun) {
|
|||
req.send(body);
|
||||
}
|
||||
|
||||
function get(url, accept, callback) {
|
||||
var req = new XMLHttpRequest();
|
||||
req.open("GET", url);
|
||||
req.setRequestHeader("Accept", accept);
|
||||
req.send();
|
||||
|
||||
req.onreadystatechange = function() {
|
||||
if (req.readyState == XMLHttpRequest.DONE) {
|
||||
callback(req);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function sync_get(path) {
|
||||
return sync_req('GET', [], path);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<iframe style="display: none;" id="authorizeFrame" src="about:blank"></iframe>
|
||||
</body>
|
||||
<script type="application/javascript" src="./rpFrame.js"></script>
|
||||
<script type="application/javascript">
|
||||
var authorizeWindow = document.getElementById('authorizeFrame').contentWindow;
|
||||
var rpFrame = RPFrame(window.parent.Singular, authorizeWindow, window);
|
||||
window.addEventListener('message', rpFrame.receiveMessage, false);
|
||||
|
||||
rpFrame.checkClientConfig();
|
||||
rpFrame.startCheckingSession();
|
||||
|
||||
window.fetchAccessToken = rpFrame.fetchAccessToken;
|
||||
window.afterAccess = rpFrame.afterAccess;
|
||||
window.afterAuthorize = rpFrame.afterAuthorize;
|
||||
</script>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script type="application/javascript">
|
||||
window.parent.afterAccess(parseInt(window.location.search.substring(1)));
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script type="application/javascript">
|
||||
window.parent.afterAuthorize();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -23,9 +23,13 @@
|
|||
</select>
|
||||
</li>
|
||||
<li id="logout">
|
||||
<% if (enable_uaa) { %>
|
||||
<input type="submit" id="loginWindow" onclick="uaa_logout_window()" value="Log out"/>
|
||||
<% } else { %>
|
||||
<form action="#/logout" method="put">
|
||||
<input type="submit" value="Log out"/>
|
||||
</form>
|
||||
<% } %>
|
||||
</li>
|
||||
</ul>
|
||||
<div id="logo">
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
<div id="login">
|
||||
<p><img src="img/rabbitmqlogo.png" alt="RabbitMQ logo" width="204" height="37"/></p>
|
||||
|
||||
<div id="login-status"></div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
# use admin context to add user and client
|
||||
uaac token client get admin -s adminsecret
|
||||
|
||||
uaac user add rabbit_user -p rabbit_password --email rabbit_user@example.com
|
||||
|
||||
# these groups will end up in the scope of the users
|
||||
uaac group add "rabbitmq.read:*/*"
|
||||
uaac group add "rabbitmq.write:*/*"
|
||||
uaac group add "rabbitmq.configure:*/*"
|
||||
uaac group add "rabbitmq.tag:management"
|
||||
uaac group add "rabbitmq.tag:administrator"
|
||||
|
||||
uaac member add "rabbitmq.read:*/*" rabbit_user
|
||||
uaac member add "rabbitmq.write:*/*" rabbit_user
|
||||
uaac member add "rabbitmq.configure:*/*" rabbit_user
|
||||
uaac member add "rabbitmq.tag:management" rabbit_user
|
||||
uaac member add "rabbitmq.tag:administrator" rabbit_user
|
||||
|
||||
# add the client for the management plugin. It has the implicit grant type.
|
||||
# add e.g. --access_token_validity 60 --refresh_token_validity 3600 to experiment with token validity
|
||||
uaac client add rabbit_user_client \
|
||||
--name rabbit_user_client \
|
||||
--secret '' \
|
||||
--scope 'rabbitmq.* openid' \
|
||||
--authorized_grant_types implicit \
|
||||
--autoapprove true \
|
||||
--redirect_uri 'http://localhost:15672/**'
|
||||
|
|
@ -172,5 +172,6 @@ dispatcher() ->
|
|||
{"/healthchecks/node", rabbit_mgmt_wm_healthchecks, []},
|
||||
{"/healthchecks/node/:node", rabbit_mgmt_wm_healthchecks, []},
|
||||
{"/reset", rabbit_mgmt_wm_reset, []},
|
||||
{"/reset/:node", rabbit_mgmt_wm_reset, []}
|
||||
{"/reset/:node", rabbit_mgmt_wm_reset, []},
|
||||
{"/auth", rabbit_mgmt_wm_auth, []}
|
||||
].
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
%% TODO sort all this out; maybe there's scope for rabbit_mgmt_request?
|
||||
|
||||
-export([is_authorized/2, is_authorized_admin/2, is_authorized_admin/4,
|
||||
vhost/1, vhost_from_headers/1]).
|
||||
is_authorized_admin/3, vhost/1, vhost_from_headers/1]).
|
||||
-export([is_authorized_vhost/2, is_authorized_user/3,
|
||||
is_authorized_monitor/2, is_authorized_policies/2,
|
||||
is_authorized_vhost_visible/2,
|
||||
|
|
@ -85,6 +85,13 @@ is_authorized_admin(ReqData, Context) ->
|
|||
<<"Not administrator user">>,
|
||||
fun(#user{tags = Tags}) -> is_admin(Tags) end).
|
||||
|
||||
is_authorized_admin(ReqData, Context, Token) ->
|
||||
is_authorized(ReqData, Context,
|
||||
rabbit_data_coercion:to_binary(
|
||||
application:get_env(rabbitmq_management, uaa_client_id, "")),
|
||||
Token, <<"Not administrator user">>,
|
||||
fun(#user{tags = Tags}) -> is_admin(Tags) end).
|
||||
|
||||
is_authorized_admin(ReqData, Context, Username, Password) ->
|
||||
is_authorized(ReqData, Context, Username, Password,
|
||||
<<"Not administrator user">>,
|
||||
|
|
@ -183,6 +190,10 @@ is_authorized1(ReqData, Context, ErrorMsg, Fun) ->
|
|||
is_authorized(ReqData, Context,
|
||||
Username, Password,
|
||||
ErrorMsg, Fun);
|
||||
{bearer, Token} ->
|
||||
Username = rabbit_data_coercion:to_binary(
|
||||
application:get_env(rabbitmq_management, uaa_client_id, "")),
|
||||
is_authorized(ReqData, Context, Username, Token, ErrorMsg, Fun);
|
||||
_ ->
|
||||
{{false, ?AUTH_REALM}, ReqData, Context}
|
||||
end.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
%% 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
|
||||
%% https://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 GoPivotal, Inc.
|
||||
%% Copyright (c) 2007-2019 Pivotal Software, Inc. All rights reserved.
|
||||
%%
|
||||
|
||||
-module(rabbit_mgmt_wm_auth).
|
||||
|
||||
-export([init/2, to_json/2, content_types_provided/2, is_authorized/2]).
|
||||
-export([variances/2]).
|
||||
|
||||
-include_lib("rabbitmq_management_agent/include/rabbit_mgmt_records.hrl").
|
||||
-include_lib("rabbit_common/include/rabbit.hrl").
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
init(Req, _State) ->
|
||||
{cowboy_rest, rabbit_mgmt_headers:set_common_permission_headers(Req, ?MODULE), #context{}}.
|
||||
|
||||
variances(Req, Context) ->
|
||||
{[<<"accept-encoding">>, <<"origin">>], Req, Context}.
|
||||
|
||||
content_types_provided(ReqData, Context) ->
|
||||
{rabbit_mgmt_util:responder_map(to_json), ReqData, Context}.
|
||||
|
||||
to_json(ReqData, Context) ->
|
||||
EnableUAA = application:get_env(rabbitmq_management, enable_uaa, false),
|
||||
Data = case EnableUAA of
|
||||
true ->
|
||||
UAAClientId = application:get_env(rabbitmq_management, uaa_client_id, ""),
|
||||
UAALocation = application:get_env(rabbitmq_management, uaa_location, ""),
|
||||
case is_invalid([UAAClientId, UAALocation]) of
|
||||
true ->
|
||||
rabbit_log:warning("Disabling OAuth 2 authorization, relevant configuration settings are missing", []),
|
||||
[{enable_uaa, false}, {uaa_client_id, <<>>}, {uaa_location, <<>>}];
|
||||
false ->
|
||||
[{enable_uaa, true},
|
||||
{uaa_client_id, rabbit_data_coercion:to_binary(UAAClientId)},
|
||||
{uaa_location, rabbit_data_coercion:to_binary(UAALocation)}]
|
||||
end;
|
||||
false ->
|
||||
[{enable_uaa, false}, {uaa_client_id, <<>>}, {uaa_location, <<>>}]
|
||||
end,
|
||||
rabbit_mgmt_util:reply(Data, ReqData, Context).
|
||||
|
||||
is_authorized(ReqData, Context) ->
|
||||
{true, ReqData, Context}.
|
||||
|
||||
is_invalid(List) ->
|
||||
lists:any(fun(V) -> V == "" end, List).
|
||||
|
|
@ -136,8 +136,15 @@ accept_multipart(ReqData0, Context) ->
|
|||
|
||||
is_authorized(ReqData, Context) ->
|
||||
case rabbit_mgmt_util:qs_val(<<"auth">>, ReqData) of
|
||||
undefined -> rabbit_mgmt_util:is_authorized_admin(ReqData, Context);
|
||||
Auth -> is_authorized_qs(ReqData, Context, Auth)
|
||||
undefined ->
|
||||
case rabbit_mgmt_util:qs_val(<<"token">>, ReqData) of
|
||||
Token ->
|
||||
rabbit_mgmt_util:is_authorized_admin(ReqData, Context, Token);
|
||||
undefined ->
|
||||
rabbit_mgmt_util:is_authorized_admin(ReqData, Context)
|
||||
end;
|
||||
Auth ->
|
||||
is_authorized_qs(ReqData, Context, Auth)
|
||||
end.
|
||||
|
||||
%% Support for the web UI - it can't add a normal "authorization"
|
||||
|
|
|
|||
|
|
@ -146,7 +146,8 @@ all_tests() -> [
|
|||
vhost_limit_set_test,
|
||||
rates_test,
|
||||
single_active_consumer_cq_test,
|
||||
single_active_consumer_qq_test].
|
||||
single_active_consumer_qq_test,
|
||||
oauth_test].
|
||||
|
||||
%% -------------------------------------------------------------------
|
||||
%% Testsuite setup/teardown.
|
||||
|
|
@ -3069,6 +3070,32 @@ stats_redirect_test(Config) ->
|
|||
assert_permanent_redirect(Config, "doc/stats.html", "/api/index.html"),
|
||||
passed.
|
||||
|
||||
oauth_test(Config) ->
|
||||
Map1 = http_get(Config, "/auth", ?OK),
|
||||
%% Defaults
|
||||
?assertEqual(false, maps:get(enable_uaa, Map1)),
|
||||
?assertEqual(<<>>, maps:get(uaa_client_id, Map1)),
|
||||
?assertEqual(<<>>, maps:get(uaa_location, Map1)),
|
||||
%% Misconfiguration
|
||||
rabbit_ct_broker_helpers:rpc(Config, 0, application, set_env,
|
||||
[rabbitmq_management, enable_uaa, true]),
|
||||
Map2 = http_get(Config, "/auth", ?OK),
|
||||
?assertEqual(false, maps:get(enable_uaa, Map2)),
|
||||
?assertEqual(<<>>, maps:get(uaa_client_id, Map2)),
|
||||
?assertEqual(<<>>, maps:get(uaa_location, Map2)),
|
||||
%% Valid config
|
||||
rabbit_ct_broker_helpers:rpc(Config, 0, application, set_env,
|
||||
[rabbitmq_management, uaa_client_id, "rabbit_user"]),
|
||||
rabbit_ct_broker_helpers:rpc(Config, 0, application, set_env,
|
||||
[rabbitmq_management, uaa_location, "http://localhost:8080/uaa"]),
|
||||
Map3 = http_get(Config, "/auth", ?OK),
|
||||
?assertEqual(true, maps:get(enable_uaa, Map3)),
|
||||
?assertEqual(<<"rabbit_user">>, maps:get(uaa_client_id, Map3)),
|
||||
?assertEqual(<<"http://localhost:8080/uaa">>, maps:get(uaa_location, Map3)),
|
||||
%% cleanup
|
||||
rabbit_ct_broker_helpers:rpc(Config, 0, application, unset_env,
|
||||
[rabbitmq_management, enable_uaa]).
|
||||
|
||||
%% -------------------------------------------------------------------
|
||||
%% Helpers.
|
||||
%% -------------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Reference in New Issue