Since every write-type auth statement takes group0_guard at the beginning, we hold read_apply_mutex and cannot have a running raft apply during our operation. Therefore, the auth cache and internal CQL reads return the same, consistent results. This makes it safe to read via cache instead of internal CQL. LDAP is an exception, but it is eventually consistent anyway.
127 lines
4.3 KiB
C++
127 lines
4.3 KiB
C++
/*
|
|
* Copyright (C) 2017-present ScyllaDB
|
|
*/
|
|
|
|
/*
|
|
* SPDX-License-Identifier: LicenseRef-ScyllaDB-Source-Available-1.0
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "auth/common.hh"
|
|
#include "auth/role_manager.hh"
|
|
#include "auth/cache.hh"
|
|
|
|
#include <string_view>
|
|
|
|
#include <seastar/core/abort_source.hh>
|
|
#include <seastar/core/future.hh>
|
|
#include <seastar/core/shared_future.hh>
|
|
#include <seastar/core/sstring.hh>
|
|
|
|
#include "cql3/description.hh"
|
|
#include "seastarx.hh"
|
|
#include "service/raft/raft_group0_client.hh"
|
|
|
|
namespace cql3 {
|
|
class query_processor;
|
|
}
|
|
|
|
namespace service {
|
|
class migration_manager;
|
|
}
|
|
|
|
namespace auth {
|
|
|
|
class standard_role_manager final : public role_manager {
|
|
cql3::query_processor& _qp;
|
|
::service::raft_group0_client& _group0_client;
|
|
::service::migration_manager& _migration_manager;
|
|
cache& _cache;
|
|
future<> _stopped;
|
|
abort_source _as;
|
|
std::string _superuser;
|
|
shared_promise<> _superuser_created_promise;
|
|
|
|
public:
|
|
standard_role_manager(cql3::query_processor&, ::service::raft_group0_client&, ::service::migration_manager&, cache&);
|
|
|
|
virtual std::string_view qualified_java_name() const noexcept override;
|
|
|
|
virtual const resource_set& protected_resources() const override;
|
|
|
|
virtual future<> start() override;
|
|
|
|
virtual future<> stop() override;
|
|
|
|
virtual future<> ensure_superuser_is_created() override;
|
|
|
|
virtual future<> create(std::string_view role_name, const role_config&, ::service::group0_batch&) override;
|
|
|
|
virtual future<> drop(std::string_view role_name, ::service::group0_batch& mc) override;
|
|
|
|
virtual future<> alter(std::string_view role_name, const role_config_update&, ::service::group0_batch&) override;
|
|
|
|
virtual future<> grant(std::string_view grantee_name, std::string_view role_name, ::service::group0_batch& mc) override;
|
|
|
|
virtual future<> revoke(std::string_view revokee_name, std::string_view role_name, ::service::group0_batch& mc) override;
|
|
|
|
virtual future<role_set> query_granted(std::string_view grantee_name, recursive_role_query) override;
|
|
|
|
virtual future<role_to_directly_granted_map> query_all_directly_granted(::service::query_state&) override;
|
|
|
|
virtual future<role_set> query_all(::service::query_state&) override;
|
|
|
|
virtual future<bool> exists(std::string_view role_name) override;
|
|
|
|
virtual future<bool> is_superuser(std::string_view role_name) override;
|
|
|
|
virtual future<bool> can_login(std::string_view role_name) override;
|
|
|
|
virtual future<std::optional<sstring>> get_attribute(std::string_view role_name, std::string_view attribute_name, ::service::query_state&) override;
|
|
|
|
virtual future<role_manager::attribute_vals> query_attribute_for_all(std::string_view attribute_name, ::service::query_state&) override;
|
|
|
|
virtual future<> set_attribute(std::string_view role_name, std::string_view attribute_name, std::string_view attribute_value, ::service::group0_batch& mc) override;
|
|
|
|
virtual future<> remove_attribute(std::string_view role_name, std::string_view attribute_name, ::service::group0_batch& mc) override;
|
|
|
|
virtual future<std::vector<cql3::description>> describe_role_grants() override;
|
|
|
|
private:
|
|
enum class membership_change { add, remove };
|
|
struct record final {
|
|
sstring name;
|
|
bool is_superuser;
|
|
bool can_login;
|
|
role_set member_of;
|
|
};
|
|
|
|
future<> create_legacy_metadata_tables_if_missing() const;
|
|
|
|
bool legacy_metadata_exists();
|
|
|
|
future<> migrate_legacy_metadata();
|
|
|
|
future<> legacy_create_default_role_if_missing();
|
|
|
|
future<> maybe_create_default_role();
|
|
future<> maybe_create_default_role_with_retries();
|
|
|
|
future<> create_or_replace(std::string_view auth_ks_name, std::string_view role_name, const role_config&, ::service::group0_batch&);
|
|
|
|
future<> legacy_modify_membership(std::string_view role_name, std::string_view grantee_name, membership_change);
|
|
|
|
future<> modify_membership(std::string_view role_name, std::string_view grantee_name, membership_change, ::service::group0_batch& mc);
|
|
|
|
future<std::optional<record>> legacy_find_record(std::string_view role_name);
|
|
future<std::optional<record>> find_record(std::string_view role_name);
|
|
future<record> require_record(std::string_view role_name);
|
|
future<> collect_roles(
|
|
std::string_view grantee_name,
|
|
bool recurse,
|
|
role_set& roles);
|
|
};
|
|
|
|
} // namespace auth
|