UserManager.cpp

Go to the documentation of this file.
00001 /** @file    UserManager.cpp
00002  *  @author  Alessandro Polo
00003  *  @version $Id: UserManager.cpp 3775 2011-01-01 16:38:17Z alex $
00004  *  @brief
00005  * File containing methods for the wosh::UserManager class.
00006  * The header for this class can be found in UserManager.h, check that file
00007  * for class description.
00008  ****************************************************************************/
00009 /* Copyright (c) 2007-2011, WOSH - Wide Open Smart Home 
00010  * by Alessandro Polo - OpenSmartHome.com
00011  * All rights reserved.
00012  *
00013  * Redistribution and use in source and binary forms, with or without
00014  * modification, are permitted provided that the following conditions are met:
00015  *     * Redistributions of source code must retain the above copyright
00016  *       notice, this list of conditions and the following disclaimer.
00017  *     * Redistributions in binary form must reproduce the above copyright
00018  *       notice, this list of conditions and the following disclaimer in the
00019  *       documentation and/or other materials provided with the distribution.
00020  *     * Neither the name of the OpenSmartHome.com WOSH nor the
00021  *       names of its contributors may be used to endorse or promote products
00022  *       derived from this software without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY Alessandro Polo ''AS IS'' AND ANY
00025  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00026  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00027  * DISCLAIMED. IN NO EVENT SHALL Alessandro Polo BE LIABLE FOR ANY
00028  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00029  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00031  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00032  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00033  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034  ****************************************************************************/
00035  
00036  #include <core/UserManager.h>
00037  #include <core/ObjectFactory.h>
00038  #include <core/FileSystem.h>
00039  #include <core/PersistenceManager.h>
00040  #include <core/WoshKernel.h>
00041  #include <core/SystemInfo.h>
00042  #include <core/MethodsCommon.h>
00043  #include <core/DataSet.h>
00044  #include <core/Utilities.h>
00045  #include <core/DateTime.h>
00046     #include <interfaces/communication/Communicator.h>
00047  #include <core/DataSet.h>
00048 //                                                              #include <core/DataSetProperty.h>
00049 
00050 using namespace std;
00051 namespace wosh {
00052 
00053 // Gamma singleton! static reference is allocated and maintained by WoshKernel
00054 extern "C" {
00055     UserManager* UserManager::getInstance() { 
00056         if ( WoshKernel::getInstance() == NULL ) return NULL;
00057         return &WoshKernel::getInstance()->users();
00058     }
00059 }
00060  // register as abstract because it is a singleton:
00061  WOSH_REGISTER_INTERFACE(wosh::UserManager, wosh::WoshModule, _UserManager_VER, core_UserManager)
00062 
00063 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00064 //////////////////////////////////////////////////////////////////////////////////////////////// CONSTRUCTORS
00065 
00066 UserManager::UserManager( const WoshKernel* parent )
00067     : WoshModule(parent, _UserManager_NAME, _UserManager_URI) {
00068 
00069     GroupsVirtualURI.setParent( Object::getURI() );
00070     GroupsVirtualURI.setName( "Groups" );
00071     GroupsVirtualURI.registerGlobal();
00072 
00073 //Log.setLevel( VERBOSE );
00074 
00075     Log(LOG_DEBUG, " Creating default User(s) and UserGroup(s).." );
00076     createDefaultUsersGroups();
00077 
00078     Log(LOG_DEBUG, " Initializing Properties.." );
00079     Properties.set( _UserManager_KEY_Users, this->users.size_safe(), Permission(Permission::Read) );
00080     Properties.set( _UserManager_KEY_UsersDB, "$DATABASE/users/users.xml", Permission::RW_R__R__() );
00081     Properties.set( _UserManager_KEY_Groups, this->groups.size_safe(), Permission(Permission::Read) );
00082     Properties.set( _UserManager_KEY_GroupsDB, "$DATABASE/users/groups.xml", Permission::RW_R__R__() );
00083     Properties.update( _KEY_Description, "Core-Module: Manage users and groups." );
00084     Properties.update( _KEY_Version, _UserManager_VER );
00085 
00086     Log(LOG_DEBUG, " Registering Methods.." );
00087     MethodRequest* mmGetUsersLocations = Methods.create<MethodRequest>( _UserManager_METHOD_listloc, "Get Users' Locations", Permission::R_XR_XR__() );
00088     mmGetUsersLocations->setMethod( this, (MethodRequestPtr)&UserManager::mmDoGetUsersLocations );
00089 
00090     MethodRequest* mmGetUsersCommunicators = Methods.create<MethodRequest>( _UserManager_METHOD_listcomm, "Get Users' Communicators", Permission::R_XR_XR__() );
00091     mmGetUsersCommunicators->setMethod( this, (MethodRequestPtr)&UserManager::mmDoGetUsersCommunicators );
00092 
00093     MethodMessageResponse* mmForceUserIn = Methods.create<MethodMessageResponse>( _UserManager_METHOD_forcelocation, "force user in a location", Permission::R_XR__R__() );
00094     mmForceUserIn->setMethod( this, (MethodMessageResponsePtr)&UserManager::mmDoForceUserIn );
00095 
00096     MethodMessageResponse* mmSearchUser = Methods.create<MethodMessageResponse>( _UserManager_METHOD_search, "search user matching pattners", Permission(Permission::RX) );
00097     mmSearchUser->setMethod( this, (MethodMessageResponsePtr)&UserManager::mmDoSearchUser );
00098 
00099     MethodDataSetFields* mmListUsers = Methods.create<MethodDataSetFields>( _METHOD_List, "List Users", Permission::R_XR_XR__() );
00100     mmListUsers->setRetriever( DataSetFieldsReader_X<User>::createFrom(&this->users) );
00101 
00102 //  MethodPropertySetList* mmListUsersP = Methods.create<MethodPropertySetList>( "plist", "List Users", Permission::R_XR_XR__() );
00103 //  mmListUsersP->setPropertyReader( DataSetPropertyReader<User>::createFromMap<string>(this->users, &User::getProperties ) );
00104 
00105 
00106     MethodDataSetFields* mmListUsersGroups = Methods.create<MethodDataSetFields>( _UserManager_METHOD_listgroups, "List Groups", Permission::R_XR_XR__() );
00107     mmListUsersGroups->setRetriever( DataSetFieldsReader_X<UserGroup>::createFrom(&this->groups) );
00108  }
00109 
00110 UserManager::~UserManager() {
00111     Log(LOG_DEBUG, ":~UserManager() Destroying.." );
00112 
00113     this->users.transactionBeginWrite();
00114     Log(LOG_VERBOSE, ":~UserManager() Freeing Users [%d]..", this->users.size() );
00115     this->users.free();
00116     this->users.transactionEnd();
00117 
00118     this->groups.transactionBeginWrite();
00119     Log(LOG_VERBOSE, ":~UserManager() Freeing Groups [%d]..", this->groups.size() );
00120     this->groups.free();
00121     this->groups.transactionEnd();
00122 
00123     Log(LOG_VERBOSE, " Destroyed." );
00124  }
00125 
00126 //////////////////////////////////////////////////////////////////////////////////////////////// CONSTRUCTORS
00127 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00128 /////////////////////////////////////////////////////////////////////////////////////////////// KERNEL EVENTS
00129 
00130 WRESULT UserManager::onKernelInitializing() {
00131     WRESULT ret = WoshModule::onKernelInitializing();
00132 
00133     BusSecurity.setMessageHandler(this);
00134     WRESULT bus_d_connected = BusSecurity.connect( _Bus_Security );
00135     if ( WFAILED(bus_d_connected) ) {
00136         SystemInfo::raise(this, &Log, SystemInfo::TYPE_ERROR, SystemInfo::MODE_PERMANENT, SystemInfo::SCOPE_SYSTEM, SystemInfo::PRIORITY_FAILURE,
00137                             "Unable to Connect Bus",
00138                             "onKernelInitializing() FAILED#%d : Connecting Bus ("_Bus_Security")..", bus_d_connected );
00139      }
00140     else
00141         Log(LOG_DEBUG, " Connected to "_Bus_Security"." );
00142 
00143     ret += UserManager::loadUsers();
00144     //ret += UserManager::loadGroups();
00145 
00146     return ret;
00147  }
00148 
00149 WRESULT UserManager::onKernelStopping() {
00150     WRESULT ret = WRET_OK;
00151     Log(LOG_VERBOSE, ":onKernelStopping() Saving Users and Groups DB.." );
00152     this->users.transactionBeginRead();
00153     ret += PersistenceManager::saveObjects( this->users.getContainer(), "XML", "$DATABASE/users/users.xml.bak" );
00154     this->users.transactionEnd();
00155     if ( WFAILED(ret) )
00156         Log(LOG_CRITICAL, ":onKernelStopping() ERROR#%d Saving Users and Groups DB.", ret );
00157     ret += WoshModule::onKernelStopping();
00158     return ret;
00159  }
00160 
00161 /////////////////////////////////////////////////////////////////////////////////////////////// KERNEL EVENTS
00162 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00163 //////////////////////////////////////////////////////////////////////////////////////// PROCESS BUS MESSAGES
00164 
00165 void UserManager::busMessage( const Message& message, const Bus* source ) {
00166     if ( message.isEmpty() ) return;
00167     // avoid message replicas
00168     if ( !MessageFilter::filterReplica( message, &BusCore ) )
00169         return;
00170 
00171     if ( message.getContent()->isFact() ) {
00172         if ( message.getContent()->isKindOf<wosh::interfaces::communication::UserAvailabilityChanged>() ) {
00173             const wosh::interfaces::communication::UserAvailabilityChanged* upEvent = message.getContent()->as<wosh::interfaces::communication::UserAvailabilityChanged>();
00174             this->users.transactionBeginWrite();
00175             User* cUser = this->users.valueOf( upEvent->getUserName() );
00176             if ( cUser == NULL ) {
00177                 this->users.transactionEnd();
00178                 return;
00179              }
00180             int64 timestamp = message.getTimestamp();
00181             if ( upEvent->isUserOnline() ) {
00182                 cUser->updateCommmunicator(message.getSource().toString(), timestamp);
00183              }
00184             else {
00185                 cUser->updateCommmunicator(message.getSource().toString(), -timestamp);
00186              }
00187             this->users.transactionEnd();
00188          }
00189         else if ( message.getContent()->isKindOf<wosh::interfaces::communication::UserInteraction>() ) {
00190             const wosh::interfaces::communication::UserInteraction* upEvent = message.getContent()->as<wosh::interfaces::communication::UserInteraction>();
00191             this->users.transactionBeginWrite();
00192             User* cUser = this->users.valueOf( upEvent->getUserName() );
00193             if ( cUser == NULL ) {
00194                 this->users.transactionEnd();
00195                 return;
00196              }
00197             int64 timestamp = message.getTimestamp();
00198             cUser->updateCommmunicator(message.getSource().toString(), timestamp);
00199             this->users.transactionEnd();
00200          }
00201         return;
00202      }
00203 
00204     if ( !message.getContent()->isRequest() ) return;
00205 
00206     if ( !message.getDestination().isChildOf(this->getURI(), true) ) {
00207         WoshModule::busMessage(message, source);
00208         return;
00209      }
00210 
00211     Log(LOG_VERBOSE, ":busMessage() = Message-Request for Child '%s'", message.getDestination().getName().c_str() );
00212     this->users.transactionBeginRead(); // following operation won't ever really add/delete a channel item
00213     MPC_mmDo_InContainerSecond(message, this->users, Log, BusCore);
00214     this->users.transactionEnd();
00215  }
00216 
00217 //////////////////////////////////////////////////////////////////////////////////////// PROCESS BUS MESSAGES
00218 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00219 /////////////////////////////////////////////////////////////////////////////////////////// COLLECTOR METHODS
00220 
00221 WRESULT UserManager::registerUser( User* user ) {
00222     if ( user == NULL ) return WRET_ERR_PARAM;
00223     MutexLockerWrite mL(&this->users.getMutex());
00224     return registerUser_( user, true );
00225  }
00226 
00227 WRESULT UserManager::registerGroup( UserGroup* usergroup ) {
00228     if ( usergroup == NULL ) return WRET_ERR_PARAM;
00229     MutexLockerWrite mL(&this->groups.getMutex());
00230     return registerGroup_( usergroup, true );
00231  }
00232 
00233 WRESULT UserManager::registerUser_( User* user, bool raise_event ) {
00234     if ( user == NULL ) return WRET_ERR_PARAM;
00235     User* oldObj = this->users.valueOf(user->getName());
00236     if ( oldObj == user ) {
00237         Log(LOG_CRITICAL, ":registerUser_(%s) Instance already registered! [ID#%ld]", user->getName().c_str(), user->getID() );
00238         return WRET_ERR_PARAM;
00239      }
00240     if ( user->getURI().isGlobal() ) user->getURI().unRegisterGlobal();
00241     user->getURI().setParent( this->getURI() );
00242     user->getURI().setName( user->getName() );
00243     user->getURI().registerGlobal();
00244     user->setPermission( Permission::RWXR_____(user->getName()) );
00245     this->groups.transactionBeginWrite();
00246     tStrUserGroupMap::ConstIterator it_g;
00247     const tStrUserGroupMap::ConstIterator it_g_end = this->groups.end();
00248     std::vector<std::string>::iterator it;
00249     bool editing = true;
00250     while (editing) {
00251         editing = false;
00252         for ( it=user->getGroups().begin(); it!=user->getGroups().end(); ++it ) {
00253             bool found = false;
00254             for ( it_g=this->groups.begin(); it_g!=it_g_end; ++it_g ) {
00255                 if ( it_g->second == NULL ) continue;
00256                 if ( it_g->second->getName() != *it ) continue;
00257                 it_g->second->setUserCount( it_g->second->getUserCount() + 1 );
00258                 found = true;
00259                 break;
00260             }
00261             if ( !found ) {
00262                 Log(LOG_WARNING, ":registerUser_(%s) Group %s NOT FOUND!", user->getName().c_str(), (*it).c_str() );
00263                 user->getGroups().erase(it);
00264                 editing = true;
00265                 break;
00266              }
00267          }
00268      }
00269     this->groups.transactionEnd();
00270     Fact* fact = NULL;
00271     if ( raise_event ) {
00272         if ( oldObj == NULL )
00273             fact = new UserManager_UserListChanged(user->getName(), UserManager_UserListChanged::EVENT_LISTITEM_ADDED );
00274         else
00275             fact = new UserManager_UserListChanged(user->getName(), UserManager_UserListChanged::EVENT_LISTITEM_UPDATED );
00276      }
00277     if ( oldObj == NULL ) {
00278         Log(LOG_INFO, ":registerUser_(%s) Registered New ID#%ld", user->getName().c_str(), user->getID() );
00279         this->users.set(user->getName(), user);
00280      }
00281     else if ( oldObj->getID() == user->getID() ) {
00282         Log(LOG_INFO, ":registerUser_(%s) User Exists, merging [ID#%ld]", user->getName().c_str(), user->getID() );
00283         oldObj->merge(*user);
00284         ObjectFactory::destroy(user);
00285      }
00286     else {
00287         Log(LOG_CRITICAL, ":registerUser_(%s) User Exists, but ID is disaligned (%ld!=%ld)", user->getName().c_str(), user->getID(), oldObj->getID() );
00288         ObjectFactory::destroy(user);
00289         if ( fact != NULL )
00290             delete fact; fact = NULL;
00291      }
00292     Properties.transactionBeginWrite();
00293     Properties.update( _UserManager_KEY_Users, this->users.size() );
00294     Properties.transactionEnd();
00295     if ( fact != NULL ) {
00296         Message* msg_event = new Message(fact);
00297         msg_event->setDestinationBroadcast(true);
00298         signMessage(msg_event);
00299         BusSecurity.postMessage(msg_event);
00300      }
00301     return WRET_OK;
00302  }
00303 
00304 WRESULT UserManager::registerGroup_( UserGroup* usergroup, bool raise_event ) {
00305     if ( usergroup == NULL ) return WRET_ERR_PARAM;
00306     UserGroup* oldObj = this->groups.valueOf(usergroup->getName());
00307     if ( oldObj == usergroup ) {
00308         Log(LOG_CRITICAL, ":registerGroup_(%s) Instance already registered! [ID#%ld]", usergroup->getName().c_str(), usergroup->getID() );
00309         return WRET_ERR_PARAM;
00310      }
00311     if ( usergroup->getName().size() < 3 ) return WRET_ERR_PARAM;
00312     usergroup->getURI().clear();
00313     usergroup->getURI().setParent( this->GroupsVirtualURI );
00314     usergroup->getURI().setName( usergroup->getName() );
00315     usergroup->getURI().registerGlobal();
00316     usergroup->setPermission( Permission::RWXRWX___("root", usergroup->getName()) );
00317     Fact* fact = NULL;
00318     if ( raise_event ) {
00319         if ( oldObj == NULL )
00320             fact = new UserManager_GroupListChanged(usergroup->getName(), UserManager_GroupListChanged::EVENT_LISTITEM_ADDED );
00321         else
00322             fact = new UserManager_GroupListChanged(usergroup->getName(), UserManager_GroupListChanged::EVENT_LISTITEM_UPDATED );
00323      }
00324     if ( oldObj == NULL ) {
00325         Log(LOG_INFO, ":registerGroup_(%s) Registered ID#%ld", usergroup->getName().c_str(), usergroup->getID() );
00326         this->groups.set(usergroup->getName(), usergroup);
00327      }
00328     else {
00329         Log(LOG_WARNING, ":registerGroup_(%s) Group Exists, merging Properties [ID#%ld]", usergroup->getName().c_str(), usergroup->getID() );
00330         // user already registered, 
00331         ///@todo should merge info!
00332         ObjectFactory::destroy(usergroup);
00333      }
00334     Properties.transactionBeginWrite();
00335     Properties.update( _UserManager_KEY_Groups, this->groups.size() );
00336     Properties.transactionEnd();
00337     if ( fact != NULL ) {
00338         Message* msg_event = new Message(fact);
00339         msg_event->setDestinationBroadcast(true);
00340         signMessage(msg_event);
00341         BusSecurity.postMessage(msg_event);
00342      }
00343     return WRET_OK;
00344  }
00345 
00346 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00347 
00348 void UserManager::createDefaultUsersGroups() {
00349     Log(LOG_VERBOSE, ":createDefaultUsersGroups() : Creating 5 Groups.." );
00350     map<long, string> def_groups;
00351     def_groups[User::UserId_root] = User::Username_root;
00352     def_groups[UserGroup::GroupId_virtual] = UserGroup::Groupname_virtual;
00353     def_groups[User::UserId_nobody] = User::Username_nobody;
00354     def_groups[UserGroup::GroupId_inhabitants] = UserGroup::Groupname_inhabitants;
00355     def_groups[UserGroup::GroupId_guest] = UserGroup::Groupname_guest;
00356     
00357     Log(LOG_VERBOSE, ":createDefaultUsersGroups() : Creating %d Groups..", def_groups.size() );
00358     map<long, string>::const_iterator it;
00359     for(it=def_groups.begin(); it!=def_groups.end(); ++it) {
00360         UserGroup* ug = new UserGroup(it->first,it->second);//ObjectFactory::createTypeOf<UserGroup>(true);
00361         ug->id = it->first;
00362         ug->setName(it->second);
00363         registerGroup_( ug, false );
00364      }
00365 
00366     Log(LOG_VERBOSE, ":createDefaultUsersGroups() : Creating 4 Users.." );
00367     registerUser_( new User(User::UserId_wosh,      User::Username_wosh,        "root;virtual"), false );
00368     registerUser_( new User(User::UserId_root,      User::Username_root,        "root;virtual"), false );
00369     registerUser_( new User(User::UserId_nobody,    User::Username_nobody,      "nobody;virtual"), false );
00370     registerUser_( new User(User::UserId_anonymous, User::Username_anonymous,   "nobody;virtual"), false );
00371  }
00372 
00373 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00374 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00375 
00376 WRESULT UserManager::loadGroups() {
00377     // may also be a folder of .xml files
00378     string xmlfile = Properties.getValueOf(_UserManager_KEY_GroupsDB).toString();
00379     Log(LOG_VERBOSE, ":loadGroups() File %s ..", xmlfile.c_str() );
00380     std::vector<UserGroup*> objects_load;
00381     WRESULT ret = PersistenceManager::loadObjects( objects_load, "XML", xmlfile );
00382     if ( WFAILED(ret) ) {
00383         Log(LOG_CRITICAL, ":loadGroups() FAILED#%ld loading objects!", ret );
00384         return ret;
00385      }
00386     this->groups.transactionBeginWrite();
00387     std::vector<UserGroup*>::iterator it_load;
00388     for ( it_load=objects_load.begin(); it_load!=objects_load.end(); ++it_load ) {
00389         UserGroup* currObj = *it_load;
00390         if ( currObj == NULL ) continue;
00391         ret += registerGroup_( currObj, true );
00392      }
00393     Log(LOG_VERBOSE, ":loadGroups() Loaded %d groups", this->groups.size() );
00394     this->groups.transactionEnd();
00395     return ret;
00396  }
00397 
00398 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00399 
00400 WRESULT UserManager::loadUsers() {
00401     // may also be a folder of .xml files
00402     string xmlfile = Properties.getValueOf(_UserManager_KEY_UsersDB).toString();
00403     Log(LOG_VERBOSE, ":loadUsers() File %s ..", xmlfile.c_str() );
00404     std::vector<User*> objects_load;
00405     WRESULT ret = PersistenceManager::loadObjects( objects_load, "XML", xmlfile );
00406     if ( WFAILED(ret) ) {
00407         Log(LOG_CRITICAL, ":loadUsers() FAILED#%d loading objects [%s]!", ret, xmlfile.c_str() );
00408         return ret;
00409      }
00410     this->users.transactionBeginWrite();
00411     std::vector<User*>::iterator it_load;
00412     for ( it_load=objects_load.begin(); it_load!=objects_load.end(); ++it_load ) {
00413         if ( *it_load == NULL ) continue;
00414         if ( (*it_load)->getName().size() < 3 ) {
00415             Log(LOG_WARNING, ":loadUsers() User '%s' invalid name", (*it_load)->getName().c_str() );
00416             delete *it_load;
00417             continue;
00418          }
00419         ret += registerUser_( *it_load, true );
00420      }
00421     Log(LOG_VERBOSE, ":loadUsers() Loaded#%d %d users [%s]", ret, this->users.size(), xmlfile.c_str() );
00422     this->users.transactionEnd();
00423     return ret;
00424  }
00425 
00426 /////////////////////////////////////////////////////////////////////////////////////////// COLLECTOR METHODS
00427 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00428 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00429 
00430 long UserManager::getUserIdOf( const std::string& username ) {
00431     UserManager* usrman = UserManager::getInstance();
00432     if ( usrman == NULL ) return false;
00433     MutexLockerRead mL(&usrman->users.getMutex());
00434     const User* oldObj = usrman->users.valueOf(username);
00435     if ( oldObj != NULL ) return 0;
00436     return oldObj->getID();
00437  }
00438 std::string UserManager::getUsernameById( long uid ) {
00439     UserManager* usrman = UserManager::getInstance();
00440     if ( usrman == NULL ) return "";
00441     MutexLockerRead mL(&usrman->users.getMutex());
00442     tStrUserMap::ConstIterator it;
00443     for ( it=usrman->users.begin(); it!=usrman->users.end(); ++it ) {
00444         if ( it->second == NULL || it->second->getID() != uid ) continue;
00445         return it->second->getName();
00446      }
00447     return "";
00448  }
00449 
00450 long UserManager::getGroupIdOf( const std::string& groupname ) {
00451     UserManager* usrman = UserManager::getInstance();
00452     if ( usrman == NULL ) return false;
00453     MutexLockerRead mL(&usrman->groups.getMutex());
00454     const UserGroup* oldObj = usrman->groups.valueOf(groupname);
00455     if ( oldObj != NULL ) return 0;
00456     return oldObj->getID();
00457  }
00458 std::string UserManager::getGroupnameById( long uid ) {
00459     UserManager* usrman = UserManager::getInstance();
00460     if ( usrman == NULL ) return "";
00461     MutexLockerRead mL(&usrman->groups.getMutex());
00462     tStrUserGroupMap::ConstIterator it;
00463     for ( it=usrman->groups.begin(); it!=usrman->groups.end(); ++it ) {
00464         if ( it->second == NULL || it->second->getID() != uid ) continue;
00465         return it->second->getName();
00466      }
00467     return "";
00468  }
00469 
00470 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00471 
00472 bool UserManager::isGroupOfUser( const std::string& user, const std::string& group ) {
00473     UserManager* usrman = UserManager::getInstance();
00474     if ( usrman == NULL ) return false;
00475     MutexLockerRead mL(&usrman->users.getMutex());
00476     const User* oldObj = usrman->users.valueOf(user);
00477     if ( oldObj == NULL ) return false;
00478     return oldObj->isMemberOf(group);
00479  }
00480 
00481 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00482 
00483 int UserManager::listUsers( std::vector<std::string>& users_names ) const {
00484     MutexLockerRead mL(&this->users.getMutex());
00485     this->users.copyKeysTo( std::back_inserter(users_names) );
00486     return users_names.size();
00487  }
00488 
00489 int UserManager::listGroups( std::vector<std::string>& groups_names ) const {
00490     MutexLockerRead mL(&this->groups.getMutex());
00491     this->groups.copyKeysTo( std::back_inserter(groups_names) );
00492     return groups_names.size();
00493  }
00494 
00495 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00496 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00497 ///////////////////////////////////////////////////////////////////////////////////////////////////// METHODS
00498 
00499 Response* UserManager::mmDoSearchUser( const Message* requestMessage ) {
00500     if ( requestMessage == NULL || requestMessage->isEmpty() ) return NULL;
00501     if ( !requestMessage->getContent()->isRequest() ) return NULL;
00502     const Request* request = requestMessage->getContent()->asRequest();
00503     if ( !request->hasData() ) {
00504         return request->replyResponse(WRET_ERR_PARAM, "Invalid data");
00505      }
00506     string key;
00507     Variant propValue;
00508     if ( request->getData()->isKindOf<Property>() ) {
00509         const Property* prop = request->getData()->as<Property>();
00510         if ( prop == NULL )
00511             return request->replyResponse(WRET_ERR_PARAM, "Invalid data");
00512         key = prop->getKey();
00513         propValue = prop->getValue();
00514      }
00515     std::vector<std::string> fusers = findUserByProperty( key, propValue, requestMessage->getSecurityToken() );
00516     Table* tbl = new Table(fusers.size(), 1, true);
00517     tbl->setTableName("Users matching -");
00518     tbl->setHeaderHorizontal("Name", 0);
00519     std::vector<std::string>::iterator it;
00520     unsigned int iRow = 0;
00521     for ( it=fusers.begin(); it!=fusers.end(); ++it, ++iRow ) {
00522         tbl->set<Variant>(*it, iRow, 0);
00523      }
00524     return request->replyResponse(WRET_OK, tbl);
00525 /*
00526     List* list = new List(fusers.size());
00527     std::vector<std::string>::iterator it;
00528     for ( it=fusers.begin(); it!=fusers.end(); ++it ) {
00529         list->push_back<Variant>(*it);
00530      }
00531     return request->replyResponse(WRET_OK, list);
00532 */
00533  }
00534 
00535 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00536 
00537 Response* UserManager::mmDoGetUsersCommunicators( const Request* request ) {
00538     if ( request == NULL ) return NULL;
00539     string option = request->getArgument().toString();
00540     Log(LOG_VERBOSE, ":mmDoGetUsersCommunicators(%s)", option.c_str() );
00541     if ( option == "s" || option == "short" ) {
00542         this->users.transactionBeginRead();
00543         List* objs = new List(this->users.size());
00544         tStrUserMap::ConstIterator it;
00545         const tStrUserMap::ConstIterator it_end = this->users.end();
00546         for ( it=this->users.begin(); it!=it_end; ++it ) {
00547             if ( it->second == NULL ) continue;
00548             objs->push_back<Variant>( it->second->getCommunicators().getLastName() );
00549          }
00550         this->users.transactionEnd();
00551         return request->replyResponse(WRET_OK, objs);
00552      }
00553     else {
00554         this->users.transactionBeginRead();
00555         Table* tbl = new Table( this->users.size(), 4, true );
00556         tbl->setTableName("Users' Communicators");
00557         tbl->setHeaderHorizontal("Username", 0);
00558         tbl->setHeaderHorizontal("LastCommunicator", 1);
00559         tbl->setHeaderHorizontal("TimeStamp", 2);
00560         tbl->setHeaderHorizontal("Ranking", 3);
00561         unsigned int iRow = 0;
00562         tStrUserMap::ConstIterator it;
00563         const tStrUserMap::ConstIterator it_end = this->users.end();
00564         for ( it=this->users.begin(); it!=it_end; ++it, ++iRow ) {
00565             if ( it->second == NULL ) continue;
00566             tbl->set( new Variant(it->second->getName()), iRow, 0);
00567             string commURI;
00568             UserInfoCommmunicatorData data;
00569             it->second->getCommunicators().getCommmunicatorLast(commURI, data);
00570             tbl->set( new Variant(commURI), iRow, 1);
00571             tbl->set( new Variant(data.timestamp), iRow, 2);
00572             tbl->set( new Variant(data.ranking), iRow, 3);
00573          }
00574         this->users.transactionEnd();
00575         return request->replyResponse(WRET_OK, tbl);
00576      }
00577  }
00578 
00579 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00580 
00581 Response* UserManager::mmDoGetUsersLocations( const Request* request ) {
00582     if ( request == NULL ) return NULL;
00583     string option = request->getArgument().toString();
00584     Log(LOG_VERBOSE, ":mmDoGetUsersLocations(%s)", option.c_str() );
00585     if ( option == "s" || option == "short" ) {
00586         this->users.transactionBeginRead();
00587         List* objs = new List(this->users.size());
00588         tStrUserMap::ConstIterator it;
00589         const tStrUserMap::ConstIterator it_end = this->users.end();
00590         for ( it=this->users.begin(); it!=it_end; ++it ) {
00591             if ( it->second == NULL ) continue;
00592             objs->push_back<Variant>( it->second->getLocation().getLastName() );
00593          }
00594         this->users.transactionEnd();
00595         return request->replyResponse(WRET_OK, objs);
00596      }
00597     else {
00598         this->users.transactionBeginRead();
00599         Table* tbl = new Table( this->users.size(), 5, true );
00600         tbl->setTableName("Users' Locations");
00601         tbl->setHeaderHorizontal( "Name", 0);
00602         tbl->setHeaderHorizontal( "AtHome", 1);
00603         tbl->setHeaderHorizontal( "LastCommunicator", 2);
00604         tbl->setHeaderHorizontal( "LastCommTs", 3);
00605         tbl->setHeaderHorizontal( "LastCommProb", 4);
00606         unsigned int iRow = 0;
00607         tStrUserMap::ConstIterator it;
00608         const tStrUserMap::ConstIterator it_end = this->users.end();
00609         for ( it=this->users.begin(); it!=it_end; ++it, ++iRow ) {
00610             if ( it->second == NULL ) continue;
00611             tbl->set<Variant>( it->second->getName(), iRow, 0);
00612             tbl->set<Variant>( it->second->isAtHome(), iRow, 1);
00613             string locURI;
00614             UserInfoLocationData data;
00615             it->second->getLocation().getLocationLast(locURI, data);
00616             tbl->set<Variant>( locURI, iRow, 2);
00617             tbl->set( new Variant(data.timestamp, Variant::DATETIME), iRow, 3);
00618             tbl->set<Variant>( data.probability, iRow, 4);
00619          }
00620         this->users.transactionEnd();
00621         return request->replyResponse(WRET_OK, tbl);
00622      }
00623  }
00624 
00625 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00626 
00627 Response* UserManager::mmDoForceUserIn( const Message* requestMessage ) {
00628     if ( requestMessage == NULL || requestMessage->isEmpty() ) return NULL;
00629     if ( !requestMessage->getContent()->isRequest() ) return NULL;
00630     const Request* request = requestMessage->getContent()->asRequest();
00631     if ( !request->hasData() )
00632         return request->replyResponse(WRET_ERR_PARAM, "Invalid data");
00633     Variant dUsername; Variant dLocation;
00634     request->extractArguments(dUsername, dLocation);
00635     if ( !dUsername.isStringNotEmpty() || !dLocation.isStringNotEmpty() ) {
00636         return request->replyResponse(WRET_ERR_PARAM, "Invalid arguments [username, location]");
00637      }
00638     std::string sender;
00639     if ( requestMessage->getSecurityToken() != NULL )
00640         sender = requestMessage->getSecurityToken()->getUsername();
00641     Log(LOG_INFO, "mmDoForceUserIn() : Force %s in %s", dUsername.asString().c_str(), dLocation.asString().c_str() );
00642     this->users.transactionBeginWrite();
00643     User* oldObj = this->users.valueOf(dUsername.asString());
00644     if ( oldObj == NULL ) {
00645         this->users.transactionEnd();
00646         return request->replyResponse(WRET_ERR_PARAM, "Invalid username");
00647      }
00648     oldObj->updateLocation(dLocation.asString(), DateTime::std_time_ms(), 1.0);
00649     this->users.transactionEnd();
00650     return request->replyResponse(WRET_OK);
00651  }
00652 
00653 ///////////////////////////////////////////////////////////////////////////////////////////////////// METHODS
00654 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00655 ////////////////////////////////////////////////////////////////////////////////////////////// STATIC METHODS
00656 
00657 Variant UserManager::getUserProperty( const std::string& user, const std::string& key, const SecurityToken* ) {
00658     UserManager* usrman = UserManager::getInstance();
00659     if ( usrman == NULL ) return Variant();
00660 
00661     MutexLockerRead mL(&usrman->users.getMutex());
00662     User* oldObj = usrman->users.valueOf(user);
00663     if ( oldObj == NULL )
00664         return Variant();
00665     return oldObj->getValueOf(key);
00666  }
00667 std::string UserManager::getUserLocation( const std::string& user, const SecurityToken* queryOwner ) {
00668     return UserManager::getUserProperty(user, "LocationLast", queryOwner).toString();
00669  }
00670 UserInfoCommmunicators* UserManager::getUserCommunicators( const std::string& user, const SecurityToken* ) {
00671     UserManager* usrman = UserManager::getInstance();
00672     if ( usrman == NULL ) return NULL;
00673     MutexLockerRead mL(&usrman->users.getMutex());
00674     User* cUser = usrman->users.valueOf(user);
00675     if ( cUser == NULL )
00676         return NULL;
00677     return cUser->getCommunicators().clone();
00678  }
00679 WRESULT UserManager::setUserProperty( const std::string& user, const std::string& key, const Variant& data, const SecurityToken* ) {
00680     UserManager* usrman = UserManager::getInstance();
00681     if ( usrman == NULL ) return WRET_ERR_ILLEGAL_USE;
00682     MutexLockerRead mL(&usrman->users.getMutex());
00683     User* oldObj = usrman->users.valueOf(user);
00684     if ( oldObj == NULL )
00685         return WRET_ERR_PARAM;
00686     return oldObj->setProperty(key, data);
00687  }
00688 WRESULT UserManager::setUserLocation( const std::string& user, const std::string& new_location, double probability, short at_home ) {
00689     UserManager* usrman = UserManager::getInstance();
00690     if ( usrman == NULL ) return WRET_ERR_ILLEGAL_USE;
00691     usrman->users.transactionBeginRead();
00692     User* oldObj = usrman->users.valueOf(user);
00693     if ( oldObj == NULL ) {
00694         usrman->users.transactionEnd();
00695         return WRET_ERR_PARAM;
00696      }
00697     oldObj->updateLocation(new_location, DateTime::std_time_ms(), probability);
00698     if ( at_home != 2 )
00699         oldObj->setAtHome(at_home);
00700     int usersAtHome = 0;
00701     tStrUserMap::ConstIterator it;
00702     const tStrUserMap::ConstIterator it_end = usrman->users.end();
00703     for ( it=usrman->users.begin(); it!=it_end; ++it ) {
00704         if ( it->second == NULL ) continue;
00705         if ( it->second->isAtHome() )
00706             ++usersAtHome;
00707      }
00708     usrman->users.transactionEnd();
00709     List* dL = new List();
00710     dL->push_back<Variant>( user );
00711     dL->push_back<Variant>( new_location );
00712     dL->push_back<Variant>( probability );
00713     dL->push_back<Variant>( at_home );
00714     Message* msg_event = new Message( new Fact( _UserManager_EVENT_located, dL) );
00715     msg_event->setSource( usrman );
00716     msg_event->setDestinationBroadcast();
00717     msg_event->setDestinationBus(_Bus_Security);
00718     usrman->BusSecurity.postMessage(msg_event);
00719     if ( usersAtHome == 0 ) {
00720         Message* msg_event = new Message( new Fact( _UserManager_EVENT_UsersAtHome, new Variant(usersAtHome)) );
00721         msg_event->setSource( usrman );
00722         msg_event->setDestinationBroadcast();
00723         msg_event->setDestinationBus(_Bus_Security);
00724         usrman->BusSecurity.postMessage(msg_event);
00725      }
00726     return WRET_OK;
00727  }
00728 WRESULT UserManager::setUserCommunicator( const std::string& user, const std::string& communicator, long timestamp, double ranking_offset ) {
00729     UserManager* usrman = UserManager::getInstance();
00730     if ( usrman == NULL ) return WRET_ERR_ILLEGAL_USE;
00731     MutexLockerRead mL(&usrman->users.getMutex());
00732     User* oldObj = usrman->users.valueOf(user);
00733     if ( oldObj == NULL )
00734         return WRET_ERR_PARAM;
00735     oldObj->updateCommmunicator(communicator, timestamp, ranking_offset);
00736     return WRET_OK;
00737  }
00738 
00739 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00740 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00741 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00742 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00743 
00744 std::vector<std::string> UserManager::findUserByProperty( const std::string& key, const Variant& value, const SecurityToken* ) {
00745     std::vector<std::string> res;
00746     UserManager* usrman = UserManager::getInstance();
00747     if ( usrman == NULL ) return res;
00748     MutexLockerRead mL(&usrman->users.getMutex());
00749     tStrUserMap::ConstIterator it;
00750     const tStrUserMap::ConstIterator it_end = usrman->users.end();
00751     for ( it=usrman->users.begin(); it!=it_end; ++it ) {
00752         if ( it->second == NULL ) continue;
00753         if ( !it->second->getProperties().exists(key) ) continue;
00754         if ( !value.isEmpty() && it->second->getValueOf(key) != value ) continue;
00755         res.push_back( it->second->getName() );
00756      }
00757     return res;
00758  }
00759 
00760 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00761 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00762 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00763 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00764 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00765 
00766  WOSH_REGISTER(wosh::UserManager_UserListChanged, wosh::Fact, 0.8711, core_UserManager_UserListChanged)
00767 
00768 std::string UserManager_UserListChanged::getUserName() const {
00769     const ISerializable* item = getItem();
00770     if ( item != NULL && item->isKindOf<wosh::User>() ) {
00771         return item->as<wosh::User>()->getName();
00772      }
00773     const Variant* var = getItemKey();
00774     if ( var == NULL ) return "";
00775     return var->toString();
00776  }
00777 
00778 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00779 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00780 
00781  WOSH_REGISTER(wosh::UserManager_GroupListChanged, wosh::Fact, 0.8711, core_UserManager_GroupListChanged)
00782 
00783 std::string UserManager_GroupListChanged::getGroupName() const {
00784     const ISerializable* item = getItem();
00785     if ( item != NULL && item->isKindOf<wosh::UserGroup>() ) {
00786         return item->as<wosh::UserGroup>()->getName();
00787      }
00788     const Variant* var = getItemKey();
00789     if ( var == NULL ) return "";
00790     return var->toString();
00791  }
00792 
00793 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00794 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
00795 
00796 
00797 }; // namespace wosh

Generated on Tue Feb 8 2011 09:33:08 for WOSH system 0.8.888 [wolf] by Alessandro Polo, using DoxyGen 1.7.2 hosted by WOSH Framework