Skip to content

Commit 93dfe8c

Browse files
ui access to databases page field - merge stable-25-1 (#18371)
2 parents 2ca9e56 + 796d958 commit 93dfe8c

File tree

5 files changed

+86
-25
lines changed

5 files changed

+86
-25
lines changed

ydb/core/grpc_services/grpc_request_check_actor.h

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,40 @@ bool TGRpcRequestProxyHandleMethods::ValidateAndReplyOnError(TCtx* ctx) {
3939
}
4040
}
4141

42-
inline const TVector<TEvTicketParser::TEvAuthorizeTicket::TEntry>& GetEntriesForAuthAndCheckRequest(TEvRequestAuthAndCheck::TPtr& ev) {
43-
if (ev->Get()->YdbToken && ev->Get()->YdbToken->StartsWith("Bearer")) {
44-
if (AppData()->AuthConfig.GetUseAccessService()
45-
&& (AppData()->DomainsConfig.GetSecurityConfig().ViewerAllowedSIDsSize() > 0 || AppData()->DomainsConfig.GetSecurityConfig().MonitoringAllowedSIDsSize() > 0)) {
46-
static TVector<NKikimr::TEvTicketParser::TEvAuthorizeTicket::TEntry> entries = {
47-
{NKikimr::TEvTicketParser::TEvAuthorizeTicket::ToPermissions({"ydb.developerApi.get", "ydb.developerApi.update"}), {{"gizmo_id", "gizmo"}}}
48-
};
49-
return entries;
42+
inline TVector<TEvTicketParser::TEvAuthorizeTicket::TEntry> GetEntriesForAuthAndCheckRequest(TEvRequestAuthAndCheck::TPtr& ev, const TVector<std::pair<TString, TString>>& rootAttributes) {
43+
const bool isBearerToken = ev->Get()->YdbToken && ev->Get()->YdbToken->StartsWith("Bearer");
44+
const bool useAccessService = AppData()->AuthConfig.GetUseAccessService();
45+
const bool needClusterAccessResourceCheck = AppData()->DomainsConfig.GetSecurityConfig().ViewerAllowedSIDsSize() > 0 ||
46+
AppData()->DomainsConfig.GetSecurityConfig().MonitoringAllowedSIDsSize() > 0;
47+
48+
if (!isBearerToken || !useAccessService || !needClusterAccessResourceCheck) {
49+
return {};
50+
}
51+
52+
const TString& accessServiceType = AppData()->AuthConfig.GetAccessServiceType();
53+
54+
if (accessServiceType == "Yandex_v2") {
55+
static const TVector<NKikimr::TEvTicketParser::TEvAuthorizeTicket::TEntry> entries = {
56+
{NKikimr::TEvTicketParser::TEvAuthorizeTicket::ToPermissions({"ydb.developerApi.get", "ydb.developerApi.update"}), {{"gizmo_id", "gizmo"}}}
57+
};
58+
return entries;
59+
} else if (accessServiceType == "Nebius_v1") {
60+
static const auto permissions = NKikimr::TEvTicketParser::TEvAuthorizeTicket::ToPermissions({
61+
"ydb.clusters.get", "ydb.clusters.monitor", "ydb.clusters.manage"
62+
});
63+
auto it = std::find_if(rootAttributes.begin(), rootAttributes.end(),
64+
[](const std::pair<TString, TString>& p) {
65+
return p.first == "folder_id";
66+
});
67+
if (it == rootAttributes.end()) {
68+
return {};
5069
}
70+
return {
71+
{permissions, {{"folder_id", it->second}}}
72+
};
73+
} else {
74+
return {};
5175
}
52-
static TVector<NKikimr::TEvTicketParser::TEvAuthorizeTicket::TEntry> emptyEntries = {};
53-
return emptyEntries;
5476
}
5577

5678
template <typename TEvent>
@@ -80,14 +102,14 @@ class TGrpcRequestCheckActor
80102

81103
static const TVector<TString>& GetPermissions();
82104

83-
void InitializeAttributesFromSchema(const TSchemeBoardEvents::TDescribeSchemeResult& schemeData) {
105+
void InitializeAttributesFromSchema(const TSchemeBoardEvents::TDescribeSchemeResult& schemeData, const TVector<std::pair<TString, TString>>& rootAttributes) {
84106
CheckedDatabaseName_ = CanonizePath(schemeData.GetPath());
85107
if (!GrpcRequestBaseCtx_->TryCustomAttributeProcess(schemeData, this)) {
86-
ProcessCommonAttributes(schemeData);
108+
ProcessCommonAttributes(schemeData, rootAttributes);
87109
}
88110
}
89111

90-
void ProcessCommonAttributes(const TSchemeBoardEvents::TDescribeSchemeResult& schemeData) {
112+
void ProcessCommonAttributes(const TSchemeBoardEvents::TDescribeSchemeResult& schemeData, const TVector<std::pair<TString, TString>>& rootAttributes) {
91113
TVector<TEvTicketParser::TEvAuthorizeTicket::TEntry> entries;
92114
static std::vector<TString> allowedAttributes = {"folder_id", "service_account_id", "database_id"};
93115
TVector<std::pair<TString, TString>> attributes;
@@ -102,7 +124,7 @@ class TGrpcRequestCheckActor
102124
}
103125

104126
if constexpr (std::is_same_v<TEvent, TEvRequestAuthAndCheck>) {
105-
const auto& e = GetEntriesForAuthAndCheckRequest(Request_);
127+
const auto& e = GetEntriesForAuthAndCheckRequest(Request_, rootAttributes);
106128
entries.insert(entries.end(), e.begin(), e.end());
107129
}
108130

@@ -115,12 +137,12 @@ class TGrpcRequestCheckActor
115137
TBase::SetEntries(entries);
116138
}
117139

118-
void InitializeAttributes(const TSchemeBoardEvents::TDescribeSchemeResult& schemeData);
140+
void InitializeAttributes(const TSchemeBoardEvents::TDescribeSchemeResult& schemeData, const TVector<std::pair<TString, TString>>& rootAttributes);
119141

120-
void Initialize(const TSchemeBoardEvents::TDescribeSchemeResult& schemeData) {
142+
void Initialize(const TSchemeBoardEvents::TDescribeSchemeResult& schemeData, const TVector<std::pair<TString, TString>>& rootAttributes) {
121143
TString peerName = GrpcRequestBaseCtx_->GetPeerName();
122144
TBase::SetPeerName(peerName);
123-
InitializeAttributes(schemeData);
145+
InitializeAttributes(schemeData, rootAttributes);
124146
TBase::SetDatabase(CheckedDatabaseName_);
125147
InitializeAuditSettings(schemeData);
126148
}
@@ -132,7 +154,8 @@ class TGrpcRequestCheckActor
132154
TAutoPtr<TEventHandle<TEvent>> request,
133155
IGRpcProxyCounters::TPtr counters,
134156
bool skipCheckConnectRights,
135-
const IFacilityProvider* facilityProvider)
157+
const IFacilityProvider* facilityProvider,
158+
const TVector<std::pair<TString, TString>>& rootAttributes)
136159
: Owner_(owner)
137160
, Request_(std::move(request))
138161
, Counters_(counters)
@@ -152,7 +175,7 @@ class TGrpcRequestCheckActor
152175
TBase::SetSecurityToken(TString(clientCertificates.front()));
153176
}
154177
}
155-
Initialize(schemeData);
178+
Initialize(schemeData, rootAttributes);
156179
}
157180

