mirror of https://gitee.com/bigwinds/arangodb
use defer release
This commit is contained in:
parent
5cb1d86d58
commit
fa9501cc0c
|
@ -54,7 +54,7 @@ CheckVersionFeature::CheckVersionFeature(
|
|||
void CheckVersionFeature::collectOptions(
|
||||
std::shared_ptr<ProgramOptions> options) {
|
||||
options->addSection("database", "Configure the database");
|
||||
|
||||
|
||||
options->addOldOption("check-version", "database.check-version");
|
||||
|
||||
options->addHiddenOption("--database.check-version",
|
||||
|
@ -70,15 +70,18 @@ void CheckVersionFeature::validateOptions(
|
|||
|
||||
ApplicationServer::forceDisableFeatures(_nonServerFeatures);
|
||||
|
||||
LoggerFeature* logger = ApplicationServer::getFeature<LoggerFeature>("Logger");
|
||||
LoggerFeature* logger =
|
||||
ApplicationServer::getFeature<LoggerFeature>("Logger");
|
||||
logger->disableThreaded();
|
||||
|
||||
DatabaseFeature* database = ApplicationServer::getFeature<DatabaseFeature>("Database");
|
||||
DatabaseFeature* database =
|
||||
ApplicationServer::getFeature<DatabaseFeature>("Database");
|
||||
database->disableReplicationApplier();
|
||||
database->disableCompactor();
|
||||
database->enableCheckVersion();
|
||||
|
||||
V8DealerFeature* v8dealer = ApplicationServer::getFeature<V8DealerFeature>("V8Dealer");
|
||||
V8DealerFeature* v8dealer =
|
||||
ApplicationServer::getFeature<V8DealerFeature>("V8Dealer");
|
||||
v8dealer->setNumberContexts(1);
|
||||
}
|
||||
|
||||
|
@ -116,6 +119,8 @@ void CheckVersionFeature::checkVersion() {
|
|||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
TRI_DEFER(V8DealerFeature::DEALER->exitContext(context));
|
||||
|
||||
{
|
||||
v8::HandleScope scope(context->_isolate);
|
||||
auto localContext =
|
||||
|
@ -136,7 +141,8 @@ void CheckVersionFeature::checkVersion() {
|
|||
for (auto& p : theLists->_databases) {
|
||||
TRI_vocbase_t* vocbase = p.second;
|
||||
|
||||
// special check script to be run just once in first thread (not in all)
|
||||
// special check script to be run just once in first thread (not in
|
||||
// all)
|
||||
// but for all databases
|
||||
|
||||
int status = TRI_CheckDatabaseVersion(vocbase, localContext);
|
||||
|
@ -144,8 +150,9 @@ void CheckVersionFeature::checkVersion() {
|
|||
LOG(DEBUG) << "version check return status " << status;
|
||||
|
||||
if (status < 0) {
|
||||
LOG(FATAL) << "Database version check failed for '" << vocbase->_name
|
||||
<< "'. Please inspect the logs for any errors";
|
||||
LOG(FATAL) << "Database version check failed for '"
|
||||
<< vocbase->_name
|
||||
<< "'. Please inspect the logs for any errors";
|
||||
FATAL_ERROR_EXIT();
|
||||
} else if (status == 3) {
|
||||
*_result = 3;
|
||||
|
@ -155,11 +162,11 @@ void CheckVersionFeature::checkVersion() {
|
|||
}
|
||||
}
|
||||
|
||||
// issue #391: when invoked with --database.auto-upgrade, the server will not always shut
|
||||
// issue #391: when invoked with --database.auto-upgrade, the server will
|
||||
// not always shut
|
||||
// down
|
||||
localContext->Exit();
|
||||
}
|
||||
V8DealerFeature::DEALER->exitContext(context);
|
||||
}
|
||||
|
||||
if (*_result == 1) {
|
||||
|
|
|
@ -63,6 +63,13 @@ void ConsoleThread::run() {
|
|||
// enter V8 context
|
||||
_context = V8DealerFeature::DEALER->enterContext(_vocbase, true);
|
||||
|
||||
if (_context != nullptr) {
|
||||
LOG(FATAL) << "cannot acquire V8 context";
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
TRI_DEFER(V8DealerFeature::DEALER->exitContext(_context));
|
||||
|
||||
// work
|
||||
try {
|
||||
inner();
|
||||
|
@ -71,14 +78,11 @@ void ConsoleThread::run() {
|
|||
LOG(ERR) << error;
|
||||
}
|
||||
} catch (...) {
|
||||
V8DealerFeature::DEALER->exitContext(_context);
|
||||
_applicationServer->beginShutdown();
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
// exit context
|
||||
V8DealerFeature::DEALER->exitContext(_context);
|
||||
_applicationServer->beginShutdown();
|
||||
}
|
||||
|
||||
|
|
|
@ -71,6 +71,14 @@ int ScriptFeature::runScript(std::vector<std::string> const& scripts) {
|
|||
auto database = ApplicationServer::getFeature<DatabaseFeature>("Database");
|
||||
V8Context* context =
|
||||
V8DealerFeature::DEALER->enterContext(database->vocbase(), true);
|
||||
|
||||
if (context != nullptr) {
|
||||
LOG(FATAL) << "cannot acquire V8 context";
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
TRI_DEFER(V8DealerFeature::DEALER->exitContext(context));
|
||||
|
||||
auto isolate = context->_isolate;
|
||||
|
||||
{
|
||||
|
@ -145,7 +153,5 @@ int ScriptFeature::runScript(std::vector<std::string> const& scripts) {
|
|||
localContext->Exit();
|
||||
}
|
||||
|
||||
V8DealerFeature::DEALER->exitContext(context);
|
||||
|
||||
return ok ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
|
|
|
@ -65,6 +65,13 @@ int UnitTestsFeature::runUnitTests(std::vector<std::string> const& unitTests) {
|
|||
V8Context* context =
|
||||
V8DealerFeature::DEALER->enterContext(database->vocbase(), true);
|
||||
|
||||
if (context != nullptr) {
|
||||
LOG(FATAL) << "cannot acquire V8 context";
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
TRI_DEFER(V8DealerFeature::DEALER->exitContext(context));
|
||||
|
||||
auto isolate = context->_isolate;
|
||||
|
||||
bool ok = false;
|
||||
|
@ -111,7 +118,5 @@ int UnitTestsFeature::runUnitTests(std::vector<std::string> const& unitTests) {
|
|||
localContext->Exit();
|
||||
}
|
||||
|
||||
V8DealerFeature::DEALER->exitContext(context);
|
||||
|
||||
return ok ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
|
|
|
@ -132,6 +132,8 @@ void UpgradeFeature::changeAdminPassword(std::string const& defaultPassword) {
|
|||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
TRI_DEFER(V8DealerFeature::DEALER->exitContext(context));
|
||||
|
||||
{
|
||||
v8::HandleScope scope(context->_isolate);
|
||||
auto localContext =
|
||||
|
@ -166,8 +168,6 @@ void UpgradeFeature::changeAdminPassword(std::string const& defaultPassword) {
|
|||
// failure when we delete the context locker below
|
||||
localContext->Exit();
|
||||
}
|
||||
|
||||
V8DealerFeature::DEALER->exitContext(context);
|
||||
}
|
||||
|
||||
// and return from the context
|
||||
|
@ -190,6 +190,8 @@ void UpgradeFeature::upgradeDatabase(std::string const& defaultPassword) {
|
|||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
TRI_DEFER(V8DealerFeature::DEALER->exitContext(context));
|
||||
|
||||
{
|
||||
v8::HandleScope scope(context->_isolate);
|
||||
auto localContext =
|
||||
|
@ -253,13 +255,9 @@ void UpgradeFeature::upgradeDatabase(std::string const& defaultPassword) {
|
|||
}
|
||||
|
||||
// finally leave the context. otherwise v8 will crash with assertion
|
||||
// failure
|
||||
// when we delete
|
||||
// the context locker below
|
||||
// failure when we delete the context locker below
|
||||
localContext->Exit();
|
||||
}
|
||||
|
||||
V8DealerFeature::DEALER->exitContext(context);
|
||||
}
|
||||
|
||||
if (_upgrade) {
|
||||
|
|
|
@ -181,7 +181,7 @@ void V8DealerFeature::start() {
|
|||
|
||||
// try to guess a suitable number of contexts
|
||||
if (0 == _nrContexts && 0 == _forceNrContexts) {
|
||||
DispatcherFeature* dispatcher =
|
||||
DispatcherFeature* dispatcher =
|
||||
ApplicationServer::getFeature<DispatcherFeature>("Dispatcher");
|
||||
|
||||
_nrContexts = dispatcher->concurrency();
|
||||
|
@ -216,7 +216,7 @@ void V8DealerFeature::start() {
|
|||
|
||||
applyContextUpdates();
|
||||
|
||||
DatabaseFeature* database =
|
||||
DatabaseFeature* database =
|
||||
ApplicationServer::getFeature<DatabaseFeature>("Database");
|
||||
|
||||
loadJavascript(database->vocbase(), "server/initialize.js");
|
||||
|
@ -262,10 +262,12 @@ void V8DealerFeature::collectGarbage() {
|
|||
bool preferFree = false;
|
||||
|
||||
// the time we'll wait for a signal
|
||||
uint64_t const regularWaitTime = static_cast<uint64_t>(_gcFrequency * 1000.0 * 1000.0);
|
||||
uint64_t const regularWaitTime =
|
||||
static_cast<uint64_t>(_gcFrequency * 1000.0 * 1000.0);
|
||||
|
||||
// the time we'll wait for a signal when the previous wait timed out
|
||||
uint64_t const reducedWaitTime = static_cast<uint64_t>(_gcFrequency * 1000.0 * 200.0);
|
||||
uint64_t const reducedWaitTime =
|
||||
static_cast<uint64_t>(_gcFrequency * 1000.0 * 200.0);
|
||||
|
||||
while (_stopping == 0) {
|
||||
V8Context* context = nullptr;
|
||||
|
@ -483,8 +485,8 @@ V8Context* V8DealerFeature::enterContext(TRI_vocbase_t* vocbase,
|
|||
_freeContexts.push_back(context);
|
||||
_dirtyContexts.pop_back();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
auto currentThread = arangodb::rest::DispatcherThread::current();
|
||||
|
||||
if (currentThread != nullptr) {
|
||||
|
@ -682,8 +684,8 @@ void V8DealerFeature::applyContextUpdates() {
|
|||
vocbase = DatabaseFeature::DATABASE->vocbase();
|
||||
}
|
||||
|
||||
V8Context* context =
|
||||
V8DealerFeature::DEALER->enterContext(vocbase, true, static_cast<ssize_t>(i));
|
||||
V8Context* context = V8DealerFeature::DEALER->enterContext(
|
||||
vocbase, true, static_cast<ssize_t>(i));
|
||||
|
||||
if (context == nullptr) {
|
||||
LOG(FATAL) << "could not updated V8 context #" << i;
|
||||
|
@ -703,7 +705,7 @@ void V8DealerFeature::applyContextUpdates() {
|
|||
|
||||
localContext->Exit();
|
||||
}
|
||||
|
||||
|
||||
V8DealerFeature::DEALER->exitContext(context);
|
||||
|
||||
LOG(TRACE) << "updated V8 context #" << i;
|
||||
|
@ -851,8 +853,9 @@ V8Context* V8DealerFeature::pickFreeContextForGc() {
|
|||
void V8DealerFeature::initializeContext(size_t i) {
|
||||
CONDITION_LOCKER(guard, _contextCondition);
|
||||
|
||||
V8PlatformFeature* v8platform =
|
||||
application_features::ApplicationServer::getFeature<V8PlatformFeature>("V8Platform");
|
||||
V8PlatformFeature* v8platform =
|
||||
application_features::ApplicationServer::getFeature<V8PlatformFeature>(
|
||||
"V8Platform");
|
||||
TRI_ASSERT(v8platform != nullptr);
|
||||
|
||||
v8::Isolate::CreateParams createParams;
|
||||
|
@ -963,7 +966,8 @@ void V8DealerFeature::initializeContext(size_t i) {
|
|||
|
||||
void V8DealerFeature::loadJavascriptFiles(TRI_vocbase_t* vocbase,
|
||||
std::string const& file, size_t i) {
|
||||
V8Context* context = V8DealerFeature::DEALER->enterContext(vocbase, true, static_cast<ssize_t>(i));
|
||||
V8Context* context = V8DealerFeature::DEALER->enterContext(
|
||||
vocbase, true, static_cast<ssize_t>(i));
|
||||
|
||||
if (context == nullptr) {
|
||||
LOG(FATAL) << "could not load JavaScript files in context #" << i;
|
||||
|
@ -979,7 +983,8 @@ void V8DealerFeature::loadJavascriptFiles(TRI_vocbase_t* vocbase,
|
|||
{
|
||||
v8::Context::Scope contextScope(localContext);
|
||||
|
||||
switch (_startupLoader.loadScript(context->_isolate, localContext, file)) {
|
||||
switch (
|
||||
_startupLoader.loadScript(context->_isolate, localContext, file)) {
|
||||
case JSLoader::eSuccess:
|
||||
LOG(TRACE) << "loaded JavaScript file '" << file << "'";
|
||||
break;
|
||||
|
@ -989,7 +994,7 @@ void V8DealerFeature::loadJavascriptFiles(TRI_vocbase_t* vocbase,
|
|||
break;
|
||||
case JSLoader::eFailExecute:
|
||||
LOG(FATAL) << "error during execution of JavaScript file '" << file
|
||||
<< "'";
|
||||
<< "'";
|
||||
FATAL_ERROR_EXIT();
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -75,6 +75,8 @@ void V8Job::work() {
|
|||
return;
|
||||
}
|
||||
|
||||
TRI_DEFER(V8DealerFeature::DEALER->exitContext(context));
|
||||
|
||||
// now execute the function within this context
|
||||
{
|
||||
auto isolate = context->_isolate;
|
||||
|
@ -131,8 +133,6 @@ void V8Job::work() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
V8DealerFeature::DEALER->exitContext(context);
|
||||
}
|
||||
|
||||
bool V8Job::cancel() {
|
||||
|
|
|
@ -71,6 +71,8 @@ void V8QueueJob::work() {
|
|||
return;
|
||||
}
|
||||
|
||||
TRI_DEFER(V8DealerFeature::DEALER->exitContext(context));
|
||||
|
||||
// now execute the function within this context
|
||||
{
|
||||
auto isolate = context->_isolate;
|
||||
|
@ -118,8 +120,6 @@ void V8QueueJob::work() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
V8DealerFeature::DEALER->exitContext(context);
|
||||
}
|
||||
|
||||
bool V8QueueJob::cancel() {
|
||||
|
|
|
@ -89,7 +89,8 @@ class v8_action_t : public TRI_action_t {
|
|||
TRI_action_result_t result;
|
||||
|
||||
// allow use datase execution in rest calls
|
||||
bool allowUseDatabaseInRestActions = ActionFeature::ACTION->allowUseDatabase();
|
||||
bool allowUseDatabaseInRestActions =
|
||||
ActionFeature::ACTION->allowUseDatabase();
|
||||
|
||||
if (_allowUseDatabase) {
|
||||
allowUseDatabaseInRestActions = true;
|
||||
|
@ -114,6 +115,8 @@ class v8_action_t : public TRI_action_t {
|
|||
return result;
|
||||
}
|
||||
|
||||
TRI_DEFER(V8DealerFeature::DEALER->exitContext(context));
|
||||
|
||||
// locate the callback
|
||||
READ_LOCKER(readLocker, _callbacksLock);
|
||||
|
||||
|
@ -124,8 +127,6 @@ class v8_action_t : public TRI_action_t {
|
|||
LOG(WARN) << "no callback function for JavaScript action '" << _url
|
||||
<< "'";
|
||||
|
||||
V8DealerFeature::DEALER->exitContext(context);
|
||||
|
||||
result.isValid = true;
|
||||
result.response =
|
||||
new HttpResponse(GeneralResponse::ResponseCode::NOT_FOUND);
|
||||
|
@ -139,9 +140,6 @@ class v8_action_t : public TRI_action_t {
|
|||
|
||||
if (*data != 0) {
|
||||
result.canceled = true;
|
||||
|
||||
V8DealerFeature::DEALER->exitContext(context);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -163,7 +161,6 @@ class v8_action_t : public TRI_action_t {
|
|||
*data = 0;
|
||||
}
|
||||
}
|
||||
V8DealerFeature::DEALER->exitContext(context);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -547,12 +544,14 @@ static HttpResponse* ResponseV8ToCpp(v8::Isolate* isolate,
|
|||
// base64-encode the result
|
||||
out = StringUtils::encodeBase64(out);
|
||||
// set the correct content-encoding header
|
||||
response->setHeaderNC(StaticStrings::ContentEncoding, StaticStrings::Base64);
|
||||
response->setHeaderNC(StaticStrings::ContentEncoding,
|
||||
StaticStrings::Base64);
|
||||
} else if (name == "base64decode") {
|
||||
// base64-decode the result
|
||||
out = StringUtils::decodeBase64(out);
|
||||
// set the correct content-encoding header
|
||||
response->setHeaderNC(StaticStrings::ContentEncoding, StaticStrings::Binary);
|
||||
response->setHeaderNC(StaticStrings::ContentEncoding,
|
||||
StaticStrings::Binary);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -726,7 +725,8 @@ static TRI_action_result_t ExecuteActionVocbase(
|
|||
|
||||
else if (tryCatch.HasCaught()) {
|
||||
if (tryCatch.CanContinue()) {
|
||||
HttpResponse* response = new HttpResponse(GeneralResponse::ResponseCode::SERVER_ERROR);
|
||||
HttpResponse* response =
|
||||
new HttpResponse(GeneralResponse::ResponseCode::SERVER_ERROR);
|
||||
response->body().appendText(TRI_StringifyV8Exception(isolate, &tryCatch));
|
||||
|
||||
result.response = response;
|
||||
|
@ -738,8 +738,7 @@ static TRI_action_result_t ExecuteActionVocbase(
|
|||
}
|
||||
|
||||
else {
|
||||
result.response =
|
||||
ResponseV8ToCpp(isolate, v8g, res);
|
||||
result.response = ResponseV8ToCpp(isolate, v8g, res);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -1173,7 +1172,8 @@ static bool clusterSendToAllServers(
|
|||
|
||||
DBServers = ci->getCurrentDBServers();
|
||||
for (auto const& sid : DBServers) {
|
||||
auto headers = std::make_unique<std::unordered_map<std::string, std::string>>();
|
||||
auto headers =
|
||||
std::make_unique<std::unordered_map<std::string, std::string>>();
|
||||
cc->asyncRequest("", coordTransactionID, "server:" + sid, method, url,
|
||||
reqBodyString, headers, nullptr, 3600.0);
|
||||
}
|
||||
|
|
|
@ -28,108 +28,154 @@ const actions = require("@arangodb/actions");
|
|||
const users = require("@arangodb/users");
|
||||
const db = require("@arangodb").db;
|
||||
|
||||
function get_api_user(req, res) {
|
||||
if (req.suffix.length === 0) {
|
||||
actions.resultOk(req, res, actions.HTTP_OK, {
|
||||
result: users.all()
|
||||
});
|
||||
return;
|
||||
// check if user is an administrator (aka member of _system)
|
||||
function needSystemUser(req, res) {
|
||||
const user = req.user;
|
||||
|
||||
// authentication disabled
|
||||
if (user === null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var user = decodeURIComponent(req.suffix[0]);
|
||||
const allowed = users.permission(user, "_system") === 'rw' ||
|
||||
users.permission(user, "*") === 'rw';
|
||||
|
||||
try {
|
||||
actions.resultOk(req, res, actions.HTTP_OK, users.document(user));
|
||||
} catch (err) {
|
||||
if (err.errorNum === arangodb.errors.ERROR_USER_NOT_FOUND.code) {
|
||||
actions.resultNotFound(req, res, arangodb.errors.ERROR_USER_NOT_FOUND.code);
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
if (!allowed) {
|
||||
actions.resultError(req, res, actions.HTTP_FORBIDDEN,
|
||||
String("you need administrator privileges"));
|
||||
}
|
||||
|
||||
return allowed;
|
||||
}
|
||||
|
||||
// check if user is asking infos for itself (or is an administrator)
|
||||
function needMyself(req, res, username) {
|
||||
const user = req.user;
|
||||
|
||||
// authentication disabled
|
||||
if (user === null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
let allowed = (user === username);
|
||||
|
||||
if (!allowed) {
|
||||
allowed = users.permission(username, "_system") === 'rw' ||
|
||||
users.permission(username, "*") === 'rw';
|
||||
}
|
||||
|
||||
if (!allowed) {
|
||||
actions.resultError(req, res, actions.HTTP_FORBIDDEN,
|
||||
String("you cannot access other users"));
|
||||
}
|
||||
|
||||
return allowed;
|
||||
}
|
||||
|
||||
// handle exception
|
||||
function handleException(req, res, err) {
|
||||
if (err.errorNum === arangodb.errors.ERROR_USER_NOT_FOUND.code) {
|
||||
actions.resultNotFound(req, res, arangodb.errors.ERROR_USER_NOT_FOUND.code);
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
function get_api_permission(req, res, key) {
|
||||
var user = decodeURIComponent(req.suffix[0]);
|
||||
// GET /_api/user | GET /_api/user/<username>
|
||||
function get_api_user(req, res) {
|
||||
if (req.suffix.length === 0) {
|
||||
if (needSystemUser(req, res)) {
|
||||
actions.resultOk(req, res, actions.HTTP_OK, {
|
||||
result: users.all()
|
||||
});
|
||||
}
|
||||
|
||||
var oldDbname = db._name();
|
||||
return;
|
||||
}
|
||||
|
||||
const user = decodeURIComponent(req.suffix[0]);
|
||||
|
||||
try {
|
||||
var doc;
|
||||
if (key !== null && key !== undefined) {
|
||||
doc = users.permission(user, key);
|
||||
if (needMyself(req, res, user)) {
|
||||
actions.resultOk(req, res, actions.HTTP_OK, users.document(user));
|
||||
}
|
||||
doc = users.permission(user);
|
||||
actions.resultOk(req, res, actions.HTTP_OK, { result: doc });
|
||||
} catch (err) {
|
||||
if (err.errorNum === arangodb.errors.ERROR_USER_NOT_FOUND.code) {
|
||||
actions.resultNotFound(req, res, arangodb.errors.ERROR_USER_NOT_FOUND.code);
|
||||
handleException(req, res, err);
|
||||
}
|
||||
}
|
||||
|
||||
// GET /_api/user/<username>/database | GET /_api/user/<username>/database/<dbname>
|
||||
function get_api_database(req, res, key) {
|
||||
const user = decodeURIComponent(req.suffix[0]);
|
||||
|
||||
try {
|
||||
if (needMyself(req, res, user)) {
|
||||
actions.resultOk(req, res, actions.HTTP_OK, {
|
||||
result: users.permission(user, key)
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
handleException(req, res, err);
|
||||
}
|
||||
}
|
||||
|
||||
// GET /_api/user/<username>/config | GET /_api/user/<username>/config/<key>
|
||||
function get_api_config(req, res, key) {
|
||||
const user = decodeURIComponent(req.suffix[0]);
|
||||
|
||||
try {
|
||||
if (needMyself(req, res, user)) {
|
||||
actions.resultOk(req, res, actions.HTTP_OK, {
|
||||
result: users.configData(user, key)
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
handleException(req, res, err);
|
||||
}
|
||||
}
|
||||
|
||||
// GET /_api/user/...
|
||||
function get_api_user_request(req, res) {
|
||||
const oldDbname = db._name();
|
||||
db._useDatabase("_system");
|
||||
|
||||
try {
|
||||
if (req.suffix.length === 0) {
|
||||
get_api_user(req, res);
|
||||
} else if (req.suffix.length === 1) {
|
||||
get_api_user(req, res);
|
||||
} else if (req.suffix.length === 2) {
|
||||
if (req.suffix[1] === "config") {
|
||||
get_api_config(req, res, null);
|
||||
} else if (req.suffix[1] === "database") {
|
||||
get_api_database(req, res, null);
|
||||
} else {
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER);
|
||||
}
|
||||
} else if (req.suffix.length === 3) {
|
||||
if (req.suffix[1] === "config") {
|
||||
get_api_config(req, res, req.suffix[2]);
|
||||
} else {
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER);
|
||||
}
|
||||
} else {
|
||||
throw err;
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER);
|
||||
}
|
||||
} finally {
|
||||
db._useDatabase(oldDbname);
|
||||
}
|
||||
}
|
||||
|
||||
function get_api_config(req, res, key) {
|
||||
var user = decodeURIComponent(req.suffix[0]);
|
||||
|
||||
if (user !== req.user) {
|
||||
actions.resultBad(req, res, arangodb.errors.ERROR_HTTP_UNAUTHORIZED.code);
|
||||
} else {
|
||||
var oldDbname = db._name();
|
||||
|
||||
try {
|
||||
var doc = users.configData(user, key);
|
||||
|
||||
actions.resultOk(req, res, actions.HTTP_OK, { result: doc });
|
||||
} catch (err) {
|
||||
if (err.errorNum === arangodb.errors.ERROR_USER_NOT_FOUND.code) {
|
||||
actions.resultNotFound(req, res, arangodb.errors.ERROR_USER_NOT_FOUND.code);
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
} finally {
|
||||
db._useDatabase(oldDbname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function get_api_user_or_config(req, res) {
|
||||
if (req.suffix.length === 0) {
|
||||
get_api_user(req, res);
|
||||
} else if (req.suffix.length === 1) {
|
||||
get_api_user(req, res);
|
||||
} else if (req.suffix.length === 2) {
|
||||
if (req.suffix[1] === "config") {
|
||||
get_api_config(req, res, null);
|
||||
} else if (req.suffix[1] === "permission") {
|
||||
get_api_permission(req, res, null);
|
||||
}
|
||||
else {
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER);
|
||||
}
|
||||
} else if (req.suffix.length === 3) {
|
||||
if (req.suffix[1] === "config") {
|
||||
get_api_config(req, res, req.suffix[2]);
|
||||
} else {
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER);
|
||||
}
|
||||
} else {
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER);
|
||||
}
|
||||
}
|
||||
|
||||
// POST /_api/user | POST /_api/user/<username>
|
||||
function post_api_user(req, res) {
|
||||
var json = actions.getJsonBody(req, res, actions.HTTP_BAD);
|
||||
const json = actions.getJsonBody(req, res, actions.HTTP_BAD);
|
||||
|
||||
if (json === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
// validate if a combination or username / password is valid
|
||||
if (req.suffix.length === 1) {
|
||||
// validate if a combination or username / password is valid
|
||||
const user = decodeURIComponent(req.suffix[0]);
|
||||
const result = users.isValid(user, json.passwd);
|
||||
|
||||
|
@ -143,57 +189,79 @@ function post_api_user(req, res) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (req.suffix.length !== 0) {
|
||||
// unexpected URL
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER);
|
||||
return;
|
||||
}
|
||||
if (needSystemUser(req, res)) {
|
||||
const user = json.user;
|
||||
const doc = users.save(user, json.passwd, json.active, json.extra,
|
||||
json.changePassword);
|
||||
|
||||
const user = json.user;
|
||||
const doc = users.save(user, json.passwd, json.active, json.extra, json.changePassword);
|
||||
if (json.passwordToken) {
|
||||
users.setPasswordToken(user, json.passwordToken);
|
||||
}
|
||||
|
||||
if (json.passwordToken) {
|
||||
users.setPasswordToken(user, json.passwordToken);
|
||||
}
|
||||
|
||||
users.reload();
|
||||
|
||||
actions.resultOk(req, res, actions.HTTP_CREATED, doc);
|
||||
}
|
||||
|
||||
function put_api_user(req, res) {
|
||||
var user = decodeURIComponent(req.suffix[0]);
|
||||
var json = actions.getJsonBody(req, res, actions.HTTP_BAD);
|
||||
|
||||
if (json === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
var doc = users.replace(user, json.passwd, json.active, json.extra, json.changePassword);
|
||||
users.reload();
|
||||
|
||||
actions.resultOk(req, res, actions.HTTP_OK, doc);
|
||||
} catch (err) {
|
||||
if (err.errorNum === arangodb.errors.ERROR_USER_NOT_FOUND.code) {
|
||||
actions.resultNotFound(req, res, arangodb.errors.ERROR_USER_NOT_FOUND.code);
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
actions.resultOk(req, res, actions.HTTP_CREATED, doc);
|
||||
}
|
||||
}
|
||||
|
||||
function put_api_permission(req, res) {
|
||||
var user = decodeURIComponent(req.suffix[0]);
|
||||
var dbname = decodeURIComponent(req.suffix[2]);
|
||||
var json = actions.getJsonBody(req, res, actions.HTTP_BAD);
|
||||
// POST /_api/user/...
|
||||
function post_api_user_request(req, res) {
|
||||
const oldDbname = db._name();
|
||||
db._useDatabase("_system");
|
||||
|
||||
try {
|
||||
if (req.suffix.length < 2) {
|
||||
post_api_user(req, res);
|
||||
} else {
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER);
|
||||
}
|
||||
} finally {
|
||||
db._useDatabase(oldDbname);
|
||||
}
|
||||
}
|
||||
|
||||
// PUT /_api/user/<username>
|
||||
function put_api_user(req, res) {
|
||||
const user = decodeURIComponent(req.suffix[0]);
|
||||
const json = actions.getJsonBody(req, res, actions.HTTP_BAD);
|
||||
|
||||
if (json === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
var doc;
|
||||
const isActive = users.document(user).active;
|
||||
|
||||
if (isActive) {
|
||||
if (needMyself(req, res, user)) {
|
||||
actions.resultOk(req, res, actions.HTTP_OK,
|
||||
users.replace(user, json.passwd, json.active, json.extra));
|
||||
}
|
||||
} else {
|
||||
if (needSystemUser(req, res, user)) {
|
||||
actions.resultOk(req, res, actions.HTTP_OK,
|
||||
users.replace(user, json.passwd, json.active, json.extra));
|
||||
}
|
||||
}
|
||||
|
||||
users.reload();
|
||||
} catch (err) {
|
||||
handleException(req, res, err);
|
||||
}
|
||||
}
|
||||
|
||||
// PUT /_api/user/<username>/database/<dbname>
|
||||
function put_api_permission(req, res) {
|
||||
const user = decodeURIComponent(req.suffix[0]);
|
||||
const dbname = decodeURIComponent(req.suffix[2]);
|
||||
const json = actions.getJsonBody(req, res, actions.HTTP_BAD);
|
||||
|
||||
if (json === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
let doc;
|
||||
|
||||
if (json.grant === "rw" || json.grant === "ro") {
|
||||
doc = users.grantDatabase(user, dbname, json.grant);
|
||||
|
@ -205,112 +273,121 @@ function put_api_permission(req, res) {
|
|||
|
||||
actions.resultOk(req, res, actions.HTTP_OK, doc);
|
||||
} catch (err) {
|
||||
if (err.errorNum === arangodb.errors.ERROR_USER_NOT_FOUND.code) {
|
||||
actions.resultNotFound(req, res, arangodb.errors.ERROR_USER_NOT_FOUND.code);
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
handleException(req, res, err);
|
||||
}
|
||||
}
|
||||
|
||||
// PUT /_api/user/<username>/config/<key>
|
||||
function put_api_config(req, res) {
|
||||
var user = decodeURIComponent(req.suffix[0]);
|
||||
|
||||
if (user !== req.user) {
|
||||
actions.resultBad(req, res, arangodb.errors.ERROR_HTTP_UNAUTHORIZED.code);
|
||||
} else {
|
||||
var oldDbname = db._name();
|
||||
|
||||
try {
|
||||
db._useDatabase("_system");
|
||||
|
||||
var key = decodeURIComponent(req.suffix[2]);
|
||||
var json = actions.getJsonBody(req, res, actions.HTTP_BAD);
|
||||
|
||||
if (json === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
users.updateConfigData(user, key, json.value);
|
||||
|
||||
actions.resultOk(req, res, actions.HTTP_OK, {});
|
||||
} catch (err) {
|
||||
if (err.errorNum === arangodb.errors.ERROR_USER_NOT_FOUND.code) {
|
||||
actions.resultNotFound(req, res, arangodb.errors.ERROR_USER_NOT_FOUND.code);
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
db._useDatabase(oldDbname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function put_api_user_or_permission(req, res) {
|
||||
if (req.suffix.length === 1) {
|
||||
put_api_user(req, res);
|
||||
} else if (req.suffix.length === 3) {
|
||||
if (req.suffix[1] === "database") {
|
||||
put_api_permission(req, res);
|
||||
} else if (req.suffix[1] === "config") {
|
||||
put_api_config(req, res);
|
||||
} else {
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER);
|
||||
}
|
||||
} else {
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER);
|
||||
}
|
||||
}
|
||||
|
||||
function patch_api_user(req, res) {
|
||||
if (req.suffix.length !== 1) {
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER);
|
||||
return;
|
||||
}
|
||||
|
||||
var user = decodeURIComponent(req.suffix[0]);
|
||||
var json = actions.getJsonBody(req, res, actions.HTTP_BAD);
|
||||
const user = decodeURIComponent(req.suffix[0]);
|
||||
const key = decodeURIComponent(req.suffix[2]);
|
||||
const json = actions.getJsonBody(req, res, actions.HTTP_BAD);
|
||||
|
||||
if (json === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
var doc = users.update(user, json.passwd, json.active, json.extra, json.changePassword);
|
||||
users.reload();
|
||||
if (needMyself(req, res, user)) {
|
||||
users.updateConfigData(user, key, json.value);
|
||||
|
||||
actions.resultOk(req, res, actions.HTTP_OK, doc);
|
||||
} catch (err) {
|
||||
if (err.errorNum === arangodb.errors.ERROR_USER_NOT_FOUND.code) {
|
||||
actions.resultNotFound(req, res, arangodb.errors.ERROR_USER_NOT_FOUND.code);
|
||||
} else {
|
||||
throw err;
|
||||
actions.resultOk(req, res, actions.HTTP_OK, {});
|
||||
}
|
||||
} catch (err) {
|
||||
handleException(req, res, err);
|
||||
}
|
||||
}
|
||||
|
||||
function delete_api_user(req, res) {
|
||||
var user = decodeURIComponent(req.suffix[0]);
|
||||
// PUT /_api/user/...
|
||||
function put_api_user_request(req, res) {
|
||||
const oldDbname = db._name();
|
||||
db._useDatabase("_system");
|
||||
|
||||
try {
|
||||
users.remove(user);
|
||||
users.reload();
|
||||
|
||||
actions.resultOk(req, res, actions.HTTP_ACCEPTED, {});
|
||||
} catch (err) {
|
||||
if (err.errorNum === arangodb.errors.ERROR_USER_NOT_FOUND.code) {
|
||||
actions.resultNotFound(req, res, arangodb.errors.ERROR_USER_NOT_FOUND.code);
|
||||
if (req.suffix.length === 1) {
|
||||
put_api_user(req, res);
|
||||
} else if (req.suffix.length === 3) {
|
||||
if (req.suffix[1] === "database") {
|
||||
put_api_permission(req, res);
|
||||
} else if (req.suffix[1] === "config") {
|
||||
put_api_config(req, res);
|
||||
} else {
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER);
|
||||
}
|
||||
} else {
|
||||
throw err;
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER);
|
||||
}
|
||||
} finally {
|
||||
db._useDatabase(oldDbname);
|
||||
}
|
||||
}
|
||||
|
||||
// PATCH /_api/user/<username>
|
||||
function patch_api_user(req, res) {
|
||||
const user = decodeURIComponent(req.suffix[0]);
|
||||
const json = actions.getJsonBody(req, res, actions.HTTP_BAD);
|
||||
|
||||
if (json === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const isActive = users.document(user).active;
|
||||
|
||||
if (isActive) {
|
||||
if (needMyself(req, res, user)) {
|
||||
actions.resultOk(req, res, actions.HTTP_OK,
|
||||
users.update(user, json.passwd, json.active, json.extra));
|
||||
}
|
||||
} else {
|
||||
if (needSystemUser(req, res, user)) {
|
||||
actions.resultOk(req, res, actions.HTTP_OK,
|
||||
users.update(user, json.passwd, json.active, json.extra));
|
||||
}
|
||||
}
|
||||
|
||||
users.reload();
|
||||
} catch (err) {
|
||||
handleException(req, res, err);
|
||||
}
|
||||
}
|
||||
|
||||
// PATCH /_api/user/...
|
||||
function patch_api_user_request(req, res) {
|
||||
const oldDbname = db._name();
|
||||
db._useDatabase("_system");
|
||||
|
||||
try {
|
||||
if (req.suffix.length === 1) {
|
||||
patch_api_user(req, res);
|
||||
} else {
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER);
|
||||
}
|
||||
} finally {
|
||||
db._useDatabase(oldDbname);
|
||||
}
|
||||
}
|
||||
|
||||
// DELETE /_api/user/<username>
|
||||
function delete_api_user(req, res) {
|
||||
const user = decodeURIComponent(req.suffix[0]);
|
||||
|
||||
try {
|
||||
if (needSystemUser(req, res)) {
|
||||
users.remove(user);
|
||||
users.reload();
|
||||
|
||||
actions.resultOk(req, res, actions.HTTP_ACCEPTED, {});
|
||||
}
|
||||
} catch (err) {
|
||||
handleException(req, res, err);
|
||||
}
|
||||
}
|
||||
|
||||
// DELETE /_api/user/<username>/database/<dbname>
|
||||
function delete_api_permission(req, res) {
|
||||
var user = decodeURIComponent(req.suffix[0]);
|
||||
var dbname = decodeURIComponent(req.suffix[2]);
|
||||
const user = decodeURIComponent(req.suffix[0]);
|
||||
const dbname = decodeURIComponent(req.suffix[2]);
|
||||
|
||||
try {
|
||||
users.revokeDatabase(user, dbname);
|
||||
|
@ -318,60 +395,60 @@ function delete_api_permission(req, res) {
|
|||
|
||||
actions.resultOk(req, res, actions.HTTP_ACCEPTED, {});
|
||||
} catch (err) {
|
||||
if (err.errorNum === arangodb.errors.ERROR_USER_NOT_FOUND.code) {
|
||||
actions.resultNotFound(req, res, arangodb.errors.ERROR_USER_NOT_FOUND.code);
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
handleException(req, res, err);
|
||||
}
|
||||
}
|
||||
|
||||
// DELETE /_api/user/<username>/config/<key>
|
||||
function delete_api_config(req, res, key) {
|
||||
var user = decodeURIComponent(req.suffix[0]);
|
||||
const user = decodeURIComponent(req.suffix[0]);
|
||||
|
||||
if (user !== req.user) {
|
||||
actions.resultBad(req, res, arangodb.errors.ERROR_HTTP_UNAUTHORIZED.code);
|
||||
} else {
|
||||
var oldDbname = db._name();
|
||||
|
||||
try {
|
||||
try {
|
||||
if (needMyself(req, res, user)) {
|
||||
users.updateConfigData(user, key);
|
||||
|
||||
actions.resultOk(req, res, actions.HTTP_ACCEPTED, {});
|
||||
} catch (err) {
|
||||
if (err.errorNum === arangodb.errors.ERROR_USER_NOT_FOUND.code) {
|
||||
actions.resultNotFound(req, res, arangodb.errors.ERROR_USER_NOT_FOUND.code);
|
||||
}
|
||||
} catch (err) {
|
||||
handleException(req, res, err);
|
||||
}
|
||||
}
|
||||
|
||||
// DELETE /_api/user/...
|
||||
function delete_api_user_request(req, res) {
|
||||
const oldDbname = db._name();
|
||||
db._useDatabase("_system");
|
||||
|
||||
try {
|
||||
if (req.suffix.length === 1) {
|
||||
if (req.suffix.length === 1) {
|
||||
delete_api_user(req, res);
|
||||
} else if (req.suffix.length === 2) {
|
||||
if (req.suffix[1] === "config") {
|
||||
delete_api_config(req, res, null);
|
||||
} else {
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER);
|
||||
}
|
||||
} else if (req.suffix.length === 3) {
|
||||
if (req.suffix[1] === "database") {
|
||||
delete_api_permission(req, res);
|
||||
} else if (req.suffix[1] === "config") {
|
||||
delete_api_config(req, res, req.suffix[2]);
|
||||
} else {
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER);
|
||||
}
|
||||
} else {
|
||||
throw err;
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER);
|
||||
}
|
||||
} finally {
|
||||
db._useDatabase(oldDbname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function delete_api_user_or_permission(req, res) {
|
||||
if (req.suffix.length === 1) {
|
||||
delete_api_user(req, res);
|
||||
} else if (req.suffix.length === 2) {
|
||||
if (req.suffix[1] === "config") {
|
||||
delete_api_config(req, res, null);
|
||||
} else {
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER);
|
||||
}
|
||||
} else if (req.suffix.length === 3) {
|
||||
if (req.suffix[1] === "database") {
|
||||
delete_api_permission(req, res);
|
||||
} else if (req.suffix[1] === "config") {
|
||||
delete_api_config(req, res, req.suffix[2]);
|
||||
} else {
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER);
|
||||
}
|
||||
} else {
|
||||
actions.resultBad(req, res, arangodb.ERROR_HTTP_BAD_PARAMETER);
|
||||
} finally {
|
||||
db._useDatabase(oldDbname);
|
||||
}
|
||||
}
|
||||
|
||||
// all api calls
|
||||
actions.defineHttp({
|
||||
url: "_api/user",
|
||||
allowUseDatabase: true,
|
||||
|
@ -380,23 +457,23 @@ actions.defineHttp({
|
|||
try {
|
||||
switch (req.requestType) {
|
||||
case actions.GET:
|
||||
get_api_user_or_config(req, res);
|
||||
get_api_user_request(req, res);
|
||||
break;
|
||||
|
||||
case actions.POST:
|
||||
post_api_user(req, res);
|
||||
post_api_user_request(req, res);
|
||||
break;
|
||||
|
||||
case actions.PUT:
|
||||
put_api_user_or_permission(req, res);
|
||||
put_api_user_request(req, res);
|
||||
break;
|
||||
|
||||
case actions.PATCH:
|
||||
patch_api_user(req, res);
|
||||
patch_api_user_request(req, res);
|
||||
break;
|
||||
|
||||
case actions.DELETE:
|
||||
delete_api_user_or_permission(req, res);
|
||||
delete_api_user_request(req, res);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
Loading…
Reference in New Issue