http_auth_server.erl 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. -module(http_auth_server).
  2. -export([ start/2
  3. , stop/0
  4. ]).
  5. -define(SUPERUSER, [[{"username", "superuser"}, {"clientid", "superclient"}]]).
  6. -define(ACL, [[{<<"username">>, <<"testuser">>},
  7. {<<"clientid">>, <<"client1">>},
  8. {<<"access">>, <<"1">>},
  9. {<<"topic">>, <<"users/testuser/1">>},
  10. {<<"ipaddr">>, <<"127.0.0.1">>},
  11. {<<"mountpoint">>, <<"null">>}],
  12. [{<<"username">>, <<"xyz">>},
  13. {<<"clientid">>, <<"client2">>},
  14. {<<"access">>, <<"2">>},
  15. {<<"topic">>, <<"a/b/c">>},
  16. {<<"ipaddr">>, <<"192.168.1.3">>},
  17. {<<"mountpoint">>, <<"null">>}],
  18. [{<<"username">>, <<"testuser1">>},
  19. {<<"clientid">>, <<"client1">>},
  20. {<<"access">>, <<"2">>},
  21. {<<"topic">>, <<"topic">>},
  22. {<<"ipaddr">>, <<"127.0.0.1">>},
  23. {<<"mountpoint">>, <<"null">>}],
  24. [{<<"username">>, <<"testuser2">>},
  25. {<<"clientid">>, <<"client2">>},
  26. {<<"access">>, <<"1">>},
  27. {<<"topic">>, <<"topic">>},
  28. {<<"ipaddr">>, <<"127.0.0.1">>},
  29. {<<"mountpoint">>, <<"null">>}]]).
  30. -define(AUTH, [[{<<"clientid">>, <<"client1">>},
  31. {<<"username">>, <<"testuser1">>},
  32. {<<"password">>, <<"pass1">>}],
  33. [{<<"clientid">>, <<"client2">>},
  34. {<<"username">>, <<"testuser2">>},
  35. {<<"password">>, <<"pass2">>}]]).
  36. %%------------------------------------------------------------------------------
  37. %% REST Interface
  38. %%------------------------------------------------------------------------------
  39. -rest_api(#{ name => auth
  40. , method => 'GET'
  41. , path => "/mqtt/auth"
  42. , func => authenticate
  43. , descr => "Authenticate user access permission"
  44. }).
  45. -rest_api(#{ name => is_superuser
  46. , method => 'GET'
  47. , path => "/mqtt/superuser"
  48. , func => is_superuser
  49. , descr => "Is super user"
  50. }).
  51. -rest_api(#{ name => acl
  52. , method => 'GET'
  53. , path => "/mqtt/acl"
  54. , func => check_acl
  55. , descr => "Check acl"
  56. }).
  57. -rest_api(#{ name => auth
  58. , method => 'POST'
  59. , path => "/mqtt/auth"
  60. , func => authenticate
  61. , descr => "Authenticate user access permission"
  62. }).
  63. -rest_api(#{ name => is_superuser
  64. , method => 'POST'
  65. , path => "/mqtt/superuser"
  66. , func => is_superuser
  67. , descr => "Is super user"
  68. }).
  69. -rest_api(#{ name => acl
  70. , method => 'POST'
  71. , path => "/mqtt/acl"
  72. , func => check_acl
  73. , descr => "Check acl"
  74. }).
  75. -export([ authenticate/2
  76. , is_superuser/2
  77. , check_acl/2
  78. ]).
  79. authenticate(_Binding, Params) ->
  80. return(check(Params, ?AUTH)).
  81. is_superuser(_Binding, Params) ->
  82. return(check(Params, ?SUPERUSER)).
  83. check_acl(_Binding, Params) ->
  84. return(check(Params, ?ACL)).
  85. return(allow) -> {200, <<"allow">>};
  86. return(deny) -> {400, <<"deny">>}.
  87. start(http, Inet) ->
  88. application:ensure_all_started(minirest),
  89. Handlers = [{"/", minirest:handler(#{modules => [?MODULE]})}],
  90. Dispatch = [{"/[...]", minirest, Handlers}],
  91. minirest:start_http(http_auth_server, #{socket_opts => [Inet, {port, 8991}]}, Dispatch);
  92. start(https, Inet) ->
  93. application:ensure_all_started(minirest),
  94. Handlers = [{"/", minirest:handler(#{modules => [?MODULE]})}],
  95. Dispatch = [{"/[...]", minirest, Handlers}],
  96. minirest:start_https(http_auth_server, #{socket_opts => [Inet, {port, 8991} | certopts()]}, Dispatch).
  97. %% @private
  98. certopts() ->
  99. Certfile = filename:join(["etc", "certs", "cert.pem"]),
  100. Keyfile = filename:join(["etc", "certs", "key.pem"]),
  101. CaCert = filename:join(["etc", "certs", "cacert.pem"]),
  102. [{verify, verify_peer},
  103. {certfile, emqx_ct_helpers:deps_path(emqx, Certfile)},
  104. {keyfile, emqx_ct_helpers:deps_path(emqx, Keyfile)},
  105. {cacertfile, emqx_ct_helpers:deps_path(emqx, CaCert)}] ++ emqx_ct_helpers:client_ssl().
  106. stop() ->
  107. minirest:stop_http(http_auth_server).
  108. -spec check(HttpReqParams :: list(), DefinedConf :: list()) -> allow | deny.
  109. check(_Params, []) ->
  110. %ct:pal("check auth_result: deny~n"),
  111. deny;
  112. check(Params, [ConfRecord|T]) ->
  113. % ct:pal("Params: ~p, ConfRecord:~p ~n", [Params, ConfRecord]),
  114. case match_config(Params, ConfRecord) of
  115. not_match ->
  116. check(Params, T);
  117. matched -> allow
  118. end.
  119. match_config([], _ConfigColumn) ->
  120. %ct:pal("match_config auth_result: matched~n"),
  121. matched;
  122. match_config([Param|T], ConfigColumn) ->
  123. %ct:pal("Param: ~p, ConfigColumn:~p ~n", [Param, ConfigColumn]),
  124. case lists:member(Param, ConfigColumn) of
  125. true ->
  126. match_config(T, ConfigColumn);
  127. false ->
  128. not_match
  129. end.