mirror of https://gitee.com/bigwinds/arangodb
Improved audit logging (#8740)
This commit is contained in:
parent
62ed576c8e
commit
777ba1a364
|
@ -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`.
|
||||
|
|
|
@ -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
|
||||
```
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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() << "'";
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
// -----------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
// -----------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue