1
0
Fork 0
arangodb/arangod/Utils/ExecContext.cpp

97 lines
3.4 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 "GeneralServer/AuthenticationFeature.h"
#include "VocBase/AuthInfo.h"
#include "VocBase/vocbase.h"
using namespace arangodb;
thread_local ExecContext const* ExecContext::CURRENT = nullptr;
ExecContext ExecContext::SUPERUSER(true, "", "", AuthLevel::RW, AuthLevel::RW);
bool ExecContext::isAuthEnabled() {
AuthenticationFeature* auth = AuthenticationFeature::INSTANCE;
TRI_ASSERT(auth != nullptr);
return auth->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* auth = AuthenticationFeature::INSTANCE;
TRI_ASSERT(auth != nullptr);
AuthLevel dbLvl = auth->authInfo()->canUseDatabase(user, dbname);
AuthLevel sysLvl = dbLvl;
if (dbname != TRI_VOC_SYSTEM_DATABASE) {
sysLvl = auth->authInfo()->canUseDatabase(user, TRI_VOC_SYSTEM_DATABASE);
}
return new ExecContext(false, user, dbname, sysLvl, dbLvl);
}
bool ExecContext::canUseDatabase(std::string const& db,
AuthLevel requested) const {
if (_internal || _database == db) {
// should be RW for superuser, RO for read-only
return requested <= _databaseAuthLevel;
}
AuthenticationFeature* auth = AuthenticationFeature::INSTANCE;
TRI_ASSERT(auth != nullptr);
if (auth->isActive()) {
AuthLevel allowed = auth->authInfo()->canUseDatabase(_user, db);
return requested <= allowed;
}
return true;
}
/// @brief returns auth level for user
AuthLevel ExecContext::collectionAuthLevel(std::string const& dbname,
std::string const& coll) const {
if (_internal) {
// should be RW for superuser, RO for read-only
return _databaseAuthLevel;
}
AuthenticationFeature* auth = AuthenticationFeature::INSTANCE;
TRI_ASSERT(auth != nullptr);
if (auth->isActive()) {
// 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 AuthLevel::NONE;
} else if (coll == "_queues") {
return AuthLevel::RO;
} else if (coll == "_frontend") {
return AuthLevel::RW;
} // fall through
return auth->authInfo()->canUseCollection(_user, dbname, coll);
}
return AuthLevel::RW;
}