Merge pull request #9241 from thalesmg/rule-jwt-worker-v44
feat: add jwt worker for rule actions
This commit is contained in:
commit
746cdef546
|
@ -28,3 +28,5 @@
|
||||||
-define(bound_v(Key, ENVS0),
|
-define(bound_v(Key, ENVS0),
|
||||||
maps:get(Key,
|
maps:get(Key,
|
||||||
maps:get(?BINDING_KEYS, ENVS0, #{}))).
|
maps:get(?BINDING_KEYS, ENVS0, #{}))).
|
||||||
|
|
||||||
|
-define(JWT_TABLE, emqx_rule_engine_jwt_table).
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
%% -*- mode: erlang -*-
|
%% -*- mode: erlang -*-
|
||||||
{deps, []}.
|
{deps, [ {jose, {git, "https://github.com/emqx/erlang-jose", {tag, "emqx-1.11.3"}}}
|
||||||
|
]}.
|
||||||
|
|
||||||
%% Comple Opts
|
%% Comple Opts
|
||||||
{erl_opts, [warn_unused_vars,
|
{erl_opts, [warn_unused_vars,
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
[{description, "EMQ X Rule Engine"},
|
[{description, "EMQ X Rule Engine"},
|
||||||
{vsn, "4.4.11"}, % strict semver, bump manually!
|
{vsn, "4.4.11"}, % strict semver, bump manually!
|
||||||
{modules, []},
|
{modules, []},
|
||||||
{registered, [emqx_rule_engine_sup, emqx_rule_registry]},
|
{registered, [emqx_rule_engine_sup, emqx_rule_registry, emqx_rule_engine_jwt_sup]},
|
||||||
{applications, [kernel,stdlib,rulesql,getopt]},
|
{applications, [kernel,stdlib,rulesql,getopt,jose]},
|
||||||
{mod, {emqx_rule_engine_app, []}},
|
{mod, {emqx_rule_engine_app, []}},
|
||||||
{env, []},
|
{env, []},
|
||||||
{licenses, ["Apache-2.0"]},
|
{licenses, ["Apache-2.0"]},
|
||||||
|
|
|
@ -2,7 +2,12 @@
|
||||||
%% Unless you know what you are doing, DO NOT edit manually!!
|
%% Unless you know what you are doing, DO NOT edit manually!!
|
||||||
{VSN,
|
{VSN,
|
||||||
[{"4.4.10",
|
[{"4.4.10",
|
||||||
[{load_module,emqx_rule_utils,brutal_purge,soft_purge,[]},
|
[{add_module,emqx_rule_engine_jwt},
|
||||||
|
{add_module,emqx_rule_engine_jwt_worker},
|
||||||
|
{add_module,emqx_rule_engine_jwt_sup},
|
||||||
|
{load_module,emqx_rule_engine_sup,brutal_purge,soft_purge,[]},
|
||||||
|
{apply,{emqx_rule_engine_sup,start_jwt_sup,[]}},
|
||||||
|
{load_module,emqx_rule_utils,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_events,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_events,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
||||||
|
@ -12,7 +17,12 @@
|
||||||
{load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.4.9",
|
{"4.4.9",
|
||||||
[{load_module,emqx_rule_utils,brutal_purge,soft_purge,[]},
|
[{add_module,emqx_rule_engine_jwt},
|
||||||
|
{add_module,emqx_rule_engine_jwt_worker},
|
||||||
|
{add_module,emqx_rule_engine_jwt_sup},
|
||||||
|
{load_module,emqx_rule_engine_sup,brutal_purge,soft_purge,[]},
|
||||||
|
{apply,{emqx_rule_engine_sup,start_jwt_sup,[]}},
|
||||||
|
{load_module,emqx_rule_utils,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_events,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_events,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
||||||
|
@ -23,7 +33,12 @@
|
||||||
{load_module,emqx_rule_metrics,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_metrics,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.4.8",
|
{"4.4.8",
|
||||||
[{load_module,emqx_rule_utils,brutal_purge,soft_purge,[]},
|
[{add_module,emqx_rule_engine_jwt},
|
||||||
|
{add_module,emqx_rule_engine_jwt_worker},
|
||||||
|
{add_module,emqx_rule_engine_jwt_sup},
|
||||||
|
{load_module,emqx_rule_engine_sup,brutal_purge,soft_purge,[]},
|
||||||
|
{apply,{emqx_rule_engine_sup,start_jwt_sup,[]}},
|
||||||
|
{load_module,emqx_rule_utils,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_events,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_events,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
||||||
|
@ -35,7 +50,12 @@
|
||||||
{load_module,emqx_rule_metrics,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_metrics,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}]},
|
||||||
{<<"4\\.4\\.[6-7]">>,
|
{<<"4\\.4\\.[6-7]">>,
|
||||||
[{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
[{add_module,emqx_rule_engine_jwt},
|
||||||
|
{add_module,emqx_rule_engine_jwt_worker},
|
||||||
|
{add_module,emqx_rule_engine_jwt_sup},
|
||||||
|
{load_module,emqx_rule_engine_sup,brutal_purge,soft_purge,[]},
|
||||||
|
{apply,{emqx_rule_engine_sup,start_jwt_sup,[]}},
|
||||||
|
{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_events,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_events,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_funcs,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_funcs,brutal_purge,soft_purge,[]},
|
||||||
|
@ -48,7 +68,12 @@
|
||||||
{load_module,emqx_rule_actions,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_actions,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.4.5",
|
{"4.4.5",
|
||||||
[{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
[{add_module,emqx_rule_engine_jwt},
|
||||||
|
{add_module,emqx_rule_engine_jwt_worker},
|
||||||
|
{add_module,emqx_rule_engine_jwt_sup},
|
||||||
|
{load_module,emqx_rule_engine_sup,brutal_purge,soft_purge,[]},
|
||||||
|
{apply,{emqx_rule_engine_sup,start_jwt_sup,[]}},
|
||||||
|
{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_events,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_events,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_funcs,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_funcs,brutal_purge,soft_purge,[]},
|
||||||
|
@ -62,7 +87,12 @@
|
||||||
{load_module,emqx_rule_validator,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_validator,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.4.4",
|
{"4.4.4",
|
||||||
[{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
[{add_module,emqx_rule_engine_jwt},
|
||||||
|
{add_module,emqx_rule_engine_jwt_worker},
|
||||||
|
{add_module,emqx_rule_engine_jwt_sup},
|
||||||
|
{load_module,emqx_rule_engine_sup,brutal_purge,soft_purge,[]},
|
||||||
|
{apply,{emqx_rule_engine_sup,start_jwt_sup,[]}},
|
||||||
|
{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_events,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_events,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_funcs,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_funcs,brutal_purge,soft_purge,[]},
|
||||||
|
@ -76,7 +106,12 @@
|
||||||
{load_module,emqx_rule_runtime,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_runtime,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_actions,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_rule_actions,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.4.3",
|
{"4.4.3",
|
||||||
[{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
[{add_module,emqx_rule_engine_jwt},
|
||||||
|
{add_module,emqx_rule_engine_jwt_worker},
|
||||||
|
{add_module,emqx_rule_engine_jwt_sup},
|
||||||
|
{load_module,emqx_rule_engine_sup,brutal_purge,soft_purge,[]},
|
||||||
|
{apply,{emqx_rule_engine_sup,start_jwt_sup,[]}},
|
||||||
|
{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_metrics,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_metrics,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_sqltester,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_sqltester,brutal_purge,soft_purge,[]},
|
||||||
|
@ -92,7 +127,12 @@
|
||||||
{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.4.2",
|
{"4.4.2",
|
||||||
[{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
[{add_module,emqx_rule_engine_jwt},
|
||||||
|
{add_module,emqx_rule_engine_jwt_worker},
|
||||||
|
{add_module,emqx_rule_engine_jwt_sup},
|
||||||
|
{load_module,emqx_rule_engine_sup,brutal_purge,soft_purge,[]},
|
||||||
|
{apply,{emqx_rule_engine_sup,start_jwt_sup,[]}},
|
||||||
|
{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_validator,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_validator,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_actions,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_actions,brutal_purge,soft_purge,[]},
|
||||||
|
@ -109,7 +149,12 @@
|
||||||
{load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.4.1",
|
{"4.4.1",
|
||||||
[{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
[{add_module,emqx_rule_engine_jwt},
|
||||||
|
{add_module,emqx_rule_engine_jwt_worker},
|
||||||
|
{add_module,emqx_rule_engine_jwt_sup},
|
||||||
|
{load_module,emqx_rule_engine_sup,brutal_purge,soft_purge,[]},
|
||||||
|
{apply,{emqx_rule_engine_sup,start_jwt_sup,[]}},
|
||||||
|
{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_validator,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_validator,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_actions,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_actions,brutal_purge,soft_purge,[]},
|
||||||
|
@ -126,7 +171,12 @@
|
||||||
{add_module,emqx_rule_date},
|
{add_module,emqx_rule_date},
|
||||||
{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.4.0",
|
{"4.4.0",
|
||||||
[{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
[{add_module,emqx_rule_engine_jwt},
|
||||||
|
{add_module,emqx_rule_engine_jwt_worker},
|
||||||
|
{add_module,emqx_rule_engine_jwt_sup},
|
||||||
|
{load_module,emqx_rule_engine_sup,brutal_purge,soft_purge,[]},
|
||||||
|
{apply,{emqx_rule_engine_sup,start_jwt_sup,[]}},
|
||||||
|
{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_validator,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_validator,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_actions,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_actions,brutal_purge,soft_purge,[]},
|
||||||
|
@ -149,37 +199,56 @@
|
||||||
{load_module,emqx_rule_events,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_events,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_engine_sup,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_metrics,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_metrics,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_funcs,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_funcs,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]},
|
||||||
|
{apply,{supervisor,terminate_child,
|
||||||
|
[emqx_rule_engine_sup,emqx_rule_engine_jwt_sup]}},
|
||||||
|
{delete_module,emqx_rule_engine_jwt_sup},
|
||||||
|
{delete_module,emqx_rule_engine_jwt_worker},
|
||||||
|
{delete_module,emqx_rule_engine_jwt}]},
|
||||||
{"4.4.9",
|
{"4.4.9",
|
||||||
[{load_module,emqx_rule_utils,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_rule_utils,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_events,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_events,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_engine_sup,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_funcs,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_funcs,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_sqltester,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_sqltester,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_metrics,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_metrics,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]},
|
||||||
|
{apply,{supervisor,terminate_child,
|
||||||
|
[emqx_rule_engine_sup,emqx_rule_engine_jwt_sup]}},
|
||||||
|
{delete_module,emqx_rule_engine_jwt_sup},
|
||||||
|
{delete_module,emqx_rule_engine_jwt_worker},
|
||||||
|
{delete_module,emqx_rule_engine_jwt}]},
|
||||||
{"4.4.8",
|
{"4.4.8",
|
||||||
[{load_module,emqx_rule_utils,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_rule_utils,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_events,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_events,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_engine_sup,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_funcs,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_funcs,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_sqltester,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_sqltester,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_runtime,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_runtime,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_metrics,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_metrics,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]},
|
||||||
|
{apply,{supervisor,terminate_child,
|
||||||
|
[emqx_rule_engine_sup,emqx_rule_engine_jwt_sup]}},
|
||||||
|
{delete_module,emqx_rule_engine_jwt_sup},
|
||||||
|
{delete_module,emqx_rule_engine_jwt_worker},
|
||||||
|
{delete_module,emqx_rule_engine_jwt}]},
|
||||||
{<<"4\\.4\\.[6-7]">>,
|
{<<"4\\.4\\.[6-7]">>,
|
||||||
[{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_events,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_events,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_engine_sup,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_funcs,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_funcs,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_metrics,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_metrics,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_sqltester,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_sqltester,brutal_purge,soft_purge,[]},
|
||||||
|
@ -188,11 +257,17 @@
|
||||||
{load_module,emqx_rule_utils,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_utils,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_runtime,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_runtime,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_actions,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_actions,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]},
|
||||||
|
{apply,{supervisor,terminate_child,
|
||||||
|
[emqx_rule_engine_sup,emqx_rule_engine_jwt_sup]}},
|
||||||
|
{delete_module,emqx_rule_engine_jwt_sup},
|
||||||
|
{delete_module,emqx_rule_engine_jwt_worker},
|
||||||
|
{delete_module,emqx_rule_engine_jwt}]},
|
||||||
{"4.4.5",
|
{"4.4.5",
|
||||||
[{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_events,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_events,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_engine_sup,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_funcs,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_funcs,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_metrics,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_metrics,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_sqltester,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_sqltester,brutal_purge,soft_purge,[]},
|
||||||
|
@ -202,11 +277,17 @@
|
||||||
{load_module,emqx_rule_actions,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_actions,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_validator,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_validator,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_runtime,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_runtime,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]},
|
||||||
|
{apply,{supervisor,terminate_child,
|
||||||
|
[emqx_rule_engine_sup,emqx_rule_engine_jwt_sup]}},
|
||||||
|
{delete_module,emqx_rule_engine_jwt_sup},
|
||||||
|
{delete_module,emqx_rule_engine_jwt_worker},
|
||||||
|
{delete_module,emqx_rule_engine_jwt}]},
|
||||||
{"4.4.4",
|
{"4.4.4",
|
||||||
[{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_events,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_events,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_engine_sup,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_funcs,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_funcs,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_metrics,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_metrics,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_sqltester,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_sqltester,brutal_purge,soft_purge,[]},
|
||||||
|
@ -216,10 +297,16 @@
|
||||||
{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_runtime,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_runtime,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_actions,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_rule_actions,brutal_purge,soft_purge,[]},
|
||||||
|
{apply,{supervisor,terminate_child,
|
||||||
|
[emqx_rule_engine_sup,emqx_rule_engine_jwt_sup]}},
|
||||||
|
{delete_module,emqx_rule_engine_jwt_sup},
|
||||||
|
{delete_module,emqx_rule_engine_jwt_worker},
|
||||||
|
{delete_module,emqx_rule_engine_jwt}]},
|
||||||
{"4.4.3",
|
{"4.4.3",
|
||||||
[{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_engine_sup,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_metrics,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_metrics,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_sqltester,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_sqltester,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_validator,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_validator,brutal_purge,soft_purge,[]},
|
||||||
|
@ -232,10 +319,16 @@
|
||||||
{load_module,emqx_rule_maps,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_maps,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]},
|
||||||
|
{apply,{supervisor,terminate_child,
|
||||||
|
[emqx_rule_engine_sup,emqx_rule_engine_jwt_sup]}},
|
||||||
|
{delete_module,emqx_rule_engine_jwt_sup},
|
||||||
|
{delete_module,emqx_rule_engine_jwt_worker},
|
||||||
|
{delete_module,emqx_rule_engine_jwt}]},
|
||||||
{"4.4.2",
|
{"4.4.2",
|
||||||
[{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_engine_sup,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_validator,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_validator,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_actions,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_actions,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_utils,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_utils,brutal_purge,soft_purge,[]},
|
||||||
|
@ -249,10 +342,16 @@
|
||||||
{delete_module,emqx_rule_date},
|
{delete_module,emqx_rule_date},
|
||||||
{load_module,emqx_rule_events,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_events,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]},
|
||||||
|
{apply,{supervisor,terminate_child,
|
||||||
|
[emqx_rule_engine_sup,emqx_rule_engine_jwt_sup]}},
|
||||||
|
{delete_module,emqx_rule_engine_jwt_sup},
|
||||||
|
{delete_module,emqx_rule_engine_jwt_worker},
|
||||||
|
{delete_module,emqx_rule_engine_jwt}]},
|
||||||
{"4.4.1",
|
{"4.4.1",
|
||||||
[{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_engine_sup,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_validator,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_validator,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_actions,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_actions,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_maps,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_maps,brutal_purge,soft_purge,[]},
|
||||||
|
@ -266,10 +365,16 @@
|
||||||
{load_module,emqx_rule_utils,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_utils,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_funcs,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_funcs,brutal_purge,soft_purge,[]},
|
||||||
{delete_module,emqx_rule_date},
|
{delete_module,emqx_rule_date},
|
||||||
{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]},
|
||||||
|
{apply,{supervisor,terminate_child,
|
||||||
|
[emqx_rule_engine_sup,emqx_rule_engine_jwt_sup]}},
|
||||||
|
{delete_module,emqx_rule_engine_jwt_sup},
|
||||||
|
{delete_module,emqx_rule_engine_jwt_worker},
|
||||||
|
{delete_module,emqx_rule_engine_jwt}]},
|
||||||
{"4.4.0",
|
{"4.4.0",
|
||||||
[{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine_app,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_engine_sup,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_validator,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_validator,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_actions,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_actions,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_maps,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_maps,brutal_purge,soft_purge,[]},
|
||||||
|
@ -283,5 +388,10 @@
|
||||||
{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_runtime,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_runtime,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]},
|
||||||
{delete_module,emqx_rule_date}]},
|
{apply,{supervisor,terminate_child,
|
||||||
|
[emqx_rule_engine_sup,emqx_rule_engine_jwt_sup]}},
|
||||||
|
{delete_module,emqx_rule_date},
|
||||||
|
{delete_module,emqx_rule_engine_jwt_sup},
|
||||||
|
{delete_module,emqx_rule_engine_jwt_worker},
|
||||||
|
{delete_module,emqx_rule_engine_jwt}]},
|
||||||
{<<".*">>,[]}]}.
|
{<<".*">>,[]}]}.
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Copyright (c) 2022 EMQ Technologies Co., Ltd. All Rights Reserved.
|
||||||
|
%%
|
||||||
|
%% Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
|
||||||
|
%%
|
||||||
|
%% Unless required by applicable law or agreed to in writing, software
|
||||||
|
%% distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
%% See the License for the specific language governing permissions and
|
||||||
|
%% limitations under the License.
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-module(emqx_rule_engine_jwt).
|
||||||
|
|
||||||
|
-include("rule_engine.hrl").
|
||||||
|
-include("rule_actions.hrl").
|
||||||
|
|
||||||
|
%% API
|
||||||
|
-export([ lookup_jwt/1
|
||||||
|
, lookup_jwt/2
|
||||||
|
]).
|
||||||
|
|
||||||
|
-type jwt() :: binary().
|
||||||
|
|
||||||
|
-spec lookup_jwt(resource_id()) -> {ok, jwt()} | {error, not_found}.
|
||||||
|
lookup_jwt(ResourceId) ->
|
||||||
|
?MODULE:lookup_jwt(?JWT_TABLE, ResourceId).
|
||||||
|
|
||||||
|
-spec lookup_jwt(ets:table(), resource_id()) -> {ok, jwt()} | {error, not_found}.
|
||||||
|
lookup_jwt(TId, ResourceId) ->
|
||||||
|
try
|
||||||
|
case ets:lookup(TId, {ResourceId, jwt}) of
|
||||||
|
[{{ResourceId, jwt}, JWT}] ->
|
||||||
|
{ok, JWT};
|
||||||
|
[] ->
|
||||||
|
{error, not_found}
|
||||||
|
end
|
||||||
|
catch
|
||||||
|
error:badarg ->
|
||||||
|
{error, not_found}
|
||||||
|
end.
|
|
@ -0,0 +1,89 @@
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Copyright (c) 2022 EMQ Technologies Co., Ltd. All Rights Reserved.
|
||||||
|
%%
|
||||||
|
%% Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
|
||||||
|
%%
|
||||||
|
%% Unless required by applicable law or agreed to in writing, software
|
||||||
|
%% distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
%% See the License for the specific language governing permissions and
|
||||||
|
%% limitations under the License.
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-module(emqx_rule_engine_jwt_sup).
|
||||||
|
|
||||||
|
-behaviour(supervisor).
|
||||||
|
|
||||||
|
-export([ start_link/0
|
||||||
|
, ensure_worker_present/2
|
||||||
|
, ensure_worker_deleted/1
|
||||||
|
]).
|
||||||
|
|
||||||
|
-export([init/1]).
|
||||||
|
|
||||||
|
-include_lib("emqx_rule_engine/include/rule_actions.hrl").
|
||||||
|
|
||||||
|
-type worker_id() :: term().
|
||||||
|
|
||||||
|
start_link() ->
|
||||||
|
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
|
||||||
|
|
||||||
|
init([]) ->
|
||||||
|
ensure_jwt_table(),
|
||||||
|
SupFlags = #{ strategy => one_for_one
|
||||||
|
, intensity => 10
|
||||||
|
, period => 5
|
||||||
|
, auto_shutdown => never
|
||||||
|
},
|
||||||
|
ChildSpecs = [],
|
||||||
|
{ok, {SupFlags, ChildSpecs}}.
|
||||||
|
|
||||||
|
%% @doc Starts a new JWT worker. The caller should use
|
||||||
|
%% `emqx_rule_engine_jwt_sup:ensure_jwt/1' to ensure that a JWT has
|
||||||
|
%% been stored, if synchronization is needed.
|
||||||
|
-spec ensure_worker_present(worker_id(), map()) ->
|
||||||
|
{ok, supervisor:child()}.
|
||||||
|
ensure_worker_present(Id, Config) ->
|
||||||
|
ChildSpec = jwt_worker_child_spec(Id, Config),
|
||||||
|
case supervisor:start_child(?MODULE, ChildSpec) of
|
||||||
|
{ok, Pid} ->
|
||||||
|
{ok, Pid};
|
||||||
|
{error, {already_started, Pid}} ->
|
||||||
|
{ok, Pid};
|
||||||
|
{error, already_present} ->
|
||||||
|
supervisor:restart_child(?MODULE, Id)
|
||||||
|
end.
|
||||||
|
|
||||||
|
%% @doc Stops a given JWT worker by its id.
|
||||||
|
-spec ensure_worker_deleted(worker_id()) -> ok.
|
||||||
|
ensure_worker_deleted(Id) ->
|
||||||
|
case supervisor:terminate_child(?MODULE, Id) of
|
||||||
|
ok -> ok;
|
||||||
|
{error, not_found} -> ok
|
||||||
|
end.
|
||||||
|
|
||||||
|
jwt_worker_child_spec(Id, Config) ->
|
||||||
|
#{ id => Id
|
||||||
|
, start => {emqx_rule_engine_jwt_worker, start_link, [Config]}
|
||||||
|
, restart => transient
|
||||||
|
, type => worker
|
||||||
|
, significant => false
|
||||||
|
, shutdown => brutal_kill
|
||||||
|
, modules => [emqx_rule_engine_jwt_worker]
|
||||||
|
}.
|
||||||
|
|
||||||
|
-spec ensure_jwt_table() -> ok.
|
||||||
|
ensure_jwt_table() ->
|
||||||
|
case ets:whereis(?JWT_TABLE) of
|
||||||
|
undefined ->
|
||||||
|
Opts = [named_table, public,
|
||||||
|
{read_concurrency, true}, ordered_set],
|
||||||
|
_ = ets:new(?JWT_TABLE, Opts),
|
||||||
|
ok;
|
||||||
|
_ ->
|
||||||
|
ok
|
||||||
|
end.
|
|
@ -0,0 +1,216 @@
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Copyright (c) 2022 EMQ Technologies Co., Ltd. All Rights Reserved.
|
||||||
|
%%
|
||||||
|
%% Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
|
||||||
|
%%
|
||||||
|
%% Unless required by applicable law or agreed to in writing, software
|
||||||
|
%% distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
%% See the License for the specific language governing permissions and
|
||||||
|
%% limitations under the License.
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-module(emqx_rule_engine_jwt_worker).
|
||||||
|
|
||||||
|
-behaviour(gen_server).
|
||||||
|
|
||||||
|
%% API
|
||||||
|
-export([ start_link/1
|
||||||
|
, ensure_jwt/1
|
||||||
|
]).
|
||||||
|
|
||||||
|
%% gen_server API
|
||||||
|
-export([ init/1
|
||||||
|
, handle_continue/2
|
||||||
|
, handle_call/3
|
||||||
|
, handle_cast/2
|
||||||
|
, handle_info/2
|
||||||
|
, format_status/1
|
||||||
|
, format_status/2
|
||||||
|
]).
|
||||||
|
|
||||||
|
-include_lib("jose/include/jose_jwk.hrl").
|
||||||
|
-include_lib("emqx_rule_engine/include/rule_engine.hrl").
|
||||||
|
-include_lib("emqx_rule_engine/include/rule_actions.hrl").
|
||||||
|
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
||||||
|
|
||||||
|
-type config() :: #{ private_key := binary()
|
||||||
|
, resource_id := resource_id()
|
||||||
|
, expiration := timer:time()
|
||||||
|
, table := ets:table()
|
||||||
|
, iss := binary()
|
||||||
|
, sub := binary()
|
||||||
|
, aud := binary()
|
||||||
|
, kid := binary()
|
||||||
|
, alg := binary()
|
||||||
|
}.
|
||||||
|
-type jwt() :: binary().
|
||||||
|
-type state() :: #{ refresh_timer := undefined | timer:tref()
|
||||||
|
, resource_id := resource_id()
|
||||||
|
, expiration := timer:time()
|
||||||
|
, table := ets:table()
|
||||||
|
, jwt := undefined | jwt()
|
||||||
|
%% only undefined during startup
|
||||||
|
, jwk := undefined | jose_jwk:key()
|
||||||
|
, iss := binary()
|
||||||
|
, sub := binary()
|
||||||
|
, aud := binary()
|
||||||
|
, kid := binary()
|
||||||
|
, alg := binary()
|
||||||
|
}.
|
||||||
|
|
||||||
|
-define(refresh_jwt, refresh_jwt).
|
||||||
|
|
||||||
|
%%-----------------------------------------------------------------------------------------
|
||||||
|
%% API
|
||||||
|
%%-----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-spec start_link(config()) -> gen_server:start_ret().
|
||||||
|
start_link(#{ private_key := _
|
||||||
|
, expiration := _
|
||||||
|
, resource_id := _
|
||||||
|
, table := _
|
||||||
|
, iss := _
|
||||||
|
, sub := _
|
||||||
|
, aud := _
|
||||||
|
, kid := _
|
||||||
|
, alg := _
|
||||||
|
} = Config) ->
|
||||||
|
gen_server:start_link(?MODULE, Config, []).
|
||||||
|
|
||||||
|
-spec ensure_jwt(pid()) -> reference().
|
||||||
|
ensure_jwt(Worker) ->
|
||||||
|
Ref = alias([reply]),
|
||||||
|
gen_server:cast(Worker, {ensure_jwt, Ref}),
|
||||||
|
Ref.
|
||||||
|
|
||||||
|
%%-----------------------------------------------------------------------------------------
|
||||||
|
%% gen_server API
|
||||||
|
%%-----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-spec init(config()) -> {ok, state(), {continue, {make_key, binary()}}}
|
||||||
|
| {stop, {error, term()}}.
|
||||||
|
init(#{private_key := PrivateKeyPEM} = Config) ->
|
||||||
|
State0 = maps:without([private_key], Config),
|
||||||
|
State = State0#{ jwk => undefined
|
||||||
|
, jwt => undefined
|
||||||
|
, refresh_timer => undefined
|
||||||
|
},
|
||||||
|
{ok, State, {continue, {make_key, PrivateKeyPEM}}}.
|
||||||
|
|
||||||
|
handle_continue({make_key, PrivateKeyPEM}, State0) ->
|
||||||
|
case jose_jwk:from_pem(PrivateKeyPEM) of
|
||||||
|
JWK = #jose_jwk{} ->
|
||||||
|
State = State0#{jwk := JWK},
|
||||||
|
{noreply, State, {continue, create_token}};
|
||||||
|
[] ->
|
||||||
|
?tp(rule_engine_jwt_worker_startup_error, #{error => empty_key}),
|
||||||
|
{stop, {shutdown, {error, empty_key}}, State0};
|
||||||
|
{error, Reason} ->
|
||||||
|
Error = {invalid_private_key, Reason},
|
||||||
|
?tp(rule_engine_jwt_worker_startup_error, #{error => Error}),
|
||||||
|
{stop, {shutdown, {error, Error}}, State0};
|
||||||
|
Error0 ->
|
||||||
|
Error = {invalid_private_key, Error0},
|
||||||
|
?tp(rule_engine_jwt_worker_startup_error, #{error => Error}),
|
||||||
|
{stop, {shutdown, {error, Error}}, State0}
|
||||||
|
end;
|
||||||
|
handle_continue(create_token, State0) ->
|
||||||
|
State = generate_and_store_jwt(State0),
|
||||||
|
{noreply, State}.
|
||||||
|
|
||||||
|
handle_call(_Req, _From, State) ->
|
||||||
|
{reply, {error, bad_call}, State}.
|
||||||
|
|
||||||
|
handle_cast({ensure_jwt, From}, State0 = #{jwt := JWT}) ->
|
||||||
|
State =
|
||||||
|
case JWT of
|
||||||
|
undefined ->
|
||||||
|
generate_and_store_jwt(State0);
|
||||||
|
_ ->
|
||||||
|
State0
|
||||||
|
end,
|
||||||
|
From ! {From, token_created},
|
||||||
|
{noreply, State};
|
||||||
|
handle_cast(_Req, State) ->
|
||||||
|
{noreply, State}.
|
||||||
|
|
||||||
|
handle_info({timeout, TRef, ?refresh_jwt}, State0 = #{refresh_timer := TRef}) ->
|
||||||
|
State = generate_and_store_jwt(State0),
|
||||||
|
{noreply, State};
|
||||||
|
handle_info(_Msg, State) ->
|
||||||
|
{noreply, State}.
|
||||||
|
|
||||||
|
format_status(State) ->
|
||||||
|
censor_secrets(State).
|
||||||
|
|
||||||
|
format_status(_Opt, [_PDict, State0]) ->
|
||||||
|
State = censor_secrets(State0),
|
||||||
|
[{data, [{"State", State}]}].
|
||||||
|
|
||||||
|
%%-----------------------------------------------------------------------------------------
|
||||||
|
%% Helper fns
|
||||||
|
%%-----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-spec do_generate_jwt(state()) -> jwt().
|
||||||
|
do_generate_jwt(#{ expiration := ExpirationMS
|
||||||
|
, iss := Iss
|
||||||
|
, sub := Sub
|
||||||
|
, aud := Aud
|
||||||
|
, kid := KId
|
||||||
|
, alg := Alg
|
||||||
|
, jwk := JWK
|
||||||
|
} = _State) ->
|
||||||
|
Headers = #{ <<"alg">> => Alg
|
||||||
|
, <<"kid">> => KId
|
||||||
|
},
|
||||||
|
Now = erlang:system_time(seconds),
|
||||||
|
ExpirationS = erlang:convert_time_unit(ExpirationMS, millisecond, second),
|
||||||
|
Claims = #{ <<"iss">> => Iss
|
||||||
|
, <<"sub">> => Sub
|
||||||
|
, <<"aud">> => Aud
|
||||||
|
, <<"iat">> => Now
|
||||||
|
, <<"exp">> => Now + ExpirationS
|
||||||
|
},
|
||||||
|
JWT0 = jose_jwt:sign(JWK, Headers, Claims),
|
||||||
|
{_, JWT} = jose_jws:compact(JWT0),
|
||||||
|
JWT.
|
||||||
|
|
||||||
|
-spec generate_and_store_jwt(state()) -> state().
|
||||||
|
generate_and_store_jwt(State0) ->
|
||||||
|
JWT = do_generate_jwt(State0),
|
||||||
|
store_jwt(State0, JWT),
|
||||||
|
?tp(rule_engine_jwt_worker_refresh, #{jwt => JWT}),
|
||||||
|
State1 = State0#{jwt := JWT},
|
||||||
|
ensure_timer(State1).
|
||||||
|
|
||||||
|
-spec store_jwt(state(), jwt()) -> ok.
|
||||||
|
store_jwt(#{resource_id := ResourceId, table := TId}, JWT) ->
|
||||||
|
true = ets:insert(TId, {{ResourceId, jwt}, JWT}),
|
||||||
|
?tp(rule_engine_jwt_worker_token_stored, #{resource_id => ResourceId}),
|
||||||
|
ok.
|
||||||
|
|
||||||
|
-spec ensure_timer(state()) -> state().
|
||||||
|
ensure_timer(State = #{ refresh_timer := undefined
|
||||||
|
, expiration := ExpirationMS0
|
||||||
|
}) ->
|
||||||
|
ExpirationMS = max(5_000, ExpirationMS0 - 5_000),
|
||||||
|
TRef = erlang:start_timer(ExpirationMS, self(), ?refresh_jwt),
|
||||||
|
State#{refresh_timer => TRef};
|
||||||
|
ensure_timer(State) ->
|
||||||
|
State.
|
||||||
|
|
||||||
|
-spec censor_secrets(state()) -> map().
|
||||||
|
censor_secrets(State) ->
|
||||||
|
maps:map(
|
||||||
|
fun(Key, _Value) when Key =:= jwt;
|
||||||
|
Key =:= jwk ->
|
||||||
|
"******";
|
||||||
|
(_Key, Value) ->
|
||||||
|
Value
|
||||||
|
end,
|
||||||
|
State).
|
|
@ -22,7 +22,9 @@
|
||||||
|
|
||||||
-export([start_link/0]).
|
-export([start_link/0]).
|
||||||
|
|
||||||
-export([start_locker/0]).
|
-export([ start_locker/0
|
||||||
|
, start_jwt_sup/0
|
||||||
|
]).
|
||||||
|
|
||||||
-export([init/1]).
|
-export([init/1]).
|
||||||
|
|
||||||
|
@ -31,8 +33,12 @@ start_link() ->
|
||||||
|
|
||||||
init([]) ->
|
init([]) ->
|
||||||
Opts = [public, named_table, set, {read_concurrency, true}],
|
Opts = [public, named_table, set, {read_concurrency, true}],
|
||||||
_ = ets:new(?ACTION_INST_PARAMS_TAB, [{keypos, #action_instance_params.id}|Opts]),
|
ensure_table(?ACTION_INST_PARAMS_TAB, [{keypos, #action_instance_params.id}|Opts]),
|
||||||
_ = ets:new(?RES_PARAMS_TAB, [{keypos, #resource_params.id}|Opts]),
|
ensure_table(?RES_PARAMS_TAB, [{keypos, #resource_params.id}|Opts]),
|
||||||
|
SupFlags = #{ strategy => one_for_one
|
||||||
|
, intensity => 10
|
||||||
|
, period => 10
|
||||||
|
},
|
||||||
Registry = #{id => emqx_rule_registry,
|
Registry = #{id => emqx_rule_registry,
|
||||||
start => {emqx_rule_registry, start_link, []},
|
start => {emqx_rule_registry, start_link, []},
|
||||||
restart => permanent,
|
restart => permanent,
|
||||||
|
@ -51,7 +57,8 @@ init([]) ->
|
||||||
shutdown => 5000,
|
shutdown => 5000,
|
||||||
type => worker,
|
type => worker,
|
||||||
modules => [emqx_rule_monitor]},
|
modules => [emqx_rule_monitor]},
|
||||||
{ok, {{one_for_one, 10, 10}, [Registry, Metrics, Monitor]}}.
|
JWTSup = jwt_sup_child_spec(),
|
||||||
|
{ok, {SupFlags, [Registry, Metrics, Monitor, JWTSup]}}.
|
||||||
|
|
||||||
start_locker() ->
|
start_locker() ->
|
||||||
Locker = #{id => emqx_rule_locker,
|
Locker = #{id => emqx_rule_locker,
|
||||||
|
@ -61,3 +68,32 @@ start_locker() ->
|
||||||
type => worker,
|
type => worker,
|
||||||
modules => [emqx_rule_locker]},
|
modules => [emqx_rule_locker]},
|
||||||
supervisor:start_child(?MODULE, Locker).
|
supervisor:start_child(?MODULE, Locker).
|
||||||
|
|
||||||
|
start_jwt_sup() ->
|
||||||
|
JWTSup = jwt_sup_child_spec(),
|
||||||
|
supervisor:start_child(?MODULE, JWTSup).
|
||||||
|
|
||||||
|
jwt_sup_child_spec() ->
|
||||||
|
#{ id => emqx_rule_engine_jwt_sup
|
||||||
|
, start => {emqx_rule_engine_jwt_sup, start_link, []}
|
||||||
|
, type => supervisor
|
||||||
|
, restart => permanent
|
||||||
|
, shutdown => 5_000
|
||||||
|
, modules => [emqx_rule_engine_jwt_sup]
|
||||||
|
}.
|
||||||
|
|
||||||
|
ensure_table(Name, Opts) ->
|
||||||
|
try
|
||||||
|
case ets:whereis(name) of
|
||||||
|
undefined ->
|
||||||
|
_ = ets:new(Name, Opts),
|
||||||
|
ok;
|
||||||
|
_ ->
|
||||||
|
ok
|
||||||
|
end
|
||||||
|
catch
|
||||||
|
%% stil the table exists (somehow can happen in hot-upgrade,
|
||||||
|
%% it seems).
|
||||||
|
error:badarg ->
|
||||||
|
ok
|
||||||
|
end.
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
-behaviour(gen_server).
|
-behaviour(gen_server).
|
||||||
|
|
||||||
-include("rule_engine.hrl").
|
-include("rule_engine.hrl").
|
||||||
|
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
||||||
|
|
||||||
%% API functions
|
%% API functions
|
||||||
-export([ start_link/0
|
-export([ start_link/0
|
||||||
|
@ -222,7 +223,9 @@ inc(Id, Metric, Val) ->
|
||||||
counters:add(couters_ref(Id), metrics_idx(Metric), Val);
|
counters:add(couters_ref(Id), metrics_idx(Metric), Val);
|
||||||
Ref ->
|
Ref ->
|
||||||
counters:add(Ref, metrics_idx(Metric), Val)
|
counters:add(Ref, metrics_idx(Metric), Val)
|
||||||
end.
|
end,
|
||||||
|
?tp(rule_metrics_inc, #{id => Id, metric => Metric, value => Val}),
|
||||||
|
ok.
|
||||||
|
|
||||||
inc_actions_taken(Id) ->
|
inc_actions_taken(Id) ->
|
||||||
inc_actions_taken(Id, 1).
|
inc_actions_taken(Id, 1).
|
||||||
|
|
|
@ -0,0 +1,248 @@
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Copyright (c) 2022 EMQ Technologies Co., Ltd. All Rights Reserved.
|
||||||
|
%%
|
||||||
|
%% Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
|
||||||
|
%%
|
||||||
|
%% Unless required by applicable law or agreed to in writing, software
|
||||||
|
%% distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
%% See the License for the specific language governing permissions and
|
||||||
|
%% limitations under the License.
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-module(emqx_rule_engine_jwt_worker_SUITE).
|
||||||
|
|
||||||
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
-include_lib("common_test/include/ct.hrl").
|
||||||
|
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
||||||
|
-include_lib("emqx_rule_engine/include/rule_engine.hrl").
|
||||||
|
-include_lib("jose/include/jose_jwt.hrl").
|
||||||
|
-include_lib("jose/include/jose_jws.hrl").
|
||||||
|
|
||||||
|
-compile([export_all, nowarn_export_all]).
|
||||||
|
|
||||||
|
%%-----------------------------------------------------------------------------
|
||||||
|
%% CT boilerplate
|
||||||
|
%%-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
all() ->
|
||||||
|
emqx_ct:all(?MODULE).
|
||||||
|
|
||||||
|
init_per_suite(Config) ->
|
||||||
|
Config.
|
||||||
|
|
||||||
|
end_per_suite(_Config) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
|
%%-----------------------------------------------------------------------------
|
||||||
|
%% Helper fns
|
||||||
|
%%-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
generate_private_key_pem() ->
|
||||||
|
PublicExponent = 65537,
|
||||||
|
Size = 2048,
|
||||||
|
Key = public_key:generate_key({rsa, Size, PublicExponent}),
|
||||||
|
DERKey = public_key:der_encode('PrivateKeyInfo', Key),
|
||||||
|
public_key:pem_encode([{'PrivateKeyInfo', DERKey, not_encrypted}]).
|
||||||
|
|
||||||
|
generate_config() ->
|
||||||
|
PrivateKeyPEM = generate_private_key_pem(),
|
||||||
|
ResourceID = emqx_guid:gen(),
|
||||||
|
#{ private_key => PrivateKeyPEM
|
||||||
|
, expiration => timer:hours(1)
|
||||||
|
, resource_id => ResourceID
|
||||||
|
, table => ets:new(test_jwt_table, [ordered_set, public])
|
||||||
|
, iss => <<"issuer">>
|
||||||
|
, sub => <<"subject">>
|
||||||
|
, aud => <<"audience">>
|
||||||
|
, kid => <<"key id">>
|
||||||
|
, alg => <<"RS256">>
|
||||||
|
}.
|
||||||
|
|
||||||
|
is_expired(JWT) ->
|
||||||
|
#jose_jwt{fields = #{<<"exp">> := Exp}} = jose_jwt:peek(JWT),
|
||||||
|
Now = erlang:system_time(seconds),
|
||||||
|
Now >= Exp.
|
||||||
|
|
||||||
|
%%-----------------------------------------------------------------------------
|
||||||
|
%% Test cases
|
||||||
|
%%-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
t_create_success(_Config) ->
|
||||||
|
Config = generate_config(),
|
||||||
|
Res = emqx_rule_engine_jwt_worker:start_link(Config),
|
||||||
|
?assertMatch({ok, _}, Res),
|
||||||
|
{ok, Worker} = Res,
|
||||||
|
Ref = emqx_rule_engine_jwt_worker:ensure_jwt(Worker),
|
||||||
|
receive
|
||||||
|
{Ref, token_created} ->
|
||||||
|
ok
|
||||||
|
after
|
||||||
|
1_000 ->
|
||||||
|
ct:fail("should have confirmed token creation; msgs: ~0p",
|
||||||
|
[process_info(self(), messages)])
|
||||||
|
end,
|
||||||
|
ok.
|
||||||
|
|
||||||
|
t_empty_key(_Config) ->
|
||||||
|
Config0 = generate_config(),
|
||||||
|
Config = Config0#{private_key := <<>>},
|
||||||
|
process_flag(trap_exit, true),
|
||||||
|
?check_trace(
|
||||||
|
?wait_async_action(
|
||||||
|
?assertMatch({ok, _}, emqx_rule_engine_jwt_worker:start_link(Config)),
|
||||||
|
#{?snk_kind := rule_engine_jwt_worker_startup_error},
|
||||||
|
1_000),
|
||||||
|
fun(Trace) ->
|
||||||
|
?assertMatch([#{error := empty_key}],
|
||||||
|
?of_kind(rule_engine_jwt_worker_startup_error, Trace)),
|
||||||
|
ok
|
||||||
|
end),
|
||||||
|
ok.
|
||||||
|
|
||||||
|
t_invalid_pem(_Config) ->
|
||||||
|
Config0 = generate_config(),
|
||||||
|
InvalidPEM = public_key:pem_encode([{'PrivateKeyInfo', <<"xxxxxx">>, not_encrypted},
|
||||||
|
{'PrivateKeyInfo', <<"xxxxxx">>, not_encrypted}]),
|
||||||
|
Config = Config0#{private_key := InvalidPEM},
|
||||||
|
process_flag(trap_exit, true),
|
||||||
|
?check_trace(
|
||||||
|
?wait_async_action(
|
||||||
|
?assertMatch({ok, _}, emqx_rule_engine_jwt_worker:start_link(Config)),
|
||||||
|
#{?snk_kind := rule_engine_jwt_worker_startup_error},
|
||||||
|
1_000),
|
||||||
|
fun(Trace) ->
|
||||||
|
?assertMatch([#{error := {invalid_private_key, _}}],
|
||||||
|
?of_kind(rule_engine_jwt_worker_startup_error, Trace)),
|
||||||
|
ok
|
||||||
|
end),
|
||||||
|
ok.
|
||||||
|
|
||||||
|
t_refresh(_Config) ->
|
||||||
|
Config0 = #{ table := Table
|
||||||
|
, resource_id := ResourceId
|
||||||
|
} = generate_config(),
|
||||||
|
Config = Config0#{expiration => 5_000},
|
||||||
|
?check_trace(
|
||||||
|
begin
|
||||||
|
{{ok, _Pid}, {ok, _Event}} =
|
||||||
|
?wait_async_action(
|
||||||
|
emqx_rule_engine_jwt_worker:start_link(Config),
|
||||||
|
#{?snk_kind := rule_engine_jwt_worker_token_stored},
|
||||||
|
5_000),
|
||||||
|
{ok, FirstJWT} = emqx_rule_engine_jwt:lookup_jwt(Table, ResourceId),
|
||||||
|
?block_until(#{?snk_kind := rule_engine_jwt_worker_refresh,
|
||||||
|
jwt := JWT0} when JWT0 =/= FirstJWT, 15_000),
|
||||||
|
{ok, SecondJWT} = emqx_rule_engine_jwt:lookup_jwt(Table, ResourceId),
|
||||||
|
?assertNot(is_expired(SecondJWT)),
|
||||||
|
?assert(is_expired(FirstJWT)),
|
||||||
|
{FirstJWT, SecondJWT}
|
||||||
|
end,
|
||||||
|
fun({FirstJWT, SecondJWT}, Trace) ->
|
||||||
|
?assertMatch([_, _ | _],
|
||||||
|
?of_kind(rule_engine_jwt_worker_token_stored, Trace)),
|
||||||
|
?assertNotEqual(FirstJWT, SecondJWT),
|
||||||
|
ok
|
||||||
|
end),
|
||||||
|
ok.
|
||||||
|
|
||||||
|
t_format_status(_Config) ->
|
||||||
|
Config = generate_config(),
|
||||||
|
{ok, Pid} = emqx_rule_engine_jwt_worker:start_link(Config),
|
||||||
|
{status, _, _, Props} = sys:get_status(Pid),
|
||||||
|
[State] = [State
|
||||||
|
|| Info = [_ | _] <- Props,
|
||||||
|
{data, Data = [_ | _]} <- Info,
|
||||||
|
{"State", State} <- Data],
|
||||||
|
?assertMatch(
|
||||||
|
#{ jwt := "******"
|
||||||
|
, jwk := "******"
|
||||||
|
},
|
||||||
|
State),
|
||||||
|
ok.
|
||||||
|
|
||||||
|
t_lookup_ok(_Config) ->
|
||||||
|
Config = #{ table := Table
|
||||||
|
, resource_id := ResourceId
|
||||||
|
, private_key := PrivateKeyPEM
|
||||||
|
, aud := Aud
|
||||||
|
, iss := Iss
|
||||||
|
, sub := Sub
|
||||||
|
, kid := KId
|
||||||
|
} = generate_config(),
|
||||||
|
{ok, Worker} = emqx_rule_engine_jwt_worker:start_link(Config),
|
||||||
|
Ref = emqx_rule_engine_jwt_worker:ensure_jwt(Worker),
|
||||||
|
receive
|
||||||
|
{Ref, token_created} ->
|
||||||
|
ok
|
||||||
|
after
|
||||||
|
500 ->
|
||||||
|
error(timeout)
|
||||||
|
end,
|
||||||
|
Res = emqx_rule_engine_jwt:lookup_jwt(Table, ResourceId),
|
||||||
|
?assertMatch({ok, _}, Res),
|
||||||
|
{ok, JWT} = Res,
|
||||||
|
?assert(is_binary(JWT)),
|
||||||
|
JWK = jose_jwk:from_pem(PrivateKeyPEM),
|
||||||
|
{IsValid, ParsedJWT, JWS} = jose_jwt:verify_strict(JWK, [<<"RS256">>], JWT),
|
||||||
|
?assertMatch(
|
||||||
|
#jose_jwt{
|
||||||
|
fields = #{ <<"aud">> := Aud
|
||||||
|
, <<"iss">> := Iss
|
||||||
|
, <<"sub">> := Sub
|
||||||
|
, <<"exp">> := _
|
||||||
|
, <<"iat">> := _
|
||||||
|
}},
|
||||||
|
ParsedJWT),
|
||||||
|
?assertNot(is_expired(JWT)),
|
||||||
|
?assertMatch(
|
||||||
|
#jose_jws{
|
||||||
|
alg = {_, 'RS256'},
|
||||||
|
fields = #{ <<"kid">> := KId
|
||||||
|
, <<"typ">> := <<"JWT">>
|
||||||
|
}},
|
||||||
|
JWS),
|
||||||
|
?assert(IsValid),
|
||||||
|
ok.
|
||||||
|
|
||||||
|
t_lookup_not_found(_Config) ->
|
||||||
|
Table = ets:new(test_jwt_table, [ordered_set, public]),
|
||||||
|
InexistentResource = <<"xxx">>,
|
||||||
|
?assertEqual({error, not_found},
|
||||||
|
emqx_rule_engine_jwt:lookup_jwt(Table, InexistentResource)),
|
||||||
|
ok.
|
||||||
|
|
||||||
|
t_lookup_badarg(_Config) ->
|
||||||
|
InexistentTable = i_dont_exist,
|
||||||
|
InexistentResource = <<"xxx">>,
|
||||||
|
?assertEqual({error, not_found},
|
||||||
|
emqx_rule_engine_jwt:lookup_jwt(InexistentTable, InexistentResource)),
|
||||||
|
ok.
|
||||||
|
|
||||||
|
t_start_supervised_worker(_Config) ->
|
||||||
|
{ok, _} = emqx_rule_engine_jwt_sup:start_link(),
|
||||||
|
Config = #{resource_id := ResourceId} = generate_config(),
|
||||||
|
{ok, Pid} = emqx_rule_engine_jwt_sup:ensure_worker_present(ResourceId, Config),
|
||||||
|
Ref = emqx_rule_engine_jwt_worker:ensure_jwt(Pid),
|
||||||
|
receive
|
||||||
|
{Ref, token_created} ->
|
||||||
|
ok
|
||||||
|
after
|
||||||
|
5_000 ->
|
||||||
|
ct:fail("timeout")
|
||||||
|
end,
|
||||||
|
MRef = monitor(process, Pid),
|
||||||
|
?assert(is_process_alive(Pid)),
|
||||||
|
ok = emqx_rule_engine_jwt_sup:ensure_worker_deleted(ResourceId),
|
||||||
|
receive
|
||||||
|
{'DOWN', MRef, process, Pid, _} ->
|
||||||
|
ok
|
||||||
|
after
|
||||||
|
1_000 ->
|
||||||
|
ct:fail("timeout")
|
||||||
|
end,
|
||||||
|
ok.
|
|
@ -6,6 +6,8 @@
|
||||||
- Added support for OCSP (Online Certificate Status Protocol) Stapling
|
- Added support for OCSP (Online Certificate Status Protocol) Stapling
|
||||||
- Added CRL (Certificate Revocation List) cache auto refresh
|
- Added CRL (Certificate Revocation List) cache auto refresh
|
||||||
|
|
||||||
|
- Added a JWT worker for creating and refreshing JWT tokens in rule engine actions. [#9241](https://github.com/emqx/emqx/pull/9241)
|
||||||
|
|
||||||
### Bug fixes
|
### Bug fixes
|
||||||
|
|
||||||
- Fix get trace list crash when trace not initialize. [#9156](https://github.com/emqx/emqx/pull/9156)
|
- Fix get trace list crash when trace not initialize. [#9156](https://github.com/emqx/emqx/pull/9156)
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
- 增加了对 OCSP (Online Certificate Status Protocol) Stapling 的支持
|
- 增加了对 OCSP (Online Certificate Status Protocol) Stapling 的支持
|
||||||
- 增加了 CRL(证书吊销列表)缓存的自动刷新功能
|
- 增加了 CRL(证书吊销列表)缓存的自动刷新功能
|
||||||
|
|
||||||
|
- 增加了一个JWT工作者,用于在规则引擎动作中创建和刷新JWT令牌。[#9241](https://github.com/emqx/emqx/pull/9241)
|
||||||
|
|
||||||
### 修复
|
### 修复
|
||||||
|
|
||||||
- 修复日志追踪模块没开启时,GET Trace 列表接口报错的问题。[#9156](https://github.com/emqx/emqx/pull/9156)
|
- 修复日志追踪模块没开启时,GET Trace 列表接口报错的问题。[#9156](https://github.com/emqx/emqx/pull/9156)
|
||||||
|
|
|
@ -31,12 +31,23 @@ start_slave(Name) ->
|
||||||
start_slave(Name, #{}).
|
start_slave(Name, #{}).
|
||||||
|
|
||||||
start_slave(Name, Opts) ->
|
start_slave(Name, Opts) ->
|
||||||
|
SlaveMod = maps:get(slave_mod, Opts, ct_slave),
|
||||||
Node = make_node_name(Name),
|
Node = make_node_name(Name),
|
||||||
case ct_slave:start(Node, [{kill_if_fail, true},
|
DoStart =
|
||||||
{monitor_master, true},
|
fun() ->
|
||||||
{init_timeout, 10000},
|
case SlaveMod of
|
||||||
{startup_timeout, 10000},
|
ct_slave ->
|
||||||
{erl_flags, ebin_path()}]) of
|
ct_slave:start(Node,
|
||||||
|
[{kill_if_fail, true},
|
||||||
|
{monitor_master, true},
|
||||||
|
{init_timeout, 10000},
|
||||||
|
{startup_timeout, 10000},
|
||||||
|
{erl_flags, ebin_path()}]);
|
||||||
|
slave ->
|
||||||
|
slave:start_link(host(), Name, ebin_path())
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
case DoStart() of
|
||||||
{ok, _} ->
|
{ok, _} ->
|
||||||
ok;
|
ok;
|
||||||
{error, started_not_connected, _} ->
|
{error, started_not_connected, _} ->
|
||||||
|
@ -115,6 +126,9 @@ setup_node(Node, #{} = Opts) ->
|
||||||
?assertEqual( node()
|
?assertEqual( node()
|
||||||
, gen_rpc:call(Node, gen_rpc, call, [node(), erlang, node, []])
|
, gen_rpc:call(Node, gen_rpc, call, [node(), erlang, node, []])
|
||||||
),
|
),
|
||||||
|
|
||||||
|
ok = snabbkaffe:forward_trace(Node),
|
||||||
|
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
%% Routes are replicated async.
|
%% Routes are replicated async.
|
||||||
|
|
Loading…
Reference in New Issue