diff --git a/apps/emqx/src/emqx_authentication.erl b/apps/emqx/src/emqx_authentication.erl index 4200190ac..40af0e7b7 100644 --- a/apps/emqx/src/emqx_authentication.erl +++ b/apps/emqx/src/emqx_authentication.erl @@ -303,8 +303,8 @@ authenticate(#{listener := Listener, protocol := Protocol} = Credential, _AuthRe do_authenticate([], _) -> {stop, {error, not_authorized}}; -do_authenticate([#authenticator{provider = Provider, state = State} | More], Credential) -> - case Provider:authenticate(Credential, State) of +do_authenticate([#authenticator{provider = Provider, state = #{'_unique' := Unique} = State} | More], Credential) -> + try Provider:authenticate(Credential, State) of ignore -> do_authenticate(More, Credential); Result -> @@ -314,6 +314,10 @@ do_authenticate([#authenticator{provider = Provider, state = State} | More], Cre %% {continue, AuthData, AuthCache} %% {error, Reason} {stop, Result} + catch + error:Reason:Stacktrace -> + ?LOG(warning, "The following error occurred in '~s' during authentication: ~p", [Unique, {Reason, Stacktrace}]), + do_authenticate(More, Credential) end. %%------------------------------------------------------------------------------ diff --git a/apps/emqx_authn/src/simple_authn/emqx_authn_http.erl b/apps/emqx_authn/src/simple_authn/emqx_authn_http.erl index 2fa29d2df..77a8a94c8 100644 --- a/apps/emqx_authn/src/simple_authn/emqx_authn_http.erl +++ b/apps/emqx_authn/src/simple_authn/emqx_authn_http.erl @@ -156,26 +156,20 @@ authenticate(#{auth_method := _}, _) -> authenticate(Credential, #{'_unique' := Unique, method := Method, request_timeout := RequestTimeout} = State) -> - try - Request = generate_request(Credential, State), - case emqx_resource:query(Unique, {Method, Request, RequestTimeout}) of - {ok, 204, _Headers} -> {ok, #{is_superuser => false}}; - {ok, 200, Headers, Body} -> - ContentType = proplists:get_value(<<"content-type">>, Headers, <<"application/json">>), - case safely_parse_body(ContentType, Body) of - {ok, NBody} -> - %% TODO: Return by user property - {ok, #{is_superuser => maps:get(<<"is_superuser">>, NBody, false), - user_property => NBody}}; - {error, _Reason} -> - {ok, #{is_superuser => false}} - end; - {error, _Reason} -> - ignore - end - catch - error:Reason -> - ?LOG(warning, "The following error occurred in '~s' during authentication: ~p", [Unique, Reason]), + Request = generate_request(Credential, State), + case emqx_resource:query(Unique, {Method, Request, RequestTimeout}) of + {ok, 204, _Headers} -> {ok, #{is_superuser => false}}; + {ok, 200, Headers, Body} -> + ContentType = proplists:get_value(<<"content-type">>, Headers, <<"application/json">>), + case safely_parse_body(ContentType, Body) of + {ok, NBody} -> + %% TODO: Return by user property + {ok, #{is_superuser => maps:get(<<"is_superuser">>, NBody, false), + user_property => NBody}}; + {error, _Reason} -> + {ok, #{is_superuser => false}} + end; + {error, _Reason} -> ignore end. diff --git a/apps/emqx_authn/src/simple_authn/emqx_authn_mongodb.erl b/apps/emqx_authn/src/simple_authn/emqx_authn_mongodb.erl index 5ad148009..d348a439c 100644 --- a/apps/emqx_authn/src/simple_authn/emqx_authn_mongodb.erl +++ b/apps/emqx_authn/src/simple_authn/emqx_authn_mongodb.erl @@ -141,29 +141,23 @@ authenticate(#{password := Password} = Credential, , selector := Selector0 , '_unique' := Unique } = State) -> - try - Selector1 = replace_placeholders(Selector0, Credential), - Selector2 = normalize_selector(Selector1), - case emqx_resource:query(Unique, {find_one, Collection, Selector2, #{}}) of - undefined -> ignore; - {error, Reason} -> - ?LOG(error, "['~s'] Query failed: ~p", [Unique, Reason]), - ignore; - Doc -> - case check_password(Password, Doc, State) of - ok -> - {ok, #{is_superuser => is_superuser(Doc, State)}}; - {error, {cannot_find_password_hash_field, PasswordHashField}} -> - ?LOG(error, "['~s'] Can't find password hash field: ~s", [Unique, PasswordHashField]), - {error, bad_username_or_password}; - {error, Reason} -> - {error, Reason} - end - end - catch - error:Error -> - ?LOG(warning, "The following error occurred in '~s' during authentication: ~p", [Unique, Error]), - ignore + Selector1 = replace_placeholders(Selector0, Credential), + Selector2 = normalize_selector(Selector1), + case emqx_resource:query(Unique, {find_one, Collection, Selector2, #{}}) of + undefined -> ignore; + {error, Reason} -> + ?LOG(error, "['~s'] Query failed: ~p", [Unique, Reason]), + ignore; + Doc -> + case check_password(Password, Doc, State) of + ok -> + {ok, #{is_superuser => is_superuser(Doc, State)}}; + {error, {cannot_find_password_hash_field, PasswordHashField}} -> + ?LOG(error, "['~s'] Can't find password hash field: ~s", [Unique, PasswordHashField]), + {error, bad_username_or_password}; + {error, Reason} -> + {error, Reason} + end end. destroy(#{'_unique' := Unique}) -> diff --git a/apps/emqx_authn/src/simple_authn/emqx_authn_mysql.erl b/apps/emqx_authn/src/simple_authn/emqx_authn_mysql.erl index 87c61da1e..2f614a249 100644 --- a/apps/emqx_authn/src/simple_authn/emqx_authn_mysql.erl +++ b/apps/emqx_authn/src/simple_authn/emqx_authn_mysql.erl @@ -114,24 +114,18 @@ authenticate(#{password := Password} = Credential, query := Query, query_timeout := Timeout, '_unique' := Unique} = State) -> - try - Params = emqx_authn_utils:replace_placeholders(PlaceHolders, Credential), - case emqx_resource:query(Unique, {sql, Query, Params, Timeout}) of - {ok, _Columns, []} -> ignore; - {ok, Columns, Rows} -> - Selected = maps:from_list(lists:zip(Columns, Rows)), - case check_password(Password, Selected, State) of - ok -> - {ok, #{is_superuser => maps:get(<<"is_superuser">>, Selected, false)}}; - {error, Reason} -> - {error, Reason} - end; - {error, _Reason} -> - ignore - end - catch - error:Error -> - ?LOG(warning, "The following error occurred in '~s' during authentication: ~p", [Unique, Error]), + Params = emqx_authn_utils:replace_placeholders(PlaceHolders, Credential), + case emqx_resource:query(Unique, {sql, Query, Params, Timeout}) of + {ok, _Columns, []} -> ignore; + {ok, Columns, Rows} -> + Selected = maps:from_list(lists:zip(Columns, Rows)), + case check_password(Password, Selected, State) of + ok -> + {ok, #{is_superuser => maps:get(<<"is_superuser">>, Selected, false)}}; + {error, Reason} -> + {error, Reason} + end; + {error, _Reason} -> ignore end. diff --git a/apps/emqx_authn/src/simple_authn/emqx_authn_pgsql.erl b/apps/emqx_authn/src/simple_authn/emqx_authn_pgsql.erl index 940c50519..78632610e 100644 --- a/apps/emqx_authn/src/simple_authn/emqx_authn_pgsql.erl +++ b/apps/emqx_authn/src/simple_authn/emqx_authn_pgsql.erl @@ -103,25 +103,19 @@ authenticate(#{password := Password} = Credential, #{query := Query, placeholders := PlaceHolders, '_unique' := Unique} = State) -> - try - Params = emqx_authn_utils:replace_placeholders(PlaceHolders, Credential), - case emqx_resource:query(Unique, {sql, Query, Params}) of - {ok, _Columns, []} -> ignore; - {ok, Columns, Rows} -> - NColumns = [Name || #column{name = Name} <- Columns], - Selected = maps:from_list(lists:zip(NColumns, Rows)), - case check_password(Password, Selected, State) of - ok -> - {ok, #{is_superuser => maps:get(<<"is_superuser">>, Selected, false)}}; - {error, Reason} -> - {error, Reason} - end; - {error, _Reason} -> - ignore - end - catch - error:Error -> - ?LOG(warning, "The following error occurred in '~s' during authentication: ~p", [Unique, Error]), + Params = emqx_authn_utils:replace_placeholders(PlaceHolders, Credential), + case emqx_resource:query(Unique, {sql, Query, Params}) of + {ok, _Columns, []} -> ignore; + {ok, Columns, Rows} -> + NColumns = [Name || #column{name = Name} <- Columns], + Selected = maps:from_list(lists:zip(NColumns, Rows)), + case check_password(Password, Selected, State) of + ok -> + {ok, #{is_superuser => maps:get(<<"is_superuser">>, Selected, false)}}; + {error, Reason} -> + {error, Reason} + end; + {error, _Reason} -> ignore end. diff --git a/apps/emqx_authn/src/simple_authn/emqx_authn_redis.erl b/apps/emqx_authn/src/simple_authn/emqx_authn_redis.erl index 5926740a8..5d73f9410 100644 --- a/apps/emqx_authn/src/simple_authn/emqx_authn_redis.erl +++ b/apps/emqx_authn/src/simple_authn/emqx_authn_redis.erl @@ -127,24 +127,18 @@ authenticate(#{password := Password} = Credential, #{ query := {Command, Key, Fields} , '_unique' := Unique } = State) -> - try - NKey = binary_to_list(iolist_to_binary(replace_placeholders(Key, Credential))), - case emqx_resource:query(Unique, {cmd, [Command, NKey | Fields]}) of - {ok, Values} -> - Selected = merge(Fields, Values), - case check_password(Password, Selected, State) of - ok -> - {ok, #{is_superuser => maps:get("is_superuser", Selected, false)}}; - {error, Reason} -> - {error, Reason} - end; - {error, Reason} -> - ?LOG(error, "['~s'] Query failed: ~p", [Unique, Reason]), - ignore - end - catch - error:{cannot_get_variable, Placeholder} -> - ?LOG(warning, "The following error occurred in '~s' during authentication: ~p", [Unique, {cannot_get_variable, Placeholder}]), + NKey = binary_to_list(iolist_to_binary(replace_placeholders(Key, Credential))), + case emqx_resource:query(Unique, {cmd, [Command, NKey | Fields]}) of + {ok, Values} -> + Selected = merge(Fields, Values), + case check_password(Password, Selected, State) of + ok -> + {ok, #{is_superuser => maps:get("is_superuser", Selected, false)}}; + {error, Reason} -> + {error, Reason} + end; + {error, Reason} -> + ?LOG(error, "['~s'] Query failed: ~p", [Unique, Reason]), ignore end. diff --git a/apps/emqx_connector/src/emqx_connector_mysql.erl b/apps/emqx_connector/src/emqx_connector_mysql.erl index 9dc194c55..0cd051512 100644 --- a/apps/emqx_connector/src/emqx_connector_mysql.erl +++ b/apps/emqx_connector/src/emqx_connector_mysql.erl @@ -76,11 +76,13 @@ on_stop(InstId, #{poolname := PoolName}) -> logger:info("stopping mysql connector: ~p", [InstId]), emqx_plugin_libs_pool:stop_pool(PoolName). -on_query(InstId, {sql, SQL}, AfterQuery, #{poolname := PoolName} = State) -> - on_query(InstId, {sql, SQL, []}, AfterQuery, #{poolname := PoolName} = State); -on_query(InstId, {sql, SQL, Params}, AfterQuery, #{poolname := PoolName} = State) -> +on_query(InstId, {sql, SQL}, AfterQuery, #{poolname := _PoolName} = State) -> + on_query(InstId, {sql, SQL, [], default_timeout}, AfterQuery, State); +on_query(InstId, {sql, SQL, Params}, AfterQuery, #{poolname := _PoolName} = State) -> + on_query(InstId, {sql, SQL, Params, default_timeout}, AfterQuery, State); +on_query(InstId, {sql, SQL, Params, Timeout}, AfterQuery, #{poolname := PoolName} = State) -> logger:debug("mysql connector ~p received sql query: ~p, at state: ~p", [InstId, SQL, State]), - case Result = ecpool:pick_and_do(PoolName, {mysql, query, [SQL, Params]}, no_handover) of + case Result = ecpool:pick_and_do(PoolName, {mysql, query, [SQL, Params, Timeout]}, no_handover) of {error, Reason} -> logger:debug("mysql connector ~p do sql query failed, sql: ~p, reason: ~p", [InstId, SQL, Reason]), emqx_resource:query_failed(AfterQuery); diff --git a/apps/emqx_connector/src/emqx_connector_pgsql.erl b/apps/emqx_connector/src/emqx_connector_pgsql.erl index 8472c661e..31e954b3c 100644 --- a/apps/emqx_connector/src/emqx_connector_pgsql.erl +++ b/apps/emqx_connector/src/emqx_connector_pgsql.erl @@ -76,8 +76,8 @@ on_stop(InstId, #{poolname := PoolName}) -> logger:info("stopping postgresql connector: ~p", [InstId]), emqx_plugin_libs_pool:stop_pool(PoolName). -on_query(InstId, {sql, SQL}, AfterQuery, #{poolname := PoolName} = State) -> - on_query(InstId, {sql, SQL, []}, AfterQuery, #{poolname := PoolName} = State); +on_query(InstId, {sql, SQL}, AfterQuery, #{poolname := _PoolName} = State) -> + on_query(InstId, {sql, SQL, []}, AfterQuery, State); on_query(InstId, {sql, SQL, Params}, AfterQuery, #{poolname := PoolName} = State) -> logger:debug("postgresql connector ~p received sql query: ~p, at state: ~p", [InstId, SQL, State]), case Result = ecpool:pick_and_do(PoolName, {?MODULE, query, [SQL, Params]}, no_handover) of