Remove unresolved dependencies while restoring with "allow_unresolved_access_dependencies = true".

This commit is contained in:
Vitaly Baranov 2024-09-18 18:44:47 +02:00
parent 91a91be172
commit 6b461fc16c
18 changed files with 98 additions and 0 deletions

View File

@ -417,11 +417,14 @@ void AccessRestorerFromBackup::generateRandomIDsAndResolveDependencies(const Acc
/// Prepare map from old UUIDs to new UUIDs.
std::unordered_map<UUID, UUID> old_to_new_ids;
std::unordered_set<UUID> unresolved_ids;
for (const auto & [id, entity_info] : entity_infos)
{
if (entity_info.new_id)
old_to_new_ids[id] = *entity_info.new_id;
else
unresolved_ids.insert(id);
}
/// Remap the UUIDs of dependencies in the access entities we're going to restore.
@ -431,6 +434,7 @@ void AccessRestorerFromBackup::generateRandomIDsAndResolveDependencies(const Acc
{
auto new_entity = entity_info.entity->clone();
new_entity->replaceDependencies(old_to_new_ids);
new_entity->removeDependencies(unresolved_ids);
entity_info.entity = new_entity;
}

View File

@ -231,4 +231,33 @@ void GrantedRoles::replaceDependencies(const std::unordered_map<UUID, UUID> & ol
}
}
void GrantedRoles::removeDependencies(const std::unordered_set<UUID> & ids)
{
bool found = false;
for (auto it = roles.begin(); it != roles.end();)
{
if (ids.contains(*it))
{
it = roles.erase(it);
found = true;
}
else
{
++it;
}
}
if (found)
{
for (auto it = roles_with_admin_option.begin(); it != roles_with_admin_option.end();)
{
if (ids.contains(*it))
it = roles_with_admin_option.erase(it);
else
++it;
}
}
}
}

View File

@ -60,6 +60,7 @@ public:
std::vector<UUID> findDependencies() const;
bool hasDependencies(const std::unordered_set<UUID> & ids) const;
void replaceDependencies(const std::unordered_map<UUID, UUID> & old_to_new_ids);
void removeDependencies(const std::unordered_set<UUID> & ids);
private:
boost::container::flat_set<UUID> roles;

View File

@ -52,6 +52,7 @@ struct IAccessEntity
/// Replaces dependencies according to a specified map.
virtual void replaceDependencies(const std::unordered_map<UUID, UUID> & /* old_to_new_ids */) {}
virtual void removeDependencies(const std::unordered_set<UUID> & /* ids */) {}
/// Whether this access entity should be written to a backup.
virtual bool isBackupAllowed() const { return false; }

View File

@ -34,4 +34,9 @@ void Quota::replaceDependencies(const std::unordered_map<UUID, UUID> & old_to_ne
to_roles.replaceDependencies(old_to_new_ids);
}
void Quota::removeDependencies(const std::unordered_set<UUID> & ids)
{
to_roles.removeDependencies(ids);
}
}

View File

@ -49,6 +49,7 @@ struct Quota : public IAccessEntity
std::vector<UUID> findDependencies() const override;
bool hasDependencies(const std::unordered_set<UUID> & ids) const override;
void replaceDependencies(const std::unordered_map<UUID, UUID> & old_to_new_ids) override;
void removeDependencies(const std::unordered_set<UUID> & ids) override;
bool isBackupAllowed() const override { return true; }
};

View File

@ -32,4 +32,10 @@ void Role::replaceDependencies(const std::unordered_map<UUID, UUID> & old_to_new
settings.replaceDependencies(old_to_new_ids);
}
void Role::removeDependencies(const std::unordered_set<UUID> & ids)
{
granted_roles.removeDependencies(ids);
settings.removeDependencies(ids);
}
}

View File

@ -23,6 +23,7 @@ struct Role : public IAccessEntity
std::vector<UUID> findDependencies() const override;
bool hasDependencies(const std::unordered_set<UUID> & ids) const override;
void replaceDependencies(const std::unordered_map<UUID, UUID> & old_to_new_ids) override;
void removeDependencies(const std::unordered_set<UUID> & ids) override;
bool isBackupAllowed() const override { return settings.isBackupAllowed(); }
};

View File

