Skip to content

Commit

Permalink
add grant/revore permissions to query service
Browse files Browse the repository at this point in the history
  • Loading branch information
VPolka committed Dec 15, 2023
1 parent e5de0d2 commit fba31d0
Show file tree
Hide file tree
Showing 7 changed files with 349 additions and 15 deletions.
8 changes: 8 additions & 0 deletions ydb/core/kqp/executer_actor/kqp_scheme_executer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,17 +139,25 @@ class TKqpSchemeExecuter : public TActorBootstrapped<TKqpSchemeExecuter> {
ev->Record.MutableTransaction()->MutableModifyScheme()->CopyFrom(modifyScheme);
break;
}

case NKqpProto::TKqpSchemeOperation::kAlterUser: {
auto modifyScheme = schemeOp.GetAlterUser();
ev->Record.MutableTransaction()->MutableModifyScheme()->CopyFrom(modifyScheme);
break;
}

case NKqpProto::TKqpSchemeOperation::kDropUser: {
auto modifyScheme = schemeOp.GetDropUser();
ev->Record.MutableTransaction()->MutableModifyScheme()->CopyFrom(modifyScheme);
break;
}

case NKqpProto::TKqpSchemeOperation::kModifyPermissions: {
auto modifyScheme = schemeOp.GetModifyPermissions();
ev->Record.MutableTransaction()->MutableModifyScheme()->CopyFrom(modifyScheme);
break;
}

default:
InternalError(TStringBuilder() << "Unexpected scheme operation: "
<< (ui32) schemeOp.GetOperationCase());
Expand Down
2 changes: 2 additions & 0 deletions ydb/core/kqp/gateway/kqp_gateway.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,8 @@ bool SplitTablePath(const TString& tableName, const TString& database, std::pair
bool SetDatabaseForLoginOperation(TString& result, bool getDomainLoginOnly, TMaybe<TString> domainName,
const TString& database);

std::pair<TString, TString> SplitPathByDirAndBaseNames(const TString& path);

} // namespace NKikimr::NKqp

template<>
Expand Down
15 changes: 7 additions & 8 deletions ydb/core/kqp/gateway/kqp_ic_gateway.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2275,14 +2275,6 @@ class TKikimrIcGateway : public IKqpGateway {
}

private:
static std::pair<TString, TString> SplitPathByDirAndBaseNames(const TString& path) {
auto splitPos = path.find_last_of('/');
if (splitPos == path.npos || splitPos + 1 == path.size()) {
ythrow yexception() << "wrong path format '" << path << "'" ;
}
return {path.substr(0, splitPos), path.substr(splitPos + 1)};
}

static TListPathResult GetListPathResult(const TPathDescription& pathDesc, const TString& path) {
if (pathDesc.GetSelf().GetPathType() != EPathTypeDir) {
return ResultFromError<TListPathResult>(TString("Directory not found: ") + path);
Expand Down Expand Up @@ -2454,6 +2446,13 @@ bool SetDatabaseForLoginOperation(TString& result, bool getDomainLoginOnly, TMay
return true;
}

std::pair<TString, TString> SplitPathByDirAndBaseNames(const TString& path) {
auto splitPos = path.find_last_of('/');
if (splitPos == path.npos || splitPos + 1 == path.size()) {
ythrow yexception() << "wrong path format '" << path << "'" ;
}
return {path.substr(0, splitPos), path.substr(splitPos + 1)};
}

} // namespace NKqp
} // namespace NKikimr
82 changes: 81 additions & 1 deletion ydb/core/kqp/host/kqp_gateway_proxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <ydb/core/grpc_services/table_settings.h>
#include <ydb/core/ydb_convert/table_description.h>
#include <ydb/core/ydb_convert/column_families.h>
#include <ydb/core/ydb_convert/ydb_convert.h>

