feat(dashboard): Support swagger dashboard API
This commit is contained in:
parent
569d54a4c0
commit
eac9420170
|
@ -1,5 +1,5 @@
|
||||||
##--------------------------------------------------------------------
|
##--------------------------------------------------------------------
|
||||||
## Dashboard for EMQ X
|
## EMQ X Dashboard
|
||||||
##--------------------------------------------------------------------
|
##--------------------------------------------------------------------
|
||||||
|
|
||||||
emqx_dashboard:{
|
emqx_dashboard:{
|
||||||
|
@ -20,7 +20,7 @@ emqx_dashboard:{
|
||||||
## ,
|
## ,
|
||||||
## {
|
## {
|
||||||
## protocol: https
|
## protocol: https
|
||||||
## port: 8081
|
## port: 18084
|
||||||
## acceptors: 2
|
## acceptors: 2
|
||||||
## backlog: 512
|
## backlog: 512
|
||||||
## send_timeout: 15s
|
## send_timeout: 15s
|
||||||
|
|
|
@ -16,95 +16,226 @@
|
||||||
|
|
||||||
-module(emqx_dashboard_api).
|
-module(emqx_dashboard_api).
|
||||||
|
|
||||||
|
-behaviour(minirest_api).
|
||||||
|
|
||||||
-include("emqx_dashboard.hrl").
|
-include("emqx_dashboard.hrl").
|
||||||
|
|
||||||
-rest_api(#{name => auth_user,
|
-import(emqx_mgmt_util, [ response_schema/1
|
||||||
method => 'POST',
|
, response_schema/2
|
||||||
path => "/auth",
|
, request_body_schema/1
|
||||||
func => auth,
|
, response_array_schema/2
|
||||||
descr => "Authenticate an user"
|
]).
|
||||||
}).
|
|
||||||
|
|
||||||
-rest_api(#{name => create_user,
|
-export([api_spec/0]).
|
||||||
method => 'POST',
|
|
||||||
path => "/users/",
|
|
||||||
func => create,
|
|
||||||
descr => "Create an user"
|
|
||||||
}).
|
|
||||||
|
|
||||||
-rest_api(#{name => list_users,
|
-export([ auth/2
|
||||||
method => 'GET',
|
, users/2
|
||||||
path => "/users/",
|
, user/2
|
||||||
func => list,
|
|
||||||
descr => "List users"
|
|
||||||
}).
|
|
||||||
|
|
||||||
-rest_api(#{name => update_user,
|
|
||||||
method => 'PUT',
|
|
||||||
path => "/users/:bin:name",
|
|
||||||
func => update,
|
|
||||||
descr => "Update an user"
|
|
||||||
}).
|
|
||||||
|
|
||||||
-rest_api(#{name => delete_user,
|
|
||||||
method => 'DELETE',
|
|
||||||
path => "/users/:bin:name",
|
|
||||||
func => delete,
|
|
||||||
descr => "Delete an user"
|
|
||||||
}).
|
|
||||||
|
|
||||||
-rest_api(#{name => change_pwd,
|
|
||||||
method => 'PUT',
|
|
||||||
path => "/change_pwd/:bin:username",
|
|
||||||
func => change_pwd,
|
|
||||||
descr => "Change password for an user"
|
|
||||||
}).
|
|
||||||
|
|
||||||
-export([ list/2
|
|
||||||
, create/2
|
|
||||||
, update/2
|
|
||||||
, delete/2
|
|
||||||
, auth/2
|
|
||||||
, change_pwd/2
|
, change_pwd/2
|
||||||
]).
|
]).
|
||||||
|
|
||||||
|
api_spec() ->
|
||||||
|
{[auth_api(), users_api(), user_api(), change_pwd_api()], schemas()}.
|
||||||
|
|
||||||
|
schemas() ->
|
||||||
|
[#{auth => #{
|
||||||
|
type => object,
|
||||||
|
properties => #{
|
||||||
|
username => #{
|
||||||
|
type => string,
|
||||||
|
description => <<"Username">>},
|
||||||
|
password => #{
|
||||||
|
type => string,
|
||||||
|
description => <<"password">>}
|
||||||
|
}
|
||||||
|
}},
|
||||||
|
#{show_user => #{
|
||||||
|
type => object,
|
||||||
|
properties => #{
|
||||||
|
username => #{
|
||||||
|
type => string,
|
||||||
|
description => <<"Username">>},
|
||||||
|
tag => #{
|
||||||
|
type => string,
|
||||||
|
description => <<"Tag">>}
|
||||||
|
}
|
||||||
|
}},
|
||||||
|
#{create_user => #{
|
||||||
|
type => object,
|
||||||
|
properties => #{
|
||||||
|
username => #{
|
||||||
|
type => string,
|
||||||
|
description => <<"Username">>},
|
||||||
|
password => #{
|
||||||
|
type => string,
|
||||||
|
description => <<"Password">>},
|
||||||
|
tag => #{
|
||||||
|
type => string,
|
||||||
|
description => <<"Tag">>}
|
||||||
|
}
|
||||||
|
}}].
|
||||||
|
|
||||||
|
auth_api() ->
|
||||||
|
Metadata = #{
|
||||||
|
post => #{
|
||||||
|
description => <<"Dashboard Auth">>,
|
||||||
|
'requestBody' => request_body_schema(auth),
|
||||||
|
responses => #{
|
||||||
|
<<"200">> =>
|
||||||
|
response_schema(<<"Dashboard Auth successfully">>),
|
||||||
|
<<"400">> => bad_request()
|
||||||
|
},
|
||||||
|
security => []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{"/auth", Metadata, auth}.
|
||||||
|
|
||||||
|
users_api() ->
|
||||||
|
Metadata = #{
|
||||||
|
get => #{
|
||||||
|
description => <<"Get dashboard users">>,
|
||||||
|
responses => #{
|
||||||
|
<<"200">> => response_array_schema(<<"">>, show_user)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{"/users", Metadata, users}.
|
||||||
|
|
||||||
|
user_api() ->
|
||||||
|
Metadata = #{
|
||||||
|
delete => #{
|
||||||
|
description => <<"Delete dashboard users">>,
|
||||||
|
responses => #{
|
||||||
|
<<"200">> => response_schema(<<"Delete User successfully">>),
|
||||||
|
<<"400">> => bad_request()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
put => #{
|
||||||
|
description => <<"Update dashboard users">>,
|
||||||
|
'requestBody' => request_body_schema(#{
|
||||||
|
type => object,
|
||||||
|
properties => #{
|
||||||
|
tags => #{
|
||||||
|
type => string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
responses => #{
|
||||||
|
<<"200">> => response_schema(<<"Update Users successfully">>),
|
||||||
|
<<"400">> => bad_request()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
post => #{
|
||||||
|
description => <<"Create dashboard users">>,
|
||||||
|
'requestBody' => request_body_schema(create_user),
|
||||||
|
responses => #{
|
||||||
|
<<"200">> => response_schema(<<"Create Users successfully">>),
|
||||||
|
<<"400">> => bad_request()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{"/users/:username", Metadata, user}.
|
||||||
|
|
||||||
|
change_pwd_api() ->
|
||||||
|
Metadata = #{
|
||||||
|
put => #{
|
||||||
|
description => <<"Update dashboard users password">>,
|
||||||
|
'requestBody' => request_body_schema(#{
|
||||||
|
type => object,
|
||||||
|
properties => #{
|
||||||
|
old_pwd => #{
|
||||||
|
type => string
|
||||||
|
},
|
||||||
|
new_pwd => #{
|
||||||
|
type => string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
responses => #{
|
||||||
|
<<"200">> => response_schema(<<"Update Users password successfully">>),
|
||||||
|
<<"400">> => bad_request()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{"/change_pwd/:username", Metadata, change_pwd}.
|
||||||
|
|
||||||
-define(EMPTY(V), (V == undefined orelse V == <<>>)).
|
-define(EMPTY(V), (V == undefined orelse V == <<>>)).
|
||||||
|
|
||||||
auth(_Bindings, Params) ->
|
auth(post, Request) ->
|
||||||
Username = proplists:get_value(<<"username">>, Params),
|
{ok, Body, _} = cowboy_req:read_body(Request),
|
||||||
Password = proplists:get_value(<<"password">>, Params),
|
Params = emqx_json:decode(Body, [return_maps]),
|
||||||
return(emqx_dashboard_admin:check(Username, Password)).
|
Username = maps:get(<<"username">>, Params),
|
||||||
|
Password = maps:get(<<"password">>, Params),
|
||||||
|
case emqx_dashboard_admin:check(Username, Password) of
|
||||||
|
ok ->
|
||||||
|
{200};
|
||||||
|
{error, Reason} ->
|
||||||
|
{400, #{code => <<"AUTH_FAIL">>, message => Reason}}
|
||||||
|
end.
|
||||||
|
|
||||||
change_pwd(#{username := Username}, Params) ->
|
users(get, _Request) ->
|
||||||
OldPwd = proplists:get_value(<<"old_pwd">>, Params),
|
{200, [row(User) || User <- emqx_dashboard_admin:all_users()]}.
|
||||||
NewPwd = proplists:get_value(<<"new_pwd">>, Params),
|
|
||||||
return(emqx_dashboard_admin:change_password(Username, OldPwd, NewPwd)).
|
|
||||||
|
|
||||||
create(_Bindings, Params) ->
|
user(put, Request) ->
|
||||||
Username = proplists:get_value(<<"username">>, Params),
|
Username = cowboy_req:binding(username, Request),
|
||||||
Password = proplists:get_value(<<"password">>, Params),
|
{ok, Body, _} = cowboy_req:read_body(Request),
|
||||||
Tags = proplists:get_value(<<"tags">>, Params),
|
Params = emqx_json:decode(Body, [return_maps]),
|
||||||
return(case ?EMPTY(Username) orelse ?EMPTY(Password) of
|
Tags = maps:get(<<"tags">>, Params),
|
||||||
true -> {error, <<"Username or password undefined">>};
|
case emqx_dashboard_admin:update_user(Username, Tags) of
|
||||||
false -> emqx_dashboard_admin:add_user(Username, Password, Tags)
|
ok -> {200};
|
||||||
end).
|
{error, Reason} ->
|
||||||
|
{400, #{code => <<"UPDATE_FAIL">>, message => Reason}}
|
||||||
|
end;
|
||||||
|
|
||||||
list(_Bindings, _Params) ->
|
user(delete, Request) ->
|
||||||
return({ok, [row(User) || User <- emqx_dashboard_admin:all_users()]}).
|
Username = cowboy_req:binding(username, Request),
|
||||||
|
case Username == <<"admin">> of
|
||||||
|
true -> {400, #{code => <<"CONNOT_DELETE_ADMIN">>,
|
||||||
|
message => <<"Cannot delete admin">>}};
|
||||||
|
false ->
|
||||||
|
_ = emqx_dashboard_admin:remove_user(Username),
|
||||||
|
{200}
|
||||||
|
end;
|
||||||
|
|
||||||
update(#{name := Username}, Params) ->
|
user(post, Request) ->
|
||||||
Tags = proplists:get_value(<<"tags">>, Params),
|
{ok, Body, _} = cowboy_req:read_body(Request),
|
||||||
return(emqx_dashboard_admin:update_user(Username, Tags)).
|
Params = emqx_json:decode(Body, [return_maps]),
|
||||||
|
Tags = maps:get(<<"tags">>, Params),
|
||||||
|
Username = maps:get(<<"username">>, Params),
|
||||||
|
Password = maps:get(<<"password">>, Params),
|
||||||
|
case ?EMPTY(Username) orelse ?EMPTY(Password) of
|
||||||
|
true ->
|
||||||
|
{400, #{code => <<"CREATE_USER_FAIL">>,
|
||||||
|
message => <<"Username or password undefined">>}};
|
||||||
|
false ->
|
||||||
|
case emqx_dashboard_admin:add_user(Username, Password, Tags) of
|
||||||
|
ok -> {200};
|
||||||
|
{error, Reason} ->
|
||||||
|
{400, #{code => <<"CREATE_USER_FAIL">>, message => Reason}}
|
||||||
|
end
|
||||||
|
end.
|
||||||
|
|
||||||
delete(#{name := <<"admin">>}, _Params) ->
|
change_pwd(put, Request) ->
|
||||||
return({error, <<"Cannot delete admin">>});
|
Username = cowboy_req:binding(username, Request),
|
||||||
|
{ok, Body, _} = cowboy_req:read_body(Request),
|
||||||
delete(#{name := Username}, _Params) ->
|
Params = emqx_json:decode(Body, [return_maps]),
|
||||||
return(emqx_dashboard_admin:remove_user(Username)).
|
OldPwd = maps:get(<<"old_pwd">>, Params),
|
||||||
|
NewPwd = maps:get(<<"new_pwd">>, Params),
|
||||||
|
case emqx_dashboard_admin:change_password(Username, OldPwd, NewPwd) of
|
||||||
|
ok -> {200};
|
||||||
|
{error, Reason} ->
|
||||||
|
{400, #{code => <<"CHANGE_PWD_FAIL">>, message => Reason}}
|
||||||
|
end.
|
||||||
|
|
||||||
row(#mqtt_admin{username = Username, tags = Tags}) ->
|
row(#mqtt_admin{username = Username, tags = Tags}) ->
|
||||||
#{username => Username, tags => Tags}.
|
#{username => Username, tags => Tags}.
|
||||||
|
|
||||||
return(_) ->
|
bad_request() ->
|
||||||
%% TODO: V5 API
|
response_schema(<<"Bad Request">>,
|
||||||
ok.
|
#{
|
||||||
|
type => object,
|
||||||
|
properties => #{
|
||||||
|
message => #{type => string},
|
||||||
|
code => #{type => string}
|
||||||
|
}
|
||||||
|
}).
|
||||||
|
|
Loading…
Reference in New Issue