mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of github.com:triAGENS/ArangoDB into devel
This commit is contained in:
commit
b7464677cc
|
@ -1,6 +1,10 @@
|
||||||
v1.3.0-alpha2 (XXXX-XX-XX)
|
v1.3.0-alpha2 (XXXX-XX-XX)
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
|
* issue #498: fixed reload of authentication info when using
|
||||||
|
`require("org/arangodb/users").reload()`
|
||||||
|
|
||||||
|
|
||||||
* added more precision for requests statistics figures
|
* added more precision for requests statistics figures
|
||||||
|
|
||||||
* added "sum" attribute for individual statistics results in statistics API
|
* added "sum" attribute for individual statistics results in statistics API
|
||||||
|
|
|
@ -39,11 +39,11 @@ You **must** specify a name and a version number for your application, otherwise
|
||||||
|
|
||||||
Now your application is done. Start ArangoDB as follows:
|
Now your application is done. Start ArangoDB as follows:
|
||||||
|
|
||||||
arangod --javascript.dev-app-path my_app /tmp/fancy_db
|
$ arangod --javascript.dev-app-path my_app /tmp/fancy_db
|
||||||
|
|
||||||
To include it to the list of apps running on your ArangoDB instance, start the ArangoDB shell and add your new application:
|
To include it to the list of apps running on your ArangoDB instance, start the ArangoDB shell and add your new application:
|
||||||
|
|
||||||
$ ./bin/arango
|
$ arangosh
|
||||||
arangosh> aal = require('org/arangodb/aal');
|
arangosh> aal = require('org/arangodb/aal');
|
||||||
arangosh> aal.installDevApp('my_app', '/my');
|
arangosh> aal.installDevApp('my_app', '/my');
|
||||||
|
|
||||||
|
|
|
@ -399,7 +399,8 @@ void ArangoServer::buildApplicationServer () {
|
||||||
_applicationScheduler,
|
_applicationScheduler,
|
||||||
_applicationDispatcher,
|
_applicationDispatcher,
|
||||||
"arangodb",
|
"arangodb",
|
||||||
TRI_CheckAuthenticationAuthInfo);
|
TRI_CheckAuthenticationAuthInfo,
|
||||||
|
TRI_FlushAuthenticationAuthInfo);
|
||||||
_applicationServer->addFeature(_applicationEndpointServer);
|
_applicationServer->addFeature(_applicationEndpointServer);
|
||||||
|
|
||||||
// .............................................................................
|
// .............................................................................
|
||||||
|
|
|
@ -202,6 +202,7 @@ static TRI_vocbase_auth_t* ConvertAuthInfo (TRI_vocbase_t* vocbase,
|
||||||
}
|
}
|
||||||
|
|
||||||
result = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_vocbase_auth_t), true);
|
result = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_vocbase_auth_t), true);
|
||||||
|
|
||||||
if (result == NULL) {
|
if (result == NULL) {
|
||||||
TRI_FreeString(TRI_CORE_MEM_ZONE, user);
|
TRI_FreeString(TRI_CORE_MEM_ZONE, user);
|
||||||
TRI_FreeString(TRI_CORE_MEM_ZONE, password);
|
TRI_FreeString(TRI_CORE_MEM_ZONE, password);
|
||||||
|
@ -266,10 +267,10 @@ bool TRI_LoadAuthInfo (TRI_vocbase_t* vocbase) {
|
||||||
TRI_WriteLockReadWriteLock(&vocbase->_authInfoLock);
|
TRI_WriteLockReadWriteLock(&vocbase->_authInfoLock);
|
||||||
|
|
||||||
// .............................................................................
|
// .............................................................................
|
||||||
// inside a read transaction
|
// inside a write transaction
|
||||||
// .............................................................................
|
// .............................................................................
|
||||||
|
|
||||||
collection->_collection->beginRead(collection->_collection);
|
collection->_collection->beginWrite(collection->_collection);
|
||||||
|
|
||||||
beg = primary->_primaryIndex._table;
|
beg = primary->_primaryIndex._table;
|
||||||
end = beg + primary->_primaryIndex._nrAlloc;
|
end = beg + primary->_primaryIndex._nrAlloc;
|
||||||
|
@ -302,12 +303,13 @@ bool TRI_LoadAuthInfo (TRI_vocbase_t* vocbase) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
collection->_collection->endRead(collection->_collection);
|
collection->_collection->endWrite(collection->_collection);
|
||||||
|
|
||||||
// .............................................................................
|
// .............................................................................
|
||||||
// outside a read transaction
|
// outside a write transaction
|
||||||
// .............................................................................
|
// .............................................................................
|
||||||
|
|
||||||
|
vocbase->_authInfoFlush = true;
|
||||||
TRI_WriteUnlockReadWriteLock(&vocbase->_authInfoLock);
|
TRI_WriteUnlockReadWriteLock(&vocbase->_authInfoLock);
|
||||||
|
|
||||||
TRI_ReleaseCollectionVocBase(vocbase, collection);
|
TRI_ReleaseCollectionVocBase(vocbase, collection);
|
||||||
|
@ -358,11 +360,33 @@ void TRI_DestroyAuthInfo (TRI_vocbase_t* vocbase) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vocbase->_authInfo._nrUsed = 0;
|
vocbase->_authInfo._nrUsed = 0;
|
||||||
|
|
||||||
TRI_WriteUnlockReadWriteLock(&vocbase->_authInfoLock);
|
TRI_WriteUnlockReadWriteLock(&vocbase->_authInfoLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief returns whether some externally cached authentication info
|
||||||
|
/// should be flushed, by querying the internal flush flag
|
||||||
|
/// checking the information may also change the state of the flag
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool TRI_FlushAuthenticationAuthInfo () {
|
||||||
|
bool res;
|
||||||
|
|
||||||
|
TRI_ReadLockReadWriteLock(&DefaultAuthInfo->_authInfoLock);
|
||||||
|
res = DefaultAuthInfo->_authInfoFlush;
|
||||||
|
TRI_ReadUnlockReadWriteLock(&DefaultAuthInfo->_authInfoLock);
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
TRI_WriteLockReadWriteLock(&DefaultAuthInfo->_authInfoLock);
|
||||||
|
DefaultAuthInfo->_authInfoFlush = false;
|
||||||
|
TRI_WriteUnlockReadWriteLock(&DefaultAuthInfo->_authInfoLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief checks the authentication
|
/// @brief checks the authentication
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -379,16 +403,11 @@ bool TRI_CheckAuthenticationAuthInfo (char const* username,
|
||||||
|
|
||||||
assert(DefaultAuthInfo);
|
assert(DefaultAuthInfo);
|
||||||
|
|
||||||
// lockup username
|
// look up username
|
||||||
TRI_ReadLockReadWriteLock(&DefaultAuthInfo->_authInfoLock);
|
TRI_ReadLockReadWriteLock(&DefaultAuthInfo->_authInfoLock);
|
||||||
auth = TRI_LookupByKeyAssociativePointer(&DefaultAuthInfo->_authInfo, username);
|
auth = TRI_LookupByKeyAssociativePointer(&DefaultAuthInfo->_authInfo, username);
|
||||||
|
|
||||||
if (auth == 0) {
|
if (auth == NULL || ! auth->_active) {
|
||||||
TRI_ReadUnlockReadWriteLock(&DefaultAuthInfo->_authInfoLock);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! auth->_active) {
|
|
||||||
TRI_ReadUnlockReadWriteLock(&DefaultAuthInfo->_authInfoLock);
|
TRI_ReadUnlockReadWriteLock(&DefaultAuthInfo->_authInfoLock);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,6 +98,14 @@ bool TRI_ReloadAuthInfo (struct TRI_vocbase_s*);
|
||||||
|
|
||||||
void TRI_DestroyAuthInfo (struct TRI_vocbase_s*);
|
void TRI_DestroyAuthInfo (struct TRI_vocbase_s*);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief returns whether some externally cached authentication info
|
||||||
|
/// should be flushed, by querying the internal flush flag
|
||||||
|
/// checking the information may also change the state of the flag
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool TRI_FlushAuthenticationAuthInfo (void);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief checks the authentication
|
/// @brief checks the authentication
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -1260,6 +1260,7 @@ TRI_vocbase_t* TRI_OpenVocBase (char const* path) {
|
||||||
|
|
||||||
TRI_InitReadWriteLock(&vocbase->_authInfoLock);
|
TRI_InitReadWriteLock(&vocbase->_authInfoLock);
|
||||||
TRI_InitReadWriteLock(&vocbase->_lock);
|
TRI_InitReadWriteLock(&vocbase->_lock);
|
||||||
|
vocbase->_authInfoFlush = true;
|
||||||
|
|
||||||
vocbase->_syncWaiters = 0;
|
vocbase->_syncWaiters = 0;
|
||||||
TRI_InitCondition(&vocbase->_syncWaitersCondition);
|
TRI_InitCondition(&vocbase->_syncWaitersCondition);
|
||||||
|
|
|
@ -309,6 +309,7 @@ typedef struct TRI_vocbase_s {
|
||||||
|
|
||||||
TRI_associative_pointer_t _authInfo;
|
TRI_associative_pointer_t _authInfo;
|
||||||
TRI_read_write_lock_t _authInfoLock;
|
TRI_read_write_lock_t _authInfoLock;
|
||||||
|
bool _authInfoFlush;
|
||||||
|
|
||||||
struct TRI_transaction_context_s* _transactionContext;
|
struct TRI_transaction_context_s* _transactionContext;
|
||||||
|
|
||||||
|
|
|
@ -81,13 +81,15 @@ ApplicationEndpointServer::ApplicationEndpointServer (ApplicationServer* applica
|
||||||
ApplicationScheduler* applicationScheduler,
|
ApplicationScheduler* applicationScheduler,
|
||||||
ApplicationDispatcher* applicationDispatcher,
|
ApplicationDispatcher* applicationDispatcher,
|
||||||
std::string const& authenticationRealm,
|
std::string const& authenticationRealm,
|
||||||
HttpHandlerFactory::auth_fptr checkAuthentication)
|
HttpHandlerFactory::auth_fptr checkAuthentication,
|
||||||
|
HttpHandlerFactory::flush_fptr flushAuthentication)
|
||||||
: ApplicationFeature("EndpointServer"),
|
: ApplicationFeature("EndpointServer"),
|
||||||
_applicationServer(applicationServer),
|
_applicationServer(applicationServer),
|
||||||
_applicationScheduler(applicationScheduler),
|
_applicationScheduler(applicationScheduler),
|
||||||
_applicationDispatcher(applicationDispatcher),
|
_applicationDispatcher(applicationDispatcher),
|
||||||
_authenticationRealm(authenticationRealm),
|
_authenticationRealm(authenticationRealm),
|
||||||
_checkAuthentication(checkAuthentication),
|
_checkAuthentication(checkAuthentication),
|
||||||
|
_flushAuthentication(flushAuthentication),
|
||||||
_handlerFactory(0),
|
_handlerFactory(0),
|
||||||
_servers(),
|
_servers(),
|
||||||
_endpointList(),
|
_endpointList(),
|
||||||
|
@ -289,7 +291,9 @@ bool ApplicationEndpointServer::prepare () {
|
||||||
// dump used endpoints for user information
|
// dump used endpoints for user information
|
||||||
_endpointList.dump();
|
_endpointList.dump();
|
||||||
|
|
||||||
_handlerFactory = new HttpHandlerFactory(_authenticationRealm, _checkAuthentication);
|
_handlerFactory = new HttpHandlerFactory(_authenticationRealm,
|
||||||
|
_checkAuthentication,
|
||||||
|
_flushAuthentication);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,8 @@ namespace triagens {
|
||||||
ApplicationScheduler*,
|
ApplicationScheduler*,
|
||||||
ApplicationDispatcher*,
|
ApplicationDispatcher*,
|
||||||
std::string const&,
|
std::string const&,
|
||||||
HttpHandlerFactory::auth_fptr);
|
HttpHandlerFactory::auth_fptr,
|
||||||
|
HttpHandlerFactory::flush_fptr);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief destructor
|
/// @brief destructor
|
||||||
|
@ -252,6 +253,12 @@ namespace triagens {
|
||||||
|
|
||||||
HttpHandlerFactory::auth_fptr _checkAuthentication;
|
HttpHandlerFactory::auth_fptr _checkAuthentication;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief authentication cache flush callback function
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
HttpHandlerFactory::flush_fptr _flushAuthentication;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief the handler factory
|
/// @brief the handler factory
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -56,9 +56,11 @@ using namespace std;
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
HttpHandlerFactory::HttpHandlerFactory (std::string const& authenticationRealm,
|
HttpHandlerFactory::HttpHandlerFactory (std::string const& authenticationRealm,
|
||||||
auth_fptr checkAuthentication)
|
auth_fptr checkAuthentication,
|
||||||
|
flush_fptr flushAuthentication)
|
||||||
: _authenticationRealm(authenticationRealm),
|
: _authenticationRealm(authenticationRealm),
|
||||||
_checkAuthentication(checkAuthentication),
|
_checkAuthentication(checkAuthentication),
|
||||||
|
_flushAuthentication(flushAuthentication),
|
||||||
_requireAuthentication(true),
|
_requireAuthentication(true),
|
||||||
_notFound(0) {
|
_notFound(0) {
|
||||||
}
|
}
|
||||||
|
@ -70,6 +72,7 @@ HttpHandlerFactory::HttpHandlerFactory (std::string const& authenticationRealm,
|
||||||
HttpHandlerFactory::HttpHandlerFactory (HttpHandlerFactory const& that)
|
HttpHandlerFactory::HttpHandlerFactory (HttpHandlerFactory const& that)
|
||||||
: _authenticationRealm(that._authenticationRealm),
|
: _authenticationRealm(that._authenticationRealm),
|
||||||
_checkAuthentication(that._checkAuthentication),
|
_checkAuthentication(that._checkAuthentication),
|
||||||
|
_flushAuthentication(that._flushAuthentication),
|
||||||
_requireAuthentication(that._requireAuthentication),
|
_requireAuthentication(that._requireAuthentication),
|
||||||
_constructors(that._constructors),
|
_constructors(that._constructors),
|
||||||
_datas(that._datas),
|
_datas(that._datas),
|
||||||
|
@ -85,6 +88,7 @@ HttpHandlerFactory& HttpHandlerFactory::operator= (HttpHandlerFactory const& tha
|
||||||
if (this != &that) {
|
if (this != &that) {
|
||||||
_authenticationRealm = that._authenticationRealm,
|
_authenticationRealm = that._authenticationRealm,
|
||||||
_checkAuthentication = that._checkAuthentication,
|
_checkAuthentication = that._checkAuthentication,
|
||||||
|
_flushAuthentication = that._flushAuthentication,
|
||||||
_requireAuthentication = that._requireAuthentication;
|
_requireAuthentication = that._requireAuthentication;
|
||||||
_constructors = that._constructors;
|
_constructors = that._constructors;
|
||||||
_datas = that._datas;
|
_datas = that._datas;
|
||||||
|
@ -115,6 +119,16 @@ HttpHandlerFactory::~HttpHandlerFactory () {
|
||||||
/// @{
|
/// @{
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief flush the authentication cache
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void HttpHandlerFactory::flushAuthentication () {
|
||||||
|
WRITE_LOCKER(_authLock);
|
||||||
|
|
||||||
|
_authCache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief require authentication
|
/// @brief require authentication
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -168,6 +182,14 @@ bool HttpHandlerFactory::authenticate (HttpRequest* request) {
|
||||||
++auth;
|
++auth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if the cache is outdated
|
||||||
|
if (_flushAuthentication()) {
|
||||||
|
// cache is outdated, now flush it
|
||||||
|
flushAuthentication();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// try reading auth info from cache first
|
||||||
{
|
{
|
||||||
READ_LOCKER(_authLock);
|
READ_LOCKER(_authLock);
|
||||||
|
|
||||||
|
@ -179,6 +201,8 @@ bool HttpHandlerFactory::authenticate (HttpRequest* request) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// auth info has not been in the cache yet
|
||||||
|
|
||||||
string up = StringUtils::decodeBase64(auth);
|
string up = StringUtils::decodeBase64(auth);
|
||||||
vector<string> split = StringUtils::split(up, ":");
|
vector<string> split = StringUtils::split(up, ":");
|
||||||
|
|
||||||
|
@ -189,6 +213,7 @@ bool HttpHandlerFactory::authenticate (HttpRequest* request) {
|
||||||
bool res = _checkAuthentication(split[0].c_str(), split[1].c_str());
|
bool res = _checkAuthentication(split[0].c_str(), split[1].c_str());
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
|
// put auth info into cache
|
||||||
WRITE_LOCKER(_authLock);
|
WRITE_LOCKER(_authLock);
|
||||||
|
|
||||||
_authCache[auth] = split[0];
|
_authCache[auth] = split[0];
|
||||||
|
|
|
@ -104,6 +104,12 @@ namespace triagens {
|
||||||
|
|
||||||
typedef bool (*auth_fptr) (char const*, char const*);
|
typedef bool (*auth_fptr) (char const*, char const*);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief authentication cache invalidation handler
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
typedef bool (*flush_fptr) ();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @}
|
/// @}
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -123,7 +129,9 @@ namespace triagens {
|
||||||
/// @brief constructs a new handler factory
|
/// @brief constructs a new handler factory
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
HttpHandlerFactory (std::string const& realm, auth_fptr checkAuthentication);
|
HttpHandlerFactory (std::string const&,
|
||||||
|
auth_fptr,
|
||||||
|
flush_fptr);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief clones a handler factory
|
/// @brief clones a handler factory
|
||||||
|
@ -162,7 +170,13 @@ namespace triagens {
|
||||||
/// @brief require authentication
|
/// @brief require authentication
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void setRequireAuthentication (bool);
|
void setRequireAuthentication (bool);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief flush the authentication cache
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void flushAuthentication ();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief returns header and body size restrictions
|
/// @brief returns header and body size restrictions
|
||||||
|
@ -182,6 +196,7 @@ namespace triagens {
|
||||||
|
|
||||||
virtual std::string const& authenticationRealm (HttpRequest * request) const;
|
virtual std::string const& authenticationRealm (HttpRequest * request) const;
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief creates a new request
|
/// @brief creates a new request
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -266,6 +281,12 @@ namespace triagens {
|
||||||
|
|
||||||
auth_fptr _checkAuthentication;
|
auth_fptr _checkAuthentication;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief authentication cache flush callback
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
flush_fptr _flushAuthentication;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief require authentication
|
/// @brief require authentication
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
Loading…
Reference in New Issue