1
0
Fork 0

Improved audit logging (#8740)

This commit is contained in:
Dan Larkin-York 2019-04-15 08:51:32 -04:00 committed by Jan
parent 62ed576c8e
commit 777ba1a364
39 changed files with 674 additions and 216 deletions

View File

@ -27,4 +27,16 @@ Hostname
`--audit.hostname name`
The name of the server used in audit log messages. By default the
system hostname is used.
system hostname is used.
Verbosity
---------
`--log.level topic=level`
By default, the server will log all audit events. Some low-priority events, such
as statistics operations, are logged with the `debug` log level. To keep such
events from cluttering the log, set the appropriate topic to `info`. All other
messages will be logged at the `info` level. Audit topics include
`audit-authentication`, `audit-collection`, `audit-database`, `audit-document`,
`audit-service`, and `audit-view`.

View File

@ -12,44 +12,47 @@ Authentication
### Unknown authentication methods
```
2016-10-03 15:44:23 | server1 | - | database1 | 127.0.0.1:61525 | - | unknown authentication method | /_api/version
2016-10-03 15:44:23 | server1 | audit-authentication | n/a | database1 | 127.0.0.1:61525 | n/a | unknown authentication method | /_api/version
```
### Missing credentials
```
2016-10-03 15:39:49 | server1 | - | database1 | 127.0.0.1:61498 | - | credentials missing | /_api/version
2016-10-03 15:39:49 | server1 | audit-authentication | n/a | database1 | 127.0.0.1:61498 | n/a | credentials missing | /_api/version
```
### Wrong credentials
```
2016-10-03 15:47:26 | server1 | user1 | database1 | 127.0.0.1:61528 | http basic | credentials wrong | /_api/version
2016-10-03 15:47:26 | server1 | audit-authentication | n/a | database1 | 127.0.0.1:61528 | http basic | credentials wrong | /_api/version
```
Please note, that the user given as fourth part is the user that requested
the login. In general it will be unavailable.
### Password change required
```
2016-10-03 16:18:53 | server1 | user1 | database1 | 127.0.0.1:62257 | - | password change required | /_api/version
2016-10-03 16:18:53 | server1 | audit-authentication | user1 | database1 | 127.0.0.1:62257 | http basic | password change required | /_api/version
```
### JWT login succeeded
```
2016-10-03 17:21:22 | server1 | - | database1 | 127.0.0.1:64214 | http jwt | user 'root' authenticated | /_open/auth
2016-10-03 17:21:22 | server1 | audit-authentication | root | database1 | 127.0.0.1:64214 | http jwt | user 'root' authenticated | /_open/auth
```
Please note, that the user given as third part is the user that requested
the login. In general, it will be empty.
Please note, that the user given as fourth part is the user that requested
the login.
### JWT login failed
```
2016-10-03 17:21:22 | server1 | - | database1 | 127.0.0.1:64214 | http jwt | user 'root' wrong credentials | /_open/auth
2016-10-03 17:21:22 | server1 | audit-authentication | root | database1 | 127.0.0.1:64214 | http jwt | user 'root' wrong credentials | /_open/auth
```
Please note, that the user given as third part is the user that requested
the login. In general, it will be empty.
Please note, that the user given as fourth part is the user that requested
the login.
Authorization
-------------
@ -57,7 +60,7 @@ Authorization
### User not authorized to access database
```
2016-10-03 16:20:52 | server1 | user1 | database2 | 127.0.0.1:62262 | http basic | not authorized | /_api/version
2016-10-03 16:20:52 | server1 | audit-authentication | user1 | database2 | 127.0.0.1:62262 | http basic | not authorized | /_api/version
```
Databases
@ -66,13 +69,13 @@ Databases
### Create a database
```
2016-10-04 15:33:25 | server1 | user1 | database1 | 127.0.0.1:56920 | http basic | create database 'database1' | ok | /_api/database
2016-10-04 15:33:25 | server1 | audit-database | user1 | database1 | 127.0.0.1:56920 | http basic | create database 'database1' | ok | /_api/database
```
### Drop a database
```
2016-10-04 15:33:25 | server1 | user1 | database1 | 127.0.0.1:56920 | http basic | delete database 'database1' | ok | /_api/database
2016-10-04 15:33:25 | server1 | audit-database | user1 | database1 | 127.0.0.1:56920 | http basic | delete database 'database1' | ok | /_api/database
```
Collections
@ -81,19 +84,19 @@ Collections
### Create a collection
```
2016-10-05 17:35:57 | server1 | user1 | database1 | 127.0.0.1:51294 | http basic | create collection 'collection1' | ok | /_api/collection
2016-10-05 17:35:57 | server1 | audit-collection | user1 | database1 | 127.0.0.1:51294 | http basic | create collection 'collection1' | ok | /_api/collection
```
### Truncate a collection
```
2016-10-05 17:36:08 | server1 | user1 | database1 | 127.0.0.1:51294 | http basic | truncate collection 'collection1' | ok | /_api/collection/collection1/truncate
2016-10-05 17:36:08 | server1 | audit-collection | user1 | database1 | 127.0.0.1:51294 | http basic | truncate collection 'collection1' | ok | /_api/collection/collection1/truncate
```
### Drop a collection
```
2016-10-05 17:36:30 | server1 | user1 | database1 | 127.0.0.1:51294 | http basic | delete collection 'collection1' | ok | /_api/collection/collection1
2016-10-05 17:36:30 | server1 | audit-collection | user1 | database1 | 127.0.0.1:51294 | http basic | delete collection 'collection1' | ok | /_api/collection/collection1
```
Indexes
@ -102,13 +105,13 @@ Indexes
### Create a index
```
2016-10-05 18:19:40 | server1 | user1 | database1 | 127.0.0.1:52467 | http basic | create index in 'collection1' | ok | {"fields":["a"],"sparse":false,"type":"skiplist","unique":false} | /_api/index?collection=collection1
2016-10-05 18:19:40 | server1 | audit-collection | user1 | database1 | 127.0.0.1:52467 | http basic | create index in 'collection1' | ok | {"fields":["a"],"sparse":false,"type":"skiplist","unique":false} | /_api/index?collection=collection1
```
### Drop a index
```
2016-10-05 18:18:28 | server1 | user1 | database1 | 127.0.0.1:52464 | http basic | drop index ':44051' | ok | /_api/index/collection1/44051
2016-10-05 18:18:28 | server1 | audit-collection | user1 | database1 | 127.0.0.1:52464 | http basic | drop index 'collection1/44051' | ok | /_api/index/collection1/44051
```
Documents
@ -117,36 +120,42 @@ Documents
### Reading a single document
```
2016-10-04 12:27:55 | server1 | user1 | database1 | 127.0.0.1:53699 | http basic | create document ok | /_api/document/collection1
2016-10-04 12:27:55 | server1 | audit-document | user1 | database1 | 127.0.0.1:53699 | http basic | read document in 'collection1' | ok | /_api/document/collection1
```
### Creating a single document
```
2016-10-04 12:27:55 | server1 | audit-document | user1 | database1 | 127.0.0.1:53699 | http basic | create document in 'collection1' | ok | /_api/document/collection1
```
### Replacing a single document
```
2016-10-04 12:28:08 | server1 | user1 | database1 | 127.0.0.1:53699 | http basic | replace document ok | /_api/document/collection1/21456?ignoreRevs=false
2016-10-04 12:28:08 | server1 | audit-document | user1 | database1 | 127.0.0.1:53699 | http basic | replace document 'collection1/21456' | ok | /_api/document/collection1/21456?ignoreRevs=false
```
### Modifying a single document
```
2016-10-04 12:28:15 | server1 | user1 | database1 | 127.0.0.1:53699 | http basic | modify document ok | /_api/document/collection1/21456?keepNull=true&ignoreRevs=false
2016-10-04 12:28:15 | server1 | audit-document | user1 | database1 | 127.0.0.1:53699 | http basic | modify document 'collection1/21456' | ok | /_api/document/collection1/21456?keepNull=true&ignoreRevs=false
```
### Deleting a single document
```
2016-10-04 12:28:23 | server1 | user1 | database1 | 127.0.0.1:53699 | http basic | delete document ok | /_api/document/collection1/21456?ignoreRevs=false
2016-10-04 12:28:23 | server1 | audit-document | user1 | database1 | 127.0.0.1:53699 | http basic | delete document 'collection1/21456' | ok | /_api/document/collection1/21456?ignoreRevs=false
```
For example, if someones tries to delete a non-existing document, it will be logged as
```
2016-10-04 12:28:26 | server1 | user1 | database1 | 127.0.0.1:53699 | http basic | delete document failed | /_api/document/collection1/21456?ignoreRevs=false
2016-10-04 12:28:26 | server1 | audit-document | user1 | database1 | 127.0.0.1:53699 | http basic | delete document 'collection/21456' | failed | /_api/document/collection1/21456?ignoreRevs=false
```
Queries
-------
```
2016-10-06 12:12:10 | server1 | user1 | database1 | 127.0.0.1:54232 | http basic | query document | ok | for i in collection1 return i | /_api/cursor
2016-10-06 12:12:10 | server1 | audit-document | user1 | database1 | 127.0.0.1:54232 | http basic | query document | ok | for i in collection1 return i | /_api/cursor
```

View File

@ -231,7 +231,7 @@ One of the possible log levels.
@RESTBODYPARAM{audit-view,string,optional,string}
One of the possible log levels.
@RESTBODYPARAM{audit-documentation,string,optional,string}
@RESTBODYPARAM{audit-document,string,optional,string}
One of the possible log levels.
@RESTBODYPARAM{audit-service,string,optional,string}
@ -252,4 +252,3 @@ is returned when an invalid HTTP method is used.
is returned if the server cannot generate the result due to an out-of-memory
error.
@endDocuBlock

View File

@ -1550,6 +1550,7 @@ Result ClusterInfo::createCollectionCoordinator( // create collection
StaticStrings::Empty);
if (name.empty() || !json.isObject() || !json.get("shards").isObject()) {
events::CreateCollection(databaseName, name, TRI_ERROR_BAD_PARAMETER);
return Result(TRI_ERROR_BAD_PARAMETER); // must not be empty
}
@ -1566,8 +1567,7 @@ Result ClusterInfo::createCollectionCoordinator( // create collection
if (it2 != (*it).second.end()) {
// collection already exists!
events::CreateCollection(name, TRI_ERROR_ARANGO_DUPLICATE_NAME);
events::CreateCollection(databaseName, name, TRI_ERROR_ARANGO_DUPLICATE_NAME);
return Result(TRI_ERROR_ARANGO_DUPLICATE_NAME);
}
}
@ -1580,8 +1580,7 @@ Result ClusterInfo::createCollectionCoordinator( // create collection
if (it2 != (*it).second.end()) {
// view already exists!
events::CreateView(name, TRI_ERROR_ARANGO_DUPLICATE_NAME);
events::CreateCollection(databaseName, name, TRI_ERROR_ARANGO_DUPLICATE_NAME);
return Result(TRI_ERROR_ARANGO_DUPLICATE_NAME);
}
}
@ -1592,14 +1591,12 @@ Result ClusterInfo::createCollectionCoordinator( // create collection
// mop: why do these ask the agency instead of checking cluster info?
if (!ac.exists("Plan/Databases/" + databaseName)) {
events::CreateCollection(name, TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
events::CreateCollection(databaseName, name, TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
return Result(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
}
if (ac.exists("Plan/Collections/" + databaseName + "/" + collectionID)) {
events::CreateCollection(name, TRI_ERROR_CLUSTER_COLLECTION_ID_EXISTS);
events::CreateCollection(databaseName, name, TRI_ERROR_CLUSTER_COLLECTION_ID_EXISTS);
return Result(TRI_ERROR_CLUSTER_COLLECTION_ID_EXISTS);
}
@ -1723,7 +1720,8 @@ Result ClusterInfo::createCollectionCoordinator( // create collection
<< "Timeout in _create collection"
<< ": database: " << databaseName << ", collId:" << collectionID
<< "\njson: " << json.toString() << "\ncould not send transaction to agency.";
events::CreateCollection(databaseName, name,
TRI_ERROR_CLUSTER_COULD_NOT_CREATE_COLLECTION_IN_PLAN);
return Result(TRI_ERROR_CLUSTER_COULD_NOT_CREATE_COLLECTION_IN_PLAN);
}
std::vector<AgencyOperation> opers(
@ -1769,6 +1767,8 @@ Result ClusterInfo::createCollectionCoordinator( // create collection
if (!tres.hasKey(std::vector<std::string>(
{AgencyCommManager::path(), "Supervision"}))) {
events::CreateCollection(databaseName, name,
TRI_ERROR_CLUSTER_COULD_NOT_CREATE_COLLECTION_IN_PLAN);
return Result(TRI_ERROR_CLUSTER_COULD_NOT_CREATE_COLLECTION_IN_PLAN);
}
@ -1783,6 +1783,8 @@ Result ClusterInfo::createCollectionCoordinator( // create collection
errorMsg += s.value.copyString();
}
events::CreateCollection(databaseName, name,
TRI_ERROR_CLUSTER_COULD_NOT_CREATE_COLLECTION_IN_PLAN);
return Result( // result
TRI_ERROR_CLUSTER_COULD_NOT_CREATE_COLLECTION_IN_PLAN, // code
errorMsg // message
@ -1807,8 +1809,8 @@ Result ClusterInfo::createCollectionCoordinator( // create collection
continue;
}
events::CreateCollection(name, TRI_ERROR_CLUSTER_COULD_NOT_CREATE_COLLECTION_IN_PLAN);
events::CreateCollection(databaseName, name,
TRI_ERROR_CLUSTER_COULD_NOT_CREATE_COLLECTION_IN_PLAN);
return Result(TRI_ERROR_CLUSTER_COULD_NOT_CREATE_COLLECTION_IN_PLAN, // code
std::string("file: ") + __FILE__ + " line: " + std::to_string(__LINE__) +
" HTTP code: " + std::to_string(res.httpCode()) +
@ -1833,7 +1835,7 @@ Result ClusterInfo::createCollectionCoordinator( // create collection
if (numberOfShards == 0 || isSmart) {
loadCurrent();
events::CreateCollection(name, TRI_ERROR_NO_ERROR);
events::CreateCollection(databaseName, name, TRI_ERROR_NO_ERROR);
return Result(TRI_ERROR_NO_ERROR);
}
@ -1846,7 +1848,7 @@ Result ClusterInfo::createCollectionCoordinator( // create collection
CONDITION_LOCKER(locker, agencyCallback->_cv);
cbGuard.fire(); // unregister cb before accessing errMsg
loadCurrent();
events::CreateCollection(name, *dbServerResult);
events::CreateCollection(databaseName, name, *dbServerResult);
return Result(tmpRes, *errMsg);
}
@ -1877,14 +1879,12 @@ Result ClusterInfo::createCollectionCoordinator( // create collection
// This is a best effort, in the worst case the collection stays:
ac.sendTransactionWithFailover(transaction);
events::CreateCollection(name, TRI_ERROR_CLUSTER_TIMEOUT);
events::CreateCollection(databaseName, name, TRI_ERROR_CLUSTER_TIMEOUT);
return Result(TRI_ERROR_CLUSTER_TIMEOUT);
}
if (application_features::ApplicationServer::isStopping()) {
events::CreateCollection(name, TRI_ERROR_SHUTTING_DOWN);
events::CreateCollection(databaseName, name, TRI_ERROR_SHUTTING_DOWN);
return Result(TRI_ERROR_SHUTTING_DOWN);
}
@ -1894,6 +1894,7 @@ Result ClusterInfo::createCollectionCoordinator( // create collection
}
if (!application_features::ApplicationServer::isRetryOK()) {
events::CreateCollection(databaseName, name, TRI_ERROR_CLUSTER_TIMEOUT);
return Result(TRI_ERROR_CLUSTER_TIMEOUT);
}
}
@ -1911,6 +1912,7 @@ Result ClusterInfo::dropCollectionCoordinator( // drop collection
double timeout // request timeout
) {
if (dbName.empty() || (dbName[0] > '0' && dbName[0] < '9')) {
events::DropCollection(dbName, collectionID, TRI_ERROR_ARANGO_DATABASE_NAME_INVALID);
return Result(TRI_ERROR_ARANGO_DATABASE_NAME_INVALID);
}
@ -1939,6 +1941,8 @@ Result ClusterInfo::dropCollectionCoordinator( // drop collection
errorMsg += ".";
events::DropCollection(dbName, collectionID,
TRI_ERROR_CLUSTER_MUST_NOT_DROP_COLL_OTHER_DISTRIBUTESHARDSLIKE);
return Result( // result
TRI_ERROR_CLUSTER_MUST_NOT_DROP_COLL_OTHER_DISTRIBUTESHARDSLIKE, // code
errorMsg // message
@ -1985,6 +1989,7 @@ Result ClusterInfo::dropCollectionCoordinator( // drop collection
LOG_TOPIC("d340d", ERR, Logger::CLUSTER)
<< "Missing shards information on dropping " << dbName << "/" << collectionID;
events::DropCollection(dbName, collectionID, TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
return Result(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
}
}
@ -2014,6 +2019,7 @@ Result ClusterInfo::dropCollectionCoordinator( // drop collection
LOG_TOPIC("f1bfb", ERR, Logger::CLUSTER) << "Could not get agency dump!";
}
events::DropCollection(dbName, collectionID, TRI_ERROR_CLUSTER_COULD_NOT_DROP_COLLECTION);
return Result(TRI_ERROR_CLUSTER_COULD_NOT_DROP_COLLECTION);
}
@ -2022,8 +2028,8 @@ Result ClusterInfo::dropCollectionCoordinator( // drop collection
if (numberOfShards == 0) {
loadCurrent();
events::DropCollection(collectionID, TRI_ERROR_NO_ERROR);
events::DropCollection(dbName, collectionID, TRI_ERROR_NO_ERROR);
return Result(TRI_ERROR_NO_ERROR);
}
@ -2036,8 +2042,8 @@ Result ClusterInfo::dropCollectionCoordinator( // drop collection
// ...remove the entire directory for the collection
ac.removeValues("Current/Collections/" + dbName + "/" + collectionID, true);
loadCurrent();
events::DropCollection(collectionID, *dbServerResult);
events::DropCollection(dbName, collectionID, *dbServerResult);
return Result(*dbServerResult);
}
@ -2055,14 +2061,14 @@ Result ClusterInfo::dropCollectionCoordinator( // drop collection
LOG_TOPIC("37297", ERR, Logger::CLUSTER) << "Could not get agency dump!";
}
events::DropCollection(collectionID, TRI_ERROR_CLUSTER_TIMEOUT);
events::DropCollection(dbName, collectionID, TRI_ERROR_CLUSTER_TIMEOUT);
return Result(TRI_ERROR_CLUSTER_TIMEOUT);
}
agencyCallback->executeByCallbackOrTimeout(interval);
if (!application_features::ApplicationServer::isRetryOK()) {
events::DropCollection(dbName, collectionID, TRI_ERROR_CLUSTER_TIMEOUT);
return Result(TRI_ERROR_CLUSTER_TIMEOUT);
}
}
@ -2136,6 +2142,12 @@ Result ClusterInfo::createViewCoordinator( // create view
auto const typeSlice = json.get(arangodb::StaticStrings::DataSourceType);
if (!typeSlice.isString()) {
std::string name;
if (json.isObject()) {
name = basics::VelocyPackHelper::getStringValue(json, StaticStrings::DataSourceName,
"");
}
events::CreateView(databaseName, name, TRI_ERROR_BAD_PARAMETER);
return Result(TRI_ERROR_BAD_PARAMETER);
}
@ -2144,6 +2156,7 @@ Result ClusterInfo::createViewCoordinator( // create view
StaticStrings::Empty);
if (name.empty()) {
events::CreateView(databaseName, name, TRI_ERROR_BAD_PARAMETER);
return Result(TRI_ERROR_BAD_PARAMETER); // must not be empty
}
@ -2158,8 +2171,7 @@ Result ClusterInfo::createViewCoordinator( // create view
if (it2 != (*it).second.end()) {
// view already exists!
events::CreateView(name, TRI_ERROR_ARANGO_DUPLICATE_NAME);
events::CreateView(databaseName, name, TRI_ERROR_ARANGO_DUPLICATE_NAME);
return Result(TRI_ERROR_ARANGO_DUPLICATE_NAME);
}
}
@ -2172,8 +2184,7 @@ Result ClusterInfo::createViewCoordinator( // create view
if (it2 != (*it).second.end()) {
// collection already exists!
events::CreateCollection(name, TRI_ERROR_ARANGO_DUPLICATE_NAME);
events::CreateCollection(databaseName, name, TRI_ERROR_ARANGO_DUPLICATE_NAME);
return Result(TRI_ERROR_ARANGO_DUPLICATE_NAME);
}
}
@ -2184,14 +2195,12 @@ Result ClusterInfo::createViewCoordinator( // create view
// mop: why do these ask the agency instead of checking cluster info?
if (!ac.exists("Plan/Databases/" + databaseName)) {
events::CreateView(name, TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
events::CreateView(databaseName, name, TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
return Result(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
}
if (ac.exists("Plan/Views/" + databaseName + "/" + viewID)) {
events::CreateView(name, TRI_ERROR_CLUSTER_VIEW_ID_EXISTS);
events::CreateView(databaseName, name, TRI_ERROR_CLUSTER_VIEW_ID_EXISTS);
return Result(TRI_ERROR_CLUSTER_VIEW_ID_EXISTS);
}
@ -2217,14 +2226,14 @@ Result ClusterInfo::createViewCoordinator( // create view
LOG_TOPIC("69f86", ERR, Logger::CLUSTER) << "Could not get agency dump!";
}
events::CreateView(databaseName, name, TRI_ERROR_CLUSTER_COULD_NOT_CREATE_VIEW_IN_PLAN);
return Result( // result
TRI_ERROR_CLUSTER_COULD_NOT_CREATE_VIEW_IN_PLAN, // code
std::string("Precondition that view ") + name + " with ID " + viewID +
" does not yet exist failed. Cannot create view.");
}
events::CreateView(name, TRI_ERROR_CLUSTER_COULD_NOT_CREATE_VIEW_IN_PLAN);
events::CreateView(databaseName, name, TRI_ERROR_CLUSTER_COULD_NOT_CREATE_VIEW_IN_PLAN);
return Result( // result
TRI_ERROR_CLUSTER_COULD_NOT_CREATE_VIEW_IN_PLAN, // code
std::string("file: ") + __FILE__ + " line: " + std::to_string(__LINE__) +
@ -2236,6 +2245,7 @@ Result ClusterInfo::createViewCoordinator( // create view
// Update our cache:
loadPlan();
events::CreateView(databaseName, name, TRI_ERROR_NO_ERROR);
return Result(TRI_ERROR_NO_ERROR);
}
@ -2290,7 +2300,7 @@ Result ClusterInfo::dropViewCoordinator( // drop view
}
}
events::DropView(viewID, result.errorNumber());
events::DropView(databaseName, viewID, result.errorNumber());
return result;
}
@ -2861,7 +2871,7 @@ Result ClusterInfo::dropIndexCoordinator( // drop index
AgencyCommResult previous = ac.getValues(planCollKey);
if (!previous.successful()) {
events::DropIndex(collectionID, idString, TRI_ERROR_CLUSTER_READING_PLAN_AGENCY);
events::DropIndex(databaseName, collectionID, idString, TRI_ERROR_CLUSTER_READING_PLAN_AGENCY);
return Result(TRI_ERROR_CLUSTER_READING_PLAN_AGENCY);
}
@ -2869,7 +2879,8 @@ Result ClusterInfo::dropIndexCoordinator( // drop index
velocypack::Slice collection = previous.slice()[0].get(std::vector<std::string>(
{AgencyCommManager::path(), "Plan", "Collections", databaseName, collectionID}));
if (!collection.isObject()) {
events::DropIndex(collectionID, idString, TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND);
events::DropIndex(databaseName, collectionID, idString,
TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND);
return Result(TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND);
}
@ -2883,6 +2894,7 @@ Result ClusterInfo::dropIndexCoordinator( // drop index
if (!indexes.isArray()) {
LOG_TOPIC("63178", DEBUG, Logger::CLUSTER) << "Failed to find index " << databaseName
<< "/" << collectionID << "/" << iid;
events::DropIndex(databaseName, collectionID, idString, TRI_ERROR_ARANGO_INDEX_NOT_FOUND);
return Result(TRI_ERROR_ARANGO_INDEX_NOT_FOUND);
}
@ -2900,6 +2912,7 @@ Result ClusterInfo::dropIndexCoordinator( // drop index
Index::IndexType type = Index::type(typeSlice.copyString());
if (type == Index::TRI_IDX_TYPE_PRIMARY_INDEX || type == Index::TRI_IDX_TYPE_EDGE_INDEX) {
events::DropIndex(databaseName, collectionID, idString, TRI_ERROR_FORBIDDEN);
return Result(TRI_ERROR_FORBIDDEN);
}
@ -2912,6 +2925,7 @@ Result ClusterInfo::dropIndexCoordinator( // drop index
if (!indexToRemove.isObject()) {
LOG_TOPIC("95fe6", DEBUG, Logger::CLUSTER) << "Failed to find index " << databaseName
<< "/" << collectionID << "/" << iid;
events::DropIndex(databaseName, collectionID, idString, TRI_ERROR_ARANGO_INDEX_NOT_FOUND);
return Result(TRI_ERROR_ARANGO_INDEX_NOT_FOUND);
}
@ -2978,7 +2992,8 @@ Result ClusterInfo::dropIndexCoordinator( // drop index
AgencyCommResult result = ac.sendTransactionWithFailover(trx, 0.0);
if (!result.successful()) {
events::DropIndex(collectionID, idString, TRI_ERROR_CLUSTER_COULD_NOT_DROP_INDEX_IN_PLAN);
events::DropIndex(databaseName, collectionID, idString,
TRI_ERROR_CLUSTER_COULD_NOT_DROP_INDEX_IN_PLAN);
return Result( // result
TRI_ERROR_CLUSTER_COULD_NOT_DROP_INDEX_IN_PLAN, // code
@ -3002,13 +3017,13 @@ Result ClusterInfo::dropIndexCoordinator( // drop index
if (*dbServerResult >= 0) {
cbGuard.fire(); // unregister cb
loadCurrent();
events::DropIndex(collectionID, idString, *dbServerResult);
events::DropIndex(databaseName, collectionID, idString, *dbServerResult);
return Result(*dbServerResult);
}
if (TRI_microtime() > endTime) {
events::DropIndex(collectionID, idString, TRI_ERROR_CLUSTER_TIMEOUT);
events::DropIndex(databaseName, collectionID, idString, TRI_ERROR_CLUSTER_TIMEOUT);
return Result(TRI_ERROR_CLUSTER_TIMEOUT);
}

View File

@ -387,14 +387,16 @@ bool ClusterCollection::dropIndex(TRI_idx_iid_t iid) {
for (std::shared_ptr<Index> index : _indexes) {
if (iid == index->id()) {
_indexes.erase(_indexes.begin() + i);
events::DropIndex("", std::to_string(iid), TRI_ERROR_NO_ERROR);
events::DropIndex(_logicalCollection.vocbase().name(), _logicalCollection.name(),
std::to_string(iid), TRI_ERROR_NO_ERROR);
return true;
}
++i;
}
// We tried to remove an index that does not exist
events::DropIndex("", std::to_string(iid), TRI_ERROR_ARANGO_INDEX_NOT_FOUND);
events::DropIndex(_logicalCollection.vocbase().name(), _logicalCollection.name(),
std::to_string(iid), TRI_ERROR_ARANGO_INDEX_NOT_FOUND);
return false;
}

View File

@ -526,7 +526,7 @@ rest::ResponseCode GeneralCommTask::canAccessPath(GeneralRequest& req) const {
VocbaseContext* vc = static_cast<VocbaseContext*>(req.requestContext());
TRI_ASSERT(vc != nullptr);
if (vc->databaseAuthLevel() == auth::Level::NONE && !StringUtils::isPrefix(path, ApiUser)) {
events::NotAuthorized(&req);
events::NotAuthorized(req);
result = rest::ResponseCode::UNAUTHORIZED;
LOG_TOPIC("0898a", TRACE, Logger::AUTHORIZATION) << "Access forbidden to " << path;

View File

@ -765,7 +765,7 @@ ResponseCode HttpCommTask::handleAuthHeader(HttpRequest* req) {
std::string const& authStr = req->header(StaticStrings::Authorization, found);
if (!found) {
if (_auth->isActive()) {
events::CredentialsMissing(req);
events::CredentialsMissing(*req);
return rest::ResponseCode::UNAUTHORIZED;
}
return rest::ResponseCode::OK;
@ -801,10 +801,10 @@ ResponseCode HttpCommTask::handleAuthHeader(HttpRequest* req) {
}
if (req->authenticated() || !_auth->isActive()) {
events::Authenticated(req, authMethod);
events::Authenticated(*req, authMethod);
return rest::ResponseCode::OK;
} else if (_auth->isActive()) {
events::CredentialsBad(req, authMethod);
events::CredentialsBad(*req, authMethod);
return rest::ResponseCode::UNAUTHORIZED;
}
@ -820,6 +820,6 @@ ResponseCode HttpCommTask::handleAuthHeader(HttpRequest* req) {
}
}
events::UnknownAuthenticationMethod(req);
events::UnknownAuthenticationMethod(*req);
return rest::ResponseCode::UNAUTHORIZED;
}

View File

@ -53,8 +53,8 @@ RestHandler::RestHandler(GeneralRequest* request, GeneralResponse* response)
_request(request),
_response(response),
_statistics(nullptr),
_handlerId(0),
_state(HandlerState::PREPARE) {}
_state(HandlerState::PREPARE),
_handlerId(0) {}
RestHandler::~RestHandler() {
RequestStatistics* stat = _statistics.exchange(nullptr);

View File

@ -138,16 +138,6 @@ class RestHandler : public std::enable_shared_from_this<RestHandler> {
void generateError(arangodb::Result const&);
private:
enum class HandlerState {
PREPARE,
EXECUTE,
PAUSED,
CONTINUED,
FINALIZE,
DONE,
FAILED
};
void runHandlerStateMachine();
void prepareEngine();
@ -159,17 +149,27 @@ class RestHandler : public std::enable_shared_from_this<RestHandler> {
void shutdownEngine();
protected:
enum class HandlerState {
PREPARE,
EXECUTE,
PAUSED,
CONTINUED,
FINALIZE,
DONE,
FAILED
};
std::atomic<bool> _canceled;
std::unique_ptr<GeneralRequest> _request;
std::unique_ptr<GeneralResponse> _response;
std::atomic<RequestStatistics*> _statistics;
HandlerState _state;
private:
uint64_t _handlerId;
HandlerState _state;
std::function<void(rest::RestHandler*)> _callback;
mutable Mutex _executionMutex;

View File

@ -31,6 +31,7 @@
#include "Aql/PlanCache.h"
#include "Aql/QueryCache.h"
#include "Basics/StaticStrings.h"
#include "Basics/VelocyPackHelper.h"
#include "RestServer/DatabaseFeature.h"
#include "RestServer/ViewTypesFeature.h"
#include "StorageEngine/EngineSelectorFeature.h"
@ -39,6 +40,7 @@
#include "StorageEngine/TransactionState.h"
#include "Transaction/Methods.h"
#include "Transaction/StandaloneContext.h"
#include "Utils/Events.h"
#include "Utils/ExecContext.h"
#include "VocBase/LogicalCollection.h"
@ -146,6 +148,12 @@ struct IResearchView::ViewFactory : public arangodb::ViewFactory {
: IResearchLinkHelper::validateLinks(vocbase, links);
if (!res.ok()) {
std::string name;
if (definition.isObject()) {
name = arangodb::basics::VelocyPackHelper::getStringValue(
definition, arangodb::StaticStrings::DataSourceName, "");
}
events::CreateView(vocbase.name(), name, res.errorNumber());
return res;
}
@ -156,10 +164,22 @@ struct IResearchView::ViewFactory : public arangodb::ViewFactory {
: arangodb::LogicalViewHelperClusterInfo::construct(impl, vocbase, definition);
if (!res.ok()) {
std::string name;
if (definition.isObject()) {
name = arangodb::basics::VelocyPackHelper::getStringValue(
definition, arangodb::StaticStrings::DataSourceName, "");
}
events::CreateView(vocbase.name(), name, res.errorNumber());
return res;
}
if (!impl) {
std::string name;
if (definition.isObject()) {
name = arangodb::basics::VelocyPackHelper::getStringValue(
definition, arangodb::StaticStrings::DataSourceName, "");
}
events::CreateView(vocbase.name(), name, TRI_ERROR_INTERNAL);
return arangodb::Result(TRI_ERROR_INTERNAL,
std::string(
"failure during instantiation while creating "
@ -167,7 +187,7 @@ struct IResearchView::ViewFactory : public arangodb::ViewFactory {
vocbase.name() + "'");
}
// create links on a best-effor basis
// create links on a best-effort basis
// link creation failure does not cause view creation failure
try {
std::unordered_set<TRI_voc_cid_t> collections;
@ -180,14 +200,34 @@ struct IResearchView::ViewFactory : public arangodb::ViewFactory {
}
} catch (arangodb::basics::Exception const& e) {
IR_LOG_EXCEPTION();
std::string name;
if (definition.isObject()) {
name = arangodb::basics::VelocyPackHelper::getStringValue(
definition, arangodb::StaticStrings::DataSourceName, "");
}
events::CreateView(vocbase.name(), name, e.code());
LOG_TOPIC("eddb2", WARN, arangodb::iresearch::TOPIC)
<< "caught exception while creating links while creating arangosearch view '" << impl->name() << "': " << e.code() << " " << e.what();
<< "caught exception while creating links while creating "
"arangosearch view '"
<< impl->name() << "': " << e.code() << " " << e.what();
} catch (std::exception const& e) {
IR_LOG_EXCEPTION();
std::string name;
if (definition.isObject()) {
name = arangodb::basics::VelocyPackHelper::getStringValue(
definition, arangodb::StaticStrings::DataSourceName, "");
}
events::CreateView(vocbase.name(), name, TRI_ERROR_INTERNAL);
LOG_TOPIC("dc829", WARN, arangodb::iresearch::TOPIC)
<< "caught exception while creating links while creating arangosearch view '" << impl->name() << "': " << e.what();
} catch (...) {
IR_LOG_EXCEPTION();
std::string name;
if (definition.isObject()) {
name = arangodb::basics::VelocyPackHelper::getStringValue(
definition, arangodb::StaticStrings::DataSourceName, "");
}
events::CreateView(vocbase.name(), name, TRI_ERROR_INTERNAL);
LOG_TOPIC("6491c", WARN, arangodb::iresearch::TOPIC)
<< "caught exception while creating links while creating arangosearch view '" << impl->name() << "'";
}

View File

@ -2263,7 +2263,7 @@ std::shared_ptr<Index> MMFilesCollection::createIndex(transaction::Methods& trx,
}
#if USE_PLAN_CACHE
arangodb::aql::PlanCache::instance()->invalidate(_logicalCollection->vocbase());
arangodb::aql::PlanCache::instance()->invalidate(_logicalCollection.vocbase());
#endif
// Until here no harm is done if sth fails. The shared ptr will clean up. if
// left before
@ -2386,7 +2386,8 @@ void MMFilesCollection::addIndexLocal(std::shared_ptr<arangodb::Index> idx) {
bool MMFilesCollection::dropIndex(TRI_idx_iid_t iid) {
if (iid == 0) {
// invalid index id or primary index
events::DropIndex("", std::to_string(iid), TRI_ERROR_NO_ERROR);
events::DropIndex(_logicalCollection.vocbase().name(), _logicalCollection.name(),
std::to_string(iid), TRI_ERROR_NO_ERROR);
return true;
}
@ -2394,7 +2395,8 @@ bool MMFilesCollection::dropIndex(TRI_idx_iid_t iid) {
if (!removeIndex(iid)) {
// We tried to remove an index that does not exist
events::DropIndex("", std::to_string(iid), TRI_ERROR_ARANGO_INDEX_NOT_FOUND);
events::DropIndex(_logicalCollection.vocbase().name(), _logicalCollection.name(),
std::to_string(iid), TRI_ERROR_ARANGO_INDEX_NOT_FOUND);
return false;
}
@ -2421,11 +2423,13 @@ bool MMFilesCollection::dropIndex(TRI_idx_iid_t iid) {
engine->dropIndexWalMarker(&vocbase, cid, markerBuilder.slice(), true, res);
if (res == TRI_ERROR_NO_ERROR) {
events::DropIndex("", std::to_string(iid), TRI_ERROR_NO_ERROR);
events::DropIndex(_logicalCollection.vocbase().name(), _logicalCollection.name(),
std::to_string(iid), TRI_ERROR_NO_ERROR);
} else {
LOG_TOPIC("96677", WARN, arangodb::Logger::ENGINES)
<< "could not save index drop marker in log: " << TRI_errno_string(res);
events::DropIndex("", std::to_string(iid), res);
events::DropIndex(_logicalCollection.vocbase().name(),
_logicalCollection.name(), std::to_string(iid), res);
}
}
return true;

View File

@ -31,6 +31,7 @@
#include "Logger/Logger.h"
#include "Rest/HttpRequest.h"
#include "Ssl/SslInterface.h"
#include "Utils/Events.h"
using namespace arangodb;
using namespace arangodb::basics;
@ -111,3 +112,15 @@ RestStatus RestAuthHandler::badRequest() {
"invalid JSON");
return RestStatus::DONE;
}
void RestAuthHandler::shutdownExecute(bool isFinalized) noexcept {
try {
if (_isValid) {
events::LoggedIn(*_request, _username);
} else {
events::CredentialsBad(*_request, _username);
}
} catch (...) {
}
RestVocbaseBaseHandler::shutdownExecute(isFinalized);
}

View File

@ -40,10 +40,7 @@ class RestAuthHandler : public RestVocbaseBaseHandler {
char const* name() const override final { return "RestAuthHandler"; }
RequestLane lane() const override final { return RequestLane::CLIENT_SLOW; }
RestStatus execute() override;
#ifdef USE_ENTERPRISE
void shutdownExecute(bool isFinalized) noexcept override;
#endif
private:
RestStatus badRequest();

View File

@ -33,6 +33,7 @@
#include "StorageEngine/StorageEngine.h"
#include "Transaction/Methods.h"
#include "Transaction/StandaloneContext.h"
#include "Utils/Events.h"
#include "Utils/OperationOptions.h"
#include "Utils/SingleCollectionTransaction.h"
#include "VocBase/LogicalCollection.h"
@ -267,6 +268,7 @@ void RestCollectionHandler::handleCommandPost() {
VPackSlice const body = this->parseVPackBody(parseSuccess);
if (!parseSuccess) {
// error message generated in parseVPackBody
events::CreateCollection(_vocbase.name(), "", TRI_ERROR_BAD_PARAMETER);
return;
}
@ -274,6 +276,7 @@ void RestCollectionHandler::handleCommandPost() {
if (!body.isObject() || !(nameSlice = body.get("name")).isString() ||
nameSlice.getStringLength() == 0) {
generateError(rest::ResponseCode::BAD, TRI_ERROR_ARANGO_ILLEGAL_NAME);
events::CreateCollection(_vocbase.name(), "", TRI_ERROR_ARANGO_ILLEGAL_NAME);
return;
}
@ -505,6 +508,7 @@ void RestCollectionHandler::handleCommandDelete() {
if (suffixes.size() != 1) {
generateError(rest::ResponseCode::BAD, TRI_ERROR_HTTP_BAD_PARAMETER,
"expected DELETE /_api/collection/<collection-name>");
events::DropCollection(_vocbase.name(), "", TRI_ERROR_HTTP_BAD_PARAMETER);
return;
}
@ -526,6 +530,7 @@ void RestCollectionHandler::handleCommandDelete() {
});
if (found.fail()) {
events::DropCollection(_vocbase.name(), name, found.errorNumber());
generateError(found);
} else if (res.fail()) {
generateError(res);

View File

@ -21,6 +21,7 @@
/// @author Jan Steemann
////////////////////////////////////////////////////////////////////////////////
#include "RestCursorHandler.h"
#include "Aql/Query.h"
#include "Aql/QueryRegistry.h"
#include "Basics/Exceptions.h"
@ -28,10 +29,10 @@
#include "Basics/StaticStrings.h"
#include "Basics/VelocyPackHelper.h"
#include "Cluster/ServerState.h"
#include "RestCursorHandler.h"
#include "Transaction/Context.h"
#include "Utils/Cursor.h"
#include "Utils/CursorRepository.h"
#include "Utils/Events.h"
#include <velocypack/Iterator.h>
#include <velocypack/Value.h>
@ -50,7 +51,8 @@ RestCursorHandler::RestCursorHandler(GeneralRequest* request, GeneralResponse* r
_leasedCursor(nullptr),
_hasStarted(false),
_queryKilled(false),
_isValidForFinalize(false) {}
_isValidForFinalize(false),
_auditLogged(false) {}
RestCursorHandler::~RestCursorHandler() {
if (_leasedCursor) {
@ -102,11 +104,57 @@ RestStatus RestCursorHandler::continueExecute() {
return RestStatus::DONE;
}
void RestCursorHandler::shutdownExecute(bool isFinalized) noexcept {
TRI_DEFER(RestVocbaseBaseHandler::shutdownExecute(isFinalized));
auto const type = _request->requestType();
// request not done yet
if (_state == HandlerState::PAUSED) {
return;
}
// only trace create cursor requests
if (type != rest::RequestType::POST) {
return;
}
if (!_isValidForFinalize || _auditLogged) {
// set by RestCursorHandler before
return;
}
try {
bool parseSuccess = true;
std::shared_ptr<VPackBuilder> parsedBody = parseVelocyPackBody(parseSuccess);
VPackSlice body = parsedBody.get()->slice();
events::QueryDocument(*_request, _response.get(), body);
_auditLogged = true;
} catch (...) {
}
}
bool RestCursorHandler::cancel() {
RestVocbaseBaseHandler::cancel();
return cancelQuery();
}
void RestCursorHandler::handleError(basics::Exception const& ex) {
TRI_DEFER(RestVocbaseBaseHandler::handleError(ex));
if (!_isValidForFinalize || _auditLogged) {
return;
}
try {
bool parseSuccess = true;
std::shared_ptr<VPackBuilder> parsedBody = parseVelocyPackBody(parseSuccess);
VPackSlice body = parsedBody.get()->slice();
events::QueryDocument(*_request, _response.get(), body);
_auditLogged = true;
} catch (...) {
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief register the query either as streaming cursor or in _query
/// the query is not executed here.

View File

@ -64,12 +64,10 @@ class RestCursorHandler : public RestVocbaseBaseHandler {
RequestLane lane() const override final { return RequestLane::CLIENT_AQL; }
virtual RestStatus continueExecute() override;
#ifdef USE_ENTERPRISE
void shutdownExecute(bool isFinalized) noexcept override;
#endif
bool cancel() override final;
void handleError(basics::Exception const&) override;
protected:
//////////////////////////////////////////////////////////////////////////////
@ -208,6 +206,9 @@ class RestCursorHandler : public RestVocbaseBaseHandler {
bool _isValidForFinalize;
/// @brief whether or not an audit message has already been logged
bool _auditLogged;
//////////////////////////////////////////////////////////////////////////////
/// @brief A shared pointer to the query options velocypack, s.t. we avoid
/// to reparse and set default options

View File

@ -24,6 +24,7 @@
#include "ApplicationFeatures/ApplicationServer.h"
#include "Rest/HttpRequest.h"
#include "Utils/Events.h"
#include "VocBase/Methods/Databases.h"
#include <velocypack/Builder.h>
@ -107,7 +108,7 @@ RestStatus RestDatabaseHandler::createDatabase() {
if (!_vocbase.isSystem()) {
generateError(GeneralResponse::responseCode(TRI_ERROR_ARANGO_USE_SYSTEM_DATABASE),
TRI_ERROR_ARANGO_USE_SYSTEM_DATABASE);
events::CreateDatabase("", TRI_ERROR_ARANGO_USE_SYSTEM_DATABASE);
return RestStatus::DONE;
}
@ -116,11 +117,13 @@ RestStatus RestDatabaseHandler::createDatabase() {
VPackSlice body = this->parseVPackBody(parseSuccess);
if (!suffixes.empty() || !parseSuccess) {
generateError(rest::ResponseCode::BAD, TRI_ERROR_HTTP_BAD_PARAMETER);
events::CreateDatabase("", TRI_ERROR_BAD_PARAMETER);
return RestStatus::DONE;
}
VPackSlice nameVal = body.get("name");
if (!nameVal.isString()) {
generateError(rest::ResponseCode::BAD, TRI_ERROR_ARANGO_DATABASE_NAME_INVALID);
events::CreateDatabase("", TRI_ERROR_ARANGO_DATABASE_NAME_INVALID);
return RestStatus::DONE;
}
std::string dbName = nameVal.copyString();
@ -149,12 +152,13 @@ RestStatus RestDatabaseHandler::deleteDatabase() {
if (!_vocbase.isSystem()) {
generateError(GeneralResponse::responseCode(TRI_ERROR_ARANGO_USE_SYSTEM_DATABASE),
TRI_ERROR_ARANGO_USE_SYSTEM_DATABASE);
events::DropDatabase("", TRI_ERROR_ARANGO_USE_SYSTEM_DATABASE);
return RestStatus::DONE;
}
std::vector<std::string> const& suffixes = _request->suffixes();
if (suffixes.size() != 1) {
generateError(rest::ResponseCode::BAD, TRI_ERROR_HTTP_BAD_PARAMETER);
events::DropDatabase("", TRI_ERROR_HTTP_BAD_PARAMETER);
return RestStatus::DONE;
}

View File

@ -21,15 +21,16 @@
/// @author Dr. Frank Celler
////////////////////////////////////////////////////////////////////////////////
#include "RestDocumentHandler.h"
#include "Basics/StaticStrings.h"
#include "Basics/StringUtils.h"
#include "Basics/VelocyPackHelper.h"
#include "Cluster/ServerState.h"
#include "Rest/HttpRequest.h"
#include "RestDocumentHandler.h"
#include "Transaction/Helpers.h"
#include "Transaction/Hints.h"
#include "Transaction/StandaloneContext.h"
#include "Utils/Events.h"
#include "Utils/OperationOptions.h"
#include "Utils/SingleCollectionTransaction.h"
#include "VocBase/vocbase.h"
@ -74,6 +75,29 @@ RestStatus RestDocumentHandler::execute() {
return RestStatus::DONE;
}
void RestDocumentHandler::shutdownExecute(bool isFinalized) noexcept {
try {
GeneralRequest const* request = _request.get();
auto const type = request->requestType();
int result = static_cast<int>(_response->responseCode());
switch (type) {
case rest::RequestType::DELETE_REQ:
case rest::RequestType::GET:
case rest::RequestType::HEAD:
case rest::RequestType::POST:
case rest::RequestType::PUT:
case rest::RequestType::PATCH:
break;
default:
events::IllegalDocumentOperation(*request, result);
break;
}
} catch (...) {
}
RestVocbaseBaseHandler::shutdownExecute(isFinalized);
}
/// @brief returns the short id of the server which should handle this request
uint32_t RestDocumentHandler::forwardingTarget() {
if (!ServerState::instance()->isCoordinator()) {

View File

@ -36,10 +36,7 @@ class RestDocumentHandler : public RestVocbaseBaseHandler {
RestStatus execute() override final;
char const* name() const override final { return "RestDocumentHandler"; }
RequestLane lane() const override final { return RequestLane::CLIENT_SLOW; }
#ifdef USE_ENTERPRISE
void shutdownExecute(bool isFinalized) noexcept override;
#endif
protected:
virtual uint32_t forwardingTarget() override;

View File

@ -26,9 +26,10 @@
#include "Cluster/ClusterInfo.h"
#include "Cluster/ServerState.h"
#include "Rest/HttpRequest.h"
#include "Utils/Events.h"
#include "Utils/SingleCollectionTransaction.h"
#include "VocBase/Methods/Indexes.h"
#include "VocBase/LogicalCollection.h"
#include "VocBase/Methods/Indexes.h"
#include <velocypack/Builder.h>
#include <velocypack/Collection.h>
@ -212,6 +213,7 @@ RestStatus RestIndexHandler::createIndex() {
return RestStatus::DONE;
}
if (!suffixes.empty()) {
events::CreateIndex(_vocbase.name(), "(unknown)", body, TRI_ERROR_BAD_PARAMETER);
generateError(rest::ResponseCode::BAD, TRI_ERROR_HTTP_BAD_PARAMETER,
"expecting POST " + _request->requestPath() +
"?collection=<collection-name>");
@ -221,12 +223,15 @@ RestStatus RestIndexHandler::createIndex() {
bool found = false;
std::string cName = _request->value("collection", found);
if (!found) {
events::CreateIndex(_vocbase.name(), "(unknown)", body,
TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND);
generateError(rest::ResponseCode::NOT_FOUND, TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND);
return RestStatus::DONE;
}
auto coll = collection(cName);
if (coll == nullptr) {
events::CreateIndex(_vocbase.name(), cName, body, TRI_ERROR_ARANGO_INDEX_NOT_FOUND);
generateError(rest::ResponseCode::NOT_FOUND, TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND);
return RestStatus::DONE;
}
@ -272,6 +277,7 @@ RestStatus RestIndexHandler::createIndex() {
RestStatus RestIndexHandler::dropIndex() {
std::vector<std::string> const& suffixes = _request->suffixes();
if (suffixes.size() != 2) {
events::DropIndex(_vocbase.name(), "(unknown)", "(unknown)", TRI_ERROR_HTTP_BAD_PARAMETER);
generateError(rest::ResponseCode::BAD, TRI_ERROR_HTTP_BAD_PARAMETER,
"expecting DELETE /<collection-name>/<index-identifier>");
return RestStatus::DONE;
@ -280,6 +286,7 @@ RestStatus RestIndexHandler::dropIndex() {
std::string const& cName = suffixes[0];
auto coll = collection(cName);
if (coll == nullptr) {
events::DropIndex(_vocbase.name(), cName, "(unknown)", TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND);
generateError(rest::ResponseCode::NOT_FOUND, TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND);
return RestStatus::DONE;
}

View File

@ -30,6 +30,7 @@
#include "Rest/GeneralResponse.h"
#include "RestServer/DatabaseFeature.h"
#include "Utils/CollectionNameResolver.h"
#include "Utils/Events.h"
#include "VocBase/LogicalView.h"
#include <velocypack/velocypack-aliases.h>
@ -140,7 +141,7 @@ RestStatus RestViewHandler::execute() {
void RestViewHandler::createView() {
if (_request->payload().isEmptyObject()) {
generateError(rest::ResponseCode::BAD, TRI_ERROR_HTTP_CORRUPTED_JSON);
events::CreateView(_vocbase.name(), "", TRI_ERROR_HTTP_CORRUPTED_JSON);
return;
}
@ -149,7 +150,7 @@ void RestViewHandler::createView() {
if (!suffixes.empty()) {
generateError(rest::ResponseCode::BAD, TRI_ERROR_BAD_PARAMETER,
"expecting POST /_api/view");
events::CreateView(_vocbase.name(), "", TRI_ERROR_BAD_PARAMETER);
return;
}
@ -157,6 +158,7 @@ void RestViewHandler::createView() {
VPackSlice const body = this->parseVPackBody(parseSuccess);
if (!parseSuccess) {
events::CreateView(_vocbase.name(), "", TRI_ERROR_BAD_PARAMETER);
return;
}
@ -168,7 +170,7 @@ void RestViewHandler::createView() {
if (!body.isObject()) {
badParamError();
events::CreateView(_vocbase.name(), "", TRI_ERROR_BAD_PARAMETER);
return;
}
@ -177,7 +179,9 @@ void RestViewHandler::createView() {
if (!nameSlice.isString() || !typeSlice.isString()) {
badParamError();
events::CreateView(_vocbase.name(),
(nameSlice.isString() ? nameSlice.copyString() : ""),
TRI_ERROR_BAD_PARAMETER);
return;
}
@ -188,7 +192,7 @@ void RestViewHandler::createView() {
if (!canUse(auth::Level::RW, _vocbase)) {
generateError(
Result(TRI_ERROR_FORBIDDEN, "insufficient rights to create view"));
events::CreateView(_vocbase.name(), nameSlice.copyString(), TRI_ERROR_FORBIDDEN);
return;
}
@ -198,14 +202,14 @@ void RestViewHandler::createView() {
if (!res.ok()) {
generateError(res);
events::CreateView(_vocbase.name(), nameSlice.copyString(), res.errorNumber());
return;
}
if (!view) {
generateError(
arangodb::Result(TRI_ERROR_INTERNAL, "problem creating view"));
events::CreateView(_vocbase.name(), nameSlice.copyString(), TRI_ERROR_INTERNAL);
return;
}
@ -216,15 +220,16 @@ void RestViewHandler::createView() {
if (!res.ok()) {
generateError(res);
return;
}
builder.close();
generateResult(rest::ResponseCode::CREATED, builder.slice());
} catch (basics::Exception const& ex) {
events::CreateView(_vocbase.name(), nameSlice.copyString(), ex.code());
generateError(arangodb::Result(ex.code(), ex.message()));
} catch (...) {
events::CreateView(_vocbase.name(), nameSlice.copyString(), TRI_errno());
generateError(arangodb::Result(TRI_errno(), "problem creating view"));
}
}
@ -389,6 +394,7 @@ void RestViewHandler::deleteView() {
generateError(rest::ResponseCode::BAD, TRI_ERROR_BAD_PARAMETER,
"expecting DELETE /_api/view/<view-name>");
events::DropView(_vocbase.name(), "", TRI_ERROR_BAD_PARAMETER);
return;
}
@ -399,6 +405,7 @@ void RestViewHandler::deleteView() {
if (!view) {
generateError(rest::ResponseCode::NOT_FOUND, TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND);
events::DropView(_vocbase.name(), name, TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND);
return;
}
@ -410,6 +417,7 @@ void RestViewHandler::deleteView() {
generateError(
Result(TRI_ERROR_FORBIDDEN, "insufficient rights to drop view"));
events::DropView(_vocbase.name(), name, TRI_ERROR_FORBIDDEN);
return;
}
@ -418,6 +426,7 @@ void RestViewHandler::deleteView() {
generateError(
Result(TRI_ERROR_FORBIDDEN, "insufficient rights to drop system view"));
events::DropView(_vocbase.name(), name, TRI_ERROR_FORBIDDEN);
return;
}

View File

@ -630,11 +630,13 @@ int DatabaseFeature::createDatabase(TRI_voc_tick_t id, std::string const& name,
LOG_TOPIC("e7444", ERR, arangodb::Logger::FIXME)
<< "initializing replication applier for database '"
<< vocbase->name() << "' failed: " << ex.what();
events::CreateDatabase(name, ex.code());
return ex.code();
} catch (std::exception const& ex) {
LOG_TOPIC("56c41", ERR, arangodb::Logger::FIXME)
<< "initializing replication applier for database '"
<< vocbase->name() << "' failed: " << ex.what();
events::CreateDatabase(name, TRI_ERROR_INTERNAL);
return TRI_ERROR_INTERNAL;
}
@ -651,6 +653,7 @@ int DatabaseFeature::createDatabase(TRI_voc_tick_t id, std::string const& name,
int res = createApplicationDirectory(name, appPath);
if (res != TRI_ERROR_NO_ERROR) {
events::CreateDatabase(name, res);
THROW_ARANGO_EXCEPTION(res);
}
}
@ -715,6 +718,7 @@ int DatabaseFeature::dropDatabase(std::string const& name, bool waitForDeletion,
bool removeAppsDirectory) {
if (name == TRI_VOC_SYSTEM_DATABASE) {
// prevent deletion of system database
events::DropDatabase(name, TRI_ERROR_FORBIDDEN);
return TRI_ERROR_FORBIDDEN;
}
@ -769,6 +773,7 @@ int DatabaseFeature::dropDatabase(std::string const& name, bool waitForDeletion,
vocbase->visitDataSources(visitor, true); // aquire a write lock to avoid potential deadlocks
if (TRI_ERROR_NO_ERROR != res) {
events::DropDatabase(name, res);
return res;
}
@ -776,6 +781,7 @@ int DatabaseFeature::dropDatabase(std::string const& name, bool waitForDeletion,
newLists->_droppedDatabases.insert(vocbase);
} catch (...) {
delete newLists;
events::DropDatabase(name, TRI_ERROR_OUT_OF_MEMORY);
return TRI_ERROR_OUT_OF_MEMORY;
}
@ -838,6 +844,7 @@ int DatabaseFeature::dropDatabase(TRI_voc_tick_t id, bool waitForDeletion,
}
if (name.empty()) {
events::DropDatabase(name, TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
return TRI_ERROR_ARANGO_DATABASE_NOT_FOUND;
}
// and call the regular drop function

View File

@ -23,15 +23,24 @@
#include "ViewTypesFeature.h"
#include "ApplicationFeatures/ApplicationServer.h"
#include "BootstrapFeature.h"
#include "Basics/StaticStrings.h"
#include "Basics/VelocyPackHelper.h"
#include "ProgramOptions/ProgramOptions.h"
#include "ProgramOptions/Section.h"
#include "RestServer/BootstrapFeature.h"
#include "Utils/Events.h"
namespace {
struct InvalidViewFactory : public arangodb::ViewFactory {
virtual arangodb::Result create(arangodb::LogicalView::ptr&, TRI_vocbase_t&,
virtual arangodb::Result create(arangodb::LogicalView::ptr&, TRI_vocbase_t& vocbase,
arangodb::velocypack::Slice const& definition) const override {
std::string name;
if (definition.isObject()) {
name = arangodb::basics::VelocyPackHelper::getStringValue(
definition, arangodb::StaticStrings::DataSourceName, "");
}
arangodb::events::CreateView(vocbase.name(), name, TRI_ERROR_INTERNAL);
return arangodb::Result(
TRI_ERROR_BAD_PARAMETER,
std::string(
@ -106,4 +115,4 @@ void ViewTypesFeature::unprepare() { _factories.clear(); }
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

View File

@ -450,7 +450,7 @@ std::shared_ptr<Index> RocksDBCollection::createIndex(VPackSlice const& info,
}
guard.unlock();
#if USE_PLAN_CACHE
arangodb::aql::PlanCache::instance()->invalidate(_logicalCollection->vocbase());
arangodb::aql::PlanCache::instance()->invalidate(_logicalCollection.vocbase());
#endif
// inBackground index might not recover selectivity estimate w/o sync
@ -516,7 +516,8 @@ bool RocksDBCollection::dropIndex(TRI_idx_iid_t iid) {
if (!toRemove) { // index not found
// We tried to remove an index that does not exist
events::DropIndex("", std::to_string(iid), TRI_ERROR_ARANGO_INDEX_NOT_FOUND);
events::DropIndex(_logicalCollection.vocbase().name(), _logicalCollection.name(),
std::to_string(iid), TRI_ERROR_ARANGO_INDEX_NOT_FOUND);
return false;
}
@ -531,7 +532,8 @@ bool RocksDBCollection::dropIndex(TRI_idx_iid_t iid) {
return false;
}
events::DropIndex("", std::to_string(iid), TRI_ERROR_NO_ERROR);
events::DropIndex(_logicalCollection.vocbase().name(), _logicalCollection.name(),
std::to_string(iid), TRI_ERROR_NO_ERROR);
cindex->compact(); // trigger compaction before deleting the object
@ -1320,7 +1322,7 @@ Result RocksDBCollection::removeDocument(arangodb::transaction::Methods* trx,
/*LOG_TOPIC("17502", ERR, Logger::ENGINES)
<< "Delete rev: " << revisionId << " trx: " << trx->state()->id()
<< " seq: " << mthds->sequenceNumber()
<< " objectID " << _objectId << " name: " << _logicalCollection->name();*/
<< " objectID " << _objectId << " name: " << _logicalCollection.name();*/
READ_LOCKER(guard, _indexesLock);
for (std::shared_ptr<Index> const& idx : _indexes) {

View File

@ -1542,14 +1542,20 @@ OperationResult transaction::Methods::document(std::string const& collectionName
if (!value.isObject() && !value.isArray()) {
// must provide a document object or an array of documents
events::ReadDocument(vocbase().name(), collectionName, value,
TRI_ERROR_ARANGO_DOCUMENT_TYPE_INVALID);
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_TYPE_INVALID);
}
OperationResult result;
if (_state->isCoordinator()) {
return documentCoordinator(collectionName, value, options);
result = documentCoordinator(collectionName, value, options);
} else {
result = documentLocal(collectionName, value, options);
}
return documentLocal(collectionName, value, options);
events::ReadDocument(vocbase().name(), collectionName, value, result.errorNumber());
return result;
}
/// @brief read one or multiple documents in a collection, coordinator
@ -1668,20 +1674,29 @@ OperationResult transaction::Methods::insert(std::string const& collectionName,
if (!value.isObject() && !value.isArray()) {
// must provide a document object or an array of documents
events::CreateDocument(vocbase().name(), collectionName, value,
TRI_ERROR_ARANGO_DOCUMENT_TYPE_INVALID);
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_TYPE_INVALID);
}
if (value.isArray() && value.length() == 0) {
events::CreateDocument(vocbase().name(), collectionName, value, TRI_ERROR_NO_ERROR);
return emptyResult(options);
}
// Validate Edges
OperationOptions optionsCopy = options;
OperationResult result;
if (_state->isCoordinator()) {
return insertCoordinator(collectionName, value, optionsCopy);
result = insertCoordinator(collectionName, value, optionsCopy);
} else {
result = insertLocal(collectionName, value, optionsCopy);
}
return insertLocal(collectionName, value, optionsCopy);
events::CreateDocument(vocbase().name(), collectionName,
((result.ok() && options.returnNew) ? result.slice() : value),
result.errorNumber());
return result;
}
/// @brief create one or multiple documents in a collection, coordinator
@ -1958,19 +1973,26 @@ OperationResult transaction::Methods::update(std::string const& collectionName,
if (!newValue.isObject() && !newValue.isArray()) {
// must provide a document object or an array of documents
events::ModifyDocument(vocbase().name(), collectionName, newValue,
TRI_ERROR_ARANGO_DOCUMENT_TYPE_INVALID);
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_TYPE_INVALID);
}
if (newValue.isArray() && newValue.length() == 0) {
events::ModifyDocument(vocbase().name(), collectionName, newValue, TRI_ERROR_NO_ERROR);
return emptyResult(options);
}
OperationOptions optionsCopy = options;
OperationResult result;
if (_state->isCoordinator()) {
return updateCoordinator(collectionName, newValue, optionsCopy);
result = updateCoordinator(collectionName, newValue, optionsCopy);
} else {
result = modifyLocal(collectionName, newValue, optionsCopy, TRI_VOC_DOCUMENT_OPERATION_UPDATE);
}
return modifyLocal(collectionName, newValue, optionsCopy, TRI_VOC_DOCUMENT_OPERATION_UPDATE);
events::ModifyDocument(vocbase().name(), collectionName, newValue, result.errorNumber());
return result;
}
/// @brief update one or multiple documents in a collection, coordinator
@ -2006,19 +2028,27 @@ OperationResult transaction::Methods::replace(std::string const& collectionName,
if (!newValue.isObject() && !newValue.isArray()) {
// must provide a document object or an array of documents
events::ReplaceDocument(vocbase().name(), collectionName, newValue,
TRI_ERROR_ARANGO_DOCUMENT_TYPE_INVALID);
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_TYPE_INVALID);
}
if (newValue.isArray() && newValue.length() == 0) {
events::ReplaceDocument(vocbase().name(), collectionName, newValue, TRI_ERROR_NO_ERROR);
return emptyResult(options);
}
OperationOptions optionsCopy = options;
OperationResult result;
if (_state->isCoordinator()) {
return replaceCoordinator(collectionName, newValue, optionsCopy);
result = replaceCoordinator(collectionName, newValue, optionsCopy);
} else {
result = modifyLocal(collectionName, newValue, optionsCopy,
TRI_VOC_DOCUMENT_OPERATION_REPLACE);
}
return modifyLocal(collectionName, newValue, optionsCopy, TRI_VOC_DOCUMENT_OPERATION_REPLACE);
events::ReplaceDocument(vocbase().name(), collectionName, newValue, result.errorNumber());
return result;
}
/// @brief replace one or multiple documents in a collection, coordinator
@ -2261,18 +2291,25 @@ OperationResult transaction::Methods::remove(std::string const& collectionName,
if (!value.isObject() && !value.isArray() && !value.isString()) {
// must provide a document object or an array of documents
events::DeleteDocument(vocbase().name(), collectionName, value,
TRI_ERROR_ARANGO_DOCUMENT_TYPE_INVALID);
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_TYPE_INVALID);
}
if (value.isArray() && value.length() == 0) {
events::DeleteDocument(vocbase().name(), collectionName, value, TRI_ERROR_NO_ERROR);
return emptyResult(options);
}
OperationResult result;
if (_state->isCoordinator()) {
return removeCoordinator(collectionName, value, options);
result = removeCoordinator(collectionName, value, options);
} else {
OperationOptions optionsCopy = options;
result = removeLocal(collectionName, value, optionsCopy);
}
OperationOptions optionsCopy = options;
return removeLocal(collectionName, value, optionsCopy);
events::DeleteDocument(vocbase().name(), collectionName, value, result.errorNumber());
return result;
}
/// @brief remove one or multiple documents in a collection, coordinator
@ -2565,7 +2602,7 @@ OperationResult transaction::Methods::truncate(std::string const& collectionName
result = truncateLocal(collectionName, optionsCopy);
}
events::TruncateCollection(collectionName, result.errorNumber());
events::TruncateCollection(vocbase().name(), collectionName, result.errorNumber());
return result;
}

View File

@ -24,20 +24,39 @@
namespace arangodb {
namespace events {
void UnknownAuthenticationMethod(GeneralRequest const*) {}
void CredentialsMissing(GeneralRequest const*) {}
void CredentialsBad(GeneralRequest const*, rest::AuthenticationMethod) {}
void PasswordChangeRequired(GeneralRequest const*) {}
void Authenticated(GeneralRequest const*, rest::AuthenticationMethod) {}
void NotAuthorized(GeneralRequest const*) {}
void CreateCollection(std::string const& name, int result) {}
void DropCollection(std::string const& name, int result) {}
void TruncateCollection(std::string const& name, int result) {}
void UnknownAuthenticationMethod(GeneralRequest const&) {}
void CredentialsMissing(GeneralRequest const&) {}
void LoggedIn(GeneralRequest const&, std::string const& username) {}
void CredentialsBad(GeneralRequest const&, std::string const& username) {}
void CredentialsBad(GeneralRequest const&, rest::AuthenticationMethod) {}
void PasswordChangeRequired(GeneralRequest const&) {}
void Authenticated(GeneralRequest const&, rest::AuthenticationMethod) {}
void NotAuthorized(GeneralRequest const&) {}
void CreateCollection(std::string const& db, std::string const& name, int result) {}
void DropCollection(std::string const& db, std::string const& name, int result) {}
void TruncateCollection(std::string const& db, std::string const& name, int result) {}
void CreateDatabase(std::string const& name, int result) {}
void DropDatabase(std::string const& name, int result) {}
void CreateIndex(std::string const& col, VPackSlice const&) {}
void DropIndex(std::string const& col, std::string const& idx, int result) {}
void CreateView(std::string const& name, int result) {}
void DropView(std::string const& name, int result) {}
void CreateIndex(std::string const& db, std::string const& col,
VPackSlice const&, int result) {}
void DropIndex(std::string const& db, std::string const& col,
std::string const& idx, int result) {}
void CreateView(std::string const& db, std::string const& name, int result) {}
void DropView(std::string const& db, std::string const& name, int result) {}
void CreateDocument(std::string const& db, std::string const& collection,
VPackSlice const& document, int) {}
void DeleteDocument(std::string const& db, std::string const& collection,
VPackSlice const& document, int) {}
void ReadDocument(std::string const& db, std::string const& collection,
VPackSlice const& document, int) {}
void ReplaceDocument(std::string const& db, std::string const& collection,
VPackSlice const& document, int) {}
void ModifyDocument(std::string const& db, std::string const& collection,
VPackSlice const& document, int) {}
void IllegalDocumentOperation(GeneralRequest const&, int result) {}
void QueryDocument(std::string const& db, std::string const&, std::string const&, int code) {}
void QueryDocument(std::string const& db, VPackSlice const&, int code) {}
void QueryDocument(GeneralRequest const&, GeneralResponse const*, VPackSlice const&) {}
} // namespace events
} // namespace arangodb

View File

@ -29,26 +29,46 @@
#include <velocypack/velocypack-aliases.h>
#include "Rest/CommonDefines.h"
#include "VocBase/LogicalCollection.h"
namespace arangodb {
class GeneralRequest;
class GeneralResponse;
struct OperationResult;
namespace events {
void UnknownAuthenticationMethod(GeneralRequest const*);
void CredentialsMissing(GeneralRequest const*);
void CredentialsBad(GeneralRequest const*, rest::AuthenticationMethod);
void PasswordChangeRequired(GeneralRequest const*);
void Authenticated(GeneralRequest const*, rest::AuthenticationMethod);
void NotAuthorized(GeneralRequest const*);
void CreateCollection(std::string const& name, int result);
void DropCollection(std::string const& name, int result);
void TruncateCollection(std::string const& name, int result);
void UnknownAuthenticationMethod(GeneralRequest const&);
void CredentialsMissing(GeneralRequest const&);
void LoggedIn(GeneralRequest const&, std::string const& username);
void CredentialsBad(GeneralRequest const&, std::string const& username);
void CredentialsBad(GeneralRequest const&, rest::AuthenticationMethod);
void PasswordChangeRequired(GeneralRequest const&);
void Authenticated(GeneralRequest const&, rest::AuthenticationMethod);
void NotAuthorized(GeneralRequest const&);
void CreateCollection(std::string const& db, std::string const& name, int result);
void DropCollection(std::string const& db, std::string const& name, int result);
void TruncateCollection(std::string const& db, std::string const& name, int result);
void CreateDatabase(std::string const& name, int result);
void DropDatabase(std::string const& name, int result);
void CreateIndex(std::string const& col, VPackSlice const&);
void DropIndex(std::string const& col, std::string const& idx, int result);
void CreateView(std::string const& name, int result);
void DropView(std::string const& name, int result);
void CreateIndex(std::string const& db, std::string const& col, VPackSlice const&, int result);
void DropIndex(std::string const& db, std::string const& col,
std::string const& idx, int result);
void CreateView(std::string const& db, std::string const& name, int result);
void DropView(std::string const& db, std::string const& name, int result);
void CreateDocument(std::string const& db, std::string const& collection,
VPackSlice const& document, int);
void DeleteDocument(std::string const& db, std::string const& collection,
VPackSlice const& document, int);
void ReadDocument(std::string const& db, std::string const& collection,
VPackSlice const& document, int);
void ReplaceDocument(std::string const& db, std::string const& collection,
VPackSlice const& document, int);
void ModifyDocument(std::string const& db, std::string const& collection,
VPackSlice const& document, int);
void IllegalDocumentOperation(GeneralRequest const&, int result);
void QueryDocument(std::string const& db, std::string const&, std::string const&, int code);
void QueryDocument(std::string const& db, VPackSlice const&, int code);
void QueryDocument(GeneralRequest const&, GeneralResponse const*, VPackSlice const&);
} // namespace events
} // namespace arangodb

View File

@ -51,6 +51,7 @@
#include "Transaction/Hints.h"
#include "Transaction/V8Context.h"
#include "Utils/CollectionNameResolver.h"
#include "Utils/Events.h"
#include "Utils/ExecContext.h"
#include "Utils/OperationOptions.h"
#include "Utils/OperationResult.h"
@ -873,14 +874,15 @@ static void JS_DropVocbaseCol(v8::FunctionCallbackInfo<v8::Value> const& args) {
v8::Local<v8::Context> context = isolate->GetCurrentContext();
v8::HandleScope scope(isolate);
auto& vocbase = GetContextVocBase(isolate);
if (vocbase.isDangling()) {
events::DropCollection(vocbase.name(), "", TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
}
auto* collection = UnwrapCollection(isolate, args.Holder());
if (!collection) {
events::DropCollection(vocbase.name(), "", TRI_ERROR_INTERNAL);
TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection");
}
@ -907,10 +909,17 @@ static void JS_DropVocbaseCol(v8::FunctionCallbackInfo<v8::Value> const& args) {
}
}
auto res = methods::Collections::drop(*collection, allowDropSystem, timeout);
if (res.fail()) {
TRI_V8_THROW_EXCEPTION(res);
try {
auto res = methods::Collections::drop(*collection, allowDropSystem, timeout);
if (res.fail()) {
TRI_V8_THROW_EXCEPTION(res);
}
} catch (basics::Exception const& ex) {
events::DropCollection(vocbase.name(), collection->name(), ex.code());
throw;
} catch (...) {
events::DropCollection(vocbase.name(), collection->name(), TRI_ERROR_INTERNAL);
throw;
}
TRI_V8_RETURN_UNDEFINED();

View File

@ -30,6 +30,7 @@
#include "RestServer/DatabaseFeature.h"
#include "Transaction/V8Context.h"
#include "Utils/CollectionNameResolver.h"
#include "Utils/Events.h"
#include "Utils/ExecContext.h"
#include "V8/v8-conv.h"
#include "V8/v8-globals.h"
@ -130,11 +131,13 @@ static void JS_CreateViewVocbase(v8::FunctionCallbackInfo<v8::Value> const& args
auto& vocbase = GetContextVocBase(isolate);
if (vocbase.isDangling()) {
events::CreateView(vocbase.name(), "", TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
}
// we require exactly 3 arguments
if (args.Length() != 3) {
events::CreateView(vocbase.name(), "", TRI_ERROR_FORBIDDEN);
TRI_V8_THROW_EXCEPTION_USAGE("_createView(<name>, <type>, <properties>)");
}
@ -147,6 +150,7 @@ static void JS_CreateViewVocbase(v8::FunctionCallbackInfo<v8::Value> const& args
std::string const type = TRI_ObjectToString(isolate, args[1]);
if (!args[2]->IsObject()) {
events::CreateView(vocbase.name(), name, TRI_ERROR_BAD_PARAMETER);
TRI_V8_THROW_TYPE_ERROR("<properties> must be an object");
}
@ -156,6 +160,7 @@ static void JS_CreateViewVocbase(v8::FunctionCallbackInfo<v8::Value> const& args
int res = TRI_V8ToVPack(isolate, properties, obj, false);
if (res != TRI_ERROR_NO_ERROR) {
events::CreateView(vocbase.name(), name, res);
TRI_V8_THROW_EXCEPTION(res);
}
@ -164,6 +169,7 @@ static void JS_CreateViewVocbase(v8::FunctionCallbackInfo<v8::Value> const& args
// ...........................................................................
if (!canUse(auth::Level::RW, vocbase)) {
events::CreateView(vocbase.name(), name, TRI_ERROR_FORBIDDEN);
TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_ERROR_FORBIDDEN,
"insufficient rights to create view");
}
@ -185,6 +191,7 @@ static void JS_CreateViewVocbase(v8::FunctionCallbackInfo<v8::Value> const& args
auto res = LogicalView::create(view, vocbase, builder.slice());
if (!res.ok()) {
// events::CreateView(vocbase.name(), name, res.errorNumber());
TRI_V8_THROW_EXCEPTION_MESSAGE(res.errorNumber(), res.errorMessage());
}
@ -201,10 +208,13 @@ static void JS_CreateViewVocbase(v8::FunctionCallbackInfo<v8::Value> const& args
TRI_V8_RETURN(result);
} catch (basics::Exception const& ex) {
events::CreateView(vocbase.name(), name, ex.code());
TRI_V8_THROW_EXCEPTION_MESSAGE(ex.code(), ex.what());
} catch (std::exception const& ex) {
events::CreateView(vocbase.name(), name, TRI_ERROR_INTERNAL);
TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, ex.what());
} catch (...) {
events::CreateView(vocbase.name(), name, TRI_ERROR_INTERNAL);
TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "cannot create view");
}
TRI_V8_TRY_CATCH_END
@ -217,11 +227,13 @@ static void JS_DropViewVocbase(v8::FunctionCallbackInfo<v8::Value> const& args)
auto& vocbase = GetContextVocBase(isolate);
if (vocbase.isDangling()) {
events::DropView(vocbase.name(), "", TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
}
// we require exactly 1 string argument and an optional boolean argument
if (args.Length() < 1 || args.Length() > 2) {
events::DropView(vocbase.name(), "", TRI_ERROR_BAD_PARAMETER);
TRI_V8_THROW_EXCEPTION_USAGE("_dropView(<name> [, allowDropSystem])");
}
@ -257,12 +269,14 @@ static void JS_DropViewVocbase(v8::FunctionCallbackInfo<v8::Value> const& args)
if (view) {
if (!view->canUse(auth::Level::RW)) { // check auth after ensuring that the view exists
events::DropView(vocbase.name(), view->name(), TRI_ERROR_FORBIDDEN);
TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_ERROR_FORBIDDEN,
"insufficient rights to drop view");
}
// prevent dropping of system views
if (!allowDropSystem && view->system()) {
events::DropView(vocbase.name(), view->name(), TRI_ERROR_FORBIDDEN);
TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_ERROR_FORBIDDEN,
"insufficient rights to drop system view");
}
@ -272,6 +286,8 @@ static void JS_DropViewVocbase(v8::FunctionCallbackInfo<v8::Value> const& args)
if (!res.ok()) {
TRI_V8_THROW_EXCEPTION(res);
}
} else {
events::DropView(vocbase.name(), name, TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND);
}
TRI_V8_RETURN_UNDEFINED();
@ -283,10 +299,11 @@ static void JS_DropViewVocbaseObj(v8::FunctionCallbackInfo<v8::Value> const& arg
TRI_V8_TRY_CATCH_BEGIN(isolate);
v8::Local<v8::Context> context = isolate->GetCurrentContext();
v8::HandleScope scope(isolate);
auto& vocbase = GetContextVocBase(isolate);
auto* view = UnwrapView(isolate, args.Holder());
if (!view) {
events::DropView(vocbase.name(), "", TRI_ERROR_BAD_PARAMETER);
TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract view");
}
@ -316,12 +333,14 @@ static void JS_DropViewVocbaseObj(v8::FunctionCallbackInfo<v8::Value> const& arg
// ...........................................................................
if (!view->canUse(auth::Level::RW)) { // check auth after ensuring that the view exists
events::DropView(vocbase.name(), view->name(), TRI_ERROR_FORBIDDEN);
TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_ERROR_FORBIDDEN,
"insufficient rights to drop view");
}
// prevent dropping of system views
if (!allowDropSystem && view->system()) {
events::DropView(vocbase.name(), view->name(), TRI_ERROR_FORBIDDEN);
TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_ERROR_FORBIDDEN,
"insufficient rights to drop system view");
}

View File

@ -62,6 +62,7 @@
#include "StorageEngine/EngineSelectorFeature.h"
#include "StorageEngine/StorageEngine.h"
#include "Transaction/V8Context.h"
#include "Utils/Events.h"
#include "Utils/ExecContext.h"
#include "V8/JSLoader.h"
#include "V8/V8LineEditor.h"
@ -672,10 +673,12 @@ static void JS_ExecuteAqlJson(v8::FunctionCallbackInfo<v8::Value> const& args) {
auto& vocbase = GetContextVocBase(isolate);
if (args.Length() < 1 || args.Length() > 2) {
events::QueryDocument(vocbase.name(), VPackSlice(), TRI_ERROR_BAD_PARAMETER);
TRI_V8_THROW_EXCEPTION_USAGE("AQL_EXECUTEJSON(<queryjson>, <options>)");
}
if (!args[0]->IsObject()) {
events::QueryDocument(vocbase.name(), VPackSlice(), TRI_ERROR_BAD_PARAMETER);
TRI_V8_THROW_TYPE_ERROR("expecting object for <queryjson>");
}
@ -683,6 +686,7 @@ static void JS_ExecuteAqlJson(v8::FunctionCallbackInfo<v8::Value> const& args) {
int res = TRI_V8ToVPack(isolate, *queryBuilder, args[0], false);
if (res != TRI_ERROR_NO_ERROR) {
events::QueryDocument(vocbase.name(), VPackSlice(), res);
TRI_V8_THROW_EXCEPTION(res);
}
@ -691,11 +695,13 @@ static void JS_ExecuteAqlJson(v8::FunctionCallbackInfo<v8::Value> const& args) {
if (args.Length() > 1) {
// we have options! yikes!
if (!args[1]->IsUndefined() && !args[1]->IsObject()) {
events::QueryDocument(vocbase.name(), queryBuilder->slice(), TRI_ERROR_BAD_PARAMETER);
TRI_V8_THROW_TYPE_ERROR("expecting object for <options>");
}
res = TRI_V8ToVPack(isolate, *options, args[1], false);
if (res != TRI_ERROR_NO_ERROR) {
events::QueryDocument(vocbase.name(), queryBuilder->slice(), res);
TRI_V8_THROW_EXCEPTION(res);
}
}
@ -706,6 +712,7 @@ static void JS_ExecuteAqlJson(v8::FunctionCallbackInfo<v8::Value> const& args) {
query.executeSync(static_cast<arangodb::aql::QueryRegistry*>(v8g->_queryRegistry));
if (queryResult.result.fail()) {
events::QueryDocument(vocbase.name(), queryBuilder->slice(), queryResult.result.errorNumber());
TRI_V8_THROW_EXCEPTION_FULL(queryResult.result.errorNumber(), queryResult.result.errorMessage());
}
@ -738,6 +745,8 @@ static void JS_ExecuteAqlJson(v8::FunctionCallbackInfo<v8::Value> const& args) {
result->Set(TRI_V8_ASCII_STRING(isolate, "cached"),
v8::Boolean::New(isolate, queryResult.cached));
events::QueryDocument(vocbase.name(), queryBuilder->slice(), TRI_ERROR_NO_ERROR);
TRI_V8_RETURN(result);
TRI_V8_TRY_CATCH_END
}
@ -752,12 +761,14 @@ static void JS_ExecuteAql(v8::FunctionCallbackInfo<v8::Value> const& args) {
auto& vocbase = GetContextVocBase(isolate);
if (args.Length() < 1 || args.Length() > 3) {
events::QueryDocument(vocbase.name(), "", "", TRI_ERROR_BAD_PARAMETER);
TRI_V8_THROW_EXCEPTION_USAGE(
"AQL_EXECUTE(<queryString>, <bindVars>, <options>)");
}
// get the query string
if (!args[0]->IsString()) {
events::QueryDocument(vocbase.name(), "", "", TRI_ERROR_BAD_PARAMETER);
TRI_V8_THROW_TYPE_ERROR("expecting string for <queryString>");
}
@ -768,6 +779,7 @@ static void JS_ExecuteAql(v8::FunctionCallbackInfo<v8::Value> const& args) {
if (args.Length() > 1) {
if (!args[1]->IsUndefined() && !args[1]->IsNull() && !args[1]->IsObject()) {
events::QueryDocument(vocbase.name(), queryString, "", TRI_ERROR_BAD_PARAMETER);
TRI_V8_THROW_TYPE_ERROR("expecting object for <bindVars>");
}
if (args[1]->IsObject()) {
@ -775,6 +787,7 @@ static void JS_ExecuteAql(v8::FunctionCallbackInfo<v8::Value> const& args) {
int res = TRI_V8ToVPack(isolate, *(bindVars.get()), args[1], false);
if (res != TRI_ERROR_NO_ERROR) {
events::QueryDocument(vocbase.name(), queryString, "", res);
TRI_V8_THROW_EXCEPTION(res);
}
}
@ -785,11 +798,16 @@ static void JS_ExecuteAql(v8::FunctionCallbackInfo<v8::Value> const& args) {
if (args.Length() > 2) {
// we have options! yikes!
if (!args[2]->IsObject()) {
events::QueryDocument(vocbase.name(), queryString,
(bindVars ? bindVars->slice().toJson() : ""),
TRI_ERROR_BAD_PARAMETER);
TRI_V8_THROW_TYPE_ERROR("expecting object for <options>");
}
int res = TRI_V8ToVPack(isolate, *options, args[2], false);
if (res != TRI_ERROR_NO_ERROR) {
events::QueryDocument(vocbase.name(), queryString,
(bindVars ? bindVars->slice().toJson() : ""), res);
TRI_V8_THROW_EXCEPTION(res);
}
}
@ -817,9 +835,15 @@ static void JS_ExecuteAql(v8::FunctionCallbackInfo<v8::Value> const& args) {
if (queryResult.result.is(TRI_ERROR_REQUEST_CANCELED)) {
TRI_GET_GLOBALS();
v8g->_canceled = true;
events::QueryDocument(vocbase.name(), queryString,
(bindVars ? bindVars->slice().toJson() : ""),
TRI_ERROR_REQUEST_CANCELED);
TRI_V8_THROW_EXCEPTION(TRI_ERROR_REQUEST_CANCELED);
}
events::QueryDocument(vocbase.name(), queryString,
(bindVars ? bindVars->slice().toJson() : ""),
queryResult.result.errorNumber());
TRI_V8_THROW_EXCEPTION_FULL(queryResult.result.errorNumber(), queryResult.result.errorMessage());
}
@ -854,6 +878,9 @@ static void JS_ExecuteAql(v8::FunctionCallbackInfo<v8::Value> const& args) {
result->Set(TRI_V8_ASCII_STRING(isolate, "cached"),
v8::Boolean::New(isolate, queryResult.cached));
events::QueryDocument(vocbase.name(), queryString,
(bindVars ? bindVars->slice().toJson() : ""), TRI_ERROR_NO_ERROR);
TRI_V8_RETURN(result);
TRI_V8_TRY_CATCH_END
}
@ -1655,6 +1682,7 @@ static void JS_CreateDatabase(v8::FunctionCallbackInfo<v8::Value> const& args) {
v8::HandleScope scope(isolate);
if (args.Length() < 1 || args.Length() > 3) {
events::CreateDatabase("", TRI_ERROR_BAD_PARAMETER);
TRI_V8_THROW_EXCEPTION_USAGE(
"db._createDatabase(<name>, <options>, <users>)");
}
@ -1664,6 +1692,7 @@ static void JS_CreateDatabase(v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_ASSERT(!vocbase.isDangling());
if (!vocbase.isSystem()) {
events::CreateDatabase("", TRI_ERROR_ARANGO_USE_SYSTEM_DATABASE);
TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_USE_SYSTEM_DATABASE);
}
@ -1683,6 +1712,7 @@ static void JS_CreateDatabase(v8::FunctionCallbackInfo<v8::Value> const& args) {
v8::Handle<v8::Value> user = ar->Get(i);
if (!user->IsObject()) {
events::CreateDatabase("", TRI_ERROR_BAD_PARAMETER);
TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER,
"user is not an object");
}
@ -1711,18 +1741,21 @@ static void JS_DropDatabase(v8::FunctionCallbackInfo<v8::Value> const& args) {
v8::HandleScope scope(isolate);
if (args.Length() != 1) {
events::DropDatabase("", TRI_ERROR_BAD_PARAMETER);
TRI_V8_THROW_EXCEPTION_USAGE("db._dropDatabase(<name>)");
}
auto& vocbase = GetContextVocBase(isolate);
if (!vocbase.isSystem()) {
events::DropDatabase("", TRI_ERROR_ARANGO_USE_SYSTEM_DATABASE);
TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_USE_SYSTEM_DATABASE);
}
ExecContext const* exec = ExecContext::CURRENT;
if (exec != nullptr && exec->systemAuthLevel() != auth::Level::RW) {
events::DropDatabase("", TRI_ERROR_FORBIDDEN);
TRI_V8_THROW_EXCEPTION(TRI_ERROR_FORBIDDEN);
}

View File

@ -127,16 +127,19 @@ static void JS_LookupIndexVocbaseCol(v8::FunctionCallbackInfo<v8::Value> const&
static void JS_DropIndexVocbaseCol(v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_TRY_CATCH_BEGIN(isolate);
v8::HandleScope scope(isolate);
auto& vocbase = GetContextVocBase(isolate);
PREVENT_EMBEDDED_TRANSACTION();
auto* collection = UnwrapCollection(isolate, args.Holder());
if (!collection) {
events::DropIndex(vocbase.name(), "", "", TRI_ERROR_INTERNAL);
TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection");
}
if (args.Length() != 1) {
events::DropIndex(vocbase.name(), "", "", TRI_ERROR_BAD_PARAMETER);
TRI_V8_THROW_EXCEPTION_USAGE("dropIndex(<index-handle>)");
}
@ -202,14 +205,17 @@ static void CreateVocBase(v8::FunctionCallbackInfo<v8::Value> const& args,
auto& vocbase = GetContextVocBase(isolate);
if (vocbase.isDangling()) {
events::CreateCollection(vocbase.name(), "", TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
} else if (args.Length() < 1 || args.Length() > 4) {
events::CreateCollection(vocbase.name(), "", TRI_ERROR_BAD_PARAMETER);
TRI_V8_THROW_EXCEPTION_USAGE(
"_create(<name>, <properties>, <type>, <options>)");
}
if (ExecContext::CURRENT != nullptr &&
!ExecContext::CURRENT->canUseDatabase(vocbase.name(), auth::Level::RW)) {
events::CreateCollection(vocbase.name(), "", TRI_ERROR_FORBIDDEN);
TRI_V8_THROW_EXCEPTION(TRI_ERROR_FORBIDDEN);
}

View File

@ -31,6 +31,7 @@
#include "RestServer/ViewTypesFeature.h"
#include "StorageEngine/EngineSelectorFeature.h"
#include "StorageEngine/StorageEngine.h"
#include "Utils/Events.h"
#include "Utils/ExecContext.h"
#include "VocBase/ticks.h"
#include "VocBase/vocbase.h"
@ -111,6 +112,12 @@ bool LogicalView::canUse(arangodb::auth::Level const& level) {
application_features::ApplicationServer::lookupFeature<ViewTypesFeature>();
if (!viewTypes) {
std::string name;
if (definition.isObject()) {
name = basics::VelocyPackHelper::getStringValue(definition, StaticStrings::DataSourceName,
"");
}
events::CreateView(vocbase.name(), name, TRI_ERROR_INTERNAL);
return Result(
TRI_ERROR_INTERNAL,
"Failure to get 'ViewTypes' feature while creating LogicalView");
@ -528,4 +535,4 @@ Result LogicalView::rename(std::string&& newName) {
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

View File

@ -42,6 +42,7 @@
#include "Sharding/ShardingFeature.h"
#include "StorageEngine/PhysicalCollection.h"
#include "Transaction/V8Context.h"
#include "Utils/Events.h"
#include "Utils/ExecContext.h"
#include "Utils/OperationCursor.h"
#include "Utils/SingleCollectionTransaction.h"
@ -211,14 +212,17 @@ void Collections::enumerate(TRI_vocbase_t* vocbase,
FuncCallback func // invoke on collection creation
) {
if (name.empty()) {
events::CreateCollection(vocbase.name(), name, TRI_ERROR_ARANGO_ILLEGAL_NAME);
return TRI_ERROR_ARANGO_ILLEGAL_NAME;
} else if (collectionType != TRI_col_type_e::TRI_COL_TYPE_DOCUMENT &&
collectionType != TRI_col_type_e::TRI_COL_TYPE_EDGE) {
events::CreateCollection(vocbase.name(), name, TRI_ERROR_ARANGO_COLLECTION_TYPE_INVALID);
return TRI_ERROR_ARANGO_COLLECTION_TYPE_INVALID;
}
ExecContext const* exec = ExecContext::CURRENT;
if (exec && !exec->canUseDatabase(vocbase.name(), auth::Level::RW)) {
events::CreateCollection(vocbase.name(), name, TRI_ERROR_FORBIDDEN);
return arangodb::Result( // result
TRI_ERROR_FORBIDDEN, // code
"cannot create collection in " + vocbase.name() // message
@ -265,6 +269,7 @@ void Collections::enumerate(TRI_vocbase_t* vocbase,
enforceReplicationFactor);
if (!col) {
events::CreateCollection(vocbase.name(), name, TRI_ERROR_INTERNAL);
return Result(TRI_ERROR_INTERNAL, "createCollectionOnCoordinator");
}
@ -281,6 +286,7 @@ void Collections::enumerate(TRI_vocbase_t* vocbase,
while (true) {
Result r = um->updateUser(ExecContext::CURRENT->user(), [&](auth::User& entry) {
entry.grantCollection(vocbase.name(), name, auth::Level::RW);
events::CreateCollection(vocbase.name(), name, TRI_ERROR_NO_ERROR);
return TRI_ERROR_NO_ERROR;
});
@ -296,6 +302,7 @@ void Collections::enumerate(TRI_vocbase_t* vocbase,
<< "Updating user failed with error: " << r.errorMessage()
<< ". giving up!";
events::CreateCollection(vocbase.name(), name, r.errorNumber());
return r;
}
@ -324,6 +331,7 @@ void Collections::enumerate(TRI_vocbase_t* vocbase,
while (true) {
Result r = um->updateUser(ExecContext::CURRENT->user(), [&](auth::User& entry) {
entry.grantCollection(vocbase.name(), name, auth::Level::RW);
events::CreateCollection(vocbase.name(), name, TRI_ERROR_NO_ERROR);
return TRI_ERROR_NO_ERROR;
});
@ -339,6 +347,7 @@ void Collections::enumerate(TRI_vocbase_t* vocbase,
<< "Updating user failed with error: " << r.errorMessage()
<< ". giving up!";
events::CreateCollection(vocbase.name(), name, r.errorNumber());
return r;
}
@ -352,13 +361,18 @@ void Collections::enumerate(TRI_vocbase_t* vocbase,
func(col);
}
} catch (basics::Exception const& ex) {
events::CreateCollection(vocbase.name(), name, ex.code());
return Result(ex.code(), ex.what());
} catch (std::exception const& ex) {
events::CreateCollection(vocbase.name(), name, TRI_ERROR_INTERNAL);
return Result(TRI_ERROR_INTERNAL, ex.what());
} catch (...) {
events::CreateCollection(vocbase.name(), name, TRI_ERROR_INTERNAL);
return Result(TRI_ERROR_INTERNAL, "cannot create collection");
}
events::CreateCollection(vocbase.name(), name, TRI_ERROR_NO_ERROR);
return TRI_ERROR_NO_ERROR;
}
@ -612,6 +626,7 @@ static Result DropVocbaseColCoordinator(arangodb::LogicalCollection* collection,
&& exec->canUseCollection(coll.name(), auth::Level::RW) // collection modifiable
)
) {
events::DropCollection(coll.vocbase().name(), coll.name(), TRI_ERROR_FORBIDDEN);
return arangodb::Result( // result
TRI_ERROR_FORBIDDEN, // code
"Insufficient rights to drop collection " + coll.name() // message
@ -660,6 +675,8 @@ static Result DropVocbaseColCoordinator(arangodb::LogicalCollection* collection,
}
}
events::DropCollection(coll.vocbase().name(), coll.name(), res.errorNumber());
return res;
}

View File

@ -32,6 +32,7 @@
#include "Rest/HttpRequest.h"
#include "RestServer/DatabaseFeature.h"
#include "RestServer/SystemDatabaseFeature.h"
#include "Utils/Events.h"
#include "Utils/ExecContext.h"
#include "V8/v8-utils.h"
#include "V8/v8-vpack.h"
@ -126,6 +127,7 @@ arangodb::Result Databases::create(std::string const& dbName, VPackSlice const&
ExecContext const* exec = ExecContext::CURRENT;
if (exec != nullptr) {
if (!exec->isAdminUser()) {
events::CreateDatabase(dbName, TRI_ERROR_FORBIDDEN);
return TRI_ERROR_FORBIDDEN;
}
}
@ -134,12 +136,14 @@ arangodb::Result Databases::create(std::string const& dbName, VPackSlice const&
if (options.isNone() || options.isNull()) {
options = VPackSlice::emptyObjectSlice();
} else if (!options.isObject()) {
events::CreateDatabase(dbName, TRI_ERROR_HTTP_BAD_PARAMETER);
return Result(TRI_ERROR_HTTP_BAD_PARAMETER, "invalid options slice");
}
VPackSlice users = inUsers;
if (users.isNone() || users.isNull()) {
users = VPackSlice::emptyArraySlice();
} else if (!users.isArray()) {
events::CreateDatabase(dbName, TRI_ERROR_HTTP_BAD_PARAMETER);
return Result(TRI_ERROR_HTTP_BAD_PARAMETER, "invalid users slice");
}
@ -148,6 +152,7 @@ arangodb::Result Databases::create(std::string const& dbName, VPackSlice const&
for (VPackSlice const& user : VPackArrayIterator(users)) {
sanitizedUsers.openObject();
if (!user.isObject()) {
events::CreateDatabase(dbName, TRI_ERROR_HTTP_BAD_PARAMETER);
return Result(TRI_ERROR_HTTP_BAD_PARAMETER);
}
@ -158,6 +163,7 @@ arangodb::Result Databases::create(std::string const& dbName, VPackSlice const&
name = user.get("user");
}
if (!name.isString()) { // empty names are silently ignored later
events::CreateDatabase(dbName, TRI_ERROR_HTTP_BAD_PARAMETER);
return Result(TRI_ERROR_HTTP_BAD_PARAMETER);
}
sanitizedUsers.add("username", name);
@ -165,6 +171,7 @@ arangodb::Result Databases::create(std::string const& dbName, VPackSlice const&
if (user.hasKey("passwd")) {
VPackSlice passwd = user.get("passwd");
if (!passwd.isString()) {
events::CreateDatabase(dbName, TRI_ERROR_HTTP_BAD_PARAMETER);
return Result(TRI_ERROR_HTTP_BAD_PARAMETER);
}
sanitizedUsers.add("passwd", passwd);
@ -189,12 +196,14 @@ arangodb::Result Databases::create(std::string const& dbName, VPackSlice const&
DatabaseFeature* databaseFeature = DatabaseFeature::DATABASE;
if (databaseFeature == nullptr) {
events::CreateDatabase(dbName, TRI_ERROR_INTERNAL);
return Result(TRI_ERROR_INTERNAL);
}
UpgradeResult upgradeRes;
if (ServerState::instance()->isCoordinator()) {
if (!TRI_vocbase_t::IsAllowedName(false, arangodb::velocypack::StringRef(dbName))) {
events::CreateDatabase(dbName, TRI_ERROR_ARANGO_DATABASE_NAME_INVALID);
return Result(TRI_ERROR_ARANGO_DATABASE_NAME_INVALID);
}
@ -215,6 +224,7 @@ arangodb::Result Databases::create(std::string const& dbName, VPackSlice const&
auto res = ci->createDatabaseCoordinator(dbName, builder.slice(), 120.0);
if (!res.ok()) {
events::CreateDatabase(dbName, res.errorNumber());
return res;
}
@ -313,6 +323,7 @@ int dropDBCoordinator(std::string const& dbName) {
TRI_vocbase_t* vocbase = databaseFeature->useDatabase(dbName);
if (vocbase == nullptr) {
events::DropDatabase(dbName, TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
return TRI_ERROR_ARANGO_DATABASE_NOT_FOUND;
}
@ -324,6 +335,7 @@ int dropDBCoordinator(std::string const& dbName) {
auto res = ci->dropDatabaseCoordinator(dbName, 120.0);
if (!res.ok()) {
events::DropDatabase(dbName, res.errorNumber());
return res.errorNumber();
}
@ -351,6 +363,7 @@ arangodb::Result Databases::drop(TRI_vocbase_t* systemVocbase, std::string const
ExecContext const* exec = ExecContext::CURRENT;
if (exec != nullptr) {
if (exec->systemAuthLevel() != auth::Level::RW) {
events::DropDatabase(dbName, TRI_ERROR_FORBIDDEN);
return TRI_ERROR_FORBIDDEN;
}
}
@ -360,6 +373,7 @@ arangodb::Result Databases::drop(TRI_vocbase_t* systemVocbase, std::string const
if (dealer != nullptr && dealer->isEnabled()) {
V8Context* v8ctx = V8DealerFeature::DEALER->enterContext(systemVocbase, true);
if (v8ctx == nullptr) {
events::DropDatabase(dbName, TRI_ERROR_INTERNAL);
return Result(TRI_ERROR_INTERNAL, "Could not get v8 context");
}
TRI_DEFER(V8DealerFeature::DEALER->exitContext(v8ctx));
@ -376,6 +390,7 @@ arangodb::Result Databases::drop(TRI_vocbase_t* systemVocbase, std::string const
res = DatabaseFeature::DATABASE->dropDatabase(dbName, false, true);
if (res != TRI_ERROR_NO_ERROR) {
events::DropDatabase(dbName, res);
return Result(res);
}

View File

@ -334,6 +334,8 @@ Result Indexes::ensureIndex(LogicalCollection* collection, VPackSlice const& inp
bool canRead = exec->canUseCollection(collection->name(), auth::Level::RO);
if ((create && (lvl != auth::Level::RW || !canModify)) ||
(lvl == auth::Level::NONE || !canRead)) {
events::CreateIndex(collection->vocbase().name(), collection->name(),
input, TRI_ERROR_FORBIDDEN);
return Result(TRI_ERROR_FORBIDDEN);
}
}
@ -346,6 +348,8 @@ Result Indexes::ensureIndex(LogicalCollection* collection, VPackSlice const& inp
);
if (res.fail()) {
events::CreateIndex(collection->vocbase().name(), collection->name(), input,
res.errorNumber());
return res;
}
@ -390,6 +394,8 @@ Result Indexes::ensureIndex(LogicalCollection* collection, VPackSlice const& inp
VPackSlice f = flds.at(i);
if (!f.isString()) {
// index attributes must be strings
events::CreateIndex(collection->vocbase().name(), collection->name(),
indexDef, TRI_ERROR_INTERNAL);
return Result(TRI_ERROR_INTERNAL,
"index field names should be strings");
}
@ -399,6 +405,8 @@ Result Indexes::ensureIndex(LogicalCollection* collection, VPackSlice const& inp
// all shard-keys must be covered by the index
for (auto& it : shardKeys) {
if (indexKeys.find(it) == indexKeys.end()) {
events::CreateIndex(collection->vocbase().name(), collection->name(),
indexDef, TRI_ERROR_CLUSTER_UNSUPPORTED);
return Result(TRI_ERROR_CLUSTER_UNSUPPORTED,
"shard key '" + it +
"' must be present in unique index");
@ -410,7 +418,8 @@ Result Indexes::ensureIndex(LogicalCollection* collection, VPackSlice const& inp
}
TRI_ASSERT(!indexDef.isNone());
events::CreateIndex(collection->name(), indexDef);
events::CreateIndex(collection->vocbase().name(), collection->name(),
indexDef, TRI_ERROR_NO_ERROR);
// ensure an index, coordinator case
if (ServerState::instance()->isCoordinator()) {
@ -421,10 +430,14 @@ Result Indexes::ensureIndex(LogicalCollection* collection, VPackSlice const& inp
Result res = Indexes::ensureIndexCoordinator(collection, indexDef, create, tmp);
#endif
if (!res.ok()) {
events::CreateIndex(collection->vocbase().name(), collection->name(),
indexDef, res.errorNumber());
return res;
} else if (tmp.slice().isNone()) {
// did not find a suitable index
return Result(create ? TRI_ERROR_OUT_OF_MEMORY : TRI_ERROR_ARANGO_INDEX_NOT_FOUND);
int code = create ? TRI_ERROR_OUT_OF_MEMORY : TRI_ERROR_ARANGO_INDEX_NOT_FOUND;
events::CreateIndex(collection->vocbase().name(), collection->name(), indexDef, code);
return Result(code);
}
// flush estimates
@ -438,9 +451,14 @@ Result Indexes::ensureIndex(LogicalCollection* collection, VPackSlice const& inp
VPackValue(collection->name() + TRI_INDEX_HANDLE_SEPARATOR_CHR + iid));
b.close();
output = VPackCollection::merge(tmp.slice(), b.slice(), false);
events::CreateIndex(collection->vocbase().name(), collection->name(),
indexDef, res.errorNumber());
return res;
} else {
return EnsureIndexLocal(collection, indexDef, create, output);
Result res = EnsureIndexLocal(collection, indexDef, create, output);
events::CreateIndex(collection->vocbase().name(), collection->name(),
indexDef, res.errorNumber());
return res;
}
}
@ -542,9 +560,11 @@ Result Indexes::extractHandle(arangodb::LogicalCollection const* collection,
}
arangodb::Result Indexes::drop(LogicalCollection* collection, VPackSlice const& indexArg) {
TRI_ASSERT(collection);
if (ExecContext::CURRENT != nullptr) {
if (ExecContext::CURRENT->databaseAuthLevel() != auth::Level::RW ||
!ExecContext::CURRENT->canUseCollection(collection->name(), auth::Level::RW)) {
events::DropIndex(collection->vocbase().name(), collection->name(), "", TRI_ERROR_FORBIDDEN);
return TRI_ERROR_FORBIDDEN;
}
}
@ -555,6 +575,8 @@ arangodb::Result Indexes::drop(LogicalCollection* collection, VPackSlice const&
Result res = Indexes::extractHandle(collection, &resolver, indexArg, iid);
if (!res.ok()) {
events::DropIndex(collection->vocbase().name(), collection->name(), "",
res.errorNumber());
return res;
}
@ -562,15 +584,15 @@ arangodb::Result Indexes::drop(LogicalCollection* collection, VPackSlice const&
collection->flushClusterIndexEstimates();
#ifdef USE_ENTERPRISE
return Indexes::dropCoordinatorEE(collection, iid);
res = Indexes::dropCoordinatorEE(collection, iid);
#else
TRI_ASSERT(collection);
auto& databaseName = collection->vocbase().name();
return ClusterInfo::instance()->dropIndexCoordinator( // drop index
databaseName, std::to_string(collection->id()), iid, 0.0 // args
res = ClusterInfo::instance()->dropIndexCoordinator( // drop index
collection->vocbase().name(), std::to_string(collection->id()), iid, 0.0 // args
);
#endif
events::DropIndex(collection->vocbase().name(), collection->name(),
std::to_string(iid), res.errorNumber());
return res;
} else {
READ_LOCKER(readLocker, collection->vocbase()._inventoryLock);
@ -580,24 +602,35 @@ arangodb::Result Indexes::drop(LogicalCollection* collection, VPackSlice const&
Result res = trx.begin();
if (!res.ok()) {
events::DropIndex(collection->vocbase().name(), collection->name(), "",
res.errorNumber());
return res;
}
LogicalCollection* col = trx.documentCollection();
res = Indexes::extractHandle(collection, trx.resolver(), indexArg, iid);
if (!res.ok()) {
events::DropIndex(collection->vocbase().name(), collection->name(),
std::to_string(iid), res.errorNumber());
return res;
}
std::shared_ptr<Index> idx = collection->lookupIndex(iid);
if (!idx || idx->id() == 0) {
events::DropIndex(collection->vocbase().name(), collection->name(),
std::to_string(iid), TRI_ERROR_ARANGO_INDEX_NOT_FOUND);
return Result(TRI_ERROR_ARANGO_INDEX_NOT_FOUND);
}
if (!idx->canBeDropped()) {
events::DropIndex(collection->vocbase().name(), collection->name(),
std::to_string(iid), TRI_ERROR_FORBIDDEN);
return Result(TRI_ERROR_FORBIDDEN);
}
bool ok = col->dropIndex(idx->id());
return ok ? Result() : Result(TRI_ERROR_FAILED);
int code = ok ? TRI_ERROR_NO_ERROR : TRI_ERROR_FAILED;
events::DropIndex(collection->vocbase().name(), collection->name(),
std::to_string(iid), code);
return Result(code);
}
}

View File

@ -409,7 +409,7 @@ std::shared_ptr<arangodb::LogicalCollection> TRI_vocbase_t::createCollectionWork
auto it = _dataSourceByName.find(name);
if (it != _dataSourceByName.end()) {
events::CreateCollection(name, TRI_ERROR_ARANGO_DUPLICATE_NAME);
events::CreateCollection(this->name(), name, TRI_ERROR_ARANGO_DUPLICATE_NAME);
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DUPLICATE_NAME);
}
@ -423,7 +423,7 @@ std::shared_ptr<arangodb::LogicalCollection> TRI_vocbase_t::createCollectionWork
// Let's try to persist it.
collection->persistPhysicalCollection();
events::CreateCollection(name, TRI_ERROR_NO_ERROR);
events::CreateCollection(this->name(), name, TRI_ERROR_NO_ERROR);
return collection;
} catch (...) {
@ -639,7 +639,7 @@ int TRI_vocbase_t::dropCollectionWorker(arangodb::LogicalCollection* collection,
TRI_ASSERT(!locker.isLocked());
if (timeout >= 0.0 && TRI_microtime() > startTime + timeout) {
events::DropCollection(colName, TRI_ERROR_LOCK_TIMEOUT);
events::DropCollection(name(), colName, TRI_ERROR_LOCK_TIMEOUT);
return TRI_ERROR_LOCK_TIMEOUT;
}
@ -685,11 +685,11 @@ int TRI_vocbase_t::dropCollectionWorker(arangodb::LogicalCollection* collection,
engine->changeCollection(*this, *collection, doSync);
} catch (arangodb::basics::Exception const& ex) {
collection->deleted(false);
events::DropCollection(colName, ex.code());
events::DropCollection(name(), colName, ex.code());
return ex.code();
} catch (std::exception const&) {
collection->deleted(false);
events::DropCollection(colName, TRI_ERROR_INTERNAL);
events::DropCollection(name(), colName, TRI_ERROR_INTERNAL);
return TRI_ERROR_INTERNAL;
}
}
@ -720,6 +720,7 @@ int TRI_vocbase_t::dropCollectionWorker(arangodb::LogicalCollection* collection,
false); // always a full-update
if (!res.ok()) {
events::DropCollection(name(), colName, res.errorNumber());
return res.errorNumber();
}
@ -735,11 +736,11 @@ int TRI_vocbase_t::dropCollectionWorker(arangodb::LogicalCollection* collection,
}
default: {
// unknown status
events::DropCollection(colName, TRI_ERROR_INTERNAL);
events::DropCollection(name(), colName, TRI_ERROR_INTERNAL);
return TRI_ERROR_INTERNAL;
}
}
events::DropCollection(colName, TRI_ERROR_NO_ERROR);
events::DropCollection(name(), colName, TRI_ERROR_NO_ERROR);
return TRI_ERROR_NO_ERROR;
}
@ -1078,6 +1079,12 @@ std::shared_ptr<arangodb::LogicalCollection> TRI_vocbase_t::createCollection(
arangodb::velocypack::Slice parameters) {
// check that the name does not contain any strange characters
if (!IsAllowedName(parameters)) {
std::string name;
if (parameters.isObject()) {
name = VelocyPackHelper::getStringValue(parameters,
StaticStrings::DataSourceName, "");
}
events::CreateCollection(this->name(), name, TRI_ERROR_ARANGO_ILLEGAL_NAME);
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_ILLEGAL_NAME);
}
@ -1190,12 +1197,14 @@ arangodb::Result TRI_vocbase_t::dropCollection(TRI_voc_cid_t cid,
auto collection = lookupCollection(cid);
if (!collection) {
events::DropCollection(name(), "", TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND);
return TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND;
}
StorageEngine* engine = EngineSelectorFeature::ENGINE;
if (!engine) {
events::DropCollection(name(), collection->name(), TRI_ERROR_INTERNAL);
return arangodb::Result(
TRI_ERROR_INTERNAL,
std::string(
@ -1205,6 +1214,7 @@ arangodb::Result TRI_vocbase_t::dropCollection(TRI_voc_cid_t cid,
if (!allowDropSystem && collection->system() && !engine->inRecovery()) {
// prevent dropping of system collections
events::DropCollection(name(), collection->name(), TRI_ERROR_FORBIDDEN);
return TRI_set_errno(TRI_ERROR_FORBIDDEN);
}
@ -1231,6 +1241,7 @@ arangodb::Result TRI_vocbase_t::dropCollection(TRI_voc_cid_t cid,
}
if (state == DROP_PERFORM || state == DROP_EXIT) {
events::DropCollection(name(), collection->name(), res);
return res;
}
@ -1501,6 +1512,12 @@ std::shared_ptr<arangodb::LogicalView> TRI_vocbase_t::createView(arangodb::veloc
auto* engine = EngineSelectorFeature::ENGINE;
if (!engine) {
std::string n;
if (parameters.isObject()) {
n = VelocyPackHelper::getStringValue(parameters,
StaticStrings::DataSourceName, "");
}
events::CreateView(name(), n, TRI_ERROR_INTERNAL);
THROW_ARANGO_EXCEPTION_MESSAGE(
TRI_ERROR_INTERNAL,
"failure to get storage engine during creation of view");
@ -1508,6 +1525,12 @@ std::shared_ptr<arangodb::LogicalView> TRI_vocbase_t::createView(arangodb::veloc
// check that the name does not contain any strange characters
if (!IsAllowedName(parameters)) {
std::string n;
if (parameters.isObject()) {
n = VelocyPackHelper::getStringValue(parameters,
StaticStrings::DataSourceName, "");
}
events::CreateView(name(), n, TRI_ERROR_ARANGO_ILLEGAL_NAME);
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_ILLEGAL_NAME);
}
@ -1515,6 +1538,12 @@ std::shared_ptr<arangodb::LogicalView> TRI_vocbase_t::createView(arangodb::veloc
auto res = LogicalView::instantiate(view, *this, parameters);
if (!res.ok() || !view) {
std::string n;
if (parameters.isObject()) {
n = VelocyPackHelper::getStringValue(parameters,
StaticStrings::DataSourceName, "");
}
events::CreateView(name(), n, TRI_ERROR_INTERNAL);
THROW_ARANGO_EXCEPTION_MESSAGE(
TRI_ERROR_INTERNAL,
std::string("failed to instantiate view from definition: ") + parameters.toString());
@ -1525,8 +1554,7 @@ std::shared_ptr<arangodb::LogicalView> TRI_vocbase_t::createView(arangodb::veloc
auto itr = _dataSourceByName.find(view->name());
if (itr != _dataSourceByName.end()) {
events::CreateView(view->name(), TRI_ERROR_ARANGO_DUPLICATE_NAME);
events::CreateView(name(), view->name(), TRI_ERROR_ARANGO_DUPLICATE_NAME);
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DUPLICATE_NAME);
}
@ -1541,11 +1569,11 @@ std::shared_ptr<arangodb::LogicalView> TRI_vocbase_t::createView(arangodb::veloc
}
} catch (...) {
unregisterView(*view);
events::CreateView(name(), view->name(), TRI_ERROR_INTERNAL);
throw;
}
events::CreateView(view->name(), TRI_ERROR_NO_ERROR);
events::CreateView(name(), view->name(), TRI_ERROR_NO_ERROR);
if (DatabaseFeature::DATABASE != nullptr &&
DatabaseFeature::DATABASE->versionTracker() != nullptr) {
@ -1563,12 +1591,14 @@ arangodb::Result TRI_vocbase_t::dropView(TRI_voc_cid_t cid, bool allowDropSystem
auto const view = lookupView(cid);
if (!view) {
events::DropView(name(), "", TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND);
return TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND;
}
StorageEngine* engine = EngineSelectorFeature::ENGINE;
if (!engine) {
events::DropView(name(), view->name(), TRI_ERROR_INTERNAL);
return arangodb::Result(
TRI_ERROR_INTERNAL,
std::string("failed to find StorageEngine while dropping view '") +
@ -1576,6 +1606,7 @@ arangodb::Result TRI_vocbase_t::dropView(TRI_voc_cid_t cid, bool allowDropSystem
}
if (!allowDropSystem && view->system() && !engine->inRecovery()) {
events::DropView(name(), view->name(), TRI_ERROR_FORBIDDEN);
return TRI_ERROR_FORBIDDEN; // prevent dropping of system views
}
@ -1618,6 +1649,7 @@ arangodb::Result TRI_vocbase_t::dropView(TRI_voc_cid_t cid, bool allowDropSystem
auto res = engine->dropView(*this, *view);
if (!res.ok()) {
events::DropView(name(), view->name(), res.errorNumber());
return res;
}
@ -1632,7 +1664,7 @@ arangodb::Result TRI_vocbase_t::dropView(TRI_voc_cid_t cid, bool allowDropSystem
locker.unlock();
writeLocker.unlock();
events::DropView(view->name(), TRI_ERROR_NO_ERROR);
events::DropView(name(), view->name(), TRI_ERROR_NO_ERROR);
if (DatabaseFeature::DATABASE != nullptr &&
DatabaseFeature::DATABASE->versionTracker() != nullptr) {

View File

@ -1482,6 +1482,11 @@ function startArango (protocol, options, addArgs, rootDir, role) {
args['server.endpoint'] = endpoint;
args['database.directory'] = dataDir;
args['log.file'] = fs.join(rootDir, 'log');
if (options.auditLoggingEnabled) {
args['audit.output'] = 'file://' + fs.join(rootDir, 'audit.log');
args['server.statistics'] = false;
args['foxx.queues'] = false;
}
if (protocol === 'ssl') {
args['ssl.keyfile'] = fs.join('UnitTests', 'server.pem');

View File

@ -26,7 +26,8 @@
// //////////////////////////////////////////////////////////////////////////////
const functionsDocumentation = {
'audit': 'audit log tests'
'audit_server': 'audit log tests executed on server',
'audit_client': 'audit log tests executed in client'
};
const optionsDocumentation = [
@ -45,40 +46,41 @@ const RESET = require('internal').COLORS.COLOR_RESET;
// const YELLOW = require('internal').COLORS.COLOR_YELLOW;
const testPaths = {
audit: [tu.pathForTesting('server/audit')]
audit_server: [tu.pathForTesting('common/audit'), tu.pathForTesting('server/audit')],
audit_client: [tu.pathForTesting('common/audit'), tu.pathForTesting('client/audit')]
};
const sharedConf = {
'audit.output': 'file://' + fs.getTempFile()
};
function auditLog(options) {
if (options.skipAudit === true) {
print('skipping audit log tests!');
return {
auditLog: {
status: true,
skipped: true
function auditLog(onServer) {
return function(options) {
if (options.skipAudit === true) {
print('skipping audit log tests!');
return {
auditLog: {
status: true,
skipped: true
}
};
}
let opts = {
audit: {
name: 'audit_' + onServer ? 'server' : 'client'
}
};
}
let opts = {
audit: {
name: 'audit',
conf: sharedConf
}
options.auditLoggingEnabled = true;
print(CYAN + 'Audit log server tests...' + RESET);
let testCases = tu.scanTestPaths(testPaths['audit_' + (onServer ? 'server' : 'client')]);
return tu.performTests(options, testCases, 'audit', onServer ? tu.runThere : tu.runInArangosh);
};
print(CYAN + 'Audit log tests...' + RESET);
let testCases = tu.scanTestPaths(testPaths.audit);
return tu.performTests(options, testCases, 'audit', tu.runThere, opts.audit.conf);
}
exports.setup = function (testFns, defaultFns, opts, fnDocs, optionsDoc, allTestPaths) {
Object.assign(allTestPaths, testPaths);
testFns['audit'] = auditLog;
testFns['audit_server'] = auditLog(true);
testFns['audit_client'] = auditLog(false);
// turn off test by default.
opts['skipAudit'] = true;

View File

@ -146,11 +146,11 @@ LogTopic Logger::VIEWS("views", LogLevel::FATAL);
#ifdef USE_ENTERPRISE
LogTopic LdapFeature::LDAP("ldap", LogLevel::INFO);
LogTopic AuditFeature::AUDIT_AUTHENTICATION("audit-authentication", LogLevel::INFO);
LogTopic AuditFeature::AUDIT_AUTHENTICATION("audit-authentication", LogLevel::DEBUG);
LogTopic AuditFeature::AUDIT_DATABASE("audit-database", LogLevel::INFO);
LogTopic AuditFeature::AUDIT_COLLECTION("audit-collection", LogLevel::INFO);
LogTopic AuditFeature::AUDIT_VIEW("audit-view", LogLevel::INFO);
LogTopic AuditFeature::AUDIT_DOCUMENT("audit-documentation", LogLevel::INFO);
LogTopic AuditFeature::AUDIT_DOCUMENT("audit-document", LogLevel::DEBUG);
LogTopic AuditFeature::AUDIT_SERVICE("audit-service", LogLevel::INFO);
#endif