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 10 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
20 changes: 20 additions & 0 deletions src/graph/service/PermissionManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,26 @@ Status PermissionManager::canWriteUser(ClientSession *session) {
}
}

// static
Status PermissionManager::canReadUser(ClientSession *session, const std::string &targetUser) {
if (!FLAGS_enable_authorize) {
return Status::OK();
}
// Cloud auth user cannot create user
heroicNeZha marked this conversation as resolved.
Show resolved Hide resolved
if (FLAGS_auth_type == "cloud") {
return Status::PermissionError("Cloud authenticate user can't write user.");
heroicNeZha marked this conversation as resolved.
Show resolved Hide resolved
}
if (session->isGod()) {
return Status::OK();
}

if (session->user() == targetUser) {
return Status::OK();
}

return Status::PermissionError("No permission to read user `%s'.", targetUser.c_str());
}

Status PermissionManager::canWriteRole(ClientSession *session,
meta::cpp2::RoleType targetRole,
GraphSpaceID spaceId,
Expand Down
1 change: 1 addition & 0 deletions src/graph/service/PermissionManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class PermissionManager final {
static Status canWriteSpace(ClientSession *session);
static Status canWriteSchema(ClientSession *session, ValidateContext *vctx);
static Status canWriteUser(ClientSession *session);
static Status canReadUser(ClientSession *session, const std::string &targetUser);
static Status canWriteRole(ClientSession *session,
meta::cpp2::RoleType targetRole,
GraphSpaceID spaceId,
Expand Down
20 changes: 20 additions & 0 deletions src/graph/validator/ACLValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,26 @@ 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::checkPermission() {
auto sentence = static_cast<DescribeUserSentence *>(sentence_);
return PermissionManager::canReadUser(qctx_->rctx()->session(), *sentence->account());
}

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
14 changes: 14 additions & 0 deletions src/graph/validator/ACLValidator.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,20 @@ 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 checkPermission() 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
Loading