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"));
|
data.add(c->name(), VPackValue("undefined"));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
lvl = authInfo->canUseCollection(user, vocbase->name(), "*");
|
lvl = authInfo->canUseCollectionNoLock(user, vocbase->name(), "*");
|
||||||
data.add("*", VPackValue(convertFromAuthLevel(lvl)));
|
data.add("*", VPackValue(convertFromAuthLevel(lvl)));
|
||||||
} else if (lvl != AuthLevel::NONE) { // hide db's without access
|
} else if (lvl != AuthLevel::NONE) { // hide db's without access
|
||||||
data.add(vocbase->name(), VPackValue(str));
|
data.add(vocbase->name(), VPackValue(str));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (full) {
|
if (full) {
|
||||||
AuthLevel lvl = authInfo->canUseDatabase(user, "*");
|
AuthLevel lvl = authInfo->canUseDatabaseNoLock(user, "*");
|
||||||
data("*", VPackValue(VPackValueType::Object))(
|
data("*", VPackValue(VPackValueType::Object))(
|
||||||
"permission", VPackValue(convertFromAuthLevel(lvl)))();
|
"permission", VPackValue(convertFromAuthLevel(lvl)))();
|
||||||
}
|
}
|
||||||
|
|
|
@ -208,8 +208,9 @@ static VPackBuilder QueryUser(aql::QueryRegistry* queryRegistry,
|
||||||
if (doc.isExternal()) {
|
if (doc.isExternal()) {
|
||||||
doc = doc.resolveExternals();
|
doc = doc.resolveExternals();
|
||||||
}
|
}
|
||||||
|
VPackBuilder result;
|
||||||
return VPackBuilder(doc);
|
result.add(doc);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ConvertLegacyFormat(VPackSlice doc, VPackBuilder& result) {
|
static void ConvertLegacyFormat(VPackSlice doc, VPackBuilder& result) {
|
||||||
|
@ -680,6 +681,7 @@ Result AuthInfo::removeAllUsers() {
|
||||||
Result res;
|
Result res;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
MUTEX_LOCKER(locker, _loadFromDBLock);
|
||||||
WRITE_LOCKER(guard, _authInfoLock);
|
WRITE_LOCKER(guard, _authInfoLock);
|
||||||
|
|
||||||
for (auto const& pair : _authInfo) {
|
for (auto const& pair : _authInfo) {
|
||||||
|
@ -698,7 +700,6 @@ Result AuthInfo::removeAllUsers() {
|
||||||
|
|
||||||
// do not get into race conditions with loadFromDB
|
// do not get into race conditions with loadFromDB
|
||||||
{
|
{
|
||||||
MUTEX_LOCKER(locker, _loadFromDBLock);
|
|
||||||
_authInfo.clear();
|
_authInfo.clear();
|
||||||
_authBasicCache.clear();
|
_authBasicCache.clear();
|
||||||
_outdated = true;
|
_outdated = true;
|
||||||
|
@ -912,6 +913,17 @@ AuthLevel AuthInfo::canUseDatabase(std::string const& username,
|
||||||
return level;
|
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
|
// internal method called by configuredCollectionAuthLevel
|
||||||
// asserts that collection name is non-empty and already translated
|
// asserts that collection name is non-empty and already translated
|
||||||
// from collection id to name
|
// from collection id to name
|
||||||
|
@ -986,6 +998,29 @@ AuthLevel AuthInfo::canUseCollection(std::string const& username,
|
||||||
return level;
|
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
|
// public called from HttpCommTask.cpp and VstCommTask.cpp
|
||||||
|
|
|
@ -126,6 +126,16 @@ class AuthInfo {
|
||||||
std::string const& dbname,
|
std::string const& dbname,
|
||||||
std::string const& coll);
|
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&);
|
void setJwtSecret(std::string const&);
|
||||||
std::string jwtSecret();
|
std::string jwtSecret();
|
||||||
std::string generateJwt(VPackBuilder const&);
|
std::string generateJwt(VPackBuilder const&);
|
||||||
|
|
Loading…
Reference in New Issue