aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Efimov <xeno@prnwatch.com>2022-06-06 16:47:14 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-06-06 16:47:14 +0300
commit9a90a0b585f215a1ac2e35c8fb28258eb24416f7 (patch)
treefcbdbde73e55e3a791b3e5fda21da499595ddbf1
parent53ff143b6db6dffa52da9b82f7e62e17d68ee1e7 (diff)
downloadydb-9a90a0b585f215a1ac2e35c8fb28258eb24416f7.tar.gz
add simple acl handler instead of heavy metainfo KIKIMR-1504122.2.38
REVIEW: 2613565 x-ydb-stable-ref: b87970e132a0056ef96d67b322d37499fe654394
-rw-r--r--ydb/core/viewer/json_acl.h213
-rw-r--r--ydb/core/viewer/viewer.cpp2
-rw-r--r--ydb/core/viewer/ya.make1
3 files changed, 216 insertions, 0 deletions
diff --git a/ydb/core/viewer/json_acl.h b/ydb/core/viewer/json_acl.h
new file mode 100644
index 0000000000..43034830fc
--- /dev/null
+++ b/ydb/core/viewer/json_acl.h
@@ -0,0 +1,213 @@
+#pragma once
+#include <library/cpp/actors/core/actor_bootstrapped.h>
+#include <library/cpp/actors/core/mon.h>
+#include <ydb/core/base/tablet_pipe.h>
+#include <ydb/core/protos/services.pb.h>
+#include <ydb/core/tx/schemeshard/schemeshard.h>
+#include <ydb/core/tx/tx_proxy/proxy.h>
+#include "viewer.h"
+#include "json_pipe_req.h"
+
+namespace NKikimr {
+namespace NViewer {
+
+using namespace NActors;
+using NSchemeShard::TEvSchemeShard;
+
+class TJsonACL : public TViewerPipeClient<TJsonACL> {
+ using TBase = TViewerPipeClient<TJsonACL>;
+ IViewer* Viewer;
+ NMon::TEvHttpInfo::TPtr Event;
+ TAutoPtr<TEvSchemeShard::TEvDescribeSchemeResult> DescribeResult;
+ TJsonSettings JsonSettings;
+ ui32 Timeout = 0;
+
+public:
+ static constexpr NKikimrServices::TActivity::EType ActorActivityType() {
+ return NKikimrServices::TActivity::VIEWER_HANDLER;
+ }
+
+ TJsonACL(IViewer* viewer, NMon::TEvHttpInfo::TPtr &ev)
+ : Viewer(viewer)
+ , Event(ev)
+ {}
+
+ void FillParams(NKikimrSchemeOp::TDescribePath* record, const TCgiParameters& params) {
+ if (params.Has("path")) {
+ record->SetPath(params.Get("path"));
+ }
+ if (params.Has("path_id")) {
+ record->SetPathId(FromStringWithDefault<ui64>(params.Get("path_id")));
+ }
+ if (params.Has("schemeshard_id")) {
+ record->SetSchemeshardId(FromStringWithDefault<ui64>(params.Get("schemeshard_id")));
+ }
+ }
+
+ void Bootstrap() {
+ const auto& params(Event->Get()->Request.GetParams());
+ JsonSettings.EnumAsNumbers = !FromStringWithDefault<bool>(params.Get("enums"), false);
+ JsonSettings.UI64AsString = !FromStringWithDefault<bool>(params.Get("ui64"), false);
+ Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
+ InitConfig(params);
+
+ if (params.Has("schemeshard_id")) {
+ THolder<TEvSchemeShard::TEvDescribeScheme> request = MakeHolder<TEvSchemeShard::TEvDescribeScheme>();
+ FillParams(&request->Record, params);
+ ui64 schemeShardId = FromStringWithDefault<ui64>(params.Get("schemeshard_id"));
+ SendRequestToPipe(ConnectTabletPipe(schemeShardId), request.Release());
+ } else {
+ THolder<TEvTxUserProxy::TEvNavigate> request = MakeHolder<TEvTxUserProxy::TEvNavigate>();
+ FillParams(request->Record.MutableDescribePath(), params);
+ request->Record.SetUserToken(Event->Get()->UserToken);
+ SendRequest(MakeTxProxyID(), request.Release());
+ }
+ Become(&TThis::StateRequestedDescribe, TDuration::MilliSeconds(Timeout), new TEvents::TEvWakeup());
+ }
+
+ STATEFN(StateRequestedDescribe) {
+ switch (ev->GetTypeRewrite()) {
+ hFunc(TEvSchemeShard::TEvDescribeSchemeResult, Handle);
+ hFunc(TEvTabletPipe::TEvClientConnected, TBase::Handle);
+ cFunc(TEvents::TSystem::Wakeup, HandleTimeout);
+ }
+ }
+
+ void Handle(TEvSchemeShard::TEvDescribeSchemeResult::TPtr& ev) {
+ DescribeResult = ev->Release();
+ RequestDone();
+ }
+
+ void ReplyAndPassAway() {
+ TStringStream json;
+ TString headers = Viewer->GetHTTPOKJSON(Event->Get());
+ if (DescribeResult != nullptr) {
+ //TProtoToJson::ProtoToJson(json, DescribeResult->GetRecord(), JsonSettings);
+ const auto& pbRecord(DescribeResult->GetRecord());
+ NKikimrViewer::TMetaInfo metaInfo;
+ NKikimrViewer::TMetaCommonInfo& pbCommon = *metaInfo.MutableCommon();
+ pbCommon.SetPath(pbRecord.GetPath());
+ if (pbRecord.HasPathDescription()) {
+ const auto& pbPathDescription(pbRecord.GetPathDescription());
+ if (pbPathDescription.HasSelf()) {
+ const auto& pbSelf(pbPathDescription.GetSelf());
+ pbCommon.SetOwner(pbSelf.GetOwner());
+ }
+ if (pbPathDescription.GetSelf().HasACL()) {
+ NACLib::TACL acl(pbPathDescription.GetSelf().GetACL());
+ auto& aces(acl.GetACE());
+ for (auto it = aces.begin(); it != aces.end(); ++it) {
+ const NACLibProto::TACE& ace = *it;
+ auto& pbAce = *pbCommon.AddACL();
+ if (static_cast<NACLib::EAccessType>(ace.GetAccessType()) == NACLib::EAccessType::Deny) {
+ pbAce.SetAccessType("Deny");
+ } else
+ if (static_cast<NACLib::EAccessType>(ace.GetAccessType()) == NACLib::EAccessType::Allow) {
+ pbAce.SetAccessType("Allow");
+ }
+ static std::unordered_map<ui32, TString> mapAccessRights = {
+ {NACLib::EAccessRights::SelectRow, "SelectRow"},
+ {NACLib::EAccessRights::UpdateRow, "UpdateRow"},
+ {NACLib::EAccessRights::EraseRow, "EraseRow"},
+ {NACLib::EAccessRights::ReadAttributes, "ReadAttributes"},
+ {NACLib::EAccessRights::WriteAttributes, "WriteAttributes"},
+ {NACLib::EAccessRights::CreateDirectory, "CreateDirectory"},
+ {NACLib::EAccessRights::CreateTable, "CreateTable"},
+ {NACLib::EAccessRights::CreateQueue, "CreateQueue"},
+ {NACLib::EAccessRights::RemoveSchema, "RemoveSchema"},
+ {NACLib::EAccessRights::DescribeSchema, "DescribeSchema"},
+ {NACLib::EAccessRights::AlterSchema, "AlterSchema"},
+ {NACLib::EAccessRights::CreateDatabase, "CreateDatabase"},
+ {NACLib::EAccessRights::DropDatabase, "DropDatabase"},
+ {NACLib::EAccessRights::GrantAccessRights, "GrantAccessRights"},
+ {NACLib::EAccessRights::WriteUserAttributes, "WriteUserAttributes"},
+ {NACLib::EAccessRights::ConnectDatabase, "ConnectDatabase"},
+ {NACLib::EAccessRights::ReadStream, "ReadStream"},
+ {NACLib::EAccessRights::WriteStream, "WriteStream"},
+ {NACLib::EAccessRights::ReadTopic, "ReadTopic"},
+ {NACLib::EAccessRights::WritTopic, "WriteTopic"}
+ };
+ auto ar = ace.GetAccessRight();
+ int shift = 0;
+ while (ar > 0) {
+ if (ar & (1 << shift)) {
+ pbAce.AddAccessRights(mapAccessRights[1 << shift]);
+ ar ^= 1 << shift;
+ }
+ ++shift;
+ }
+ pbAce.SetSubject(ace.GetSID());
+ auto inht = ace.GetInheritanceType();
+ if ((inht & NACLib::EInheritanceType::InheritObject) != 0) {
+ pbAce.AddInheritanceType("InheritObject");
+ }
+ if ((inht & NACLib::EInheritanceType::InheritContainer) != 0) {
+ pbAce.AddInheritanceType("InheritContainer");
+ }
+ if ((inht & NACLib::EInheritanceType::InheritOnly) != 0) {
+ pbAce.AddInheritanceType("InheritOnly");
+ }
+ }
+ }
+ }
+
+ TProtoToJson::ProtoToJson(json, metaInfo, JsonSettings);
+
+ switch (DescribeResult->GetRecord().GetStatus()) {
+ case NKikimrScheme::StatusAccessDenied:
+ headers = HTTPFORBIDDENJSON;
+ break;
+ default:
+ break;
+ }
+ } else {
+ json << "null";
+ }
+
+ Send(Event->Sender, new NMon::TEvHttpInfoRes(headers + json.Str(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ PassAway();
+ }
+
+ void HandleTimeout() {
+ Send(Event->Sender, new NMon::TEvHttpInfoRes(Viewer->GetHTTPGATEWAYTIMEOUT(), 0, NMon::IEvHttpInfoRes::EContentType::Custom));
+ PassAway();
+ }
+};
+
+template <>
+struct TJsonRequestSchema<TJsonACL> {
+ static TString GetSchema() {
+ TStringStream stream;
+ TProtoToJson::ProtoToJsonSchema<NKikimrViewer::TMetaInfo>(stream);
+ return stream.Str();
+ }
+};
+
+template <>
+struct TJsonRequestParameters<TJsonACL> {
+ static TString GetParameters() {
+ return R"___([{"name":"path","in":"query","description":"schema path","required":false,"type":"string"},
+ {"name":"schemeshard_id","in":"query","description":"schemeshard identifier (tablet id)","required":false,"type":"integer"},
+ {"name":"path_id","in":"query","description":"path id","required":false,"type":"integer"},
+ {"name":"enums","in":"query","description":"convert enums to strings","required":false,"type":"boolean"},
+ {"name":"ui64","in":"query","description":"return ui64 as number","required":false,"type":"boolean"},
+ {"name":"timeout","in":"query","description":"timeout in ms","required":false,"type":"integer"}])___";
+ }
+};
+
+template <>
+struct TJsonRequestSummary<TJsonACL> {
+ static TString GetSummary() {
+ return "\"ACL information\"";
+ }
+};
+
+template <>
+struct TJsonRequestDescription<TJsonACL> {
+ static TString GetDescription() {
+ return "\"Returns information about acl of an object\"";
+ }
+};
+
+}
+}
diff --git a/ydb/core/viewer/viewer.cpp b/ydb/core/viewer/viewer.cpp
index 6aff691c0a..99c5442787 100644
--- a/ydb/core/viewer/viewer.cpp
+++ b/ydb/core/viewer/viewer.cpp
@@ -48,6 +48,7 @@
#include "counters_hosts.h"
#include "json_healthcheck.h"
#include "json_nodes.h"
+#include "json_acl.h"
namespace NKikimr {
namespace NViewer {
@@ -208,6 +209,7 @@ public:
JsonHandlers["/json/compute"] = new TJsonHandler<TJsonCompute>;
JsonHandlers["/json/healthcheck"] = new TJsonHandler<TJsonHealthCheck>;
JsonHandlers["/json/nodes"] = new TJsonHandler<TJsonNodes>;
+ JsonHandlers["/json/acl"] = new TJsonHandler<TJsonACL>;
}
}
diff --git a/ydb/core/viewer/ya.make b/ydb/core/viewer/ya.make
index 8ebde73686..b57132547f 100644
--- a/ydb/core/viewer/ya.make
+++ b/ydb/core/viewer/ya.make
@@ -14,6 +14,7 @@ SRCS(
browse_pq.h
browse.h
counters_hosts.h
+ json_acl.h
json_browse.h
json_bscontrollerinfo.h
json_bsgroupinfo.h