Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

describe the user #3300

Merged
merged 23 commits into from
Nov 25, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions src/clients/meta/MetaClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2481,6 +2481,19 @@ folly::Future<StatusOr<std::unordered_map<std::string, std::string>>> MetaClient
return future;
}

folly::Future<StatusOr<cpp2::UserDescItem>> MetaClient::describeUser(std::string account) {
cpp2::DescribeUserReq req;
req.set_account(account);
folly::Promise<StatusOr<cpp2::UserDescItem>> promise;
auto future = promise.getFuture();
getResponse(
std::move(req),
[](auto client, auto request) { return client->future_describeUser(request); },
[](cpp2::DescribeUserResp&& resp) -> decltype(auto) { return std::move(resp.get_user()); },
std::move(promise));
return future;
}

folly::Future<StatusOr<std::vector<cpp2::RoleItem>>> MetaClient::listRoles(GraphSpaceID space) {
cpp2::ListRolesReq req;
req.set_space_id(std::move(space));
Expand Down
2 changes: 2 additions & 0 deletions src/clients/meta/MetaClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,8 @@ class MetaClient {

folly::Future<StatusOr<std::unordered_map<std::string, std::string>>> listUsers();

folly::Future<StatusOr<cpp2::UserDescItem>> describeUser(std::string account);

folly::Future<StatusOr<std::vector<cpp2::RoleItem>>> listRoles(GraphSpaceID space);

folly::Future<StatusOr<bool>> changePassword(std::string account,
Expand Down
1 change: 1 addition & 0 deletions src/graph/executor/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ nebula_add_library(
admin/ChangePasswordExecutor.cpp
admin/ListUserRolesExecutor.cpp
admin/ListUsersExecutor.cpp
admin/DescribeUserExecutor.cpp
admin/ListRolesExecutor.cpp
admin/SubmitJobExecutor.cpp
admin/BalanceExecutor.cpp
Expand Down
4 changes: 4 additions & 0 deletions src/graph/executor/Executor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "graph/executor/admin/CharsetExecutor.h"
#include "graph/executor/admin/ConfigExecutor.h"
#include "graph/executor/admin/CreateUserExecutor.h"
#include "graph/executor/admin/DescribeUserExecutor.h"
#include "graph/executor/admin/DownloadExecutor.h"
#include "graph/executor/admin/DropUserExecutor.h"
#include "graph/executor/admin/GrantRoleExecutor.h"
Expand Down Expand Up @@ -389,6 +390,9 @@ Executor *Executor::makeExecutor(QueryContext *qctx, const PlanNode *node) {
case PlanNode::Kind::kListRoles: {
return pool->add(new ListRolesExecutor(node, qctx));
}
case PlanNode::Kind::kDescribeUser: {
return pool->add(new DescribeUserExecutor(node, qctx));
}
case PlanNode::Kind::kBalanceLeaders: {
return pool->add(new BalanceLeadersExecutor(node, qctx));
}
Expand Down
61 changes: 61 additions & 0 deletions src/graph/executor/admin/DescribeUserExecutor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/* Copyright (c) 2020 vesoft inc. All rights reserved.
*
* This source code is licensed under Apache 2.0 License.
*/

#include "graph/executor/admin/DescribeUserExecutor.h"

#include <thrift/lib/cpp/util/EnumUtils.h>

#include "graph/context/QueryContext.h"
#include "graph/planner/plan/Admin.h"
#include "interface/gen-cpp2/meta_types.h"

namespace nebula {
namespace graph {

folly::Future<Status> DescribeUserExecutor::execute() {
SCOPED_TIMER(&execTime_);
return describeUser();
}

folly::Future<Status> DescribeUserExecutor::describeUser() {
auto* duNode = asNode<DescribeUser>(node());
return qctx()
->getMetaClient()
->describeUser(*duNode->username())
.via(runner())
.thenValue([this](StatusOr<meta::cpp2::UserDescItem>&& resp) {
SCOPED_TIMER(&execTime_);
if (!resp.ok()) {
return std::move(resp).status();
}

nebula::DataSet v({"Account", "Roles in spaces"});
auto user = std::move(resp).value();
auto spaceRoleMap = user.get_space_role_map();
std::vector<std::string> rolesInSpacesStrVector;
for (auto& item : spaceRoleMap) {
auto spaceNameResult = qctx_->schemaMng()->toGraphSpaceName(item.first);
if (!spaceNameResult.ok()) {
if (item.first == 0) {
rolesInSpacesStrVector.emplace_back(folly::sformat(
" {} in ALL_SPACE", apache::thrift::util::enumNameSafe(item.second)));
} else {
LOG(ERROR) << " Space name of " << item.first << " no found";
return Status::Error("Space not found");
}
} else {
rolesInSpacesStrVector.emplace_back(
folly::sformat(" {} in {}",
apache::thrift::util::enumNameSafe(item.second),
spaceNameResult.value()));
}
}
v.emplace_back(nebula::Row({user.get_account(), folly::join(',', rolesInSpacesStrVector)}));
return finish(std::move(v));
});
}

} // namespace graph
} // namespace nebula
28 changes: 28 additions & 0 deletions src/graph/executor/admin/DescribeUserExecutor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* Copyright (c) 2020 vesoft inc. All rights reserved.
*
* This source code is licensed under Apache 2.0 License.
*/

#ifndef GRAPH_EXECUTOR_ADMIN_DESCRIBEUSEREXECUTOR_H_
#define GRAPH_EXECUTOR_ADMIN_DESCRIBEUSEREXECUTOR_H_

#include "graph/executor/Executor.h"

namespace nebula {
namespace graph {

class DescribeUserExecutor final : public Executor {
public:
DescribeUserExecutor(const PlanNode *node, QueryContext *qctx)
: Executor("DescribeUsersExecutor", node, qctx) {}

folly::Future<Status> execute() override;

private:
folly::Future<Status> describeUser();
};

} // namespace graph
} // namespace nebula

#endif // GRAPH_EXECUTOR_ADMIN_LISTUSERSEXECUTOR_H_
6 changes: 6 additions & 0 deletions src/graph/planner/plan/Admin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,12 @@ std::unique_ptr<PlanNodeDescription> ChangePassword::explain() const {
return desc;
}

std::unique_ptr<PlanNodeDescription> DescribeUser::explain() const {
auto desc = SingleDependencyNode::explain();
addDescription("username", *username_, desc.get());
return desc;
}

std::unique_ptr<PlanNodeDescription> ListUserRoles::explain() const {
auto desc = SingleDependencyNode::explain();
addDescription("username", *username_, desc.get());
Expand Down
17 changes: 17 additions & 0 deletions src/graph/planner/plan/Admin.h
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,23 @@ class ListUsers final : public SingleDependencyNode {
: SingleDependencyNode(qctx, Kind::kListUsers, dep) {}
};

class DescribeUser final : public SingleDependencyNode {
public:
static DescribeUser* make(QueryContext* qctx, PlanNode* dep, const std::string* username) {
return qctx->objPool()->add(new DescribeUser(qctx, dep, username));
}

std::unique_ptr<PlanNodeDescription> explain() const override;

const std::string* username() const { return username_; }

private:
explicit DescribeUser(QueryContext* qctx, PlanNode* dep, const std::string* username)
: SingleDependencyNode(qctx, Kind::kDescribeUser, dep), username_(username) {}

const std::string* username_;
};

class ListRoles final : public SingleDependencyNode {
public:
static ListRoles* make(QueryContext* qctx, PlanNode* dep, GraphSpaceID space) {
Expand Down
2 changes: 2 additions & 0 deletions src/graph/planner/plan/PlanNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ const char* PlanNode::toString(PlanNode::Kind kind) {
return "ListUserRoles";
case Kind::kListUsers:
return "ListUsers";
case Kind::kDescribeUser:
return "DescribeUser";
case Kind::kListRoles:
return "ListRoles";
case Kind::kShowCreateSpace:
Expand Down
1 change: 1 addition & 0 deletions src/graph/planner/plan/PlanNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ class PlanNode {
kListUserRoles,
kListUsers,
kListRoles,
kDescribeUser,

// Snapshot
kCreateSnapshot,
Expand Down
1 change: 1 addition & 0 deletions src/graph/service/PermissionCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ Status PermissionCheck::permissionCheck(ClientSession *session,
case Sentence::Kind::kShowRoles: {
return PermissionManager::canReadSpace(session, targetSpace);
}
case Sentence::Kind::kDescribeUser:
case Sentence::Kind::kShowUsers:
case Sentence::Kind::kShowSnapshots:
case Sentence::Kind::kShowTSClients:
Expand Down
15 changes: 15 additions & 0 deletions src/graph/validator/ACLValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,21 @@ Status RevokeRoleValidator::toPlan() {
sentence->getAclItemClause()->getRoleType());
}

// describe user
Status DescribeUserValidator::validateImpl() {
auto sentence = static_cast<DescribeUserSentence *>(sentence_);
if (sentence->account()->size() > kUsernameMaxLength) {
heroicNeZha marked this conversation as resolved.
Show resolved Hide resolved
return Status::SemanticError("Username exceed maximum length %ld characters.",
kUsernameMaxLength);
}
return Status::OK();
}

Status DescribeUserValidator::toPlan() {
auto sentence = static_cast<DescribeUserSentence *>(sentence_);
return genSingleNodePlan<DescribeUser>(sentence->account());
}

// show roles in space
Status ShowRolesInSpaceValidator::validateImpl() {
auto sentence = static_cast<ShowRolesSentence *>(sentence_);
Expand Down
12 changes: 12 additions & 0 deletions src/graph/validator/ACLValidator.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,18 @@ class RevokeRoleValidator final : public Validator {
Status toPlan() override;
};

class DescribeUserValidator final : public Validator {
public:
DescribeUserValidator(Sentence* sentence, QueryContext* context) : Validator(sentence, context) {
setNoSpaceRequired();
}

private:
Status validateImpl() override;

Status toPlan() override;
};

class ShowRolesInSpaceValidator final : public Validator {
public:
ShowRolesInSpaceValidator(Sentence* sentence, QueryContext* context)
Expand Down
2 changes: 2 additions & 0 deletions src/graph/validator/Validator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ std::unique_ptr<Validator> Validator::makeValidator(Sentence* sentence, QueryCon
return std::make_unique<RevokeRoleValidator>(sentence, context);
case Sentence::Kind::kShowRoles:
return std::make_unique<ShowRolesInSpaceValidator>(sentence, context);
case Sentence::Kind::kDescribeUser:
return std::make_unique<DescribeUserValidator>(sentence, context);
case Sentence::Kind::kBalance:
return std::make_unique<BalanceValidator>(sentence, context);
case Sentence::Kind::kAdminJob:
Expand Down
18 changes: 18 additions & 0 deletions src/interface/meta.thrift
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,23 @@ struct ListUsersResp {
3: map<binary, binary> (cpp.template = "std::unordered_map") users,
}

struct DescribeUserReq {
1: binary account,
}

struct DescribeUserResp {
1: common.ErrorCode code,
// Valid if ret equals E_LEADER_CHANGED.
2: common.HostAddr leader,
3: UserDescItem user,
}

struct UserDescItem {
1: binary account,
// map<space, role>
2: map<common.GraphSpaceID, RoleType> (cpp.template = "std::map") space_role_map,
}

struct ListRolesReq {
1: common.GraphSpaceID space_id,
}
Expand Down Expand Up @@ -1217,6 +1234,7 @@ service MetaService {
ExecResp grantRole(1: GrantRoleReq req);
ExecResp revokeRole(1: RevokeRoleReq req);
ListUsersResp listUsers(1: ListUsersReq req);
DescribeUserResp describeUser(1: DescribeUserReq req);
heroicNeZha marked this conversation as resolved.
Show resolved Hide resolved
ListRolesResp listRoles(1: ListRolesReq req);
ListRolesResp getUserRoles(1: GetUserRolesReq req);
ExecResp changePassword(1: ChangePasswordReq req);
Expand Down
6 changes: 6 additions & 0 deletions src/meta/MetaServiceHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,12 @@ folly::Future<cpp2::ListUsersResp> MetaServiceHandler::future_listUsers(
RETURN_FUTURE(processor);
}

folly::Future<cpp2::DescribeUserResp> MetaServiceHandler::future_describeUser(
const cpp2::DescribeUserReq& req) {
auto* processor = DescribeUserProcessor::instance(kvstore_);
RETURN_FUTURE(processor);
}

folly::Future<cpp2::ListRolesResp> MetaServiceHandler::future_listRoles(
const cpp2::ListRolesReq& req) {
auto* processor = ListRolesProcessor::instance(kvstore_);
Expand Down
3 changes: 3 additions & 0 deletions src/meta/MetaServiceHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ class MetaServiceHandler final : public cpp2::MetaServiceSvIf {

folly::Future<cpp2::ListUsersResp> future_listUsers(const cpp2::ListUsersReq& req) override;

folly::Future<cpp2::DescribeUserResp> future_describeUser(
const cpp2::DescribeUserReq& req) override;

folly::Future<cpp2::ListRolesResp> future_listRoles(const cpp2::ListRolesReq& req) override;

folly::Future<cpp2::ExecResp> future_changePassword(const cpp2::ChangePasswordReq& req) override;
Expand Down
32 changes: 32 additions & 0 deletions src/meta/processors/user/AuthenticationProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,38 @@ void ListUsersProcessor::process(const cpp2::ListUsersReq& req) {
onFinished();
}

void DescribeUserProcessor::process(const cpp2::DescribeUserReq& req) {
UNUSED(req);
heroicNeZha marked this conversation as resolved.
Show resolved Hide resolved
folly::SharedMutex::ReadHolder rHolder1(LockUtils::userLock());
auto rolePrefix = MetaKeyUtils::rolesPrefix();
auto roleRet = doPrefix(rolePrefix);
if (!nebula::ok(roleRet)) {
auto retCode = nebula::error(roleRet);
LOG(ERROR) << "Prefix roles failed, error: " << apache::thrift::util::enumNameSafe(retCode);
handleErrorCode(retCode);
onFinished();
return;
}
auto& act = req.get_account();
std::map<::nebula::cpp2::GraphSpaceID, ::nebula::meta::cpp2::RoleType> map;
auto iter = nebula::value(roleRet).get();
while (iter->valid()) {
auto account = MetaKeyUtils::parseRoleUser(iter->key());
if (account == act) {
auto spaceId = MetaKeyUtils::parseRoleSpace(iter->key());
auto val = iter->val();
map[spaceId] = *reinterpret_cast<const cpp2::RoleType*>(val.begin());
}
iter->next();
}
nebula::meta::cpp2::UserDescItem user;
user.set_account(std::move(act));
user.set_space_role_map(std::move(map));
resp_.set_user(std::move(user));
handleErrorCode(nebula::cpp2::ErrorCode::SUCCEEDED);
onFinished();
}

void ListRolesProcessor::process(const cpp2::ListRolesReq& req) {
auto spaceId = req.get_space_id();
CHECK_SPACE_ID_AND_RETURN(spaceId);
Expand Down
13 changes: 13 additions & 0 deletions src/meta/processors/user/AuthenticationProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,19 @@ class ListUsersProcessor : public BaseProcessor<cpp2::ListUsersResp> {
: BaseProcessor<cpp2::ListUsersResp>(kvstore) {}
};

class DescribeUserProcessor : public BaseProcessor<cpp2::DescribeUserResp> {
public:
static DescribeUserProcessor* instance(kvstore::KVStore* kvstore) {
return new DescribeUserProcessor(kvstore);
}

void process(const cpp2::DescribeUserReq& req);

private:
explicit DescribeUserProcessor(kvstore::KVStore* kvstore)
: BaseProcessor<cpp2::DescribeUserResp>(kvstore) {}
};

class ListRolesProcessor : public BaseProcessor<cpp2::ListRolesResp> {
public:
static ListRolesProcessor* instance(kvstore::KVStore* kvstore) {
Expand Down
4 changes: 4 additions & 0 deletions src/parser/AdminSentences.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ std::string ShowPartsSentence::toString() const { return std::string("SHOW PARTS

std::string ShowUsersSentence::toString() const { return std::string("SHOW USERS"); }

std::string DescribeUserSentence::toString() const {
return folly::stringPrintf("DESCRIBE USER %s", account_.get()->c_str());
}

std::string ShowRolesSentence::toString() const {
return folly::stringPrintf("SHOW ROLES IN %s", name_.get()->c_str());
}
Expand Down
Loading