summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ydb/core/sys_view/auth/auth_scan_base.h21
-rw-r--r--ydb/core/sys_view/auth/group_members.cpp43
-rw-r--r--ydb/core/sys_view/auth/groups.cpp12
-rw-r--r--ydb/core/sys_view/auth/permissions.cpp62
-rw-r--r--ydb/core/sys_view/auth/sort_helpers.h24
-rw-r--r--ydb/core/sys_view/auth/users.cpp47
-rw-r--r--ydb/core/sys_view/common/schema.h2
-rw-r--r--ydb/core/sys_view/ut_kqp.cpp323
8 files changed, 428 insertions, 106 deletions
diff --git a/ydb/core/sys_view/auth/auth_scan_base.h b/ydb/core/sys_view/auth/auth_scan_base.h
index efb60aa0b14..a0363601360 100644
--- a/ydb/core/sys_view/auth/auth_scan_base.h
+++ b/ydb/core/sys_view/auth/auth_scan_base.h
@@ -1,5 +1,7 @@
#pragma once
+#include "sort_helpers.h"
+
#include <ydb/core/base/auth.h>
#include <ydb/core/sys_view/common/events.h>
#include <ydb/core/sys_view/common/schema.h>
@@ -21,7 +23,22 @@ template <typename TDerived>
class TAuthScanBase : public TScanActorBase<TDerived> {
struct TTraversingChildren {
TNavigate::TEntry Entry;
+ TVector<const TNavigate::TListNodeEntry::TChild*> SortedChildren;
size_t Index = 0;
+
+ TTraversingChildren() = default;
+
+ TTraversingChildren(TNavigate::TEntry&& entry)
+ : Entry(std::move(entry))
+ , SortedChildren(::Reserve(Entry.ListNodeEntry->Children.size()))
+ {
+ for (const auto& child : Entry.ListNodeEntry->Children) {
+ SortedChildren.push_back(&child);
+ }
+ SortBatch(SortedChildren, [](const auto* left, const auto* right) {
+ return left->Name < right->Name;
+ });
+ }
};
public:
@@ -96,9 +113,9 @@ protected:
return;
}
- auto& children = last.Entry.ListNodeEntry->Children;
+ auto& children = last.SortedChildren;
if (last.Index < children.size()) {
- auto& child = children.at(last.Index++);
+ const auto& child = *children.at(last.Index++);
if (child.Kind == TSchemeCacheNavigate::KindExtSubdomain || child.Kind == TSchemeCacheNavigate::KindSubdomain) {
continue;
diff --git a/ydb/core/sys_view/auth/group_members.cpp b/ydb/core/sys_view/auth/group_members.cpp
index a8a223e881a..da290a40ec7 100644
--- a/ydb/core/sys_view/auth/group_members.cpp
+++ b/ydb/core/sys_view/auth/group_members.cpp
@@ -31,27 +31,36 @@ protected:
Y_ABORT_UNLESS(entry.Status == TNavigate::EStatus::Ok);
Y_ABORT_UNLESS(CanonizePath(entry.Path) == TBase::TenantName);
- TVector<TCell> cells(::Reserve(Columns.size()));
-
+ TVector<std::pair<const TDomainInfo::TGroup*, const TString*>> memberships;
for (const auto& group : entry.DomainInfo->Groups) {
for (const auto& member : group.Members) {
- for (auto& column : Columns) {
- switch (column.Tag) {
- case Schema::AuthGroupMembers::GroupSid::ColumnId:
- cells.push_back(TCell(group.Sid.data(), group.Sid.size()));
- break;
- case Schema::AuthGroupMembers::MemberSid::ColumnId:
- cells.push_back(TCell(member.data(), member.size()));
- break;
- default:
- cells.emplace_back();
- }
- }
+ memberships.emplace_back(&group, &member);
+ }
+ }
+ SortBatch(memberships, [](const auto& left, const auto& right) {
+ return left.first->Sid < right.first->Sid ||
+ left.first->Sid == right.first->Sid && *left.second < *right.second;
+ });
- TArrayRef<const TCell> ref(cells);
- batch.Rows.emplace_back(TOwnedCellVec::Make(ref));
- cells.clear();
+ TVector<TCell> cells(::Reserve(Columns.size()));
+
+ for (const auto& [group, member] : memberships) {
+ for (auto& column : Columns) {
+ switch (column.Tag) {
+ case Schema::AuthGroupMembers::GroupSid::ColumnId:
+ cells.push_back(TCell(group->Sid.data(), group->Sid.size()));
+ break;
+ case Schema::AuthGroupMembers::MemberSid::ColumnId:
+ cells.push_back(TCell(member->data(), member->size()));
+ break;
+ default:
+ cells.emplace_back();
+ }
}
+
+ TArrayRef<const TCell> ref(cells);
+ batch.Rows.emplace_back(TOwnedCellVec::Make(ref));
+ cells.clear();
}
batch.Finished = true;
diff --git a/ydb/core/sys_view/auth/groups.cpp b/ydb/core/sys_view/auth/groups.cpp
index c7ca81d9c99..d5add729896 100644
--- a/ydb/core/sys_view/auth/groups.cpp
+++ b/ydb/core/sys_view/auth/groups.cpp
@@ -30,14 +30,22 @@ protected:
void FillBatch(NKqp::TEvKqpCompute::TEvScanData& batch, const TNavigate::TEntry& entry) override {
Y_ABORT_UNLESS(entry.Status == TNavigate::EStatus::Ok);
Y_ABORT_UNLESS(CanonizePath(entry.Path) == TBase::TenantName);
+
+ TVector<const TDomainInfo::TGroup*> groups(::Reserve(entry.DomainInfo->Groups.size()));
+ for (const auto& group : entry.DomainInfo->Groups) {
+ groups.push_back(&group);
+ }
+ SortBatch(groups, [](const auto* left, const auto* right) {
+ return left->Sid < right->Sid;
+ });
TVector<TCell> cells(::Reserve(Columns.size()));
- for (const auto& group : entry.DomainInfo->Groups) {
+ for (const auto* group : groups) {
for (auto& column : Columns) {
switch (column.Tag) {
case Schema::AuthGroups::Sid::ColumnId:
- cells.push_back(TCell(group.Sid.data(), group.Sid.size()));
+ cells.push_back(TCell(group->Sid.data(), group->Sid.size()));
break;
default:
cells.emplace_back();
diff --git a/ydb/core/sys_view/auth/permissions.cpp b/ydb/core/sys_view/auth/permissions.cpp
index 11d1066ccb4..30fb45653f6 100644
--- a/ydb/core/sys_view/auth/permissions.cpp
+++ b/ydb/core/sys_view/auth/permissions.cpp
@@ -37,10 +37,7 @@ protected:
return;
}
- TVector<TCell> cells(::Reserve(Columns.size()));
-
- auto entryPath = CanonizePath(entry.Path);
-
+ TVector<std::pair<TString, TString>> permissions;
for (const NACLibProto::TACE& ace : entry.SecurityObject->GetACL().GetACE()) {
if (ace.GetAccessType() != (ui32)NACLib::EAccessType::Allow) {
continue;
@@ -49,32 +46,45 @@ protected:
continue;
}
- auto permissions = ConvertACLMaskToYdbPermissionNames(ace.GetAccessRight());
- for (const auto& permission : permissions) {
- for (auto& column : Columns) {
- switch (column.Tag) {
- case Schema::AuthPermissions::Path::ColumnId:
- cells.push_back(TCell(entryPath.data(), entryPath.size()));
- break;
- case Schema::AuthPermissions::Sid::ColumnId:
- if (ace.HasSID()) {
- cells.push_back(TCell(ace.GetSID().data(), ace.GetSID().size()));
- } else {
- cells.emplace_back();
- }
- break;
- case Schema::AuthPermissions::Permission::ColumnId:
- cells.push_back(TCell(permission.data(), permission.size()));
- break;
- default:
+ auto acePermissions = ConvertACLMaskToYdbPermissionNames(ace.GetAccessRight());
+ for (const auto& permission : acePermissions) {
+ permissions.emplace_back(ace.HasSID() ? ace.GetSID() : TString{}, std::move(permission));
+ }
+ }
+ // Note: due to rights inheritance permissions may be duplicated
+ SortBatch(permissions, [](const auto& left, const auto& right) {
+ return left.first < right.first ||
+ left.first == right.first && left.second < right.second;
+ }, false);
+
+ TVector<TCell> cells(::Reserve(Columns.size()));
+
+ auto entryPath = CanonizePath(entry.Path);
+
+ for (const auto& [sid, permission] : permissions) {
+ for (auto& column : Columns) {
+ switch (column.Tag) {
+ case Schema::AuthPermissions::Path::ColumnId:
+ cells.push_back(TCell(entryPath.data(), entryPath.size()));
+ break;
+ case Schema::AuthPermissions::Sid::ColumnId:
+ if (sid) {
+ cells.push_back(TCell(sid.data(), sid.size()));
+ } else {
cells.emplace_back();
}
+ break;
+ case Schema::AuthPermissions::Permission::ColumnId:
+ cells.push_back(TCell(permission.data(), permission.size()));
+ break;
+ default:
+ cells.emplace_back();
}
-
- TArrayRef<const TCell> ref(cells);
- batch.Rows.emplace_back(TOwnedCellVec::Make(ref));
- cells.clear();
}
+
+ TArrayRef<const TCell> ref(cells);
+ batch.Rows.emplace_back(TOwnedCellVec::Make(ref));
+ cells.clear();
}
batch.Finished = false;
diff --git a/ydb/core/sys_view/auth/sort_helpers.h b/ydb/core/sys_view/auth/sort_helpers.h
new file mode 100644
index 00000000000..55d46b188e8
--- /dev/null
+++ b/ydb/core/sys_view/auth/sort_helpers.h
@@ -0,0 +1,24 @@
+#pragma once
+
+#include <algorithm>
+#include <util/generic/vector.h>
+#include <util/system/yassert.h>
+
+namespace NKikimr::NSysView::NAuth {
+
+template<typename TElement, class TCompLess>
+void SortBatch(TVector<TElement>& batch, TCompLess compLess, bool requireUnique = true) {
+ std::sort(batch.begin(), batch.end(), compLess);
+
+ auto uniqueEnd = std::unique(batch.begin(), batch.end(), [&compLess](const TElement& left, const TElement& right) {
+ return !compLess(left, right) && !compLess(right, left);
+ });
+
+ if (requireUnique) {
+ Y_DEBUG_ABORT_UNLESS(uniqueEnd == batch.end());
+ } else {
+ batch.erase(uniqueEnd, batch.end());
+ }
+}
+
+}
diff --git a/ydb/core/sys_view/auth/users.cpp b/ydb/core/sys_view/auth/users.cpp
index 374b410eef6..263ac0bd52e 100644
--- a/ydb/core/sys_view/auth/users.cpp
+++ b/ydb/core/sys_view/auth/users.cpp
@@ -1,5 +1,5 @@
-#include "auth_scan_base.h"
#include "users.h"
+#include "sort_helpers.h"
#include <ydb/core/base/auth.h>
#include <ydb/core/sys_view/common/events.h>
@@ -94,53 +94,60 @@ protected:
}
void FillBatch(NKqp::TEvKqpCompute::TEvScanData& batch, const NKikimrScheme::TEvListUsersResult& result) {
- TVector<TCell> cells(::Reserve(Columns.size()));
-
+ TVector<const ::NKikimrScheme::TEvListUsersResult_TUser*> users(::Reserve(result.UsersSize()));
for (const auto& user : result.GetUsers()) {
if (!user.HasName() || !CanAccessUser(user.GetName())) {
continue;
}
-
+ users.push_back(&user);
+ }
+ SortBatch(users, [](const auto* left, const auto* right) {
+ return left->GetName() < right->GetName();
+ });
+
+ TVector<TCell> cells(::Reserve(Columns.size()));
+
+ for (const auto* user : users) {
for (auto& column : Columns) {
switch (column.Tag) {
case Schema::AuthUsers::Sid::ColumnId:
- cells.push_back(user.HasName()
- ? TCell(user.GetName().data(), user.GetName().size())
+ cells.push_back(user->HasName()
+ ? TCell(user->GetName().data(), user->GetName().size())
: TCell());
break;
case Schema::AuthUsers::IsEnabled::ColumnId:
- cells.push_back(user.HasIsEnabled()
- ? TCell::Make(user.GetIsEnabled())
+ cells.push_back(user->HasIsEnabled()
+ ? TCell::Make(user->GetIsEnabled())
: TCell());
break;
case Schema::AuthUsers::IsLockedOut::ColumnId:
- cells.push_back(user.HasIsLockedOut()
- ? TCell::Make(user.GetIsLockedOut())
+ cells.push_back(user->HasIsLockedOut()
+ ? TCell::Make(user->GetIsLockedOut())
: TCell());
break;
case Schema::AuthUsers::CreatedAt::ColumnId:
- cells.push_back(user.HasCreatedAt()
- ? TCell::Make(user.GetCreatedAt())
+ cells.push_back(user->HasCreatedAt()
+ ? TCell::Make(user->GetCreatedAt())
: TCell());
break;
case Schema::AuthUsers::LastSuccessfulAttemptAt::ColumnId:
- cells.push_back(user.HasLastSuccessfulAttemptAt()
- ? TCell::Make(user.GetLastSuccessfulAttemptAt())
+ cells.push_back(user->HasLastSuccessfulAttemptAt()
+ ? TCell::Make(user->GetLastSuccessfulAttemptAt())
: TCell());
break;
case Schema::AuthUsers::LastFailedAttemptAt::ColumnId:
- cells.push_back(user.HasLastFailedAttemptAt()
- ? TCell::Make(user.GetLastFailedAttemptAt())
+ cells.push_back(user->HasLastFailedAttemptAt()
+ ? TCell::Make(user->GetLastFailedAttemptAt())
: TCell());
break;
case Schema::AuthUsers::FailedAttemptCount::ColumnId:
- cells.push_back(user.HasFailedAttemptCount()
- ? TCell::Make(user.GetFailedAttemptCount())
+ cells.push_back(user->HasFailedAttemptCount()
+ ? TCell::Make(user->GetFailedAttemptCount())
: TCell());
break;
case Schema::AuthUsers::PasswordHash::ColumnId:
- cells.push_back(user.HasPasswordHash()
- ? TCell(user.GetPasswordHash().data(), user.GetPasswordHash().size())
+ cells.push_back(user->HasPasswordHash()
+ ? TCell(user->GetPasswordHash().data(), user->GetPasswordHash().size())
: TCell());
break;
default:
diff --git a/ydb/core/sys_view/common/schema.h b/ydb/core/sys_view/common/schema.h
index f81a882829a..8710a197a0f 100644
--- a/ydb/core/sys_view/common/schema.h
+++ b/ydb/core/sys_view/common/schema.h
@@ -667,7 +667,7 @@ struct Schema : NIceDb::Schema {
struct Path: Column<1, NScheme::NTypeIds::Utf8> {};
struct Sid: Column<2, NScheme::NTypeIds::Utf8> {};
- using TKey = TableKey<Path, Sid>;
+ using TKey = TableKey<Path>;
using TColumns = TableColumns<
Path,
Sid
diff --git a/ydb/core/sys_view/ut_kqp.cpp b/ydb/core/sys_view/ut_kqp.cpp
index 8d97010880c..434adf07511 100644
--- a/ydb/core/sys_view/ut_kqp.cpp
+++ b/ydb/core/sys_view/ut_kqp.cpp
@@ -2229,8 +2229,8 @@ Y_UNIT_TEST_SUITE(SystemView) {
)").GetValueSync();
auto expected = R"([
- [["user4"];[%true];[%false];[0u];[0u];[0u]];
[["user3"];[%true];[%false];[0u];[0u];[0u]];
+ [["user4"];[%true];[%false];[0u];[0u];[0u]];
])";
NKqp::CompareYson(expected, NKqp::StreamResultToYson(it));
@@ -2276,8 +2276,8 @@ Y_UNIT_TEST_SUITE(SystemView) {
)").GetValueSync();
auto expected = R"([
- [["user2"]];
[["user1rootadmin"]];
+ [["user2"]];
])";
NKqp::CompareYson(expected, NKqp::StreamResultToYson(it));
}
@@ -2289,8 +2289,8 @@ Y_UNIT_TEST_SUITE(SystemView) {
)").GetValueSync();
auto expected = R"([
- [["user4"]];
[["user3"]];
+ [["user4"]];
])";
NKqp::CompareYson(expected, NKqp::StreamResultToYson(it));
}
@@ -2335,6 +2335,47 @@ Y_UNIT_TEST_SUITE(SystemView) {
// and test tenant user and tenant admin
}
+ Y_UNIT_TEST(AuthUsers_ResultOrder) {
+ TTestEnv env;
+ SetupAuthEnvironment(env);
+ TTableClient client(env.GetDriver());
+
+ for (auto user : {
+ "user3",
+ "user1",
+ "user2",
+ "user",
+ "user33",
+ "user21",
+ "user22",
+ "userrr",
+ "u",
+ "asdf",
+ }) {
+ env.GetClient().CreateUser("/Root", user, "password");
+ }
+
+ auto it = client.StreamExecuteScanQuery(R"(
+ SELECT Sid
+ FROM `Root/.sys/auth_users`
+ )").GetValueSync();
+
+ auto expected = R"([
+ [["asdf"]];
+ [["u"]];
+ [["user"]];
+ [["user1"]];
+ [["user2"]];
+ [["user21"]];
+ [["user22"]];
+ [["user3"]];
+ [["user33"]];
+ [["userrr"]];
+ ])";
+
+ NKqp::CompareYson(expected, NKqp::StreamResultToYson(it));
+ }
+
Y_UNIT_TEST(AuthGroups) {
TTestEnv env;
SetupAuthEnvironment(env);
@@ -2384,8 +2425,8 @@ Y_UNIT_TEST_SUITE(SystemView) {
)").GetValueSync();
auto expected = R"([
- [["group4"]];
[["group3"]];
+ [["group4"]];
])";
NKqp::CompareYson(expected, NKqp::StreamResultToYson(it));
@@ -2433,8 +2474,8 @@ Y_UNIT_TEST_SUITE(SystemView) {
)").GetValueSync();
auto expected = R"([
- [["group2"]];
[["group1"]];
+ [["group2"]];
])";
NKqp::CompareYson(expected, NKqp::StreamResultToYson(it));
}
@@ -2446,8 +2487,8 @@ Y_UNIT_TEST_SUITE(SystemView) {
)").GetValueSync();
auto expected = R"([
- [["group4"]];
[["group3"]];
+ [["group4"]];
])";
NKqp::CompareYson(expected, NKqp::StreamResultToYson(it));
}
@@ -2486,7 +2527,48 @@ Y_UNIT_TEST_SUITE(SystemView) {
// and test tenant user and tenant admin
}
- Y_UNIT_TEST(AuthMembers) {
+ Y_UNIT_TEST(AuthGroups_ResultOrder) {
+ TTestEnv env;
+ SetupAuthEnvironment(env);
+ TTableClient client(env.GetDriver());
+
+ for (auto group : {
+ "group3",
+ "group1",
+ "group2",
+ "group",
+ "group33",
+ "group21",
+ "group22",
+ "grouprr",
+ "g",
+ "asdf",
+ }) {
+ env.GetClient().CreateGroup("/Root", group);
+ }
+
+ auto it = client.StreamExecuteScanQuery(R"(
+ SELECT *
+ FROM `Root/.sys/auth_groups`
+ )").GetValueSync();
+
+ auto expected = R"([
+ [["asdf"]];
+ [["g"]];
+ [["group"]];
+ [["group1"]];
+ [["group2"]];
+ [["group21"]];
+ [["group22"]];
+ [["group3"]];
+ [["group33"]];
+ [["grouprr"]];
+ ])";
+
+ NKqp::CompareYson(expected, NKqp::StreamResultToYson(it));
+ }
+
+ Y_UNIT_TEST(AuthGroupMembers) {
TTestEnv env;
SetupAuthEnvironment(env);
TTableClient client(env.GetDriver());
@@ -2545,18 +2627,18 @@ Y_UNIT_TEST_SUITE(SystemView) {
)").GetValueSync();
auto expected = R"([
- [["group4"];["group4"]];
+ [["group3"];["user4"]];
[["group4"];["group3"]];
- [["group4"];["user4"]];
+ [["group4"];["group4"]];
[["group4"];["user3"]];
- [["group3"];["user4"]];
+ [["group4"];["user4"]];
])";
NKqp::CompareYson(expected, NKqp::StreamResultToYson(it));
}
}
- Y_UNIT_TEST(AuthMembers_Access) {
+ Y_UNIT_TEST(AuthGroupMembers_Access) {
TTestEnv env;
SetupAuthAccessEnvironment(env);
TTableClient client(env.GetDriver());
@@ -2602,8 +2684,8 @@ Y_UNIT_TEST_SUITE(SystemView) {
)").GetValueSync();
auto expected = R"([
- [["group2"];["user2"]];
[["group1"];["user1rootadmin"]];
+ [["group2"];["user2"]];
])";
NKqp::CompareYson(expected, NKqp::StreamResultToYson(it));
}
@@ -2615,8 +2697,8 @@ Y_UNIT_TEST_SUITE(SystemView) {
)").GetValueSync();
auto expected = R"([
- [["group4"];["user4"]];
[["group3"];["user3"]];
+ [["group4"];["user4"]];
])";
NKqp::CompareYson(expected, NKqp::StreamResultToYson(it));
}
@@ -2655,6 +2737,56 @@ Y_UNIT_TEST_SUITE(SystemView) {
// and test tenant user and tenant admin
}
+ Y_UNIT_TEST(AuthGroupMembers_ResultOrder) {
+ TTestEnv env;
+ SetupAuthEnvironment(env);
+ TTableClient client(env.GetDriver());
+
+ for (auto group : {
+ "group3",
+ "group1",
+ "group2",
+ "group",
+ }) {
+ env.GetClient().CreateGroup("/Root", group);
+ }
+
+ for (auto user : {
+ "user1",
+ "user2",
+ "user"
+ }) {
+ env.GetClient().CreateUser("/Root", user, "password");
+ }
+
+ for (auto membership : TVector<std::pair<TString, TString>>{
+ {"group3", "user1"},
+ {"group3", "user2"},
+ {"group2", "user"},
+ {"group2", "user1"},
+ {"group2", "user2"},
+ {"group", "user2"},
+ }) {
+ env.GetClient().AddGroupMembership("/Root", membership.first, membership.second);
+ }
+
+ auto it = client.StreamExecuteScanQuery(R"(
+ SELECT *
+ FROM `Root/.sys/auth_group_members`
+ )").GetValueSync();
+
+ auto expected = R"([
+ [["group"];["user2"]];
+ [["group2"];["user"]];
+ [["group2"];["user1"]];
+ [["group2"];["user2"]];
+ [["group3"];["user1"]];
+ [["group3"];["user2"]];
+ ])";
+
+ NKqp::CompareYson(expected, NKqp::StreamResultToYson(it));
+ }
+
Y_UNIT_TEST(AuthOwners) {
TTestEnv env;
SetupAuthEnvironment(env);
@@ -2859,6 +2991,53 @@ Y_UNIT_TEST_SUITE(SystemView) {
// and test tenant user and tenant admin
}
+ Y_UNIT_TEST(AuthOwners_ResultOrder) {
+ TTestEnv env;
+ SetupAuthEnvironment(env);
+ TTableClient client(env.GetDriver());
+
+ for (auto path : {
+ "Dir2/SubDir2",
+ "Dir1/SubDir1",
+ "Dir2/SubDir1",
+ "Dir1/SubDir2",
+ "Dir2/SubDir3",
+ "Dir1/SubDir3",
+ "Dir11/SubDir",
+ "Dir/SubDir",
+ }) {
+ env.GetClient().MkDir("/Root", path);
+ }
+
+ auto it = client.StreamExecuteScanQuery(R"(
+ SELECT *
+ FROM `Root/.sys/auth_owners`
+ )").GetValueSync();
+
+ auto expected = R"([
+ [["/Root"];["root@builtin"]];
+ [["/Root/.metadata"];["metadata@system"]];
+ [["/Root/.metadata/workload_manager"];["metadata@system"]];
+ [["/Root/.metadata/workload_manager/pools"];["metadata@system"]];
+ [["/Root/.metadata/workload_manager/pools/default"];["metadata@system"]];
+ [["/Root/Dir"];["root@builtin"]];
+ [["/Root/Dir/SubDir"];["root@builtin"]];
+ [["/Root/Dir1"];["root@builtin"]];
+ [["/Root/Dir1/SubDir1"];["root@builtin"]];
+ [["/Root/Dir1/SubDir2"];["root@builtin"]];
+ [["/Root/Dir1/SubDir3"];["root@builtin"]];
+ [["/Root/Dir11"];["root@builtin"]];
+ [["/Root/Dir11/SubDir"];["root@builtin"]];
+ [["/Root/Dir2"];["root@builtin"]];
+ [["/Root/Dir2/SubDir1"];["root@builtin"]];
+ [["/Root/Dir2/SubDir2"];["root@builtin"]];
+ [["/Root/Dir2/SubDir3"];["root@builtin"]];
+ [["/Root/Table0"];["root@builtin"]]
+ ])";
+
+ NKqp::CompareYson(expected, NKqp::StreamResultToYson(it));
+ }
+
Y_UNIT_TEST(AuthPermissions) {
TTestEnv env;
SetupAuthEnvironment(env);
@@ -2925,13 +3104,13 @@ Y_UNIT_TEST_SUITE(SystemView) {
auto expected = R"([
[["/Root"];["ydb.generic.use"];["user1"]];
- [["/Root/.metadata/workload_manager/pools/default"];["ydb.granular.select_row"];["all-users@well-known"]];
[["/Root/.metadata/workload_manager/pools/default"];["ydb.granular.describe_schema"];["all-users@well-known"]];
- [["/Root/.metadata/workload_manager/pools/default"];["ydb.granular.select_row"];["root@builtin"]];
+ [["/Root/.metadata/workload_manager/pools/default"];["ydb.granular.select_row"];["all-users@well-known"]];
[["/Root/.metadata/workload_manager/pools/default"];["ydb.granular.describe_schema"];["root@builtin"]];
+ [["/Root/.metadata/workload_manager/pools/default"];["ydb.granular.select_row"];["root@builtin"]];
[["/Root/Dir1"];["ydb.generic.use"];["user1"]];
- [["/Root/Dir1/SubDir1"];["ydb.granular.select_row"];["user1"]];
[["/Root/Dir1/SubDir1"];["ydb.granular.erase_row"];["user1"]];
+ [["/Root/Dir1/SubDir1"];["ydb.granular.select_row"];["user1"]];
])";
NKqp::CompareYson(expected, NKqp::StreamResultToYson(it));
@@ -3009,14 +3188,14 @@ Y_UNIT_TEST_SUITE(SystemView) {
auto expected = R"([
[["/Root"];["ydb.generic.use"];["user1rootadmin"]];
[["/Root"];["ydb.generic.use"];["user2"]];
- [["/Root/.metadata/workload_manager/pools/default"];["ydb.generic.full"];["root@builtin"]];
- [["/Root/.metadata/workload_manager/pools/default"];["ydb.generic.full"];["user1rootadmin"]];
- [["/Root/.metadata/workload_manager/pools/default"];["ydb.granular.select_row"];["all-users@well-known"]];
[["/Root/.metadata/workload_manager/pools/default"];["ydb.granular.describe_schema"];["all-users@well-known"]];
- [["/Root/.metadata/workload_manager/pools/default"];["ydb.granular.select_row"];["root@builtin"]];
+ [["/Root/.metadata/workload_manager/pools/default"];["ydb.granular.select_row"];["all-users@well-known"]];
+ [["/Root/.metadata/workload_manager/pools/default"];["ydb.generic.full"];["root@builtin"]];
[["/Root/.metadata/workload_manager/pools/default"];["ydb.granular.describe_schema"];["root@builtin"]];
+ [["/Root/.metadata/workload_manager/pools/default"];["ydb.granular.select_row"];["root@builtin"]];
+ [["/Root/.metadata/workload_manager/pools/default"];["ydb.generic.full"];["user1rootadmin"]];
[["/Root/Dir1"];["ydb.granular.select_row"];["user1rootadmin"]];
- [["/Root/Dir2"];["ydb.granular.erase_row"];["user2"]]
+ [["/Root/Dir2"];["ydb.granular.erase_row"];["user2"]];
])";
NKqp::CompareYson(expected, NKqp::StreamResultToYson(it));
}
@@ -3040,14 +3219,14 @@ Y_UNIT_TEST_SUITE(SystemView) {
auto expected = R"([
[["/Root"];["ydb.generic.use"];["user1rootadmin"]];
[["/Root"];["ydb.generic.use"];["user2"]];
- [["/Root/.metadata/workload_manager/pools/default"];["ydb.generic.full"];["root@builtin"]];
- [["/Root/.metadata/workload_manager/pools/default"];["ydb.generic.full"];["user1rootadmin"]];
- [["/Root/.metadata/workload_manager/pools/default"];["ydb.granular.select_row"];["all-users@well-known"]];
[["/Root/.metadata/workload_manager/pools/default"];["ydb.granular.describe_schema"];["all-users@well-known"]];
- [["/Root/.metadata/workload_manager/pools/default"];["ydb.granular.select_row"];["root@builtin"]];
+ [["/Root/.metadata/workload_manager/pools/default"];["ydb.granular.select_row"];["all-users@well-known"]];
+ [["/Root/.metadata/workload_manager/pools/default"];["ydb.generic.full"];["root@builtin"]];
[["/Root/.metadata/workload_manager/pools/default"];["ydb.granular.describe_schema"];["root@builtin"]];
+ [["/Root/.metadata/workload_manager/pools/default"];["ydb.granular.select_row"];["root@builtin"]];
+ [["/Root/.metadata/workload_manager/pools/default"];["ydb.generic.full"];["user1rootadmin"]];
[["/Root/Dir1"];["ydb.granular.select_row"];["user1rootadmin"]];
- [["/Root/Dir2"];["ydb.granular.erase_row"];["user2"]]
+ [["/Root/Dir2"];["ydb.granular.erase_row"];["user2"]];
])";
NKqp::CompareYson(expected, NKqp::StreamResultToYson(it));
}
@@ -3060,7 +3239,7 @@ Y_UNIT_TEST_SUITE(SystemView) {
auto expected = R"([
[["/Root/Tenant1/Dir3"];["ydb.granular.select_row"];["user3"]];
- [["/Root/Tenant1/Dir3"];["ydb.granular.erase_row"];["user4"]]
+ [["/Root/Tenant1/Dir3"];["ydb.granular.erase_row"];["user4"]];
])";
NKqp::CompareYson(expected, NKqp::StreamResultToYson(it));
}
@@ -3088,12 +3267,12 @@ Y_UNIT_TEST_SUITE(SystemView) {
auto expected = R"([
[["/Root"];["ydb.generic.use"];["user1rootadmin"]];
[["/Root"];["ydb.generic.use"];["user2"]];
- [["/Root/.metadata/workload_manager/pools/default"];["ydb.generic.full"];["root@builtin"]];
- [["/Root/.metadata/workload_manager/pools/default"];["ydb.generic.full"];["user1rootadmin"]];
- [["/Root/.metadata/workload_manager/pools/default"];["ydb.granular.select_row"];["all-users@well-known"]];
[["/Root/.metadata/workload_manager/pools/default"];["ydb.granular.describe_schema"];["all-users@well-known"]];
- [["/Root/.metadata/workload_manager/pools/default"];["ydb.granular.select_row"];["root@builtin"]];
+ [["/Root/.metadata/workload_manager/pools/default"];["ydb.granular.select_row"];["all-users@well-known"]];
+ [["/Root/.metadata/workload_manager/pools/default"];["ydb.generic.full"];["root@builtin"]];
[["/Root/.metadata/workload_manager/pools/default"];["ydb.granular.describe_schema"];["root@builtin"]];
+ [["/Root/.metadata/workload_manager/pools/default"];["ydb.granular.select_row"];["root@builtin"]];
+ [["/Root/.metadata/workload_manager/pools/default"];["ydb.generic.full"];["user1rootadmin"]];
[["/Root/Dir1"];["ydb.granular.select_row"];["user1rootadmin"]];
])";
NKqp::CompareYson(expected, NKqp::StreamResultToYson(it));
@@ -3103,6 +3282,76 @@ Y_UNIT_TEST_SUITE(SystemView) {
// and test tenant user and tenant admin
}
+ Y_UNIT_TEST(AuthPermissions_ResultOrder) {
+ TTestEnv env;
+ SetupAuthEnvironment(env);
+ TTableClient client(env.GetDriver());
+
+ for (auto user : {
+ "user1",
+ "user2",
+ "user"
+ }) {
+ env.GetClient().CreateUser("/Root", user, "password");
+ }
+
+ for (auto dir : {
+ "Dir",
+ "Dir1",
+ "Dir2",
+ "Dir/SubDir1",
+ "Dir/SubDir2"
+ }) {
+ env.GetClient().MkDir("/Root", dir);
+ }
+
+ for (auto acl : TVector<std::tuple<TString, TString, TString, NACLib::EAccessRights>>{
+ {"/", "Root", "user1", NACLib::SelectRow},
+ {"/", "Root", "user1", NACLib::EraseRow},
+ {"/", "Root", "user1", NACLib::AlterSchema},
+ {"/", "Root", "user2", NACLib::GenericUse},
+ {"/Root", "Dir1", "user2", NACLib::GenericUse},
+ {"/Root", "Dir1", "user1", NACLib::GenericUse},
+ {"/Root", "Dir2", "user2", NACLib::GenericUse},
+ {"/Root", "Dir2", "user", NACLib::GenericUse},
+ {"/Root", "Dir2", "user1", NACLib::GenericUse},
+ {"/Root", "Dir", "user1", NACLib::GenericUse},
+ {"/Root", "Dir1", "user1", NACLib::AlterSchema},
+ {"/Root/Dir1", "SubDir1", "user1", NACLib::AlterSchema},
+ {"/Root/Dir1", "SubDir2", "user2", NACLib::AlterSchema},
+ {"/Root/Dir1", "SubDir2", "user1", NACLib::AlterSchema}
+ }) {
+ NACLib::TDiffACL diffAcl;
+ diffAcl.AddAccess(NACLib::EAccessType::Allow, std::get<3>(acl), std::get<2>(acl));
+ env.GetClient().ModifyACL(std::get<0>(acl), std::get<1>(acl), diffAcl.SerializeAsString());
+ }
+
+ auto it = client.StreamExecuteScanQuery(R"(
+ SELECT Path, Sid, Permission
+ FROM `Root/.sys/auth_permissions`
+ )").GetValueSync();
+
+ auto expected = R"([
+ [["/Root"];["user1"];["ydb.granular.alter_schema"]];
+ [["/Root"];["user1"];["ydb.granular.erase_row"]];
+ [["/Root"];["user1"];["ydb.granular.select_row"]];
+ [["/Root"];["user2"];["ydb.generic.use"]];
+ [["/Root/.metadata/workload_manager/pools/default"];["all-users@well-known"];["ydb.granular.describe_schema"]];
+ [["/Root/.metadata/workload_manager/pools/default"];["all-users@well-known"];["ydb.granular.select_row"]];
+ [["/Root/.metadata/workload_manager/pools/default"];["root@builtin"];["ydb.granular.describe_schema"]];
+ [["/Root/.metadata/workload_manager/pools/default"];["root@builtin"];["ydb.granular.select_row"]];
+ [["/Root/Dir"];["user1"];["ydb.generic.use"]];
+ [["/Root/Dir1"];["user1"];["ydb.generic.use"]];
+ [["/Root/Dir1"];["user1"];["ydb.granular.alter_schema"]];
+ [["/Root/Dir1"];["user2"];["ydb.generic.use"]];
+ [["/Root/Dir2"];["user"];["ydb.generic.use"]];
+ [["/Root/Dir2"];["user1"];["ydb.generic.use"]];
+ [["/Root/Dir2"];["user2"];["ydb.generic.use"]];
+ ])";
+
+ NKqp::CompareYson(expected, NKqp::StreamResultToYson(it));
+ }
+
Y_UNIT_TEST(AuthEffectivePermissions) {
TTestEnv env;
SetupAuthEnvironment(env);
@@ -3138,11 +3387,11 @@ Y_UNIT_TEST_SUITE(SystemView) {
[["/Root/.metadata"];["ydb.generic.use"];["user1"]];
[["/Root/.metadata/workload_manager"];["ydb.generic.use"];["user1"]];
[["/Root/.metadata/workload_manager/pools"];["ydb.generic.use"];["user1"]];
- [["/Root/.metadata/workload_manager/pools/default"];["ydb.generic.use"];["user1"]];
- [["/Root/.metadata/workload_manager/pools/default"];["ydb.granular.select_row"];["all-users@well-known"]];
[["/Root/.metadata/workload_manager/pools/default"];["ydb.granular.describe_schema"];["all-users@well-known"]];
- [["/Root/.metadata/workload_manager/pools/default"];["ydb.granular.select_row"];["root@builtin"]];
+ [["/Root/.metadata/workload_manager/pools/default"];["ydb.granular.select_row"];["all-users@well-known"]];
[["/Root/.metadata/workload_manager/pools/default"];["ydb.granular.describe_schema"];["root@builtin"]];
+ [["/Root/.metadata/workload_manager/pools/default"];["ydb.granular.select_row"];["root@builtin"]];
+ [["/Root/.metadata/workload_manager/pools/default"];["ydb.generic.use"];["user1"]];
[["/Root/Dir1"];["ydb.generic.use"];["user1"]];
[["/Root/Table0"];["ydb.generic.use"];["user1"]]
])";
@@ -3234,8 +3483,8 @@ Y_UNIT_TEST_SUITE(SystemView) {
auto expected = R"([
[["/Root/Dir1"];["ydb.granular.select_row"];["user2"]];
- [["/Root/Dir1/SubDir1"];["ydb.granular.select_row"];["user2"]];
[["/Root/Dir1/SubDir1"];["ydb.granular.erase_row"];["user2"]];
+ [["/Root/Dir1/SubDir1"];["ydb.granular.select_row"];["user2"]];
])";
NKqp::CompareYson(expected, NKqp::StreamResultToYson(it));
@@ -3248,12 +3497,10 @@ Y_UNIT_TEST_SUITE(SystemView) {
WHERE Sid = "user2"
)").GetValueSync();
- // TODO: make result unique
auto expected = R"([
[["/Root/Dir1"];["ydb.granular.select_row"];["user2"]];
- [["/Root/Dir1/SubDir1"];["ydb.granular.select_row"];["user2"]];
- [["/Root/Dir1/SubDir1"];["ydb.granular.select_row"];["user2"]];
[["/Root/Dir1/SubDir1"];["ydb.granular.erase_row"];["user2"]];
+ [["/Root/Dir1/SubDir1"];["ydb.granular.select_row"];["user2"]];
[["/Root/Dir1/SubDir2"];["ydb.granular.select_row"];["user2"]];
])";