aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormolotkov-and <molotkov-and@ydb.tech>2023-11-13 15:05:28 +0300
committermolotkov-and <molotkov-and@ydb.tech>2023-11-13 15:36:37 +0300
commit9ad62ad914b3f3db1d6fa7a437d67d85f4d8de97 (patch)
tree055472c6b34ea050ea82d3f253503649d0e84865
parent3b418aaf377d71e99c6f83ace0d9dd92b0c0793b (diff)
downloadydb-9ad62ad914b3f3db1d6fa7a437d67d85f4d8de97.tar.gz
KIKIMR-19848: Add check of resource path for gizmo object in ticket parser
-rw-r--r--ydb/core/base/ticket_parser.h2
-rw-r--r--ydb/core/mon/mon.cpp87
-rw-r--r--ydb/core/mon/mon.h4
-rw-r--r--ydb/core/security/ticket_parser_impl.h33
-rw-r--r--ydb/core/security/ticket_parser_ut.cpp12
-rw-r--r--ydb/library/testlib/service_mocks/access_service_mock.h6
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;