mirror of https://gitee.com/bigwinds/arangodb
Fix auth with dump
This commit is contained in:
parent
b610d99d9f
commit
223895d34d
|
@ -224,7 +224,6 @@ void ClusterInfo::cleanup() {
|
||||||
_plannedViews.clear();
|
_plannedViews.clear();
|
||||||
_plannedCollections.clear();
|
_plannedCollections.clear();
|
||||||
_shards.clear();
|
_shards.clear();
|
||||||
_shardKeys.clear();
|
|
||||||
_shardIds.clear();
|
_shardIds.clear();
|
||||||
_currentCollections.clear();
|
_currentCollections.clear();
|
||||||
}
|
}
|
||||||
|
@ -235,6 +234,7 @@ void ClusterInfo::triggerBackgroundGetIds() {
|
||||||
_uniqid._nextUpperValue = 0ULL;
|
_uniqid._nextUpperValue = 0ULL;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
_idLock.assertLockedByCurrentThread();
|
||||||
if (_uniqid._backgroundJobIsRunning) {
|
if (_uniqid._backgroundJobIsRunning) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -598,7 +598,7 @@ void ClusterInfo::loadPlan() {
|
||||||
// >
|
// >
|
||||||
decltype(_shards) newShards;
|
decltype(_shards) newShards;
|
||||||
decltype(_shardServers) newShardServers;
|
decltype(_shardServers) newShardServers;
|
||||||
decltype(_shardKeys) newShardKeys;
|
decltype(_shardToName) newShardToName;
|
||||||
|
|
||||||
bool swapDatabases = false;
|
bool swapDatabases = false;
|
||||||
bool swapCollections = false;
|
bool swapCollections = false;
|
||||||
|
@ -957,17 +957,16 @@ void ClusterInfo::loadPlan() {
|
||||||
databaseCollections.try_emplace(collectionId, newCollection);
|
databaseCollections.try_emplace(collectionId, newCollection);
|
||||||
}
|
}
|
||||||
|
|
||||||
newShardKeys.try_emplace(collectionId, std::make_shared<std::vector<std::string>>(
|
|
||||||
newCollection->shardKeys()));
|
|
||||||
|
|
||||||
auto shardIDs = newCollection->shardIds();
|
auto shardIDs = newCollection->shardIds();
|
||||||
auto shards = std::make_shared<std::vector<std::string>>();
|
auto shards = std::make_shared<std::vector<std::string>>();
|
||||||
shards->reserve(shardIDs->size());
|
shards->reserve(shardIDs->size());
|
||||||
|
newShardToName.reserve(shardIDs->size());
|
||||||
|
|
||||||
for (auto const& p : *shardIDs) {
|
for (auto const& p : *shardIDs) {
|
||||||
TRI_ASSERT(p.first.size() >= 2);
|
TRI_ASSERT(p.first.size() >= 2);
|
||||||
shards->push_back(p.first);
|
shards->push_back(p.first);
|
||||||
newShardServers.try_emplace(p.first, p.second);
|
newShardServers.try_emplace(p.first, p.second);
|
||||||
|
newShardToName.try_emplace(p.first, newCollection->name());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort by the number in the shard ID ("s0000001" for example):
|
// Sort by the number in the shard ID ("s0000001" for example):
|
||||||
|
@ -1053,8 +1052,8 @@ void ClusterInfo::loadPlan() {
|
||||||
if (swapCollections) {
|
if (swapCollections) {
|
||||||
_plannedCollections.swap(newCollections);
|
_plannedCollections.swap(newCollections);
|
||||||
_shards.swap(newShards);
|
_shards.swap(newShards);
|
||||||
_shardKeys.swap(newShardKeys);
|
|
||||||
_shardServers.swap(newShardServers);
|
_shardServers.swap(newShardServers);
|
||||||
|
_shardToName.swap(newShardToName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (swapViews) {
|
if (swapViews) {
|
||||||
|
@ -4287,6 +4286,16 @@ arangodb::Result ClusterInfo::getShardServers(ShardID const& shardId,
|
||||||
return arangodb::Result(TRI_ERROR_FAILED);
|
return arangodb::Result(TRI_ERROR_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CollectionID ClusterInfo::getCollectionNameForShard(ShardID const& shardId) {
|
||||||
|
READ_LOCKER(readLocker, _planProt.lock);
|
||||||
|
|
||||||
|
auto it = _shardToName.find(shardId);
|
||||||
|
if (it != _shardToName.end()) {
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
return StaticStrings::Empty;
|
||||||
|
}
|
||||||
|
|
||||||
arangodb::Result ClusterInfo::agencyDump(std::shared_ptr<VPackBuilder> body) {
|
arangodb::Result ClusterInfo::agencyDump(std::shared_ptr<VPackBuilder> body) {
|
||||||
AgencyCommResult dump = _agency.dump();
|
AgencyCommResult dump = _agency.dump();
|
||||||
|
|
||||||
|
|
|
@ -815,6 +815,9 @@ class ClusterInfo final {
|
||||||
* @return List of DB servers serving the shard
|
* @return List of DB servers serving the shard
|
||||||
*/
|
*/
|
||||||
arangodb::Result getShardServers(ShardID const& shardId, std::vector<ServerID>&);
|
arangodb::Result getShardServers(ShardID const& shardId, std::vector<ServerID>&);
|
||||||
|
|
||||||
|
/// @brief map shardId to collection name (not ID)
|
||||||
|
CollectionID getCollectionNameForShard(ShardID const& shardId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Lock agency's hot backup with TTL 60 seconds
|
* @brief Lock agency's hot backup with TTL 60 seconds
|
||||||
|
@ -956,8 +959,7 @@ class ClusterInfo final {
|
||||||
ProtectionData _planProt;
|
ProtectionData _planProt;
|
||||||
|
|
||||||
uint64_t _planVersion; // This is the version in the Plan which underlies
|
uint64_t _planVersion; // This is the version in the Plan which underlies
|
||||||
// the data in _plannedCollections, _shards and
|
// the data in _plannedCollections and _shards
|
||||||
// _shardKeys
|
|
||||||
uint64_t _currentVersion; // This is the version in Current which underlies
|
uint64_t _currentVersion; // This is the version in Current which underlies
|
||||||
// the data in _currentDatabases,
|
// the data in _currentDatabases,
|
||||||
// _currentCollections and _shardsIds
|
// _currentCollections and _shardsIds
|
||||||
|
@ -978,11 +980,10 @@ class ClusterInfo final {
|
||||||
std::shared_ptr<std::vector<std::string>>>
|
std::shared_ptr<std::vector<std::string>>>
|
||||||
_shards; // from Plan/Collections/
|
_shards; // from Plan/Collections/
|
||||||
// (may later come from Current/Collections/ )
|
// (may later come from Current/Collections/ )
|
||||||
std::unordered_map<CollectionID,
|
|
||||||
std::shared_ptr<std::vector<std::string>>>
|
|
||||||
_shardKeys; // from Plan/Collections/
|
|
||||||
// planned shard => servers map
|
// planned shard => servers map
|
||||||
std::unordered_map<ShardID, std::vector<ServerID>> _shardServers;
|
std::unordered_map<ShardID, std::vector<ServerID>> _shardServers;
|
||||||
|
// planned shard ID => collection name
|
||||||
|
std::unordered_map<ShardID, CollectionID> _shardToName;
|
||||||
|
|
||||||
AllViews _plannedViews; // from Plan/Views/
|
AllViews _plannedViews; // from Plan/Views/
|
||||||
AllViews _newPlannedViews; // views that have been created during `loadPlan`
|
AllViews _newPlannedViews; // views that have been created during `loadPlan`
|
||||||
|
|
|
@ -140,8 +140,12 @@ futures::Future<Result> RestHandler::forwardRequest(bool& forwarded) {
|
||||||
|
|
||||||
std::map<std::string, std::string> headers{_request->headers().begin(),
|
std::map<std::string, std::string> headers{_request->headers().begin(),
|
||||||
_request->headers().end()};
|
_request->headers().end()};
|
||||||
|
|
||||||
if (headers.find(StaticStrings::Authorization) == headers.end()) {
|
// we never override auth headers for internal requests
|
||||||
|
bool const forwardAuth = serverId.compare(0, 5, "CRDN-") == 0;
|
||||||
|
if (!forwardAuth) {
|
||||||
|
headers.erase(StaticStrings::Authorization);
|
||||||
|
} else if (headers.find(StaticStrings::Authorization) == headers.end()) {
|
||||||
// No authorization header is set, this is in particular the case if this
|
// No authorization header is set, this is in particular the case if this
|
||||||
// request is coming in with VelocyStream, where the authentication happens
|
// request is coming in with VelocyStream, where the authentication happens
|
||||||
// once at the beginning of the connection and not with every request.
|
// once at the beginning of the connection and not with every request.
|
||||||
|
|
|
@ -592,24 +592,43 @@ BAD_CALL:
|
||||||
/// @brief returns the short id of the server which should handle this request
|
/// @brief returns the short id of the server which should handle this request
|
||||||
std::string RestReplicationHandler::forwardingTarget() {
|
std::string RestReplicationHandler::forwardingTarget() {
|
||||||
if (!ServerState::instance()->isCoordinator()) {
|
if (!ServerState::instance()->isCoordinator()) {
|
||||||
return "";
|
return StaticStrings::Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto const& suffixes = _request->suffixes();
|
auto const& suffixes = _request->suffixes();
|
||||||
size_t const len = suffixes.size();
|
size_t const len = suffixes.size();
|
||||||
if (len >= 1) {
|
if (len < 1) {
|
||||||
auto const type = _request->requestType();
|
return StaticStrings::Empty;
|
||||||
std::string const& command = suffixes[0];
|
}
|
||||||
if ((command == Batch) || (command == Inventory && type == rest::RequestType::GET) ||
|
|
||||||
(command == Dump && type == rest::RequestType::GET)) {
|
auto const type = _request->requestType();
|
||||||
ServerID const& DBserver = _request->value("DBserver");
|
std::string const& command = suffixes[0];
|
||||||
if (!DBserver.empty()) {
|
if ((command == Inventory && type == rest::RequestType::GET) ||
|
||||||
return DBserver;
|
(command == Dump && type == rest::RequestType::GET) ||
|
||||||
|
(command == Batch)) {
|
||||||
|
ServerID const& DBserver = _request->value("DBserver");
|
||||||
|
if (DBserver.empty()) {
|
||||||
|
return StaticStrings::Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command == Dump) { // check auth here
|
||||||
|
bool found = false;
|
||||||
|
std::string const& shard = _request->value("collection", found);
|
||||||
|
if (found) {
|
||||||
|
auto& ci = server().getFeature<ClusterFeature>().clusterInfo();
|
||||||
|
auto cname = ci.getCollectionNameForShard(shard);
|
||||||
|
auto& exec = ExecContext::current();
|
||||||
|
ExecContextSuperuserScope escope(exec.isAdminUser());
|
||||||
|
if (!exec.canUseCollection(cname, auth::Level::RO)) {
|
||||||
|
return StaticStrings::Empty;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return DBserver;
|
||||||
}
|
}
|
||||||
|
|
||||||
return "";
|
return StaticStrings::Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -711,9 +730,16 @@ void RestReplicationHandler::handleCommandClusterInventory() {
|
||||||
resultBuilder.add(VPackValue(StaticStrings::Properties));
|
resultBuilder.add(VPackValue(StaticStrings::Properties));
|
||||||
vocbase->toVelocyPack(resultBuilder);
|
vocbase->toVelocyPack(resultBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& exec = ExecContext::current();
|
||||||
|
ExecContextSuperuserScope escope(exec.isAdminUser());
|
||||||
|
|
||||||
resultBuilder.add("collections", VPackValue(VPackValueType::Array));
|
resultBuilder.add("collections", VPackValue(VPackValueType::Array));
|
||||||
for (std::shared_ptr<LogicalCollection> const& c : cols) {
|
for (std::shared_ptr<LogicalCollection> const& c : cols) {
|
||||||
|
if (!exec.canUseCollection(vocbase->name(), c->name(), auth::Level::RO)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// We want to check if the collection is usable and all followers
|
// We want to check if the collection is usable and all followers
|
||||||
// are in sync:
|
// are in sync:
|
||||||
std::shared_ptr<ShardMap> shardMap = c->shardIds();
|
std::shared_ptr<ShardMap> shardMap = c->shardIds();
|
||||||
|
|
Loading…
Reference in New Issue