Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce defaults in the auth section #3439

Merged
merged 8 commits into from
Dec 10, 2021
Merged

Conversation

chrzaszcz
Copy link
Member

@chrzaszcz chrzaszcz commented Dec 8, 2021

Goal: POC of defaults for nested options in an optional section to see how they would look like and decide if we want to proceed with this approach for the whole configuration file.

Scope: Defaults for methods, sasl_mechanisms and sasl_external in the auth section.

Motivation - advantages of defaults:

  • Easy to find the default value in the code.
  • Simpler code for fetching the values.
  • No need to recompute larger values like the default list of SASL mechanisms every time they are fetched.

Challenges:

  • Optional sections (like auth) need to be always included to make the defaults present. This cannot be a universal rule as most sections need to be included only when particular features are enabled.
  • Small tests: nested values need to be checked selectively instead of comparing the whole configuration terms. However, this seems like a general improvement and the test cases look cleaner afterwards.
  • Small tests: defaults need to be inserted into the expected options for the file tests. To fix this, the last commit changes the static *.options files into dynamic lists created by Erlang code. This seems to provide more flexibility, but you can check the last commit and see if you like the new, less verbose version more.

See the commit messages for more details.

Some subsections (e.g. auth.password) group similar config options
and their presence or absence does not change system behaviour.
For example, user can skip 'auth.password' or define it as empty
and the system still stores passwords, just with the default settings.

When such subsections include defaults, they need to be always
present, hence specifying 'include = always' makes the defaults
always available.

Such behaviour cannot be applied universally as for most sections
their presence or absence is meaningful.
The defaults should be always available even if auth section
is missing from the config (which is valid),
so the top-level auth section needs to be always included.
Also remove processing of old (already removed) 'sasl_external' values.
As there are more and more defaults, it becomes necessary to check
only one expected option value even if it is nested in maps,
e.g. for auth options.

It is now possible to do it with ?cfg and ?cfgh macros, e.g.
  ?cfg(Path, ExpectedValue, RawConfig)
Check only the required options - otherwise all expected default
values would need to be provided in each assertion.
Listing the sasl mechanisms is verbose, but there is no better way to
do it right now. If the number of such default values grows a lot, it
might be necessary to

- either have a dynamic way of listing them
- or reduce the number of host (types) in the files.

So far it does not seem to be a major issue.
@mongoose-im

This comment has been minimized.

@mongoose-im

This comment has been minimized.

@codecov
Copy link

codecov bot commented Dec 8, 2021

Codecov Report

Merging #3439 (953b388) into master (e1e1e08) will increase coverage by 0.01%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #3439      +/-   ##
==========================================
+ Coverage   80.77%   80.78%   +0.01%     
==========================================
  Files         415      415              
  Lines       32318    32316       -2     
==========================================
+ Hits        26105    26107       +2     
+ Misses       6213     6209       -4     
Impacted Files Coverage Δ
src/sasl/cyrsasl.erl 90.90% <ø> (ø)
src/auth/ejabberd_auth.erl 83.24% <100.00%> (ø)
src/config/mongoose_config_parser_toml.erl 99.27% <100.00%> (+0.01%) ⬆️
src/config/mongoose_config_spec.erl 98.77% <100.00%> (+<0.01%) ⬆️
src/sasl/cyrsasl_external.erl 88.31% <100.00%> (+4.16%) ⬆️
src/mongoose_tcp_listener.erl 76.59% <0.00%> (-4.26%) ⬇️
src/mam/mod_mam_rdbms_async_pool_writer.erl 66.66% <0.00%> (-3.93%) ⬇️
src/mod_roster.erl 77.08% <0.00%> (-1.44%) ⬇️
src/mod_roster_rdbms.erl 95.38% <0.00%> (-0.77%) ⬇️
src/pubsub/mod_pubsub_db_mnesia.erl 92.43% <0.00%> (-0.43%) ⬇️
... and 10 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update e1e1e08...953b388. Read the comment docs.

