Skip to content

Commit

Permalink
Merge branch 'master' into bug-fix
Browse files Browse the repository at this point in the history
  • Loading branch information
yixinglu committed Nov 25, 2021
2 parents 8e21ae2 + a14d7b4 commit e23f135
Show file tree
Hide file tree
Showing 36 changed files with 731 additions and 219 deletions.
1 change: 1 addition & 0 deletions src/graph/executor/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ nebula_add_library(
admin/ChangePasswordExecutor.cpp
admin/ListUserRolesExecutor.cpp
admin/ListUsersExecutor.cpp
admin/DescribeUserExecutor.cpp
admin/ListRolesExecutor.cpp
admin/SubmitJobExecutor.cpp
admin/ShowHostsExecutor.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 @@ -20,6 +20,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 @@ -385,6 +386,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::kShowConfigs: {
return pool->add(new ShowConfigsExecutor(node, qctx));
}
Expand Down
57 changes: 57 additions & 0 deletions src/graph/executor/admin/DescribeUserExecutor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/* 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()
->getUserRoles(*duNode->username())
.via(runner())
.thenValue([this](StatusOr<std::vector<meta::cpp2::RoleItem>>&& resp) {
SCOPED_TIMER(&execTime_);
if (!resp.ok()) {
return std::move(resp).status();
}

DataSet v({"role", "space"});
auto roleItemList = std::move(resp).value();
for (auto& item : roleItemList) {
if (item.get_space_id() == 0) {
v.emplace_back(
nebula::Row({apache::thrift::util::enumNameSafe(item.get_role_type()), ""}));
} else {
auto spaceNameResult = qctx_->schemaMng()->toGraphSpaceName(item.get_space_id());
if (spaceNameResult.ok()) {
v.emplace_back(nebula::Row({apache::thrift::util::enumNameSafe(item.get_role_type()),
spaceNameResult.value()}));
} else {
LOG(ERROR) << " Space name of " << item.get_space_id() << " no found";
return Status::Error("Space not found");
}
}
}
return finish(
ResultBuilder().value(Value(std::move(v))).iter(Iterator::Kind::kSequential).build());
});
}

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

// static
Status PermissionManager::canReadUser(ClientSession *session, const std::string &targetUser) {
if (!FLAGS_enable_authorize) {
return Status::OK();
}
if (FLAGS_auth_type == "cloud") {
return Status::PermissionError("Cloud authenticate user can't read user.");
}
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
25 changes: 25 additions & 0 deletions src/graph/validator/ACLValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,31 @@ Status RevokeRoleValidator::toPlan() {
sentence->getAclItemClause()->getRoleType());
}

// describe user
Status DescribeUserValidator::validateImpl() {
auto sentence = static_cast<DescribeUserSentence *>(sentence_);
if (sentence->account()->size() > kUsernameMaxLength) {
return Status::SemanticError("Username exceed maximum length %ld characters.",
kUsernameMaxLength);
}
if (!inputs_.empty()) {
return Status::SemanticError("Show queries sentence do not support input");
}
outputs_.emplace_back("role", Value::Type::STRING);
outputs_.emplace_back("space", Value::Type::STRING);
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 @@ -131,6 +131,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::kAdminJob:
case Sentence::Kind::kAdminShowJobs:
return std::make_unique<AdminJobValidator>(sentence, context);
Expand Down
1 change: 1 addition & 0 deletions src/interface/raftex.thrift
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ struct AskForVoteRequest {
5: TermID term; // Proposed term
6: LogID last_log_id; // The last received log id
7: TermID last_log_term; // The term receiving the last log
8: bool is_pre_vote; // Is pre vote or not
}


Expand Down
5 changes: 2 additions & 3 deletions src/kvstore/Listener.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ void Listener::start(std::vector<HostAddr>&& peers, bool) {

lastLogId_ = wal_->lastLogId();
lastLogTerm_ = wal_->lastLogTerm();
term_ = proposedTerm_ = lastLogTerm_;
term_ = lastLogTerm_;

// Set the quorum number
quorum_ = (peers.size() + 1) / 2;
Expand Down Expand Up @@ -273,10 +273,9 @@ void Listener::resetListener() {
reset();
VLOG(1) << folly::sformat(
"The listener has been reset : leaderCommitId={},"
"proposedTerm={}, lastLogTerm={}, term={},"
"lastLogTerm={}, term={},"
"lastApplyLogId={}",
leaderCommitId_,
proposedTerm_,
lastLogTerm_,
term_,
lastApplyLogId_);
Expand Down
Loading

0 comments on commit e23f135

Please sign in to comment.