28 using System.Collections.Generic;
30 using System.Reflection;
31 using System.Threading;
33 using OpenSim.Framework;
34 using OpenSim.Framework.Console;
35 using OpenSim.Framework.Monitoring;
36 using OpenSim.Region.ClientStack.LindenUDP;
37 using OpenSim.Region.Framework;
38 using OpenSim.Region.Framework.Interfaces;
39 using OpenSim.Region.Framework.Scenes;
40 using OpenSim.Services.Interfaces;
41 using OpenSim.Services.Connectors.Hypergrid;
44 using OpenMetaverse.Packets;
51 namespace OpenSim.
Region.CoreModules.Framework.UserManagement
53 [Extension(Path =
"/OpenSim/RegionModules", NodeName =
"RegionModule", Id =
"UserManagementModule")]
56 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
59 protected List<Scene> m_Scenes =
new List<Scene>();
63 protected Dictionary<UUID, UserData> m_UserCache =
new Dictionary<UUID, UserData>();
65 protected bool m_DisplayChangingHomeURI =
false;
67 #region ISharedRegionModule
71 string umanmod = config.Configs[
"Modules"].GetString(
"UserManagementModule", Name);
76 m_log.DebugFormat(
"[USER MANAGEMENT MODULE]: {0} is enabled", Name);
84 IConfig userManagementConfig = config.Configs[
"UserManagement"];
85 if (userManagementConfig == null)
88 m_DisplayChangingHomeURI = userManagementConfig.GetBoolean(
"DisplayChangingHomeURI",
false);
91 public bool IsSharedModule
96 public virtual string Name
98 get {
return "BasicUserManagementModule"; }
101 public Type ReplaceableInterface
116 scene.RegisterModuleInterface<
IPeople>(
this);
117 scene.EventManager.OnNewClient +=
new EventManager.OnNewClientDelegate(EventManager_OnNewClient);
118 scene.EventManager.OnPrimsLoaded +=
new EventManager.PrimsLoaded(EventManager_OnPrimsLoaded);
129 m_Scenes.Remove(scene);
136 if (m_Enabled && m_ServiceThrottle == null)
155 #endregion ISharedRegionModule
158 #region Event Handlers
160 void EventManager_OnPrimsLoaded(
Scene s)
163 m_log.DebugFormat(
"[USER MANAGEMENT MODULE]: Caching creators' data from {0} ({1} objects)...", s.RegionInfo.RegionName, s.GetEntities().Length);
167 void EventManager_OnNewClient(
IClientAPI client)
169 client.OnConnectionClosed +=
new Action<IClientAPI>(HandleConnectionClosed);
170 client.OnNameFromUUIDRequest +=
new UUIDNameRequest(HandleUUIDNameRequest);
174 void HandleConnectionClosed(
IClientAPI client)
176 client.OnNameFromUUIDRequest -=
new UUIDNameRequest(HandleUUIDNameRequest);
180 void HandleUUIDNameRequest(UUID uuid,
IClientAPI client)
185 if(m_Scenes.Count <= 0)
188 if (m_Scenes[0].LibraryService != null && (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid))
190 client.SendNameReply(uuid,
"Mr",
"OpenSim");
198 if (m_UserCache.TryGetValue(uuid, out user))
200 if (!user.IsUnknownUser && user.HasGridUserTried)
202 client.SendNameReply(uuid, user.FirstName, user.LastName);
209 m_ServiceThrottle.Enqueue(
"name", uuid.ToString(), delegate
219 if (GetUser(uuid, out user))
221 client.SendNameReply(uuid, user.FirstName, user.LastName);
235 m_log.DebugFormat(
"[USER MANAGEMENT MODULE]: HandleAvatarPickerRequest for {0}", query);
237 List<UserData> users = GetUserData(query, 500, 1);
242 AvatarPickerReplyPacket.DataBlock[] searchData =
243 new AvatarPickerReplyPacket.DataBlock[users.Count];
244 AvatarPickerReplyPacket.AgentDataBlock agentData =
new AvatarPickerReplyPacket.AgentDataBlock();
246 agentData.AgentID = avatarID;
247 agentData.QueryID = RequestID;
248 replyPacket.AgentData = agentData;
254 UUID translatedIDtem = item.Id;
255 searchData[i] =
new AvatarPickerReplyPacket.DataBlock();
256 searchData[i].AvatarID = translatedIDtem;
257 searchData[i].FirstName = Utils.StringToBytes((string)item.
FirstName);
258 searchData[i].LastName = Utils.StringToBytes((string)item.
LastName);
261 if (users.Count == 0)
263 searchData =
new AvatarPickerReplyPacket.DataBlock[0];
265 replyPacket.Data = searchData;
268 agent_data.AgentID = replyPacket.AgentData.AgentID;
269 agent_data.QueryID = replyPacket.AgentData.QueryID;
271 List<AvatarPickerReplyDataArgs> data_args =
new List<AvatarPickerReplyDataArgs>();
272 for (i = 0; i < replyPacket.Data.Length; i++)
275 data_arg.AvatarID = replyPacket.Data[i].AvatarID;
276 data_arg.FirstName = replyPacket.Data[i].FirstName;
277 data_arg.LastName = replyPacket.Data[i].LastName;
278 data_args.Add(data_arg);
280 client.SendAvatarPickerReply(agent_data, data_args);
287 #endregion Event Handlers
291 public List<UserData>
GetUserData(
string query,
int page_size,
int page_number)
293 if(m_Scenes.Count <= 0)
294 return new List<UserData>();;
297 List<UserAccount> accs = m_Scenes[0].UserAccountService.GetUserAccounts(m_Scenes[0].RegionInfo.ScopeID, query);
299 List<UserData> users =
new List<UserData>();
305 ud.FirstName = acc.FirstName;
306 ud.LastName = acc.LastName;
307 ud.Id = acc.PrincipalID;
308 ud.HasGridUserTried =
true;
309 ud.IsUnknownUser =
false;
315 foreach (
UserData data
in m_UserCache.Values)
318 users.Find(delegate(
UserData d) {
return d.Id == data.Id; }) == null &&
319 (data.
FirstName.ToLower().StartsWith(query.ToLower()) || data.LastName.ToLower().StartsWith(query.ToLower())))
323 AddAdditionalUsers(query, users);
350 private bool TryGetUserNames(UUID uuid,
string[] names)
353 names =
new string[2];
355 if (TryGetUserNamesFromCache(uuid, names))
358 if (TryGetUserNamesFromServices(uuid, names))
364 private bool TryGetUserNamesFromCache(UUID uuid,
string[] names)
368 if (m_UserCache.ContainsKey(uuid))
370 names[0] = m_UserCache[uuid].FirstName;
371 names[1] = m_UserCache[uuid].LastName;
386 private bool TryGetUserNamesFromServices(UUID uuid,
string[] names)
388 if(m_Scenes.Count <= 0)
391 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(UUID.Zero, uuid);
395 names[0] = account.FirstName;
396 names[1] = account.LastName;
399 user.FirstName = account.FirstName;
400 user.LastName = account.LastName;
403 m_UserCache[uuid] = user;
410 GridUserInfo uInfo = m_Scenes[0].GridUserService.GetGridUserInfo(uuid.ToString());
413 string url, first, last, tmp;
415 if (Util.ParseUniversalUserIdentifier(uInfo.UserID, out u, out url, out first, out last, out tmp))
417 AddUser(uuid, first, last, url);
419 if (m_UserCache.ContainsKey(uuid))
421 names[0] = m_UserCache[uuid].FirstName;
422 names[1] = m_UserCache[uuid].LastName;
428 m_log.DebugFormat(
"[USER MANAGEMENT MODULE]: Unable to parse UUI {0}", uInfo.UserID);
435 names[0] =
"Unknown";
436 names[1] =
"UserUMMTGUN9";
443 #region IUserManagement
447 string[] parts = name.Split(
new string[] {
" " }, StringSplitOptions.RemoveEmptyEntries);
448 if (parts.Length < 2)
449 throw new Exception(
"Name must have 2 components");
451 return GetUserIdByName(parts[0], parts[1]);
456 if(m_Scenes.Count <= 0)
462 foreach (
UserData user
in m_UserCache.Values)
469 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(UUID.Zero, firstName, lastName);
472 return account.PrincipalID;
480 GetUser(uuid, out user);
481 return user.FirstName +
" " + user.LastName;
487 if(GetUser(userID, out user))
497 if(!GetUser(userID, out userdata))
502 if (userdata.ServerURLs != null && userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null)
504 return userdata.ServerURLs[serverType].ToString();
507 if (!
string.IsNullOrEmpty(userdata.HomeURL))
514 userdata.ServerURLs = uConn.GetServerURLs(userID);
516 catch(System.Net.WebException e)
518 m_log.DebugFormat(
"[USER MANAGEMENT MODULE]: GetServerURLs call failed {0}", e.Message);
519 userdata.ServerURLs =
new Dictionary<string, object>();
523 m_log.Debug(
"[USER MANAGEMENT MODULE]: GetServerURLs call failed ", e);
524 userdata.ServerURLs =
new Dictionary<string, object>();
527 if (userdata.ServerURLs != null && userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null)
528 return userdata.ServerURLs[serverType].ToString();
537 GetUserUUI(userID, out uui);
544 bool result = GetUser(userID, out ud);
548 string homeURL = ud.HomeURL;
549 string first = ud.FirstName, last = ud.LastName;
550 if (ud.LastName.StartsWith(
"@"))
552 string[] parts = ud.FirstName.Split(
'.');
553 if (parts.Length >= 2)
558 uui = userID +
";" + homeURL +
";" + first +
" " + last;
562 uui = userID.ToString();
566 #region Cache Management
569 if(m_Scenes.Count <= 0)
577 if (m_UserCache.TryGetValue(uuid, out userdata))
579 if (userdata.HasGridUserTried)
587 userdata.HasGridUserTried =
false;
589 userdata.FirstName =
"Unknown";
590 userdata.LastName =
"UserUMMAU42";
591 userdata.HomeURL = string.Empty;
592 userdata.IsUnknownUser =
true;
593 userdata.HasGridUserTried =
false;
600 if (!userdata.HasGridUserTried)
603 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, uuid);
606 userdata.FirstName = account.FirstName;
607 userdata.LastName = account.LastName;
608 userdata.HomeURL = string.Empty;
609 userdata.IsUnknownUser =
false;
610 userdata.HasGridUserTried =
true;
614 if (!userdata.HasGridUserTried)
617 if (null != m_Scenes[0].GridUserService)
619 uInfo = m_Scenes[0].GridUserService.GetGridUserInfo(uuid.ToString());
623 string url, first, last, tmp;
625 if(uInfo.
UserID.Length <= 36)
629 else if (Util.ParseUniversalUserIdentifier(uInfo.
UserID, out u, out url, out first, out last, out tmp))
631 if (url !=
string.Empty)
633 userdata.FirstName = first.Replace(
" ",
".") +
"." + last.Replace(
" ",
".");
634 userdata.HomeURL = url;
637 userdata.LastName =
"@" +
new Uri(url).Authority;
638 userdata.IsUnknownUser =
false;
642 userdata.LastName =
"@unknown";
644 userdata.HasGridUserTried =
true;
648 m_log.DebugFormat(
"[USER MANAGEMENT MODULE]: Unable to parse UUI {0}", uInfo.UserID);
655 m_UserCache[uuid] = userdata;
657 return !userdata.IsUnknownUser;
660 public void AddUser(UUID uuid,
string first,
string last)
664 if(!m_UserCache.ContainsKey(uuid))
668 user.FirstName = first;
669 user.LastName = last;
670 user.IsUnknownUser =
false;
671 user.HasGridUserTried =
false;
672 m_UserCache.Add(uuid, user);
677 public void AddUser(UUID uuid,
string first,
string last,
string homeURL)
684 if (m_UserCache.TryGetValue(uuid, out oldUser))
686 if (!oldUser.IsUnknownUser)
688 if (homeURL != oldUser.HomeURL && m_DisplayChangingHomeURI)
690 m_log.DebugFormat(
"[USER MANAGEMENT MODULE]: Different HomeURI for {0} {1} ({2}): {3} and {4}",
691 first, last, uuid.ToString(), homeURL, oldUser.HomeURL);
697 else if(!m_UserCache.ContainsKey(uuid))
700 oldUser.HasGridUserTried =
false;
701 oldUser.IsUnknownUser =
false;
702 if (homeURL !=
string.Empty)
704 oldUser.FirstName = first.Replace(
" ",
".") +
"." + last.Replace(
" ",
".");
707 oldUser.LastName =
"@" +
new Uri(homeURL).Authority;
708 oldUser.IsUnknownUser =
false;
712 oldUser.LastName =
"@unknown";
717 oldUser.FirstName = first;
718 oldUser.LastName = last;
720 oldUser.HomeURL = homeURL;
722 m_UserCache.Add(uuid, oldUser);
727 public void AddUser(UUID
id,
string creatorData)
731 if(
string.IsNullOrEmpty(creatorData))
733 AddUser(
id,
string.Empty,
string.Empty,
string.Empty);
738 string firstname = string.Empty;
739 string lastname = string.Empty;
743 string[] parts = creatorData.Split(
';');
746 string[] nameparts = parts[1].Split(
' ');
747 firstname = nameparts[0];
748 for(
int xi = 1; xi < nameparts.Length; ++xi)
754 lastname += nameparts[xi];
759 firstname =
"Unknown";
760 lastname =
"UserUMMAU5";
762 if (parts.Length >= 1)
765 if(Uri.IsWellFormedUriString(homeURL, UriKind.Absolute))
767 AddUser(
id, firstname, lastname, homeURL);
771 m_log.DebugFormat(
"[SCENE]: Unable to parse Uri {0} for CreatorID {1}", parts[0], creatorData);
775 if(!m_UserCache.ContainsKey(
id))
779 newUser.FirstName = firstname +
"." + lastname.Replace(
' ',
'.');
780 newUser.LastName =
"@unknown";
781 newUser.HomeURL = string.Empty;
782 newUser.HasGridUserTried =
false;
783 newUser.IsUnknownUser =
true;
784 m_UserCache.Add(id, newUser);
793 if(!m_UserCache.ContainsKey(
id))
797 newUser.FirstName =
"Unknown";
798 newUser.LastName =
"UserUMMAU4";
799 newUser.HomeURL = string.Empty;
800 newUser.IsUnknownUser =
true;
801 newUser.HasGridUserTried =
false;
802 m_UserCache.Add(id, newUser);
812 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, uuid);
813 if (account == null || (account != null && !account.
LocalToGrid))
819 #endregion IUserManagement
823 AddUser(
UUID.Zero,
"Unknown",
"User");
824 RegisterConsoleCmds();
829 MainConsole.Instance.Commands.AddCommand(
"Users",
true,
832 "Show the bindings between a single user UUID and a user name",
836 MainConsole.Instance.Commands.AddCommand(
"Users",
true,
839 "Show the bindings between user UUIDs and user names",
843 MainConsole.Instance.Commands.AddCommand(
"Users",
true,
846 "reset user cache to allow changed settings to be applied",
848 HandleResetUserCache);
851 private void HandleResetUserCache(
string module,
string[] cmd)
859 private void HandleShowUser(
string module,
string[] cmd)
863 MainConsole.Instance.OutputFormat(
"Usage: show name <uuid>");
873 if(!GetUser(userId, out ud))
875 MainConsole.Instance.OutputFormat(
"No name known for user with id {0}", userId);
880 cdt.AddColumn(
"UUID", 36);
881 cdt.AddColumn(
"Name", 30);
882 cdt.AddColumn(
"HomeURL", 40);
883 cdt.AddRow(userId, string.Format(
"{0} {1}", ud.FirstName, ud.LastName), ud.HomeURL);
885 MainConsole.Instance.Output(cdt.ToString());
888 private void HandleShowUsers(
string module,
string[] cmd)
891 cdt.AddColumn(
"UUID", 36);
892 cdt.AddColumn(
"Name", 30);
893 cdt.AddColumn(
"HomeURL", 40);
894 cdt.AddColumn(
"Checked", 10);
896 Dictionary<UUID, UserData> copyDict;
899 copyDict =
new Dictionary<UUID, UserData>(m_UserCache);
902 foreach(KeyValuePair<UUID, UserData> kvp
in copyDict)
904 cdt.AddRow(kvp.Key, string.Format(
"{0} {1}", kvp.Value.FirstName, kvp.Value.LastName), kvp.Value.HomeURL, kvp.Value.HasGridUserTried ?
"yes" :
"no");
907 MainConsole.Instance.Output(cdt.ToString());
IServiceThrottleModule m_ServiceThrottle
static bool TryParseConsoleUuid(ICommandConsole console, string rawUuid, out UUID uuid)
Try to parse a console UUID from the console.
void RemoveRegion(Scene scene)
This is called whenever a Scene is removed. For shared modules, this can happen several times...
void Initialise(IConfigSource config)
This is called to initialize the region module. For shared modules, this is called exactly once...
UUID GetUserIdByName(string firstName, string lastName)
Get user ID by the given name.
Used to generated a formatted table for the console.
string GetUserUUI(UUID userID)
void Close()
This is the inverse to Initialise. After a Close(), this instance won't be usable anymore...
void AddUser(UUID uuid, string first, string last)
Add a user.
bool GetUserUUI(UUID userID, out string uui)
A scene object group is conceptually an object in the scene. The object is constituted of SceneObject...
void AddRegion(Scene scene)
This is called whenever a Scene is added. For shared modules, this can happen several times...
Represents an item in a task inventory
Records user information specific to a grid but which is not part of a user's account.
void RegisterConsoleCmds()
bool IsLocalGridUser(UUID uuid)
string CreatorData
Data about the creator in the form home_url;name
TaskInventoryDictionary TaskInventory
List< UserData > GetUserData(string query, int page_size, int page_number)
static ICommandConsole Instance
void HandleAvatarPickerRequest(IClientAPI client, UUID avatarID, UUID RequestID, string query)
bool GetUser(UUID uuid, out UserData userdata)
string GetUserName(UUID uuid)
UUID GetUserIdByName(string name)
Get user ID by the given name.
static PacketPool Instance
void AddUser(UUID uuid, string first, string last, string homeURL)
Add a user.
Args to return to a client that queries picker data
string GetUserServerURL(UUID userID, string serverType)
string GetUserHomeURL(UUID userID)
virtual void AddAdditionalUsers(string query, List< UserData > users)
Packet GetPacket(PacketType type)
Gets a packet of the given type.
void AddUser(UUID id, string creatorData)
Add a user.
OpenMetaverse.DirectoryManager.DirFindFlags DirFindFlags
This maintains the relationship between a UUID and a user name.
void RegionLoaded(Scene s)
This will be called once for every scene loaded. In a shared module this will be multiple times in on...
delegate void AvatarPickerRequest(IClientAPI remoteClient, UUID agentdata, UUID queryID, string UserQuery)
OpenMetaverse.DirectoryManager.DirFindFlags DirFindFlags
delegate void UUIDNameRequest(UUID id, IClientAPI remote_client)
void PostInitialise()
This is called exactly once after all the shared region-modules have been instanciated and IRegionMod...