namespace NKikimr::NKqp {

Expand Down Expand Up @@ -784,7 +785,86 @@ class TKqpGatewayProxy : public IKikimrGateway {
TFuture<TGenericResult> ModifyPermissions(const TString& cluster,
const TModifyPermissionsSettings& settings) override
{
FORWARD_ENSURE_NO_PREPARE(ModifyPermissions, cluster, settings);
CHECK_PREPARED_DDL(ModifyPermissions);

auto modifyPermissionsPromise = NewPromise<TGenericResult>();

if (settings.Permissions.empty() && !settings.IsPermissionsClear) {
return MakeFuture(ResultFromError<TGenericResult>("No permissions names for modify permissions"));
}

if (settings.Pathes.empty()) {
return MakeFuture(ResultFromError<TGenericResult>("No pathes for modify permissions"));
}

if (settings.Roles.empty()) {
return MakeFuture(ResultFromError<TGenericResult>("No roles for modify permissions"));
}

NACLib::TDiffACL acl;
switch (settings.Action) {
case NYql::TModifyPermissionsSettings::EAction::Grant: {
for (const auto& sid : settings.Roles) {
for (const auto& permission : settings.Permissions) {
TACLAttrs aclAttrs = ConvertYdbPermissionNameToACLAttrs(permission);
acl.AddAccess(NACLib::EAccessType::Allow, aclAttrs.AccessMask, sid, aclAttrs.InheritanceType);
}
}
}
break;
case NYql::TModifyPermissionsSettings::EAction::Revoke: {
if (settings.IsPermissionsClear) {
for (const auto& sid : settings.Roles) {
acl.ClearAccessForSid(sid);
}
} else {
for (const auto& sid : settings.Roles) {
for (const auto& permission : settings.Permissions) {
TACLAttrs aclAttrs = ConvertYdbPermissionNameToACLAttrs(permission);
acl.RemoveAccess(NACLib::EAccessType::Allow, aclAttrs.AccessMask, sid, aclAttrs.InheritanceType);
}
}
}
}
break;
default: {
return MakeFuture(ResultFromError<TGenericResult>("Unknown permission action"));
}
}

const auto serializedDiffAcl = acl.SerializeAsString();

TVector<std::pair<const TString*, std::pair<TString, TString>>> pathPairs;
pathPairs.reserve(settings.Pathes.size());
for (const auto& path : settings.Pathes) {
pathPairs.push_back(std::make_pair(&path, SplitPathByDirAndBaseNames(path)));
}

if (IsPrepare()) {
for (const auto& path : pathPairs) {
const auto& [dirname, basename] = path.second;

NKikimrSchemeOp::TModifyScheme schemeTx;
schemeTx.SetOperationType(NKikimrSchemeOp::ESchemeOpModifyACL);
schemeTx.SetWorkingDir(dirname);
schemeTx.MutableModifyACL()->SetName(basename);
schemeTx.MutableModifyACL()->SetDiffACL(serializedDiffAcl);

auto& phyQuery = *SessionCtx->Query().PreparingQuery->MutablePhysicalQuery();
auto& phyTx = *phyQuery.AddTransactions();
phyTx.SetType(NKqpProto::TKqpPhyTx::TYPE_SCHEME);
phyTx.MutableSchemeOperation()->MutableModifyPermissions()->Swap(&schemeTx);
}

TGenericResult result;
result.SetSuccess();
modifyPermissionsPromise.SetValue(result);

} else {
return Gateway->ModifyPermissions(cluster, settings);
}

return modifyPermissionsPromise;
}

TFuture<TGenericResult> CreateUser(const TString& cluster, const TCreateUserSettings& settings) override {
Expand Down
7 changes: 1 addition & 6 deletions ydb/core/kqp/provider/yql_kikimr_exec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1671,10 +1671,6 @@ class TKiSinkCallableExecutionTransformer : public TAsyncCallbackTransformer<TKi
}

if (auto maybeGrantPermissions = TMaybeNode<TKiModifyPermissions>(input)) {
if (!EnsureNotPrepare("MODIFY PERMISSIONS", input->Pos(), SessionCtx->Query(), ctx)) {
return SyncError();
}

auto requireStatus = RequireChild(*input, 0);
if (requireStatus.Level != TStatus::Ok) {
return SyncStatus(requireStatus);
Expand All @@ -1683,8 +1679,7 @@ class TKiSinkCallableExecutionTransformer : public TAsyncCallbackTransformer<TKi
auto cluster = TString(maybeGrantPermissions.Cast().DataSink().Cluster());
TModifyPermissionsSettings settings = ParsePermissionsSettings(maybeGrantPermissions.Cast());

bool prepareOnly = SessionCtx->Query().PrepareOnly;
auto future = prepareOnly ? CreateDummySuccess() : Gateway->ModifyPermissions(cluster, settings);
auto future = Gateway->ModifyPermissions(cluster, settings);

return WrapFuture(future,
[](const IKikimrGateway::TGenericResult& res, const TExprNode::TPtr& input, TExprContext& ctx) {
Expand Down
Loading

0 comments on commit fba31d0

Please sign in to comment.