|
2 | 2 | #include <library/cpp/testing/unittest/tests_data.h>
|
3 | 3 | #include <ydb/library/actors/interconnect/interconnect.h>
|
4 | 4 | #include <ydb/library/actors/helpers/selfping_actor.h>
|
| 5 | +#include <library/cpp/http/misc/httpcodes.h> |
| 6 | +#include <library/cpp/http/simple/http_client.h> |
5 | 7 | #include <library/cpp/json/json_value.h>
|
6 | 8 | #include <library/cpp/json/json_reader.h>
|
7 | 9 | #include <util/stream/null.h>
|
|
23 | 25 | #include <ydb/core/node_whiteboard/node_whiteboard.h>
|
24 | 26 | #include <ydb/library/actors/core/interconnect.h>
|
25 | 27 |
|
| 28 | +#include <util/string/builder.h> |
| 29 | + |
26 | 30 | using namespace NKikimr;
|
27 | 31 | using namespace NViewer;
|
28 | 32 | using namespace NKikimrWhiteboard;
|
@@ -1503,4 +1507,142 @@ Y_UNIT_TEST_SUITE(Viewer) {
|
1503 | 1507 | Y_UNIT_TEST(JsonStorageListingV2PDiskIdFilter) {
|
1504 | 1508 | JsonStorage9Nodes9GroupsListingTest("v2", false, true, true, 4, 8);
|
1505 | 1509 | }
|
| 1510 | + |
| 1511 | + struct TFakeTicketParserActor : public TActor<TFakeTicketParserActor> { |
| 1512 | + TFakeTicketParserActor() |
| 1513 | + : TActor<TFakeTicketParserActor>(&TFakeTicketParserActor::StFunc) |
| 1514 | + {} |
| 1515 | + |
| 1516 | + STFUNC(StFunc) { |
| 1517 | + switch (ev->GetTypeRewrite()) { |
| 1518 | + hFunc(TEvTicketParser::TEvAuthorizeTicket, Handle); |
| 1519 | + default: |
| 1520 | + break; |
| 1521 | + } |
| 1522 | + } |
| 1523 | + |
| 1524 | + void Handle(TEvTicketParser::TEvAuthorizeTicket::TPtr& ev) { |
| 1525 | + LOG_INFO_S(*TlsActivationContext, NKikimrServices::TICKET_PARSER, "Ticket parser: got TEvAuthorizeTicket event: " << ev->Get()->Ticket << " " << ev->Get()->Database << " " << ev->Get()->Entries.size()); |
| 1526 | + ++AuthorizeTicketRequests; |
| 1527 | + |
| 1528 | + if (ev->Get()->Database != "/Root") { |
| 1529 | + Fail(ev, TStringBuilder() << "Incorrect database " << ev->Get()->Database); |
| 1530 | + return; |
| 1531 | + } |
| 1532 | + |
| 1533 | + if (ev->Get()->Ticket != "test_ydb_token") { |
| 1534 | + Fail(ev, TStringBuilder() << "Incorrect token " << ev->Get()->Ticket); |
| 1535 | + return; |
| 1536 | + } |
| 1537 | + |
| 1538 | + bool databaseIdFound = false; |
| 1539 | + bool folderIdFound = false; |
| 1540 | + for (const TEvTicketParser::TEvAuthorizeTicket::TEntry& entry : ev->Get()->Entries) { |
| 1541 | + for (const std::pair<TString, TString>& attr : entry.Attributes) { |
| 1542 | + if (attr.first == "database_id") { |
| 1543 | + databaseIdFound = true; |
| 1544 | + if (attr.second != "test_database_id") { |
| 1545 | + Fail(ev, TStringBuilder() << "Incorrect database_id " << attr.second); |
| 1546 | + return; |
| 1547 | + } |
| 1548 | + } else if (attr.first == "folder_id") { |
| 1549 | + folderIdFound = true; |
| 1550 | + if (attr.second != "test_folder_id") { |
| 1551 | + Fail(ev, TStringBuilder() << "Incorrect folder_id " << attr.second); |
| 1552 | + return; |
| 1553 | + } |
| 1554 | + } |
| 1555 | + } |
| 1556 | + } |
| 1557 | + if (!databaseIdFound) { |
| 1558 | + Fail(ev, "database_id not found"); |
| 1559 | + return; |
| 1560 | + } |
| 1561 | + if (!folderIdFound) { |
| 1562 | + Fail(ev, "folder_id not found"); |
| 1563 | + return; |
| 1564 | + } |
| 1565 | + |
| 1566 | + Success(ev); |
| 1567 | + } |
| 1568 | + |
| 1569 | + void Fail(TEvTicketParser::TEvAuthorizeTicket::TPtr& ev, const TString& message) { |
| 1570 | + ++AuthorizeTicketFails; |
| 1571 | + TEvTicketParser::TError err; |
| 1572 | + err.Retryable = false; |
| 1573 | + err.Message = message ? message : "Test error"; |
| 1574 | + LOG_INFO_S(*TlsActivationContext, NKikimrServices::TICKET_PARSER, "Send TEvAuthorizeTicketResult: " << err.Message); |
| 1575 | + Send(ev->Sender, new TEvTicketParser::TEvAuthorizeTicketResult(ev->Get()->Ticket, err)); |
| 1576 | + } |
| 1577 | + |
| 1578 | + void Success(TEvTicketParser::TEvAuthorizeTicket::TPtr& ev) { |
| 1579 | + ++AuthorizeTicketSuccesses; |
| 1580 | + NACLib::TUserToken::TUserTokenInitFields args; |
| 1581 | + args.UserSID = "user_name"; |
| 1582 | + args.GroupSIDs.push_back("group_name"); |
| 1583 | + TIntrusivePtr<NACLib::TUserToken> userToken = MakeIntrusive<NACLib::TUserToken>(args); |
| 1584 | + LOG_INFO_S(*TlsActivationContext, NKikimrServices::TICKET_PARSER, "Send TEvAuthorizeTicketResult success"); |
| 1585 | + Send(ev->Sender, new TEvTicketParser::TEvAuthorizeTicketResult(ev->Get()->Ticket, userToken)); |
| 1586 | + } |
| 1587 | + |
| 1588 | + size_t AuthorizeTicketRequests = 0; |
| 1589 | + size_t AuthorizeTicketSuccesses = 0; |
| 1590 | + size_t AuthorizeTicketFails = 0; |
| 1591 | + }; |
| 1592 | + |
| 1593 | + Y_UNIT_TEST(AuthorizeYdbTokenWithDatabaseAttributes) { |
| 1594 | + TPortManager tp; |
| 1595 | + ui16 port = tp.GetPort(2134); |
| 1596 | + ui16 grpcPort = tp.GetPort(2135); |
| 1597 | + ui16 monPort = tp.GetPort(8765); |
| 1598 | + auto settings = TServerSettings(port); |
| 1599 | + settings.InitKikimrRunConfig() |
| 1600 | + .SetNodeCount(1) |
| 1601 | + .SetUseRealThreads(true) |
| 1602 | + .SetDomainName("Root") |
| 1603 | + .SetMonitoringPortOffset(monPort, true); // authorization is implemented only in async mon |
| 1604 | + |
| 1605 | + auto& securityConfig = *settings.AppConfig->MutableDomainsConfig()->MutableSecurityConfig(); |
| 1606 | + securityConfig.SetEnforceUserTokenCheckRequirement(true); |
| 1607 | + |
| 1608 | + TFakeTicketParserActor* ticketParser = nullptr; |
| 1609 | + settings.CreateTicketParser = [&](const TTicketParserSettings&) -> IActor* { |
| 1610 | + ticketParser = new TFakeTicketParserActor(); |
| 1611 | + return ticketParser; |
| 1612 | + }; |
| 1613 | + |
| 1614 | + TServer server(settings); |
| 1615 | + server.EnableGRpc(grpcPort); |
| 1616 | + TClient client(settings); |
| 1617 | + |
| 1618 | + const auto alterAttrsStatus = client.AlterUserAttributes("/", "Root", { |
| 1619 | + { "folder_id", "test_folder_id" }, |
| 1620 | + { "database_id", "test_database_id" }, |
| 1621 | + }); |
| 1622 | + UNIT_ASSERT_EQUAL(alterAttrsStatus, NMsgBusProxy::MSTATUS_OK); |
| 1623 | + |
| 1624 | + TTestActorRuntime& runtime = *server.GetRuntime(); |
| 1625 | + runtime.SetLogPriority(NKikimrServices::GRPC_SERVER, NLog::PRI_TRACE); |
| 1626 | + runtime.SetLogPriority(NKikimrServices::TICKET_PARSER, NLog::PRI_TRACE); |
| 1627 | + |
| 1628 | + TKeepAliveHttpClient httpClient("localhost", monPort); |
| 1629 | + TStringStream responseStream; |
| 1630 | + TKeepAliveHttpClient::THeaders headers; |
| 1631 | + headers["Content-Type"] = "application/json"; |
| 1632 | + headers["Authorization"] = "test_ydb_token"; |
| 1633 | + TString requestBody = R"json({ |
| 1634 | + "query": "SELECT 42;", |
| 1635 | + "database": "/Root", |
| 1636 | + "action": "execute-script", |
| 1637 | + "syntax": "yql_v1", |
| 1638 | + "stats": "profile" |
| 1639 | + })json"; |
| 1640 | + const TKeepAliveHttpClient::THttpCode statusCode = httpClient.DoPost("/viewer/query?timeout=600000&base64=false&schema=modern", requestBody, &responseStream, headers); |
| 1641 | + const TString response = responseStream.ReadAll(); |
| 1642 | + UNIT_ASSERT_EQUAL_C(statusCode, HTTP_OK, statusCode << ": " << response); |
| 1643 | + |
| 1644 | + UNIT_ASSERT(ticketParser); |
| 1645 | + UNIT_ASSERT_VALUES_EQUAL_C(ticketParser->AuthorizeTicketRequests, 1, response); |
| 1646 | + UNIT_ASSERT_VALUES_EQUAL_C(ticketParser->AuthorizeTicketSuccesses, 1, response); |
| 1647 | + } |
1506 | 1648 | }
|
0 commit comments