mirror of https://gitee.com/bigwinds/arangodb
119 lines
4.2 KiB
C++
119 lines
4.2 KiB
C++
////////////////////////////////////////////////////////////////////////////////
|
|
/// DISCLAIMER
|
|
///
|
|
/// Copyright 2017 ArangoDB GmbH, Cologne, Germany
|
|
///
|
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|
/// you may not use this file except in compliance with the License.
|
|
/// You may obtain a copy of the License at
|
|
///
|
|
/// http://www.apache.org/licenses/LICENSE-2.0
|
|
///
|
|
/// Unless required by applicable law or agreed to in writing, software
|
|
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
/// See the License for the specific language governing permissions and
|
|
/// limitations under the License.
|
|
///
|
|
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
|
///
|
|
/// @author Simon Grätzer
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "ExecContext.h"
|
|
|
|
#include "Cluster/ServerState.h"
|
|
#include "GeneralServer/AuthenticationFeature.h"
|
|
#include "VocBase/vocbase.h"
|
|
|
|
using namespace arangodb;
|
|
|
|
thread_local ExecContext const* ExecContext::CURRENT = nullptr;
|
|
|
|
ExecContext ExecContext::SUPERUSER(ExecContext::Type::Internal, "", "",
|
|
auth::Level::RW, auth::Level::RW);
|
|
|
|
bool ExecContext::isAuthEnabled() {
|
|
AuthenticationFeature* af = AuthenticationFeature::instance();
|
|
TRI_ASSERT(af != nullptr);
|
|
return af->isActive();
|
|
}
|
|
|
|
/// @brief an internal superuser context, is
|
|
/// a singleton instance, deleting is an error
|
|
ExecContext const* ExecContext::superuser() { return &ExecContext::SUPERUSER; }
|
|
|
|
ExecContext* ExecContext::create(std::string const& user, std::string const& dbname) {
|
|
AuthenticationFeature* af = AuthenticationFeature::instance();
|
|
TRI_ASSERT(af != nullptr);
|
|
auth::Level dbLvl = auth::Level::RW;
|
|
auth::Level sysLvl = auth::Level::RW;
|
|
if (af->isActive()) {
|
|
auth::UserManager* um = af->userManager();
|
|
TRI_ASSERT(um != nullptr);
|
|
if (um == nullptr) {
|
|
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL,
|
|
"unable to find userManager instance");
|
|
}
|
|
dbLvl = sysLvl = um->databaseAuthLevel(user, dbname);
|
|
if (dbname != TRI_VOC_SYSTEM_DATABASE) {
|
|
sysLvl = um->databaseAuthLevel(user, TRI_VOC_SYSTEM_DATABASE);
|
|
}
|
|
}
|
|
return new ExecContext(ExecContext::Type::Default, user, dbname, sysLvl, dbLvl);
|
|
}
|
|
|
|
bool ExecContext::canUseDatabase(std::string const& db, auth::Level requested) const {
|
|
if (isInternal() || _database == db) {
|
|
// should be RW for superuser, RO for read-only
|
|
return requested <= _databaseAuthLevel;
|
|
}
|
|
|
|
AuthenticationFeature* af = AuthenticationFeature::instance();
|
|
TRI_ASSERT(af != nullptr);
|
|
if (af->isActive()) {
|
|
auth::UserManager* um = af->userManager();
|
|
TRI_ASSERT(um != nullptr);
|
|
if (um == nullptr) {
|
|
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL,
|
|
"unable to find userManager instance");
|
|
}
|
|
auth::Level allowed = um->databaseAuthLevel(_user, db);
|
|
return requested <= allowed;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/// @brief returns auth level for user
|
|
auth::Level ExecContext::collectionAuthLevel(std::string const& dbname,
|
|
std::string const& coll) const {
|
|
if (isInternal()) {
|
|
// should be RW for superuser, RO for read-only
|
|
return _databaseAuthLevel;
|
|
}
|
|
|
|
AuthenticationFeature* af = AuthenticationFeature::instance();
|
|
TRI_ASSERT(af != nullptr);
|
|
if (!af->isActive()) {
|
|
return auth::Level::RW;
|
|
}
|
|
// handle fixed permissions here outside auth module.
|
|
// TODO: move this block above, such that it takes effect
|
|
// when authentication is disabled
|
|
if (dbname == TRI_VOC_SYSTEM_DATABASE && coll == TRI_COL_NAME_USERS) {
|
|
return auth::Level::NONE;
|
|
} else if (coll == "_queues") {
|
|
return auth::Level::RO;
|
|
} else if (coll == "_frontend") {
|
|
return auth::Level::RW;
|
|
} // intentional fall through
|
|
|
|
auth::UserManager* um = af->userManager();
|
|
TRI_ASSERT(um != nullptr);
|
|
if (um == nullptr) {
|
|
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL,
|
|
"unable to find userManager instance");
|
|
}
|
|
return um->collectionAuthLevel(_user, dbname, coll);
|
|
}
|