diff options
author | molotkov-and <molotkov-and@ydb.tech> | 2023-11-13 15:05:28 +0300 |
---|---|---|
committer | molotkov-and <molotkov-and@ydb.tech> | 2023-11-13 15:36:37 +0300 |
commit | 9ad62ad914b3f3db1d6fa7a437d67d85f4d8de97 (patch) | |
tree | 055472c6b34ea050ea82d3f253503649d0e84865 | |
parent | 3b418aaf377d71e99c6f83ace0d9dd92b0c0793b (diff) | |
download | ydb-9ad62ad914b3f3db1d6fa7a437d67d85f4d8de97.tar.gz |
KIKIMR-19848: Add check of resource path for gizmo object in ticket parser
-rw-r--r-- | ydb/core/base/ticket_parser.h | 2 | ||||
-rw-r--r-- | ydb/core/mon/mon.cpp | 87 | ||||
-rw-r--r-- | ydb/core/mon/mon.h | 4 | ||||
-rw-r--r-- | ydb/core/security/ticket_parser_impl.h | 33 | ||||
-rw-r--r-- | ydb/core/security/ticket_parser_ut.cpp | 12 | ||||
-rw-r--r-- | ydb/library/testlib/service_mocks/access_service_mock.h | 6 |
6 files changed, 99 insertions, 45 deletions
diff --git a/ydb/core/base/ticket_parser.h b/ydb/core/base/ticket_parser.h index f715dec164..3bf1a82699 100644 --- a/ydb/core/base/ticket_parser.h +++ b/ydb/core/base/ticket_parser.h @@ -1,4 +1,4 @@ - #pragma once +#pragma once #include <library/cpp/containers/stack_vector/stack_vec.h> #include <ydb/core/base/defs.h> #include <ydb/core/base/events.h> diff --git a/ydb/core/mon/mon.cpp b/ydb/core/mon/mon.cpp index 30874e675c..4d31af077a 100644 --- a/ydb/core/mon/mon.cpp +++ b/ydb/core/mon/mon.cpp @@ -7,42 +7,35 @@ namespace NActors { using namespace NMonitoring; -IMonPage* TMon::RegisterActorPage(TIndexMonPage* index, const TString& relPath, - const TString& title, bool preTag, TActorSystem* actorSystem, const TActorId& actorId, bool useAuth, bool sortPages) { - return RegisterActorPage({ - .Title = title, - .RelPath = relPath, - .ActorSystem = actorSystem, - .Index = index, - .PreTag = preTag, - .ActorId = actorId, - .UseAuth = useAuth, - .SortPages = sortPages, - }); +namespace { + +const std::vector<NKikimr::TEvTicketParser::TEvAuthorizeTicket::TEntry>& GetEntries(const TString& ticket) { + if (ticket.StartsWith("Bearer")) { + static std::vector<NKikimr::TEvTicketParser::TEvAuthorizeTicket::TEntry> entries = { + {NKikimr::TEvTicketParser::TEvAuthorizeTicket::ToPermissions({"ydb.developerApi.get", "ydb.developerApi.update"}), {{"gizmo_id", "gizmo"}}} + }; + return entries; + } + static std::vector<NKikimr::TEvTicketParser::TEvAuthorizeTicket::TEntry> emptyEntries = {}; + return emptyEntries; } -NActors::IEventHandle* TMon::DefaultAuthorizer(const NActors::TActorId& owner, NMonitoring::IMonHttpRequest& request) { +} // namespace + +NActors::IEventHandle* SelectAuthorizationScheme(const NActors::TActorId& owner, NMonitoring::IMonHttpRequest& request) { TStringBuf ydbSessionId = request.GetCookie("ydb_session_id"); TStringBuf authorization = request.GetHeader("Authorization"); if (!authorization.empty()) { - return new NActors::IEventHandle( - NKikimr::MakeTicketParserID(), - owner, - new NKikimr::TEvTicketParser::TEvAuthorizeTicket({ - .Ticket = TString(authorization) - }), - IEventHandle::FlagTrackDelivery - ); + return GetAuthorizeTicketHandle(owner, TString(authorization)); } else if (!ydbSessionId.empty()) { - return new NActors::IEventHandle( - NKikimr::MakeTicketParserID(), - owner, - new NKikimr::TEvTicketParser::TEvAuthorizeTicket({ - .Ticket = TString("Login ") + TString(ydbSessionId) - }), - IEventHandle::FlagTrackDelivery - ); - } else if (NKikimr::AppData()->EnforceUserTokenRequirement && NKikimr::AppData()->DefaultUserSIDs.empty()) { + return GetAuthorizeTicketHandle(owner, TString("Login ") + TString(ydbSessionId)); + } else { + return nullptr; + } +} + +NActors::IEventHandle* GetAuthorizeTicketResult(const NActors::TActorId& owner) { + if (NKikimr::AppData()->EnforceUserTokenRequirement && NKikimr::AppData()->DefaultUserSIDs.empty()) { return new NActors::IEventHandle( owner, owner, @@ -63,4 +56,38 @@ NActors::IEventHandle* TMon::DefaultAuthorizer(const NActors::TActorId& owner, N } } +IEventHandle* GetAuthorizeTicketHandle(const NActors::TActorId& owner, const TString& ticket) { + return new NActors::IEventHandle( + NKikimr::MakeTicketParserID(), + owner, + new NKikimr::TEvTicketParser::TEvAuthorizeTicket({ + .Ticket = ticket, + .Entries = GetEntries(ticket), + }), + IEventHandle::FlagTrackDelivery + ); +} + +IMonPage* TMon::RegisterActorPage(TIndexMonPage* index, const TString& relPath, + const TString& title, bool preTag, TActorSystem* actorSystem, const TActorId& actorId, bool useAuth, bool sortPages) { + return RegisterActorPage({ + .Title = title, + .RelPath = relPath, + .ActorSystem = actorSystem, + .Index = index, + .PreTag = preTag, + .ActorId = actorId, + .UseAuth = useAuth, + .SortPages = sortPages, + }); +} + +NActors::IEventHandle* TMon::DefaultAuthorizer(const NActors::TActorId& owner, NMonitoring::IMonHttpRequest& request) { + NActors::IEventHandle* eventHandle = SelectAuthorizationScheme(owner, request); + if (eventHandle != nullptr) { + return eventHandle; + } + return GetAuthorizeTicketResult(owner); +} + } diff --git a/ydb/core/mon/mon.h b/ydb/core/mon/mon.h index b10996eb34..c9aa5bc233 100644 --- a/ydb/core/mon/mon.h +++ b/ydb/core/mon/mon.h @@ -13,6 +13,10 @@ namespace NActors { +IEventHandle* GetAuthorizeTicketHandle(const NActors::TActorId& owner, const TString& ticket); +IEventHandle* SelectAuthorizationScheme(const NActors::TActorId& owner, NMonitoring::IMonHttpRequest& request); +IEventHandle* GetAuthorizeTicketResult(const NActors::TActorId& owner); + class TActorSystem; struct TActorId; diff --git a/ydb/core/security/ticket_parser_impl.h b/ydb/core/security/ticket_parser_impl.h index c7c5229853..08bdc0273a 100644 --- a/ydb/core/security/ticket_parser_impl.h +++ b/ydb/core/security/ticket_parser_impl.h @@ -358,28 +358,30 @@ private: auto request = CreateAccessServiceRequest<TEvAccessServiceAuthorizeRequest>(key, record); + auto addResourcePath = [&request] (const TString& id, const TString& type) { + auto* resourcePath = request->Request.add_resource_path(); + resourcePath->set_id(id); + resourcePath->set_type(type); + }; + request->Request.set_permission(permission); if (const auto databaseId = record.GetAttributeValue(permission, "database_id"); databaseId) { - auto* resourcePath = request->Request.add_resource_path(); - resourcePath->set_id(databaseId); - resourcePath->set_type("ydb.database"); + addResourcePath(databaseId, "ydb.database"); } else if (const auto serviceAccountId = record.GetAttributeValue(permission, "service_account_id"); serviceAccountId) { - auto* resourcePath = request->Request.add_resource_path(); - resourcePath->set_id(serviceAccountId); - resourcePath->set_type("iam.serviceAccount"); + addResourcePath(serviceAccountId, "iam.serviceAccount"); } if (const auto folderId = record.GetAttributeValue(permission, "folder_id"); folderId) { - auto* resourcePath = request->Request.add_resource_path(); - resourcePath->set_id(folderId); - resourcePath->set_type("resource-manager.folder"); + addResourcePath(folderId, "resource-manager.folder"); } if (const auto cloudId = record.GetAttributeValue(permission, "cloud_id"); cloudId) { - auto* resourcePath = request->Request.add_resource_path(); - resourcePath->set_id(cloudId); - resourcePath->set_type("resource-manager.cloud"); + addResourcePath(cloudId, "resource-manager.cloud"); + } + + if (const TString gizmoId = record.GetAttributeValue(permission, "gizmo_id"); gizmoId) { + addResourcePath(gizmoId, "iam.gizmo"); } record.ResponsesLeft++; @@ -1103,7 +1105,12 @@ protected: void AddPermissionSids(TVector<TString>& sids, const TTokenRecordBase& record, const TString& permission) const { sids.emplace_back(permission + '@' + AccessServiceDomain); - sids.emplace_back(permission + '-' + record.GetAttributeValue(permission, "database_id") + '@' + AccessServiceDomain); + if (const TString databaseId = record.GetAttributeValue(permission, "database_id"); databaseId) { + sids.emplace_back(permission + '-' + databaseId + '@' + AccessServiceDomain); + } + if (const TString gizmoId = record.GetAttributeValue(permission, "gizmo_id"); gizmoId) { + sids.emplace_back(permission + '-' + gizmoId + '@' + AccessServiceDomain); + } } template <typename TTokenRecord> diff --git a/ydb/core/security/ticket_parser_ut.cpp b/ydb/core/security/ticket_parser_ut.cpp index d4f6cef78f..9f3fa8b862 100644 --- a/ydb/core/security/ticket_parser_ut.cpp +++ b/ydb/core/security/ticket_parser_ut.cpp @@ -1500,6 +1500,18 @@ Y_UNIT_TEST_SUITE(TTicketParserTest) { result = runtime->GrabEdgeEvent<TEvTicketParser::TEvAuthorizeTicketResult>(handle); UNIT_ASSERT(result->Error.empty()); UNIT_ASSERT(result->Token->IsExist("something.read-bbbb4554@as")); + + // Authorization successful for gizmo resource + accessServiceMock.AllowedResourceIds.clear(); + accessServiceMock.AllowedResourceIds.emplace("gizmo"); + runtime->Send(new IEventHandle(MakeTicketParserID(), sender, new TEvTicketParser::TEvAuthorizeTicket( + userToken, + {{"gizmo_id", "gizmo"}, }, + {"monitoring.view"})), 0); + result = runtime->GrabEdgeEvent<TEvTicketParser::TEvAuthorizeTicketResult>(handle); + UNIT_ASSERT(result->Error.empty()); + UNIT_ASSERT(result->Token->IsExist("monitoring.view@as")); + UNIT_ASSERT(result->Token->IsExist("monitoring.view-gizmo@as")); } Y_UNIT_TEST(AuthorizationWithRequiredPermissions) { diff --git a/ydb/library/testlib/service_mocks/access_service_mock.h b/ydb/library/testlib/service_mocks/access_service_mock.h index e684744a7f..927f7fdc48 100644 --- a/ydb/library/testlib/service_mocks/access_service_mock.h +++ b/ydb/library/testlib/service_mocks/access_service_mock.h @@ -133,7 +133,11 @@ public: } } - THashSet<TString> AllowedUserPermissions = {"user1-something.read", "ApiKey-value-valid-something.read", "ApiKey-value-valid-ydb.api.kafkaPlainAuth"}; + THashSet<TString> AllowedUserPermissions = { + "user1-something.read", + "ApiKey-value-valid-something.read", + "ApiKey-value-valid-ydb.api.kafkaPlainAuth", + "user1-monitoring.view"}; THashMap<TString, TString> AllowedServicePermissions = {{"service1-something.write", "root1/folder1"}}; THashSet<TString> AllowedResourceIds = {}; THashSet<TString> UnavailableUserPermissions; |