158181
void Bootstrap(const TActorContext& ctx) {
@@ -595,11 +618,11 @@ class TGrpcRequestCheckActor
595618

596619
// default behavior - attributes in schema
597620
template <typename TEvent>
598-
void TGrpcRequestCheckActor<TEvent>::InitializeAttributes(const TSchemeBoardEvents::TDescribeSchemeResult& schemeData) {
621+
void TGrpcRequestCheckActor<TEvent>::InitializeAttributes(const TSchemeBoardEvents::TDescribeSchemeResult& schemeData, const TVector<std::pair<TString, TString>>& rootAttributes) {
599622
for (const auto& attr : schemeData.GetPathDescription().GetUserAttributes()) {
600623
Attributes_.emplace_back(std::make_pair(attr.GetKey(), attr.GetValue()));
601624
}
602-
InitializeAttributesFromSchema(schemeData);
625+
InitializeAttributesFromSchema(schemeData, rootAttributes);
603626
}
604627

605628
template<typename T>
@@ -643,9 +666,10 @@ IActor* CreateGrpcRequestCheckActor(
643666
TAutoPtr<TEventHandle<TEvent>> request,
644667
IGRpcProxyCounters::TPtr counters,
645668
bool skipCheckConnectRights,
669+
const TVector<std::pair<TString, TString>>& rootAttributes,
646670
const IFacilityProvider* facilityProvider) {
647671

648-
return new TGrpcRequestCheckActor<TEvent>(owner, schemeData, std::move(securityObject), std::move(request), counters, skipCheckConnectRights, facilityProvider);
672+
return new TGrpcRequestCheckActor<TEvent>(owner, schemeData, std::move(securityObject), std::move(request), counters, skipCheckConnectRights, facilityProvider, rootAttributes);
649673
}
650674

651675
}

ydb/core/grpc_services/grpc_request_proxy.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,25 @@ class TGRpcRequestProxyImpl
227227
}
228228

229229
if (database) {
230+
TVector<std::pair<TString, TString>> rootAttributes;
231+
auto rootIt = Databases.find(RootDatabase);
232+
if (rootIt == Databases.end() || !rootIt->second.IsDatabaseReady() || !rootIt->second.SchemeBoardResult) {
233+
Counters->IncDatabaseUnavailableCounter();
234+
const TString error = "Grpc proxy is not ready to accept request, root database unknown";
235+
LOG_ERROR(ctx, NKikimrServices::GRPC_SERVER, error);
236+
const auto issue = MakeIssue(NKikimrIssues::TIssuesIds::YDB_DB_NOT_READY, error);
237+
requestBaseCtx->RaiseIssue(issue);
238+
requestBaseCtx->ReplyWithYdbStatus(Ydb::StatusIds::UNAVAILABLE);
239+
requestBaseCtx->FinishSpan();
240+
return;
241+
}
242+
243+
const auto& schemeData = rootIt->second.SchemeBoardResult->DescribeSchemeResult;
244+
rootAttributes.reserve(schemeData.GetPathDescription().UserAttributesSize());
245+
for (const auto& attr : schemeData.GetPathDescription().GetUserAttributes()) {
246+
rootAttributes.emplace_back(std::make_pair(attr.GetKey(), attr.GetValue()));
247+
}
248+
230249
if (database->SchemeBoardResult) {
231250
const auto& domain = database->SchemeBoardResult->DescribeSchemeResult.GetPathDescription().GetDomainDescription();
232251
if (domain.HasResourcesDomainKey() && !skipResourceCheck && DynamicNode) {
@@ -272,6 +291,7 @@ class TGRpcRequestProxyImpl
272291
event.Release(),
273292
Counters,
274293
skipCheckConnectRigths,
294+
rootAttributes,
275295
this));
276296
return;
277297
}

ydb/core/grpc_services/grpc_request_proxy_simple.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ class TGRpcRequestProxySimple
132132

133133
{
134134
TSchemeBoardEvents::TDescribeSchemeResult schemeData;
135-
Register(CreateGrpcRequestCheckActor<TEvent>(SelfId(), schemeData, nullptr, event.Release(), Counters, false, this));
135+
Register(CreateGrpcRequestCheckActor<TEvent>(SelfId(), schemeData, nullptr, event.Release(), Counters, false, {}, this));
136136
return;
137137
}
138138

ydb/core/security/ticket_parser_impl.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,7 @@ class TTicketParserImpl : public TActorBootstrapped<TDerived> {
462462
pathsContainer->mutable_resource_path()->add_path()->set_id(id);
463463
}
464464

465-
static void AddNebiusContainerId(nebius::iam::v1::AuthorizeCheck* pathsContainer, const TString& id) {
465+
static void SetNebiusContainerId(nebius::iam::v1::AuthorizeCheck* pathsContainer, const TString& id) {
466466
pathsContainer->set_container_id(id);
467467
}
468468

@@ -477,7 +477,7 @@ class TTicketParserImpl : public TActorBootstrapped<TDerived> {
477477
// Use attribute "folder_id" as container id that contains our database
478478
// IAM can link roles for containers hierarchy
479479
if (const auto folderId = record.GetAttributeValue(permission, "folder_id"); folderId) {
480-
AddNebiusContainerId(pathsContainer, folderId);
480+
SetNebiusContainerId(pathsContainer, folderId);
481481
}
482482
}
483483

ydb/core/security/ticket_parser_ut.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1671,8 +1671,25 @@ Y_UNIT_TEST_SUITE(TTicketParserTest) {
16711671
{"monitoring.view"})), 0);
16721672
result = runtime->GrabEdgeEvent<TEvTicketParser::TEvAuthorizeTicketResult>(handle);
16731673
UNIT_ASSERT_C(result->Error.empty(), result->Error);
1674+
UNIT_ASSERT_VALUES_EQUAL_C(result->Token->GetGroupSIDs().size(), 4, result->Token->ShortDebugString());
1675+
UNIT_ASSERT_C(result->Token->IsExist("all-users@well-known"), result->Token->ShortDebugString());
16741676
UNIT_ASSERT_C(result->Token->IsExist("monitoring.view@as"), result->Token->ShortDebugString());
16751677
UNIT_ASSERT_C(result->Token->IsExist("monitoring.view-gizmo@as"), result->Token->ShortDebugString());
1678+
UNIT_ASSERT_C(result->Token->IsExist("user1@as"), result->Token->ShortDebugString());
1679+
} else {
1680+
// Authorization successful for cluster resource
1681+
accessServiceMock.AllowedResourceIds.clear();
1682+
accessServiceMock.AllowedResourceIds.emplace("folder");
1683+
runtime->Send(new IEventHandle(MakeTicketParserID(), sender, new TEvTicketParser::TEvAuthorizeTicket(
1684+
userToken,
1685+
{{"folder_id", "folder"}, },
1686+
{"monitoring.view"})), 0);
1687+
result = runtime->GrabEdgeEvent<TEvTicketParser::TEvAuthorizeTicketResult>(handle);
1688+
UNIT_ASSERT_C(result->Error.empty(), result->Error);
1689+
UNIT_ASSERT_VALUES_EQUAL_C(result->Token->GetGroupSIDs().size(), 3, result->Token->ShortDebugString());
1690+
UNIT_ASSERT_C(result->Token->IsExist("all-users@well-known"), result->Token->ShortDebugString());
1691+
UNIT_ASSERT_C(result->Token->IsExist("monitoring.view@as"), result->Token->ShortDebugString());
1692+
UNIT_ASSERT_C(result->Token->IsExist("user1@as"), result->Token->ShortDebugString());
16761693
}
16771694
}
16781695

0 commit comments

Comments
 (0)