@ -354,4 +354,23 @@ void RolesOrUsersSet::replaceDependencies(const std::unordered_map<UUID, UUID> &
boost::range::copy(new_ids, std::inserter(except_ids, except_ids.end()));
}
void RolesOrUsersSet::removeDependencies(const std::unordered_set<UUID> & dependencies_ids)
{
for (auto it = ids.begin(); it != ids.end();)
{
if (dependencies_ids.contains(*it))
it = ids.erase(it);
else
++it;
}
for (auto it = except_ids.begin(); it != except_ids.end();)
{
if (dependencies_ids.contains(*it))
except_ids.erase(it);
else
++it;
}
}
}

View File

@ -66,6 +66,7 @@ struct RolesOrUsersSet
std::vector<UUID> findDependencies() const;
bool hasDependencies(const std::unordered_set<UUID> & dependencies_ids) const;
void replaceDependencies(const std::unordered_map<UUID, UUID> & old_to_new_ids);
void removeDependencies(const std::unordered_set<UUID> & dependencies_ids);
bool all = false;
boost::container::flat_set<UUID> ids;

View File

@ -73,4 +73,9 @@ void RowPolicy::replaceDependencies(const std::unordered_map<UUID, UUID> & old_t
to_roles.replaceDependencies(old_to_new_ids);
}
void RowPolicy::removeDependencies(const std::unordered_set<UUID> & ids)
{
to_roles.removeDependencies(ids);
}
}

View File

@ -52,6 +52,7 @@ struct RowPolicy : public IAccessEntity
std::vector<UUID> findDependencies() const override;
bool hasDependencies(const std::unordered_set<UUID> & ids) const override;
void replaceDependencies(const std::unordered_map<UUID, UUID> & old_to_new_ids) override;
void removeDependencies(const std::unordered_set<UUID> & ids) override;
bool isBackupAllowed() const override { return true; }

View File

@ -32,4 +32,10 @@ void SettingsProfile::replaceDependencies(const std::unordered_map<UUID, UUID> &
to_roles.replaceDependencies(old_to_new_ids);
}
void SettingsProfile::removeDependencies(const std::unordered_set<UUID> & ids)
{
elements.removeDependencies(ids);
to_roles.removeDependencies(ids);
}
}

View File

@ -24,6 +24,7 @@ struct SettingsProfile : public IAccessEntity
std::vector<UUID> findDependencies() const override;
bool hasDependencies(const std::unordered_set<UUID> & ids) const override;
void replaceDependencies(const std::unordered_map<UUID, UUID> & old_to_new_ids) override;
void removeDependencies(const std::unordered_set<UUID> & ids) override;
bool isBackupAllowed() const override { return elements.isBackupAllowed(); }
};

View File

@ -188,6 +188,13 @@ void SettingsProfileElements::replaceDependencies(const std::unordered_map<UUID,
}
void SettingsProfileElements::removeDependencies(const std::unordered_set<UUID> & ids)
{
std::erase_if(
*this, [&](const SettingsProfileElement & element) { return element.parent_profile && ids.contains(*element.parent_profile); });
}
void SettingsProfileElements::merge(const SettingsProfileElements & other)
{
insert(end(), other.begin(), other.end());

View File

@ -65,6 +65,7 @@ public:
std::vector<UUID> findDependencies() const;
bool hasDependencies(const std::unordered_set<UUID> & ids) const;
void replaceDependencies(const std::unordered_map<UUID, UUID> & old_to_new_ids);
void removeDependencies(const std::unordered_set<UUID> & ids);
void merge(const SettingsProfileElements & other);

View File

@ -62,4 +62,12 @@ void User::replaceDependencies(const std::unordered_map<UUID, UUID> & old_to_new
settings.replaceDependencies(old_to_new_ids);
}
void User::removeDependencies(const std::unordered_set<UUID> & ids)
{
default_roles.removeDependencies(ids);
granted_roles.removeDependencies(ids);
grantees.removeDependencies(ids);
settings.removeDependencies(ids);
}
}

View File

@ -34,6 +34,7 @@ struct User : public IAccessEntity
std::vector<UUID> findDependencies() const override;
bool hasDependencies(const std::unordered_set<UUID> & ids) const override;
void replaceDependencies(const std::unordered_map<UUID, UUID> & old_to_new_ids) override;
void removeDependencies(const std::unordered_set<UUID> & ids) override;
bool isBackupAllowed() const override { return settings.isBackupAllowed(); }
};