mirror of https://gitee.com/bigwinds/arangodb
Fixed a dead-lock issue in authinfo (#3764)
This commit is contained in:
parent
ce537af092
commit
7d95de46e8
|
@ -211,14 +211,14 @@ void RestUsersHandler::generateDatabaseResult(AuthInfo* authInfo,
|
|||
data.add(c->name(), VPackValue("undefined"));
|
||||
}
|
||||
});
|
||||
lvl = authInfo->canUseCollection(user, vocbase->name(), "*");
|
||||
lvl = authInfo->canUseCollectionNoLock(user, vocbase->name(), "*");
|
||||
data.add("*", VPackValue(convertFromAuthLevel(lvl)));
|
||||
} else if (lvl != AuthLevel::NONE) { // hide db's without access
|
||||
data.add(vocbase->name(), VPackValue(str));
|
||||
}
|
||||
});
|
||||
if (full) {
|
||||
AuthLevel lvl = authInfo->canUseDatabase(user, "*");
|
||||
AuthLevel lvl = authInfo->canUseDatabaseNoLock(user, "*");
|
||||
data("*", VPackValue(VPackValueType::Object))(
|
||||
"permission", VPackValue(convertFromAuthLevel(lvl)))();
|
||||
}
|
||||
|
|
|
@ -208,8 +208,9 @@ static VPackBuilder QueryUser(aql::QueryRegistry* queryRegistry,
|
|||
if (doc.isExternal()) {
|
||||
doc = doc.resolveExternals();
|
||||
}
|
||||
|
||||
return VPackBuilder(doc);
|
||||
VPackBuilder result;
|
||||
result.add(doc);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void ConvertLegacyFormat(VPackSlice doc, VPackBuilder& result) {
|
||||
|
@ -680,6 +681,7 @@ Result AuthInfo::removeAllUsers() {
|
|||
Result res;
|
||||
|
||||
{
|
||||
MUTEX_LOCKER(locker, _loadFromDBLock);
|
||||
WRITE_LOCKER(guard, _authInfoLock);
|
||||
|
||||
for (auto const& pair : _authInfo) {
|
||||
|
@ -698,7 +700,6 @@ Result AuthInfo::removeAllUsers() {
|
|||
|
||||
// do not get into race conditions with loadFromDB
|
||||
{
|
||||
MUTEX_LOCKER(locker, _loadFromDBLock);
|
||||
_authInfo.clear();
|
||||
_authBasicCache.clear();
|
||||
_outdated = true;
|
||||
|
@ -912,6 +913,17 @@ AuthLevel AuthInfo::canUseDatabase(std::string const& username,
|
|||
return level;
|
||||
}
|
||||
|
||||
AuthLevel AuthInfo::canUseDatabaseNoLock(std::string const& username,
|
||||
std::string const& dbname) {
|
||||
AuthLevel level = configuredDatabaseAuthLevelInternal(username, dbname, 0);
|
||||
static_assert(AuthLevel::RO < AuthLevel::RW, "ro < rw");
|
||||
if (level > AuthLevel::RO && !ServerState::writeOpsEnabled()) {
|
||||
return AuthLevel::RO;
|
||||
}
|
||||
return level;
|
||||
}
|
||||
|
||||
|
||||
// internal method called by configuredCollectionAuthLevel
|
||||
// asserts that collection name is non-empty and already translated
|
||||
// from collection id to name
|
||||
|
@ -986,6 +998,29 @@ AuthLevel AuthInfo::canUseCollection(std::string const& username,
|
|||
return level;
|
||||
}
|
||||
|
||||
AuthLevel AuthInfo::canUseCollectionNoLock(std::string const& username,
|
||||
std::string const& dbname,
|
||||
std::string const& coll) {
|
||||
if (coll.empty()) {
|
||||
// no collection name given
|
||||
return AuthLevel::NONE;
|
||||
}
|
||||
|
||||
AuthLevel level;
|
||||
if (coll[0] >= '0' && coll[0] <= '9') {
|
||||
std::string tmpColl = DatabaseFeature::DATABASE->translateCollectionName(dbname, coll);
|
||||
level = configuredCollectionAuthLevelInternal(username, dbname, tmpColl, 0);
|
||||
} else {
|
||||
level = configuredCollectionAuthLevelInternal(username, dbname, coll, 0);
|
||||
}
|
||||
|
||||
static_assert(AuthLevel::RO < AuthLevel::RW, "ro < rw");
|
||||
if (level > AuthLevel::RO && !ServerState::writeOpsEnabled()) {
|
||||
return AuthLevel::RO;
|
||||
}
|
||||
return level;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// public called from HttpCommTask.cpp and VstCommTask.cpp
|
||||
|
|
|
@ -126,6 +126,16 @@ class AuthInfo {
|
|||
std::string const& dbname,
|
||||
std::string const& coll);
|
||||
|
||||
// No Lock variants of the above to be used in callbacks
|
||||
// Use with CARE! You need to make sure that the lock
|
||||
// is held from outside.
|
||||
AuthLevel canUseDatabaseNoLock(std::string const& username,
|
||||
std::string const& dbname);
|
||||
AuthLevel canUseCollectionNoLock(std::string const& username,
|
||||
std::string const& dbname,
|
||||
std::string const& coll);
|
||||
|
||||
|
||||
void setJwtSecret(std::string const&);
|
||||
std::string jwtSecret();
|
||||
std::string generateJwt(VPackBuilder const&);
|
||||
|
|
Loading…
Reference in New Issue