mirror of https://gitee.com/bigwinds/arangodb
added CURRENT_USER function for AQL
This commit is contained in:
parent
f3d2e28379
commit
02a532a122
|
@ -1,6 +1,13 @@
|
|||
v2.1.0 (XXXX-XX-XX)
|
||||
-------------------
|
||||
|
||||
* added AQL CURRENT_USER() function
|
||||
|
||||
This function returns the current user from an AQL query. The current user is the
|
||||
username that was specified in the `Authorization` HTTP header of the request. If
|
||||
authentication is turned off or the query was executed outside a request context,
|
||||
the function will return `null`.
|
||||
|
||||
* fixed issue #796: Searching with newline chars broken?
|
||||
|
||||
fixed slightly different handling of backslash escape characters in a few
|
||||
|
|
|
@ -1751,6 +1751,11 @@ function categories:
|
|||
- @FN{COLLECTIONS()}: Returns a list of collections. Each collection is returned as a document
|
||||
with attributes `name` and `_id`
|
||||
|
||||
- @FN{CURRENT_USER()}: Returns the name of the current user. The current user is the user
|
||||
account name that was specified in the `Authorization` HTTP header of the request. It will
|
||||
only be populated if authentication on the server is turned on, and if the query was executed
|
||||
inside a request context. Otherwise, the return value of this function will be `null`.
|
||||
|
||||
- @FN{DOCUMENT(@FA{collection}, @FA{id})}: Returns the document which is uniquely identified by
|
||||
the @FA{id}. ArangoDB will try to find the document using the `_id` value of the document
|
||||
in the specified collection. If there is a mismatch between the @FA{collection} passed and
|
||||
|
|
|
@ -719,6 +719,7 @@ TRI_associative_pointer_t* TRI_CreateFunctionsAql (void) {
|
|||
REGISTER_FUNCTION("FIRST_DOCUMENT", "FIRST_DOCUMENT", true, false, ".|+", NULL);
|
||||
REGISTER_FUNCTION("PARSE_IDENTIFIER", "PARSE_IDENTIFIER", true, false, ".", NULL);
|
||||
REGISTER_FUNCTION("SKIPLIST", "SKIPLIST_QUERY", false, false, "h,a|n,n", NULL);
|
||||
REGISTER_FUNCTION("CURRENT_USER", "CURRENT_USER", false, false, "", NULL);
|
||||
|
||||
if (! result) {
|
||||
TRI_FreeFunctionsAql(functions);
|
||||
|
|
|
@ -668,12 +668,12 @@ static TRI_action_result_t ExecuteActionVocbase (TRI_vocbase_t* vocbase,
|
|||
v8::Handle<v8::Function> callback,
|
||||
HttpRequest* request) {
|
||||
TRI_action_result_t result;
|
||||
TRI_v8_global_t const* v8g;
|
||||
TRI_v8_global_t* v8g;
|
||||
|
||||
v8::HandleScope scope;
|
||||
v8::TryCatch tryCatch;
|
||||
|
||||
v8g = (TRI_v8_global_t const*) isolate->GetData();
|
||||
v8g = static_cast<TRI_v8_global_t*>(isolate->GetData());
|
||||
|
||||
v8::Handle<v8::Object> req = RequestCppToV8(v8g, request);
|
||||
|
||||
|
@ -698,12 +698,22 @@ static TRI_action_result_t ExecuteActionVocbase (TRI_vocbase_t* vocbase,
|
|||
// copy full path
|
||||
req->Set(v8g->PathKey, v8::String::New(path.c_str(), (int) path.size()));
|
||||
|
||||
// execute the callback
|
||||
// create the response object
|
||||
v8::Handle<v8::Object> res = v8::Object::New();
|
||||
|
||||
// register request & response in the context
|
||||
v8g->_currentRequest = req;
|
||||
v8g->_currentResponse = res;
|
||||
|
||||
// execute the callback
|
||||
v8::Handle<v8::Value> args[2] = { req, res };
|
||||
|
||||
callback->Call(callback, 2, args);
|
||||
|
||||
// invalidate request / response objects
|
||||
v8g->_currentRequest = v8::Undefined();
|
||||
v8g->_currentResponse = v8::Undefined();
|
||||
|
||||
// convert the result
|
||||
result.isValid = true;
|
||||
|
||||
|
@ -859,6 +869,40 @@ static v8::Handle<v8::Value> JS_ExecuteGlobalContextFunction (v8::Arguments cons
|
|||
return scope.Close(v8::Undefined());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief get the current request
|
||||
///
|
||||
/// @FUN{internal.getCurrentRequest()}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static v8::Handle<v8::Value> JS_GetCurrentRequest (v8::Arguments const& argv) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
if (argv.Length() != 0) {
|
||||
TRI_V8_EXCEPTION_USAGE(scope, "getCurrentRequest()");
|
||||
}
|
||||
|
||||
TRI_v8_global_t* v8g = static_cast<TRI_v8_global_t*>(v8::Isolate::GetCurrent()->GetData());
|
||||
return scope.Close(v8g->_currentRequest);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief get the current response
|
||||
///
|
||||
/// @FUN{internal.getCurrentRequest()}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static v8::Handle<v8::Value> JS_GetCurrentResponse (v8::Arguments const& argv) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
if (argv.Length() != 0) {
|
||||
TRI_V8_EXCEPTION_USAGE(scope, "getCurrentResponse()");
|
||||
}
|
||||
|
||||
TRI_v8_global_t* v8g = static_cast<TRI_v8_global_t*>(v8::Isolate::GetCurrent()->GetData());
|
||||
return scope.Close(v8g->_currentResponse);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief function to test sharding
|
||||
///
|
||||
|
@ -884,8 +928,7 @@ class CallbackTest : public ClusterCommCallback {
|
|||
static v8::Handle<v8::Value> JS_ClusterTest (v8::Arguments const& argv) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
TRI_v8_global_t* v8g = (TRI_v8_global_t*)
|
||||
v8::Isolate::GetCurrent()->GetData();
|
||||
TRI_v8_global_t* v8g = static_cast<TRI_v8_global_t*>(v8::Isolate::GetCurrent()->GetData());
|
||||
|
||||
if (argv.Length() != 9) {
|
||||
TRI_V8_EXCEPTION_USAGE(scope,
|
||||
|
@ -1275,6 +1318,8 @@ void TRI_InitV8Actions (v8::Handle<v8::Context> context,
|
|||
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_DEFINE_ACTION", JS_DefineAction);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_EXECUTE_GLOBAL_CONTEXT_FUNCTION", JS_ExecuteGlobalContextFunction);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_GET_CURRENT_REQUEST", JS_GetCurrentRequest);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_GET_CURRENT_RESPONSE", JS_GetCurrentResponse);
|
||||
|
||||
#ifdef TRI_ENABLE_CLUSTER
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_CLUSTER_TEST", JS_ClusterTest, true);
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
REPLICATION_SYNCHRONISE, REPLICATION_SERVER_ID, CONFIGURE_ENDPOINT, REMOVE_ENDPOINT, LIST_ENDPOINTS,
|
||||
SYS_BASE64DECODE, SYS_BASE64ENCODE, SYS_DEBUG_SEGFAULT,
|
||||
SYS_DEBUG_CAN_USE_FAILAT, SYS_DEBUG_SET_FAILAT, SYS_DEBUG_REMOVE_FAILAT, SYS_DEBUG_CLEAR_FAILAT,
|
||||
SYS_DOWNLOAD, SYS_EXECUTE, SYS_LOAD, SYS_LOG_LEVEL, SYS_MD5, SYS_OUTPUT, SYS_PROCESS_STATISTICS,
|
||||
SYS_DOWNLOAD, SYS_EXECUTE, SYS_GET_CURRENT_REQUEST, SYS_GET_CURRENT_RESPONSE,
|
||||
SYS_LOAD, SYS_LOG_LEVEL, SYS_MD5, SYS_OUTPUT, SYS_PROCESS_STATISTICS,
|
||||
SYS_RAND, SYS_SERVER_STATISTICS, SYS_SPRINTF, SYS_TIME, SYS_START_PAGER, SYS_STOP_PAGER,
|
||||
SYS_SHA256, SYS_SLEEP, SYS_WAIT, SYS_PARSE, SYS_IMPORT_CSV_FILE, SYS_IMPORT_JSON_FILE, SYS_LOG,
|
||||
SYS_GEN_RANDOM_NUMBERS, SYS_GEN_RANDOM_ALPHA_NUMBERS, SYS_GEN_RANDOM_SALT, SYS_CREATE_NONCE,
|
||||
|
@ -481,6 +482,24 @@
|
|||
delete SYS_EXECUTE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief getCurrentRequest
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
if (typeof SYS_GET_CURRENT_REQUEST !== "undefined") {
|
||||
exports.getCurrentRequest = SYS_GET_CURRENT_REQUEST;
|
||||
delete SYS_GET_CURRENT_REQUEST;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief getCurrentResponse
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
if (typeof SYS_GET_CURRENT_RESPONSE !== "undefined") {
|
||||
exports.getCurrentResponse = SYS_GET_CURRENT_RESPONSE;
|
||||
delete SYS_GET_CURRENT_RESPONSE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief extend
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
REPLICATION_SYNCHRONISE, REPLICATION_SERVER_ID, CONFIGURE_ENDPOINT, REMOVE_ENDPOINT, LIST_ENDPOINTS,
|
||||
SYS_BASE64DECODE, SYS_BASE64ENCODE, SYS_DEBUG_SEGFAULT,
|
||||
SYS_DEBUG_CAN_USE_FAILAT, SYS_DEBUG_SET_FAILAT, SYS_DEBUG_REMOVE_FAILAT, SYS_DEBUG_CLEAR_FAILAT,
|
||||
SYS_DOWNLOAD, SYS_EXECUTE, SYS_LOAD, SYS_LOG_LEVEL, SYS_MD5, SYS_OUTPUT, SYS_PROCESS_STATISTICS,
|
||||
SYS_DOWNLOAD, SYS_EXECUTE, SYS_GET_CURRENT_REQUEST, SYS_GET_CURRENT_RESPONSE,
|
||||
SYS_LOAD, SYS_LOG_LEVEL, SYS_MD5, SYS_OUTPUT, SYS_PROCESS_STATISTICS,
|
||||
SYS_RAND, SYS_SERVER_STATISTICS, SYS_SPRINTF, SYS_TIME, SYS_START_PAGER, SYS_STOP_PAGER,
|
||||
SYS_SHA256, SYS_SLEEP, SYS_WAIT, SYS_PARSE, SYS_IMPORT_CSV_FILE, SYS_IMPORT_JSON_FILE, SYS_LOG,
|
||||
SYS_GEN_RANDOM_NUMBERS, SYS_GEN_RANDOM_ALPHA_NUMBERS, SYS_GEN_RANDOM_SALT, SYS_CREATE_NONCE,
|
||||
|
@ -481,6 +482,24 @@
|
|||
delete SYS_EXECUTE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief getCurrentRequest
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
if (typeof SYS_GET_CURRENT_REQUEST !== "undefined") {
|
||||
exports.getCurrentRequest = SYS_GET_CURRENT_REQUEST;
|
||||
delete SYS_GET_CURRENT_REQUEST;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief getCurrentResponse
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
if (typeof SYS_GET_CURRENT_RESPONSE !== "undefined") {
|
||||
exports.getCurrentResponse = SYS_GET_CURRENT_RESPONSE;
|
||||
delete SYS_GET_CURRENT_RESPONSE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief extend
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -3678,6 +3678,24 @@ function SLEEP (duration) {
|
|||
INTERNAL.sleep(duration);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief return the current user
|
||||
/// note: this might be null if the query is not executed in a context that
|
||||
/// has a user
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function CURRENT_USER () {
|
||||
"use strict";
|
||||
|
||||
var req = INTERNAL.getCurrentRequest();
|
||||
|
||||
if (typeof req === 'object') {
|
||||
return req.user;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief always fail
|
||||
///
|
||||
|
@ -4368,6 +4386,7 @@ exports.MERGE_RECURSIVE = MERGE_RECURSIVE;
|
|||
exports.MATCHES = MATCHES;
|
||||
exports.PASSTHRU = PASSTHRU;
|
||||
exports.SLEEP = SLEEP;
|
||||
exports.CURRENT_USER = CURRENT_USER;
|
||||
exports.FAIL = FAIL;
|
||||
|
||||
exports.reload = reloadUserFunctions;
|
||||
|
|
|
@ -3753,6 +3753,32 @@ function ahuacatlFunctionsTestSuite () {
|
|||
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, "RETURN STDDEV_POPULATION({ })");
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test current user function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testCurrentUser : function () {
|
||||
var actual = getQueryResults("RETURN CURRENT_USER()");
|
||||
// there is no current user in the non-request context
|
||||
assertEqual([ null ], actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test sleep function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testSleep : function () {
|
||||
var start = require("internal").time();
|
||||
var actual = getQueryResults("LET a = SLEEP(2) RETURN 1");
|
||||
|
||||
var diff = Math.round(require("internal").time() - start, 1);
|
||||
|
||||
assertEqual([ 1 ], actual);
|
||||
|
||||
// allow some tolerance for the time diff
|
||||
assertTrue(diff >= 1.5 && diff <= 2.5);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test non-existing functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -133,6 +133,8 @@ TRI_v8_global_s::TRI_v8_global_s (v8::Isolate* isolate)
|
|||
_RevKey(),
|
||||
_ToKey(),
|
||||
|
||||
_currentRequest(0),
|
||||
_currentResponse(0),
|
||||
_currentTransaction(0),
|
||||
_server(0),
|
||||
_vocbase(0),
|
||||
|
|
|
@ -730,6 +730,18 @@ typedef struct TRI_v8_global_s {
|
|||
// --SECTION-- DATABASE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief currently request object (might be invalid!)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
v8::Handle<v8::Value> _currentRequest;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief currently response object (might be invalid!)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
v8::Handle<v8::Value> _currentResponse;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief currently running transaction
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
Loading…
Reference in New Issue