@mongoose-im

This comment has been minimized.

@chrzaszcz chrzaszcz marked this pull request as ready for review December 9, 2021 08:13
Copy link
Contributor

@Premwoik Premwoik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me :)

@mongoose-im

This comment has been minimized.

@mongoose-im
Copy link
Collaborator

mongoose-im commented Dec 9, 2021

small_tests_24 / small_tests / 2a98f47
Reports root / small


small_tests_23 / small_tests / 2a98f47
Reports root / small


dynamic_domains_pgsql_mnesia_23 / pgsql_mnesia / 2a98f47
Reports root/ big
OK: 2726 / Failed: 0 / User-skipped: 186 / Auto-skipped: 0


dynamic_domains_mysql_redis_24 / mysql_redis / 2a98f47
Reports root/ big
OK: 2709 / Failed: 0 / User-skipped: 203 / Auto-skipped: 0


dynamic_domains_pgsql_mnesia_24 / pgsql_mnesia / 2a98f47
Reports root/ big
OK: 2726 / Failed: 0 / User-skipped: 186 / Auto-skipped: 0


dynamic_domains_mssql_mnesia_24 / odbc_mssql_mnesia / 2a98f47
Reports root/ big
OK: 2726 / Failed: 0 / User-skipped: 186 / Auto-skipped: 0


ldap_mnesia_24 / ldap_mnesia / 2a98f47
Reports root/ big
OK: 1503 / Failed: 1 / User-skipped: 389 / Auto-skipped: 0

