1
0
Fork 0

Merge branch 'devel' of github.com:triAGENS/ArangoDB into devel

This commit is contained in:
Michael Hackstein 2013-05-02 14:39:57 +02:00
commit b7464677cc
11 changed files with 112 additions and 21 deletions

View File

@ -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

View File

@ -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');

View File

@ -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);
// ............................................................................. // .............................................................................

View File

@ -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);
@ -363,6 +365,28 @@ void TRI_DestroyAuthInfo (TRI_vocbase_t* vocbase) {
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;
} }

View File

@ -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
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -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);

View File

@ -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;

View File

@ -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;
} }

View File

@ -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
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -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];

View File

@ -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
@ -164,6 +172,12 @@ namespace triagens {
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
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////