From 0686852b5bfcad806e42692460202863b0e01341 Mon Sep 17 00:00:00 2001 From: "n.fraison" Date: Mon, 28 Jun 2021 15:11:22 +0200 Subject: [PATCH] Implement List Roles Implement query_all in rest role manager which is called to get the list of roles --- auth/rest_role_manager.cc | 37 ++++++++++++++++++++++++--- docs/guides/rest_authc_authz.md | 5 ++++ test/boost/rest_authenticator_test.cc | 26 +++++++++++++++++++ 3 files changed, 64 insertions(+), 4 deletions(-) diff --git a/auth/rest_role_manager.cc b/auth/rest_role_manager.cc index b3ab3ff31c01..f8237fe1d759 100644 --- a/auth/rest_role_manager.cc +++ b/auth/rest_role_manager.cc @@ -209,8 +209,12 @@ namespace auth { } future rest_role_manager::can_login(std::string_view role_name) const { - return require_record(_qp, role_name).then([](record r) { - return r.can_login; + return find_record(_qp, role_name).then([](std::optional mr) { + if (mr) { + record r = *mr; + return r.can_login; + } + return false; }); } @@ -252,7 +256,32 @@ namespace auth { } future rest_role_manager::query_all() const { - throw std::logic_error("Not Implemented"); - } + static const sstring query = format("SELECT {},member_of from {}", + meta::roles_table::role_col_name, + meta::roles_table::qualified_name); + // To avoid many copies of a view. + static const auto role_col_name_string = sstring(meta::roles_table::role_col_name); + static const auto member_of_col_name_string = sstring("member_of"); + + return _qp.execute_internal( + query, + db::consistency_level::QUORUM, + internal_distributed_timeout_config()).then([](::shared_ptr results) { + role_set roles; + + std::for_each( + results->begin(), + results->end(), + [&roles](const cql3::untyped_result_set_row &row) { + roles.insert(row.get_as(role_col_name_string)); + if (row.has(member_of_col_name_string)) { + for (auto member : row.get_set(member_of_col_name_string)) { + roles.insert(member); + } + } + }); + return roles; + }); + } } diff --git a/docs/guides/rest_authc_authz.md b/docs/guides/rest_authc_authz.md index f97fd3eac7ac..92d0f483da65 100644 --- a/docs/guides/rest_authc_authz.md +++ b/docs/guides/rest_authc_authz.md @@ -71,3 +71,8 @@ Run Test client $ ./tools/rest_authenticator_server/scylla_client.sh ``` +## UnitTest + +```bash +./tools/toolchain/dbuild ninja build/debug/test/boost/rest_authenticator_test && ./tools/toolchain/dbuild ./build/debug/test/boost/rest_authenticator_test +``` diff --git a/test/boost/rest_authenticator_test.cc b/test/boost/rest_authenticator_test.cc index 7ea7450dd595..9dc1f57b6c9e 100644 --- a/test/boost/rest_authenticator_test.cc +++ b/test/boost/rest_authenticator_test.cc @@ -495,3 +495,29 @@ SEASTAR_TEST_CASE(update_superuser_password) { BOOST_REQUIRE(is_superuser(qp, "cassandra").get()); }); } + + +SEASTAR_TEST_CASE(get_list_of_roles) { + return with_dummy_authentication_server([](cql_test_env &env) { + auto &a = env.local_auth_service().underlying_authenticator(); + auto &rm = env.local_auth_service().underlying_role_manager(); + + auth::role_set roles; + roles.insert(sstring("tester")); + + BOOST_REQUIRE_EQUAL(rm.query_all().get(), roles); + + auto creds = auth::authenticator::credentials_map{ + {auth::authenticator::USERNAME_KEY, sstring("alice")}, + {auth::authenticator::PASSWORD_KEY, sstring("password")} + }; + + a.authenticate(creds).get(); + + roles.insert(sstring("scylla-rw")); + roles.insert(sstring("other")); + roles.insert(sstring("alice")); + + BOOST_REQUIRE_EQUAL(rm.query_all().get(), roles); + }); +}