rest_client_SUITE:messages:msg_is_sent_and_delivered_over_sse
{error,{{badmap,{error,timeout}},
    [{erlang,map_get,
         [data,{error,timeout}],
         [{error_info,#{module => erl_erts_errors}}]},
     {rest_client_SUITE,msg_is_sent_and_delivered_over_sse,1,
              [{file,"/home/circleci/project/big_tests/tests/rest_client_SUITE.erl"},
               {line,217}]},
     {test_server,ts_tc,3,[{file,"test_server.erl"},{line,1783}]},
     {test_server,run_test_case_eval1,6,
            [{file,"test_server.erl"},{line,1292}]},
     {test_server,run_test_case_eval,9,
            [{file,"test_server.erl"},{line,1224}]}]}}

Report log


ldap_mnesia_23 / ldap_mnesia / 2a98f47
Reports root/ big
OK: 1502 / Failed: 0 / User-skipped: 386 / Auto-skipped: 0


internal_mnesia_24 / internal_mnesia / 2a98f47
Reports root/ big
OK: 1587 / Failed: 0 / User-skipped: 301 / Auto-skipped: 0


elasticsearch_and_cassandra_24 / elasticsearch_and_cassandra_mnesia / 2a98f47
Reports root/ big
OK: 1880 / Failed: 0 / User-skipped: 313 / Auto-skipped: 0


pgsql_mnesia_24 / pgsql_mnesia / 2a98f47
Reports root/ big
OK: 3113 / Failed: 0 / User-skipped: 195 / Auto-skipped: 0


pgsql_mnesia_23 / pgsql_mnesia / 2a98f47
Reports root/ big
OK: 3113 / Failed: 0 / User-skipped: 195 / Auto-skipped: 0


mssql_mnesia_24 / odbc_mssql_mnesia / 2a98f47
Reports root/ big
OK: 3113 / Failed: 0 / User-skipped: 195 / Auto-skipped: 0


riak_mnesia_24 / riak_mnesia / 2a98f47
Reports root/ big
OK: 1726 / Failed: 0 / User-skipped: 314 / Auto-skipped: 0

Move away from explicit Erlang terms to avoid increasing verbosity
when introducing defaults and having to copy-paste code fragments when
such defaults change.
Copy link
Collaborator

@NelsonVides NelsonVides left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... don't know if it is too late for this idea, but the fact that we'd have defaults for entire sections seems to make some things more verbose 🤔 Didn't we consider setting these defaults per-option, like, in

-record(option, {type :: mongoose_config_spec:option_type(),
, it could have a new element like

-record(option, {type :: mongoose_config_spec:option_type(),
                 default :: some_type(),
                 validate = any :: mongoose_config_validator:validator(),
                 process :: undefined | mongoose_config_parser_toml:processor(),
                 wrap = default :: mongoose_config_spec:wrapper()}).

Probably there's some reasons not to do this one, like, Erlang would just create all the records with undefined there, but that's probably possible to work around. Maybe the work-around would be much more tedious and we should discard that idea?
Asking for some thoughts 🙂

@mongoose-im
Copy link
Collaborator

mongoose-im commented Dec 9, 2021

small_tests_24 / small_tests / 953b388
Reports root / small


small_tests_23 / small_tests / 953b388
Reports root / small


dynamic_domains_mysql_redis_24 / mysql_redis / 953b388
Reports root/ big
OK: 2709 / Failed: 0 / User-skipped: 203 / Auto-skipped: 0


dynamic_domains_pgsql_mnesia_24 / pgsql_mnesia / 953b388
Reports root/ big
OK: 2754 / Failed: 1 / User-skipped: 186 / Auto-skipped: 0

sm_SUITE:parallel:messages_are_properly_flushed_during_resumption_p1_fsm_old
{error,
  {{badmatch,
     {error,
       {connection_step_failed,
         {#Fun<sm_SUITE.11.68776247>,
          {client,
            <<"alicE_messages_are_properly_flushed_during_resumption_p1_fsm_old_1925@domain.example.com">>,
            escalus_tcp,<0.31491.1>,undefined,
            [{username,
               <<"alicE_messages_are_properly_flushed_during_resumption_p1_fsm_old_1925">>},
             {server,<<"domain.example.com">>},
             {host,<<"localhost">>},
             {password,<<"matygrysa">>},
             {stream_management,true},
             {stream_id,<<"964a7edbe8588105">>}]},
          [{compression,[<<"zlib">>]},
           {starttls,true},
           {stream_management,true},
           {advanced_message_processing,true},
           {client_state_indication,false},
           {sasl_mechanisms,[<<"SCRAM-SHA-256">>,<<"PLAIN">>]},
           {caps,undefined}]},
         {timeout,get_resumed}}}},
   [{sm_SUITE,
      '-messages_are_properly_flushed_during_resumption_p1_fsm_old/1-fun-1-',
      3,
      [{file,"/home/circleci/project/big_tests/tests/sm_SUITE.erl"},
       {line,1270}]},
    {escalus_story,story,4,
      [{file,
         "/home/circleci/project/big_tests/_build/default/lib/escalus/src/escalus_story.erl"},
       {line,72}]},
    {test_server,ts_tc,3,[{file,"test_server.erl"},{line,1783}]},
    {test_server,run_test_case_eval1,6,
      [{file,"test_server.erl"},{line,1292}]},
    {test_server,run_test_case_eval,9,
      [{file,"test_se...

Report log


dynamic_domains_pgsql_mnesia_23 / pgsql_mnesia / 953b388
Reports root/ big
OK: 2726 / Failed: 0 / User-skipped: 186 / Auto-skipped: 0


ldap_mnesia_23 / ldap_mnesia / 953b388
Reports root/ big
OK: 1502 / Failed: 0 / User-skipped: 386 / Auto-skipped: 0


internal_mnesia_24 / internal_mnesia / 953b388
Reports root/ big
OK: 1587 / Failed: 0 / User-skipped: 301 / Auto-skipped: 0


dynamic_domains_mssql_mnesia_24 / odbc_mssql_mnesia / 953b388
Reports root/ big
OK: 2726 / Failed: 0 / User-skipped: 186 / Auto-skipped: 0


ldap_mnesia_24 / ldap_mnesia / 953b388
Reports root/ big
OK: 1502 / Failed: 0 / User-skipped: 386 / Auto-skipped: 0


elasticsearch_and_cassandra_24 / elasticsearch_and_cassandra_mnesia / 953b388
Reports root/ big
OK: 1880 / Failed: 0 / User-skipped: 313 / Auto-skipped: 0


pgsql_mnesia_24 / pgsql_mnesia / 953b388
Reports root/ big
OK: 3113 / Failed: 0 / User-skipped: 195 / Auto-skipped: 0


pgsql_mnesia_23 / pgsql_mnesia / 953b388
Reports root/ big
OK: 3113 / Failed: 0 / User-skipped: 195 / Auto-skipped: 0


mysql_redis_24 / mysql_redis / 953b388
Reports root/ big
OK: 3108 / Failed: 0 / User-skipped: 200 / Auto-skipped: 0


mssql_mnesia_24 / odbc_mssql_mnesia / 953b388
Reports root/ big
OK: 3118 / Failed: 7 / User-skipped: 195 / Auto-skipped: 0

pep_SUITE:pep_tests:authorize_access_model
{error,
  {timeout_when_waiting_for_stanza,
    [{escalus_client,wait_for_stanza,
       [{client,<<"alicE_authorize_access_model_1852@localhost/res1">>,
          escalus_tcp,<0.29059.1>,
          [{event_manager,<0.29029.1>},
           {server,<<"localhost">>},
           {username,<<"alicE_authorize_access_model_1852">>},
           {resource,<<"res1">>}],
          [{event_client,
             [{event_manager,<0.29029.1>},
            {server,<<"localhost">>},
            {username,<<"alicE_authorize_access_model_1852">>},
            {resource,<<"res1">>}]},
           {resource,<<"res1">>},
           {username,<<"alicE_authorize_access_model_1852">>},
           {server,<<"localhost">>},
           {host,<<"localhost">>},
           {port,5222},
           {auth,{escalus_auth,auth_plain}},
           {wspath,undefined},
           {username,<<"alicE_authorize_access_model_1852">>},
           {server,<<"localhost">>},
           {password,<<"matygrysa">>},
           {stream_id,<<"08e248a050f4e372">>}]},
        5000],
       [{file,
          "/home/circleci/project/big_tests/_build/default/lib/escalus/src/escalus_client.erl"},
        {line,136}]},
     {pubsub_tools,receive_response,3,
       [{file,"/home/circleci/project/big_tests/tests/pubsub_tools.erl"},
        {line,479}]},
     {pubsub_tools,receive_and_check_response,4,
       [{file,"/home/circleci/project/big_tests/tests/pubsub_tools.erl"},
        {line,470}]},
     {pep_SUITE,'-authorize_access_model/1...

Report log

pep_SUITE:pep_tests:delayed_receive_with_sm
{error,{{badmatch,[]},
    [{pep_SUITE,'-delayed_receive_with_sm/1-fun-0-',3,
          [{file,"/home/circleci/project/big_tests/tests/pep_SUITE.erl"},
           {line,295}]},
     {escalus_story,story,4,
            [{file,"/home/circleci/project/big_tests/_build/default/lib/escalus/src/escalus_story.erl"},
             {line,72}]},
     {test_server,ts_tc,3,[{file,"test_server.erl"},{line,1783}]},
     {test_server,run_test_case_eval1,6,
            [{file,"test_server.erl"},{line,1292}]},
     {test_server,run_test_case_eval,9,
            [{file,"test_server.erl"},{line,1224}]}]}}

Report log

pep_SUITE:pep_tests:send_caps_after_login_test
{error,{{assertion_failed,assert_many,false,[is_roster_set,is_presence],[],[]},
    [{escalus_new_assert,assert_true,2,
               [{file,"/home/circleci/project/big_tests/_build/default/lib/escalus/src/escalus_new_assert.erl"},
                {line,84}]},
     {escalus_story,'-make_all_clients_friends/1-fun-0-',2,
            [{file,"/home/circleci/project/big_tests/_build/default/lib/escalus/src/escalus_story.erl"},
             {line,111}]},
     {escalus_utils,'-each_with_index/3-fun-0-',3,
            [{file,"/home/circleci/project/big_tests/_build/default/lib/escalus/src/escalus_utils.erl"},
             {line,87}]},
     {lists,foldl,3,[{file,"lists.erl"},{line,1267}]},
     {escalus_utils,'-each_with_index/3-fun-0-',3,
            [{file,"/home/circleci/project/big_tests/_build/default/lib/escalus/src/escalus_utils.erl"},
             {line,87}]},
     {lists,foldl,3,[{file,"lists.erl"},{line,1267}]},
     {escalus_utils,distinct_pairs,2,
            [{file,"/home/circleci/project/big_tests/_build/default/lib/escalus/src/escalus_utils.erl"},
             {line,60}]},
     {escalus_story,make_all_clients_friends,1,
            [{file,"/home/circleci/project/big_tests/_build/default/lib/escalus/src/escalus_story.erl"},
             {line,106}]}]}}

Report log

pep_SUITE:pep_tests:unsubscribe_after_presence_unsubscription
{error,{{assertion_failed,assert_many,false,
              [is_roster_set,is_presence,is_presence],
              [],[]},
    [{escalus_new_assert,assert_true,2,
               [{file,"/home/circleci/project/big_tests/_build/default/lib/escalus/src/escalus_new_assert.erl"},
                {line,84}]},
     {escalus_story,'-make_all_clients_friends/1-fun-0-',2,
            [{file,"/home/circleci/project/big_tests/_build/default/lib/escalus/src/escalus_story.erl"},
             {line,114}]},
     {escalus_utils,'-each_with_index/3-fun-0-',3,
            [{file,"/home/circleci/project/big_tests/_build/default/lib/escalus/src/escalus_utils.erl"},
             {line,87}]},
     {lists,foldl,3,[{file,"lists.erl"},{line,1267}]},
     {escalus_utils,'-each_with_index/3-fun-0-',3,
            [{file,"/home/circleci/project/big_tests/_build/default/lib/escalus/src/escalus_utils.erl"},
             {line,87}]},
     {lists,foldl,3,[{file,"lists.erl"},{line,1267}]},
     {escalus_utils,distinct_pairs,2,
            [{file,"/home/circleci/project/big_tests/_build/default/lib/escalus/src/escalus_utils.erl"},
             {line,60}]},
     {escalus_story,make_all_clients_friends,1,
            [{file,"/home/circleci/project/big_tests/_build/default/lib/escalus/src/escalus_story.erl"},
             {line,106}]}]}}

Report log

pep_SUITE:pep_tests:delayed_receive
{error,{thrown,{timeout,stream_end}}}

Report log

pep_SUITE:pep_tests:h_ok_after_notify_test
{error,
  {timeout_when_waiting_for_stanza,
    [{escalus_client,wait_for_stanza,
       [{client,<<"alicE_h_ok_after_notify_test_1851@localhost/res1">>,
          escalus_tcp,<0.29046.1>,
          [{event_manager,<0.29022.1>},
           {server,<<"localhost">>},
           {username,<<"alicE_h_ok_after_notify_test_1851">>},
           {resource,<<"res1">>}],
          [{event_client,
             [{event_manager,<0.29022.1>},
            {server,<<"localhost">>},
            {username,<<"alicE_h_ok_after_notify_test_1851">>},
            {resource,<<"res1">>}]},
           {resource,<<"res1">>},
           {username,<<"alicE_h_ok_after_notify_test_1851">>},
           {server,<<"localhost">>},
           {host,<<"localhost">>},
           {port,5222},
           {auth,{escalus_auth,auth_plain}},
           {wspath,undefined},
           {username,<<"alicE_h_ok_after_notify_test_1851">>},
           {server,<<"localhost">>},
           {password,<<"matygrysa">>},
           {stream_id,<<"9e2dce0ce59c6b68">>}]},
        5000],
       [{file,
          "/home/circleci/project/big_tests/_build/default/lib/escalus/src/escalus_client.erl"},
        {line,136}]},
     {pubsub_tools,receive_response,3,
       [{file,"/home/circleci/project/big_tests/tests/pubsub_tools.erl"},
        {line,479}]},
     {pubsub_tools,receive_and_check_response,4,
       [{file,"/home/circleci/project/big_tests/tests/pubsub_tools.erl"},
        {line,470}]},
     {pep_SUITE,'-h_ok_after_notify_test/1...

Report log

pep_SUITE:pep_tests:publish_and_notify_test
{error,{{assertion_failed,assert_many,false,
              [is_roster_set,is_presence,is_presence],
              [{xmlel,<<"presence">>,
                  [{<<"from">>,
                  <<"alicE_publish_and_notify_test_1846@localhost/res1">>},
                   {<<"to">>,
                  <<"bob_publish_and_notify_test_1846@localhost/res1">>},
                   {<<"xml:lang">>,<<"en">>}],
                  []}],
              "   <presence from='alicE_publish_and_notify_test_1846@localhost/res1' to='bob_publish_and_notify_test_1846@localhost/res1' xml:lang='en'/>"},
    [{escalus_new_assert,assert_true,2,
               [{file,"/home/circleci/project/big_tests/_build/default/lib/escalus/src/escalus_new_assert.erl"},
                {line,84}]},
     {escalus_utils,'-each_with_index/3-fun-0-',3,
            [{file,"/home/circleci/project/big_tests/_build/default/lib/escalus/src/escalus_utils.erl"},
             {line,87}]},
     {lists,foldl,3,[{file,"lists.erl"},{line,1267}]},
     {escalus_utils,'-each_with_index/3-fun-0-',3,
            [{file,"/home/circleci/project/big_tests/_build/default/lib/escalus/src/escalus_utils.erl"},
             {line,87}]},
     {lists,foldl,3,[{file,"lists.erl"},{line,1267}]},
     {escalus_utils,distinct_pairs,2,
            [{file,"/home/circleci/project/big_tests/_build/default/lib/escalus/src/escalus_utils.erl"},
             {line,60}]},
     {escalus_story,make_all_clients_friends,1,
            [{file,"/home/circleci/project/big_te...

Report log


riak_mnesia_24 / riak_mnesia / 953b388
Reports root/ big
OK: 1726 / Failed: 0 / User-skipped: 314 / Auto-skipped: 0

@chrzaszcz
Copy link
Member Author

chrzaszcz commented Dec 9, 2021

Hmm... don't know if it is too late for this idea, but the fact that we'd have defaults for entire sections seems to make some things more verbose 🤔 Didn't we consider setting these defaults per-option

It's a good idea and actually this was my initial attempt of the POC that I summarized at a grooming when I was introducing the whole concept of defaults.

However, implementation for the general section showed the following issues:

  • The default would work if we are in a section, but would make no sense if we are not in a section, so you would always need to go one level up (which is tricky) to verify if it makes sense or not
  • Sections have defaults only if they are not in host_config and having the defaults scattered around would mean a lot of extra code to have the second version for host_config without the defaults (see the code for the general section).
  • Parser code was more complicated.
  • Defaults should be defined at the same level as required keys.

Copy link
Collaborator

@NelsonVides NelsonVides left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All right, the design makes sense, thanks for this work 👌🏽

use_common_name -> [standard, common_name];
allow_just_user_identity -> [standard, auth_id]
end.
mongoose_config:get_opt([{auth, HostType}, sasl_external]).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah these kinds of things improve so much 😄

@NelsonVides NelsonVides merged commit 40b2319 into master Dec 10, 2021
@NelsonVides NelsonVides deleted the auth-password-config branch December 10, 2021 09:00
@Premwoik Premwoik added this to the 5.1.0 milestone May 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants