From 5ef66d68a0b36b66fcbfcdbffa9d87b173e40731 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 27 Aug 2020 18:31:28 +0100 Subject: [PATCH] several changes to usermanagement and profiles --- .../FetchInventory/FetchInvDescHandler.cs | 5 +- OpenSim/Framework/ExpiringCacheOS.cs | 45 + .../Avatar/UserProfiles/UserProfileModule.cs | 148 +-- .../UserManagement/HGUserManagementModule.cs | 25 +- .../UserManagement/UserManagementModule.cs | 996 +++++++++--------- .../World/WorldMap/HGWorldMapModule.cs | 3 +- .../Region/Framework/Scenes/EventManager.cs | 1 + .../Services/Interfaces/IUserManagement.cs | 11 +- 8 files changed, 645 insertions(+), 589 deletions(-) diff --git a/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescHandler.cs b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescHandler.cs index 1142d8d4b0..298bfbbc25 100644 --- a/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescHandler.cs +++ b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescHandler.cs @@ -72,6 +72,8 @@ namespace OpenSim.Capabilities.Handlers { OSDArray foldersrequested = null; OSD tmp = OSDParser.DeserializeLLSDXml(httpRequest.InputStream); + httpRequest.InputStream.Dispose(); + OSDMap map = (OSDMap)tmp; if(map.TryGetValue("folders", out tmp) && tmp is OSDArray) foldersrequested = tmp as OSDArray; @@ -111,7 +113,8 @@ namespace OpenSim.Capabilities.Handlers } } foldersrequested = null; - tmp = null; + map.Clear(); + map = null; } catch (Exception e) { diff --git a/OpenSim/Framework/ExpiringCacheOS.cs b/OpenSim/Framework/ExpiringCacheOS.cs index 7a966087b2..64c21d1be8 100644 --- a/OpenSim/Framework/ExpiringCacheOS.cs +++ b/OpenSim/Framework/ExpiringCacheOS.cs @@ -436,5 +436,50 @@ namespace OpenSim.Framework return success; } + public ICollection Values + { + get + { + bool gotLock = false; + try + { + try { } + finally + { + m_rwLock.EnterUpgradeableReadLock(); + gotLock = true; + } + return m_values.Values; + } + finally + { + if (gotLock) + m_rwLock.ExitUpgradeableReadLock(); + } + } + } + + public ICollection Keys + { + get + { + bool gotLock = false; + try + { + try { } + finally + { + m_rwLock.EnterUpgradeableReadLock(); + gotLock = true; + } + return m_values.Keys; + } + finally + { + if (gotLock) + m_rwLock.ExitUpgradeableReadLock(); + } + } + } } } \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs index 5fe1239102..0fbdc8dfe0 100644 --- a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs @@ -72,9 +72,6 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles IAssetCache m_assetCache; IGroupsModule m_groupsModule = null; - static readonly UUID m_MrOpenSimID = new UUID("11111111-1111-0000-0000-000100bba000"); - static readonly DateTime m_MrOpenSimBorn = new DateTime(2007,1,1,0,0,0,DateTimeKind.Utc); - private JsonRpcRequestManager rpc = new JsonRpcRequestManager(); private bool m_allowUserProfileWebURLs = true; @@ -110,62 +107,53 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles ScenePresence p = req.presence; string serverURI = string.Empty; + + bool ok = true; bool foreign = GetUserProfileServerURI(avatarID, out serverURI); - - UserAccount account = null; - - if (!foreign) - account = Scene.UserAccountService.GetUserAccount(Scene.RegionInfo.ScopeID, avatarID); + if(serverURI == string.Empty) + ok = false; Byte[] membershipType = new Byte[1]; string born = string.Empty; uint flags = 0x00; - if (null != account) - { - if (account.UserTitle == "") - membershipType[0] = (Byte)((account.UserFlags & 0xf00) >> 8); + if (ok && GetUserAccountData(avatarID, out UserAccount acc)) + { + int val_flags = acc.UserFlags; + flags = (uint)(val_flags & 0xff); + + if (acc.UserTitle == "") + membershipType[0] = (byte)((val_flags & 0x0f00) >> 8); else - membershipType = Utils.StringToBytes(account.UserTitle); + membershipType = Utils.StringToBytes(acc.UserTitle); - born = Util.ToDateTime(account.Created).ToString( - "M/d/yyyy", CultureInfo.InvariantCulture); - flags = (uint)(account.UserFlags & 0xff); - } - else - { - if (GetUserAccountData(avatarID, out Dictionary userInfo) == true) - { - if ((string)userInfo["user_title"] == "") - membershipType[0] = (Byte)(((Byte)userInfo["user_flags"] & 0xf00) >> 8); - else - membershipType = Utils.StringToBytes((string)userInfo["user_title"]); - - int val_born = (int)userInfo["user_created"]; - if (val_born != 0) - born = Util.ToDateTime(val_born).ToString( - "M/d/yyyy", CultureInfo.InvariantCulture); + int val_born = acc.Created; + if (val_born != 0) + born = Util.ToDateTime(val_born).ToString("M/d/yyyy", CultureInfo.InvariantCulture); // picky, picky - int val_flags = (int)userInfo["user_flags"]; - flags = (uint)(val_flags & 0xff); - } } + else + ok = false; UserProfileProperties props = new UserProfileProperties(); props.UserId = avatarID; - string result = string.Empty; - if (!GetProfileData(ref props, foreign, serverURI, out result)) + if(ok) { - props.AboutText = "Profile not available at this time. User may still be unknown to this grid"; + string result = string.Empty; + if (!GetProfileData(ref props, foreign, serverURI, out result)) + ok = false; } + if (!ok) + props.AboutText = "Profile not available at this time. User may still be unknown to this grid"; + if (!m_allowUserProfileWebURLs) props.WebUrl = ""; GroupMembershipData[] agentGroups = null; - if(m_groupsModule != null) + if(ok && m_groupsModule != null) agentGroups = m_groupsModule.GetMembershipData(avatarID); HashSet clients; @@ -515,7 +503,7 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles if(!UUID.TryParse(args[0], out targetID) || targetID == UUID.Zero) return; - if (targetID == m_MrOpenSimID) + if (targetID == Constants.m_MrOpenSimID) { remoteClient.SendAvatarClassifiedReply(targetID, classifieds); return; @@ -916,7 +904,7 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles Dictionary picks = new Dictionary(); - if (targetId == m_MrOpenSimID) + if (targetId == Constants.m_MrOpenSimID) { remoteClient.SendAvatarPicksReply(targetId, picks); return; @@ -1336,7 +1324,7 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles /// public void NotesUpdate(IClientAPI remoteClient, UUID queryTargetID, string queryNotes) { - if (queryTargetID == m_MrOpenSimID) + if (queryTargetID == Constants.m_MrOpenSimID) return; ScenePresence p = FindPresence(queryTargetID); @@ -1503,9 +1491,9 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles return; } - if (avatarID == m_MrOpenSimID) + if (avatarID == Constants.m_MrOpenSimID) { - remoteClient.SendAvatarProperties(avatarID, "Creator of OpenSimulator shared assets library", m_MrOpenSimBorn.ToString(), + remoteClient.SendAvatarProperties(avatarID, "Creator of OpenSimulator shared assets library", Constants.m_MrOpenSimBorn.ToString(), Utils.StringToBytes("System agent"), "MrOpenSim has no life", 0x10, UUID.Zero, UUID.Zero, "", UUID.Zero); remoteClient.SendAvatarInterestsReply(avatarID, 0, "", @@ -1758,7 +1746,7 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles return false; } - object Prop = (object)properties; + object Prop = properties; if (!rpc.JsonRpcRequest(ref Prop, "avatar_properties_request", serverURI, UUID.Random().ToString())) { // If it's a foreign user then try again using OpenProfile, in case that's what the grid is using @@ -1789,7 +1777,6 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles { message = string.Format("JsonRpcRequest for user {0} to {1} failed", properties.UserId, serverURI); m_log.DebugFormat("[PROFILES]: {0}", message); - return false; } } @@ -1820,77 +1807,48 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles /// /// If set to true user info. /// - bool GetUserAccountData(UUID userID, out Dictionary userInfo) + bool GetUserAccountData(UUID userID, out UserAccount account) { - Dictionary info = new Dictionary(); - + account = null; if (UserManagementModule.IsLocalGridUser(userID)) { // Is local IUserAccountService uas = Scene.UserAccountService; - UserAccount account = uas.GetUserAccount(Scene.RegionInfo.ScopeID, userID); - - info["user_flags"] = account.UserFlags; - info["user_created"] = account.Created; - - if (!String.IsNullOrEmpty(account.UserTitle)) - info["user_title"] = account.UserTitle; - else - info["user_title"] = ""; - - userInfo = info; - - return false; + account = uas.GetUserAccount(Scene.RegionInfo.ScopeID, userID); + return account != null; } else { // Is Foreign - string home_url = UserManagementModule.GetUserServerURL(userID, "HomeURI"); - - if (String.IsNullOrEmpty(home_url)) - { - info["user_flags"] = 0; - info["user_created"] = 0; - info["user_title"] = "Unavailable"; - - userInfo = info; - return true; - } + string home_url = UserManagementModule.GetUserServerURL(userID, "HomeURI", out bool recentFailedWeb); + if (recentFailedWeb || String.IsNullOrEmpty(home_url)) + return false; UserAgentServiceConnector uConn = new UserAgentServiceConnector(home_url); - Dictionary account; + Dictionary info; try { - account = uConn.GetUserInfo(userID); + info = uConn.GetUserInfo(userID); } catch (Exception e) { m_log.Debug("[PROFILES]: GetUserInfo call failed ", e); - account = new Dictionary(); + UserManagementModule.UserWebFailed(userID); + return false; } - if (account.Count > 0) - { - if (account.ContainsKey("user_flags")) - info["user_flags"] = account["user_flags"]; - else - info["user_flags"] = ""; + if (info.Count == 0) + return false; - if (account.ContainsKey("user_created")) - info["user_created"] = account["user_created"]; - else - info["user_created"] = ""; + account = new UserAccount(); + if (info.ContainsKey("user_flags")) + account.UserFlags = (int)info["user_flags"]; - info["user_title"] = "HG Visitor"; - } - else - { - info["user_flags"] = 0; - info["user_created"] = 0; - info["user_title"] = "HG Visitor"; - } - userInfo = info; + if (info.ContainsKey("user_created")) + account.Created = (int)info["user_created"]; + + account.UserTitle = "HG Visitor"; return true; } } @@ -1945,7 +1903,9 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles if (!local) { - serverURI = UserManagementModule.GetUserServerURL(userID, "ProfileServerURI"); + serverURI = UserManagementModule.GetUserServerURL(userID, "ProfileServerURI", out bool failled); + if(failled) + serverURI = string.Empty; // Is Foreign return true; } diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs index 3e0a6108fd..80d8107166 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs @@ -58,7 +58,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement if (umanmod == Name) { m_Enabled = true; - Init(); + base.Init(config); m_log.DebugFormat("[USER MANAGEMENT MODULE]: {0} is enabled", Name); } } @@ -70,7 +70,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement #endregion ISharedRegionModule - protected override void AddAdditionalUsers(string query, List users) + protected override void AddAdditionalUsers(string query, List users, HashSet found) { if (query.Contains("@")) // First.Last@foo.com, maybe? { @@ -82,13 +82,15 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement } words[0] = words[0].Trim(); // it has at least 1 - words[1] = words[1].Trim(); - + words[1] = words[1].Trim().ToLower(); + string match1 = "@" + words[1]; if (words[0] == String.Empty) // query was @foo.com? { - foreach (UserData d in m_UserCache.Values) + foreach (UserData d in m_userCacheByID.Values) { - if (d.LastName.ToLower().StartsWith("@" + words[1].ToLower())) + if(found.Contains(d.Id)) + continue; + if (d.LastName.ToLower().StartsWith(match1)) users.Add(d); } @@ -96,13 +98,15 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement return; } + string match0 = words[0].ToLower(); // words.Length == 2 and words[0] != string.empty // first.last@foo.com ? - foreach (UserData d in m_UserCache.Values) + foreach (UserData d in m_userCacheByID.Values) { - if (d.LastName.StartsWith("@") && - d.FirstName.ToLower().Equals(words[0].ToLower()) && - d.LastName.ToLower().Equals("@" + words[1].ToLower())) + if (found.Contains(d.Id)) + continue; + if (d.LastName.ToLower().Equals(match1) && + d.FirstName.ToLower().Equals(match0)) { users.Add(d); // It's cached. We're done @@ -116,7 +120,6 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement string[] names = words[0].Split(new char[] { '.' }); if (names.Length >= 2) { - string uriStr = "http://" + words[1]; // Let's check that the last name is a valid address try diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index 407c83f733..0b55563319 100755 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs @@ -60,11 +60,40 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement protected List m_Scenes = new List(); protected IServiceThrottleModule m_ServiceThrottle; + protected IUserAccountService m_userAccountService = null; + protected IGridUserService m_gridUserService = null; + string m_ThisGatekeeperHost; + HashSet m_ThisGateKeeperAlias = new HashSet(); + // The cache - protected Dictionary m_UserCache = new Dictionary(); + protected ExpiringCacheOS m_userCacheByID = new ExpiringCacheOS(60000); protected bool m_DisplayChangingHomeURI = false; + UUID m_scopeID = UUID.Zero; + + ~UserManagementModule() + { + Dispose(false); + } + + private bool disposed = false; + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (!disposed) + { + disposed = true; + m_userCacheByID.Dispose(); + m_userCacheByID = null; + } + } + #region ISharedRegionModule public virtual void Initialise(IConfigSource config) @@ -73,20 +102,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement if (umanmod == Name) { m_Enabled = true; - Init(); + Init(config); m_log.DebugFormat("[USER MANAGEMENT MODULE]: {0} is enabled", Name); } - - if(!m_Enabled) - { - return; - } - - IConfig userManagementConfig = config.Configs["UserManagement"]; - if (userManagementConfig == null) - return; - - m_DisplayChangingHomeURI = userManagementConfig.GetBoolean("DisplayChangingHomeURI", false); } public virtual bool IsSharedModule @@ -115,8 +133,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement scene.RegisterModuleInterface(this); scene.RegisterModuleInterface(this); - scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(EventManager_OnNewClient); - scene.EventManager.OnPrimsLoaded += new EventManager.PrimsLoaded(EventManager_OnPrimsLoaded); + scene.EventManager.OnNewClient += EventManager_OnNewClient; + scene.EventManager.OnPrimsLoaded += EventManager_OnPrimsLoaded; } } @@ -134,8 +152,16 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement public virtual void RegionLoaded(Scene s) { - if (m_Enabled && m_ServiceThrottle == null) + if (!m_Enabled) + return; + if(m_ServiceThrottle == null) m_ServiceThrottle = s.RequestModuleInterface(); + if(m_userAccountService == null) + m_userAccountService = s.UserAccountService; + if(m_gridUserService == null) + m_gridUserService = s.GridUserService; + if (s.RegionInfo.ScopeID != UUID.Zero) + m_scopeID = s.RegionInfo.ScopeID; } public virtual void PostInitialise() @@ -144,18 +170,17 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement public virtual void Close() { + m_Enabled = false; lock (m_Scenes) { m_Scenes.Clear(); } - lock (m_UserCache) - m_UserCache.Clear(); + Dispose(false); } #endregion ISharedRegionModule - #region Event Handlers protected virtual void EventManager_OnPrimsLoaded(Scene s) @@ -167,16 +192,16 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement protected virtual void EventManager_OnNewClient(IClientAPI client) { - client.OnConnectionClosed += new Action(HandleConnectionClosed); - client.OnNameFromUUIDRequest += new UUIDNameRequest(HandleUUIDNameRequest); - client.OnAvatarPickerRequest += new AvatarPickerRequest(HandleAvatarPickerRequest); + client.OnConnectionClosed += HandleConnectionClosed; + client.OnNameFromUUIDRequest += HandleUUIDNameRequest; + client.OnAvatarPickerRequest += HandleAvatarPickerRequest; } protected virtual void HandleConnectionClosed(IClientAPI client) { - client.OnNameFromUUIDRequest -= new UUIDNameRequest(HandleUUIDNameRequest); - client.OnAvatarPickerRequest -= new AvatarPickerRequest(HandleAvatarPickerRequest); - client.OnConnectionClosed -= new Action(HandleConnectionClosed); + client.OnNameFromUUIDRequest -= HandleUUIDNameRequest; + client.OnAvatarPickerRequest -= HandleAvatarPickerRequest; + client.OnConnectionClosed -= HandleConnectionClosed; } protected virtual void HandleUUIDNameRequest(UUID uuid, IClientAPI client) @@ -187,24 +212,12 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement if(m_Scenes.Count <= 0) return; - if (m_Scenes[0].LibraryService != null && (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid)) + if (m_userCacheByID.TryGetValue(uuid, out UserData user)) { - client.SendNameReply(uuid, "Mr", "OpenSim"); - } - else - { - UserData user; - /* bypass that continuation here when entry is already available */ - lock (m_UserCache) + if (user.HasGridUserTried) { - if (m_UserCache.TryGetValue(uuid, out user)) - { - if (!user.IsUnknownUser && user.HasGridUserTried) - { - client.SendNameReply(uuid, user.FirstName, user.LastName); - return; - } - } + client.SendNameReply(uuid, user.FirstName, user.LastName); + return; } } @@ -236,50 +249,94 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement client.SendAvatarPickerReply(RequestID, users); } - protected virtual void AddAdditionalUsers(string query, List users) + public bool CheckUrl(string url, out bool islocal, out Uri uri) + { + islocal = false; + if (string.IsNullOrWhiteSpace(url)) + { + uri = null; + islocal = true; + return true; + } + try + { + uri = new Uri(url, UriKind.Absolute); + } + catch + { + uri = null; + islocal = true; + return false; + } + + string host = uri.DnsSafeHost.ToLower(); + + if (m_ThisGatekeeperHost.Equals(host)) + islocal = true; + else if (m_ThisGateKeeperAlias.Contains(host)) + islocal = true; + return true; + } + + protected virtual void AddAdditionalUsers(string query, List users, HashSet found) { } #endregion Event Handlers #region IPeople + public virtual UserData GetUserData(UUID id) + { + if(GetUser(id, out UserData u)) + return u; + return null; + } public virtual List GetUserData(string query, int page_size, int page_number) { - if(m_Scenes.Count <= 0) + if(m_Scenes.Count <= 0 || m_userAccountService == null) return new List();; - // search the user accounts service - List accs = m_Scenes[0].UserAccountService.GetUserAccounts(m_Scenes[0].RegionInfo.ScopeID, query); + var users = new List(); + var found = new HashSet(); - List users = new List(); - if (accs != null) + // search the user accounts service + if (m_userAccountService != null) { - foreach (UserAccount acc in accs) + List accs = m_userAccountService.GetUserAccounts(m_scopeID, query); + if (accs != null) { - UserData ud = new UserData(); - ud.FirstName = acc.FirstName; - ud.LastName = acc.LastName; - ud.Id = acc.PrincipalID; - ud.HasGridUserTried = true; - ud.IsUnknownUser = false; - users.Add(ud); + for(int i = 0; i < accs.Count; ++i) + { + UserAccount acc = accs[i]; + UUID id = acc.PrincipalID; + UserData ud = new UserData(); + ud.FirstName = acc.FirstName; + ud.LastName = acc.LastName; + ud.Id = id; + ud.HasGridUserTried = true; + ud.IsUnknownUser = false; + ud.IsLocal = acc.LocalToGrid; + users.Add(ud); + found.Add(id); + } } } // search the local cache - foreach (UserData data in m_UserCache.Values) + string q = query.ToLower(); + foreach (UserData data in m_userCacheByID.Values) { - if (data.Id != UUID.Zero && !data.IsUnknownUser && - users.Find(delegate(UserData d) { return d.Id == data.Id; }) == null && - (data.FirstName.ToLower().StartsWith(query.ToLower()) || data.LastName.ToLower().StartsWith(query.ToLower()))) + if (found.Contains(data.Id)) + continue; + if (data.Id == UUID.Zero || data.IsUnknownUser) + continue; + if (data.FirstName.ToLower().StartsWith(q) || data.LastName.ToLower().StartsWith(q)) users.Add(data); } - AddAdditionalUsers(query, users); - + AddAdditionalUsers(query, users, found); return users; - } #endregion IPeople @@ -308,94 +365,18 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement if (names == null) names = new string[2]; - if (TryGetUserNamesFromCache(uuid, names)) - return true; - - if (TryGetUserNamesFromServices(uuid, names)) + if(GetUser(uuid, out UserData u)) + { + names[0] = u.FirstName; + names[1] = u.LastName; return true; + } + names[0] = "UnknownUMM3"; + names[1] = uuid.ToString(); return false; } - protected virtual bool TryGetUserNamesFromCache(UUID uuid, string[] names) - { - lock (m_UserCache) - { - if (m_UserCache.ContainsKey(uuid)) - { - names[0] = m_UserCache[uuid].FirstName; - names[1] = m_UserCache[uuid].LastName; - - return true; - } - } - - return false; - } - - /// - /// Try to get the names bound to the given uuid, from the services. - /// - /// True if the name was found, false if not. - /// - /// The array of names if found. If not found, then names[0] = "Unknown" and names[1] = "User" - protected virtual bool TryGetUserNamesFromServices(UUID uuid, string[] names) - { - if(m_Scenes.Count <= 0) - return false; - - UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(UUID.Zero, uuid); - - if (account != null) - { - names[0] = account.FirstName; - names[1] = account.LastName; - - UserData user = new UserData(); - user.FirstName = account.FirstName; - user.LastName = account.LastName; - - lock (m_UserCache) - m_UserCache[uuid] = user; - - return true; - } - else - { - // Let's try the GridUser service - GridUserInfo uInfo = m_Scenes[0].GridUserService.GetGridUserInfo(uuid.ToString()); - if (uInfo != null) - { - string url, first, last, tmp; - UUID u; - if (Util.ParseUniversalUserIdentifier(uInfo.UserID, out u, out url, out first, out last, out tmp)) - { - AddUser(uuid, first, last, url); - - if (m_UserCache.ContainsKey(uuid)) - { - names[0] = m_UserCache[uuid].FirstName; - names[1] = m_UserCache[uuid].LastName; - - return true; - } - } - else - m_log.DebugFormat("[USER MANAGEMENT MODULE]: Unable to parse UUI {0}", uInfo.UserID); - } -// else -// { -// m_log.DebugFormat("[USER MANAGEMENT MODULE]: No grid user found for {0}", uuid); -// } - - names[0] = "Unknown"; - names[1] = "UserUMMTGUN9"; - - return false; - } - } - - #region IUserManagement public virtual UUID GetUserIdByName(string name) @@ -413,28 +394,30 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement return UUID.Zero; // TODO: Optimize for reverse lookup if this gets used by non-console commands. - lock (m_UserCache) + foreach (UserData user in m_userCacheByID.Values) { - foreach (UserData user in m_UserCache.Values) - { - if (user.FirstName == firstName && user.LastName == lastName) - return user.Id; - } + if (user.FirstName.Equals(firstName, StringComparison.InvariantCultureIgnoreCase) && + user.LastName.Equals(lastName, StringComparison.InvariantCultureIgnoreCase)) + return user.Id; } - UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(UUID.Zero, firstName, lastName); - - if (account != null) - return account.PrincipalID; - + if(m_userAccountService != null) + { + UserAccount account = m_userAccountService.GetUserAccount(UUID.Zero, firstName, lastName); + if (account != null) + { + AddUser(account); + return account.PrincipalID; + } + } return UUID.Zero; } public virtual string GetUserName(UUID uuid) { - UserData user; - GetUser(uuid, out user); - return user.FirstName + " " + user.LastName; + if(GetUser(uuid, out UserData user)) + return user.FirstName + " " + user.LastName; + return "UnknownUMM2 " + uuid.ToString(); } public virtual Dictionary GetUsersNames(string[] ids, UUID scopeID) @@ -443,8 +426,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement if(m_Scenes.Count <= 0) return ret; - List missing = new List(); - Dictionary untried = new Dictionary(); + var missing = new List(); // look in cache UserData userdata = new UserData(); @@ -454,139 +436,42 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement { if(UUID.TryParse(id, out uuid)) { - lock (m_UserCache) - { - if (m_UserCache.TryGetValue(uuid, out userdata) && - userdata.FirstName != "Unknown" && userdata.FirstName != string.Empty) - { - string name = userdata.FirstName + " " + userdata.LastName; - - if(userdata.HasGridUserTried) - ret[uuid] = name; - else - { - untried[uuid] = name; - missing.Add(id); - } - } - else - missing.Add(id); - } + if (GetUser(uuid, out userdata)) + ret[uuid] = userdata.FirstName + " " + userdata.LastName; + else + ret[uuid] = "UnknownUMM1 " + uuid.ToString(); } + else + ret[uuid] = "UnknownUMM0 " + id; } - - if(missing.Count == 0) - return ret; - - // try user account service - List accounts = m_Scenes[0].UserAccountService.GetUserAccounts( - scopeID, missing); - - if(accounts.Count != 0) - { - foreach(UserAccount uac in accounts) - { - if(uac != null) - { - string name = uac.FirstName + " " + uac.LastName; - ret[uac.PrincipalID] = name; - missing.Remove(uac.PrincipalID.ToString()); // slowww - untried.Remove(uac.PrincipalID); - - userdata = new UserData(); - userdata.Id = uac.PrincipalID; - userdata.FirstName = uac.FirstName; - userdata.LastName = uac.LastName; - userdata.HomeURL = string.Empty; - userdata.IsUnknownUser = false; - userdata.HasGridUserTried = true; - lock (m_UserCache) - m_UserCache[uac.PrincipalID] = userdata; - } - } - } - - if (missing.Count == 0 || m_Scenes[0].GridUserService == null) - return ret; - - // try grid user service - - GridUserInfo[] pinfos = m_Scenes[0].GridUserService.GetGridUserInfo(missing.ToArray()); - if(pinfos.Length > 0) - { - foreach(GridUserInfo uInfo in pinfos) - { - if (uInfo != null) - { - string url, first, last, tmp; - - if(uInfo.UserID.Length <= 36) - continue; - - if (Util.ParseUniversalUserIdentifier(uInfo.UserID, out uuid, out url, out first, out last, out tmp)) - { - if (url != string.Empty) - { - try - { - userdata = new UserData(); - userdata.FirstName = first.Replace(" ", ".") + "." + last.Replace(" ", "."); - userdata.LastName = "@" + new Uri(url).Authority; - userdata.Id = uuid; - userdata.HomeURL = url; - userdata.IsUnknownUser = false; - userdata.HasGridUserTried = true; - lock (m_UserCache) - m_UserCache[uuid] = userdata; - - string name = userdata.FirstName + " " + userdata.LastName; - ret[uuid] = name; - missing.Remove(uuid.ToString()); - untried.Remove(uuid); - } - catch - { - } - } - } - } - } - } - - // add the untried in cache that still failed - if(untried.Count > 0) - { - foreach(KeyValuePair kvp in untried) - { - ret[kvp.Key] = kvp.Value; - missing.Remove((kvp.Key).ToString()); - } - } - - // add the UMMthings ( not sure we should) - if(missing.Count > 0) - { - foreach(string id in missing) - { - if(UUID.TryParse(id, out uuid) && uuid != UUID.Zero) - { - if (m_Scenes[0].LibraryService != null && - (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid)) - ret[uuid] = "Mr OpenSim"; - else - ret[uuid] = "Unknown UserUMMAU43"; - } - } - } - return ret; } public virtual string GetUserHomeURL(UUID userID) { UserData user; - if(GetUser(userID, out user)) + if (GetUser(userID, out user)) { + if (user.LastWebFail > 0 && Util.GetTimeStamp() - user.LastWebFail > 5 * 60) + user.LastWebFail = -1; + return user.HomeURL; + } + return string.Empty; + } + + public virtual string GetUserHomeURL(UUID userID, out bool recentFail) + { + UserData user; + recentFail = false; + if (GetUser(userID, out user)) + { + if (user.LastWebFail > 0) + { + if (Util.GetTimeStamp() - user.LastWebFail > 5 * 60) + user.LastWebFail = -1; + else + recentFail = true; + } return user.HomeURL; } return string.Empty; @@ -596,16 +481,27 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement { UserData userdata; if(!GetUser(userID, out userdata)) - { return string.Empty; - } - if (userdata.ServerURLs != null && userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null) + if(userdata.IsLocal) + return string.Empty; + + if(userdata.LastWebFail > 0) { - return userdata.ServerURLs[serverType].ToString(); + if(Util.GetTimeStamp() - userdata.LastWebFail > 5 * 60) // 5 minutes + return string.Empty; + userdata.LastWebFail = -1; } - if (!string.IsNullOrEmpty(userdata.HomeURL)) + if (userdata.ServerURLs != null) + { + if(userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null) + return userdata.ServerURLs[serverType].ToString(); + else + return string.Empty; + } + + if (!string.IsNullOrEmpty(userdata.HomeURL) && !WebUtil.GlobalExpiringBadURLs.ContainsKey(userdata.HomeURL)) { // m_log.DebugFormat("[USER MANAGEMENT MODULE]: Requested url type {0} for {1}", serverType, userID); @@ -617,6 +513,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement catch(System.Net.WebException e) { m_log.DebugFormat("[USER MANAGEMENT MODULE]: GetServerURLs call failed {0}", e.Message); + WebUtil.GlobalExpiringBadURLs.Add(userdata.HomeURL, 120000); userdata.ServerURLs = new Dictionary(); } catch (Exception e) @@ -628,7 +525,69 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement if (userdata.ServerURLs != null && userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null) return userdata.ServerURLs[serverType].ToString(); } + return string.Empty; + } + public void UserWebFailed(UUID id) + { + if(m_userCacheByID.TryGetValue(id, out UserData u)) + u.LastWebFail = Util.GetTimeStamp(); + } + + public virtual string GetUserServerURL(UUID userID, string serverType, out bool recentFail) + { + recentFail = false; + UserData userdata; + if (!GetUser(userID, out userdata)) + return string.Empty; + + if (userdata.IsLocal) + return string.Empty; + + if (userdata.LastWebFail > 0) + { + if (Util.GetTimeStamp() - userdata.LastWebFail > 5 * 60) // 5 minutes + recentFail = true; + else + userdata.LastWebFail = -1; + } + + if (userdata.ServerURLs != null) + { + if (userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null) + return userdata.ServerURLs[serverType].ToString(); + else + return string.Empty; + } + + if (!recentFail && !string.IsNullOrEmpty(userdata.HomeURL) && !WebUtil.GlobalExpiringBadURLs.ContainsKey(userdata.HomeURL)) + { + // m_log.DebugFormat("[USER MANAGEMENT MODULE]: Requested url type {0} for {1}", serverType, userID); + + UserAgentServiceConnector uConn = new UserAgentServiceConnector(userdata.HomeURL); + try + { + userdata.ServerURLs = uConn.GetServerURLs(userID); + } + catch (System.Net.WebException e) + { + m_log.DebugFormat("[USER MANAGEMENT MODULE]: GetServerURLs call failed {0}", e.Message); + userdata.ServerURLs = new Dictionary(); + userdata.LastWebFail = Util.GetTimeStamp(); + WebUtil.GlobalExpiringBadURLs.Add(userdata.HomeURL, 120000); + recentFail = true; + } + catch (Exception e) + { + m_log.Debug("[USER MANAGEMENT MODULE]: GetServerURLs call failed ", e); + userdata.ServerURLs = new Dictionary(); + userdata.LastWebFail = Util.GetTimeStamp(); + recentFail = true; + } + + if (userdata.ServerURLs != null && userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null) + return userdata.ServerURLs[serverType].ToString(); + } return string.Empty; } @@ -641,8 +600,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement public virtual bool GetUserUUI(UUID userID, out string uui) { - UserData ud; - bool result = GetUser(userID, out ud); + bool result = GetUser(userID, out UserData ud); if (ud != null) { @@ -668,12 +626,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement #region Cache Management public virtual bool GetUser(UUID uuid, out UserData userdata) { - if (m_Scenes.Count <= 0) - { - userdata = new UserData(); - return false; - } - return GetUser(uuid, m_Scenes[0].RegionInfo.ScopeID, out userdata); + return GetUser(uuid, m_scopeID, out userdata); } public virtual bool GetUser(UUID uuid, UUID scopeID, out UserData userdata) @@ -684,104 +637,140 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement return false; } - lock (m_UserCache) + if (m_userCacheByID.TryGetValue(uuid, out userdata)) { - if (m_UserCache.TryGetValue(uuid, out userdata)) - { - if (userdata.HasGridUserTried) - { - return true; - } - } - else - { - userdata = new UserData(); - userdata.Id = uuid; - userdata.FirstName = "Unknown"; - userdata.LastName = "UserUMMAU42"; - userdata.HomeURL = string.Empty; - userdata.IsUnknownUser = true; - userdata.HasGridUserTried = false; - } + if (userdata.HasGridUserTried) + return true; + } + else + { + userdata = new UserData(); + userdata.Id = uuid; + userdata.FirstName = "Unknown"; + userdata.LastName = uuid.ToString(); + userdata.HomeURL = string.Empty; + userdata.IsUnknownUser = true; + userdata.HasGridUserTried = false; } - /* BEGIN: do not wrap this code in any lock here - * There are HTTP calls in here. - */ if (!userdata.HasGridUserTried) { /* rewrite here */ - UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(scopeID, uuid); + UserAccount account = m_userAccountService.GetUserAccount(scopeID, uuid); if (account != null) { userdata.FirstName = account.FirstName; userdata.LastName = account.LastName; userdata.HomeURL = string.Empty; userdata.IsUnknownUser = false; + userdata.IsLocal = true; userdata.HasGridUserTried = true; + AddUser(account); } } if (!userdata.HasGridUserTried) { GridUserInfo uInfo = null; - if (null != m_Scenes[0].GridUserService) + if (null != m_gridUserService) { - uInfo = m_Scenes[0].GridUserService.GetGridUserInfo(uuid.ToString()); + uInfo = m_gridUserService.GetGridUserInfo(uuid.ToString()); } if (uInfo != null) { string url, first, last, tmp; UUID u; - if(uInfo.UserID.Length <= 36) + if (uInfo.UserID.Length >= 36 && Util.ParseUniversalUserIdentifier(uInfo.UserID, out u, out url, out first, out last, out tmp)) { - /* not a UUI */ - } - else if (Util.ParseUniversalUserIdentifier(uInfo.UserID, out u, out url, out first, out last, out tmp)) - { - if (url != string.Empty) + bool islocal; + Uri uri; + bool isvalid = CheckUrl(url, out islocal, out uri); + + if (isvalid) { - userdata.FirstName = first.Replace(" ", ".") + "." + last.Replace(" ", "."); - userdata.HomeURL = url; - try + if(islocal) { - userdata.LastName = "@" + new Uri(url).Authority; + userdata.FirstName = first; + userdata.LastName = last; + userdata.HomeURL = string.Empty; + userdata.IsLocal = true; userdata.IsUnknownUser = false; } - catch + else { - userdata.LastName = "@unknown"; + userdata.FirstName = first.Replace(" ", ".") + "." + last.Replace(" ", "."); + userdata.HomeURL = uri.AbsoluteUri; + userdata.LastName = "@" + uri.Authority; + userdata.IsLocal = false; + userdata.IsUnknownUser = false; } - userdata.HasGridUserTried = true; } } else m_log.DebugFormat("[USER MANAGEMENT MODULE]: Unable to parse UUI {0}", uInfo.UserID); } + userdata.HasGridUserTried = true; } /* END: do not wrap this code in any lock here */ - lock (m_UserCache) - { - m_UserCache[uuid] = userdata; - } return !userdata.IsUnknownUser; } - public virtual void AddUser(UUID uuid, string first, string last, bool isNPC = false) + public void AddUser(UserAccount account) { - lock (m_UserCache) + UUID id = account.PrincipalID; + if (!m_userCacheByID.ContainsKey(id)) { - if (!m_UserCache.ContainsKey(uuid)) + UserData user = new UserData(); + user.Id = id; + user.FirstName = account.FirstName; + user.LastName = account.LastName; + user.HomeURL = string.Empty; + user.IsUnknownUser = false; + user.HasGridUserTried = true; + user.IsLocal = account.LocalToGrid; + m_userCacheByID.Add(id, user, 1800000); + } + } + + public virtual void AddUser(UUID uuid, string first, string last, bool isNPC = false, int expire = 1800000) + { + if (!m_userCacheByID.ContainsKey(uuid)) + { + UserData user = new UserData(); + user.Id = uuid; + user.FirstName = first; + user.LastName = last; + user.HasGridUserTried = isNPC; + if (!isNPC && last.StartsWith("@")) { - UserData user = new UserData(); - user.Id = uuid; - user.FirstName = first; - user.LastName = last; - user.IsUnknownUser = false; - user.HasGridUserTried = isNPC; - m_UserCache.Add(uuid, user); + string url = last.Substring(1); + bool local; + Uri uri; + if(CheckUrl(url, out local, out uri)) + { + if(local) + { + user.IsLocal = true; + user.HomeURL = string.Empty; + user.HasGridUserTried = true; + } + else + { + user.IsLocal = false; + user.HomeURL = uri.AbsoluteUri; + user.HasGridUserTried = false; + } + user.IsUnknownUser = false; + } } + else + { + user.IsUnknownUser = false; + user.IsLocal = true; + user.HasGridUserTried = true; + } + m_userCacheByID.Add(uuid, user, expire); } } @@ -790,49 +779,55 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement //m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, first {1}, last {2}, url {3}", uuid, first, last, homeURL); UserData oldUser; - lock (m_UserCache) + if (m_userCacheByID.TryGetValue(uuid, out oldUser)) { - if (m_UserCache.TryGetValue(uuid, out oldUser)) + if (!oldUser.IsUnknownUser) { - if (!oldUser.IsUnknownUser) + if (homeURL != oldUser.HomeURL && m_DisplayChangingHomeURI) { - if (homeURL != oldUser.HomeURL && m_DisplayChangingHomeURI) - { - m_log.DebugFormat("[USER MANAGEMENT MODULE]: Different HomeURI for {0} {1} ({2}): {3} and {4}", - first, last, uuid.ToString(), homeURL, oldUser.HomeURL); - } - /* no update needed */ - return; + m_log.DebugFormat("[USER MANAGEMENT MODULE]: Different HomeURI for {0} {1} ({2}): {3} and {4}", + first, last, uuid.ToString(), homeURL, oldUser.HomeURL); } - } - else if(!m_UserCache.ContainsKey(uuid)) - { - oldUser = new UserData(); - oldUser.HasGridUserTried = false; - oldUser.IsUnknownUser = false; - if (homeURL != string.Empty) - { - oldUser.FirstName = first.Replace(" ", ".") + "." + last.Replace(" ", "."); - try - { - oldUser.LastName = "@" + new Uri(homeURL).Authority; - oldUser.IsUnknownUser = false; - } - catch - { - oldUser.LastName = "@unknown"; - } - } - else - { - oldUser.FirstName = first; - oldUser.LastName = last; - } - oldUser.HomeURL = homeURL; - oldUser.Id = uuid; - m_UserCache.Add(uuid, oldUser); + /* no update needed */ + return; } } + + oldUser = new UserData(); + oldUser.Id = uuid; + oldUser.HasGridUserTried = false; + oldUser.IsUnknownUser = false; + + bool local; + Uri uri; + if (CheckUrl(homeURL, out local, out uri)) + { + if (local) + { + oldUser.FirstName = first; + oldUser.LastName = last; + oldUser.IsLocal = true; + oldUser.HomeURL = string.Empty; + oldUser.HasGridUserTried = true; + } + else + { + oldUser.FirstName = first.Replace(" ", ".") + "." + last.Replace(" ", "."); + oldUser.LastName = "@" + uri.Authority; + oldUser.HomeURL = uri.AbsoluteUri; + oldUser.IsLocal = false; + } + } + else + { + oldUser.FirstName = first.Replace(" ", ".") + "." + last.Replace(" ", "."); + oldUser.LastName = "UMMM0Unknown"; + oldUser.IsLocal = true; + oldUser.HomeURL = string.Empty; + oldUser.HasGridUserTried = true; + oldUser.IsUnknownUser = true; + } + m_userCacheByID.Add(uuid, oldUser, 300000); } public virtual void AddUser(UUID id, string creatorData) @@ -840,113 +835,162 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement // m_log.InfoFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, creatorData {1}", id, creatorData); if(string.IsNullOrEmpty(creatorData)) + return; + + if(m_userCacheByID.ContainsKey(id)) + return; + + string homeURL; + string firstname = string.Empty; + string lastname = string.Empty; + + //creatorData = ; + string[] parts = creatorData.Split(';'); + if(parts.Length > 1) { - AddUser(id, string.Empty, string.Empty, string.Empty); + string[] nameparts = parts[1].Split(' '); + if(nameparts.Length < 2) + return; + firstname = nameparts[0]; + for(int xi = 1; xi < nameparts.Length; ++xi) + { + if(xi != 1) + { + lastname += " "; + } + lastname += nameparts[xi]; + } + if (string.IsNullOrWhiteSpace(firstname)) + return; + if (string.IsNullOrWhiteSpace(lastname)) + return; + } + else + return; + + homeURL = parts[0]; + if(homeURL.Length > 10) + { + string test = homeURL.Substring(10); + int indx = test.IndexOf("/"); + if(indx > 0 && indx != test.Length - 1) + homeURL = homeURL.Substring(0, indx + 10); + } + + bool local; + Uri uri; + + var oldUser = new UserData(); + oldUser.Id = id; + oldUser.HasGridUserTried = false; + oldUser.IsUnknownUser = false; + + if (CheckUrl(homeURL, out local, out uri)) + { + if (local) + { + oldUser.FirstName = firstname; + oldUser.LastName = lastname; + oldUser.IsLocal = true; + oldUser.HomeURL = string.Empty; + oldUser.HasGridUserTried = true; + } + else + { + oldUser.FirstName = firstname.Replace(" ", ".") + "." + firstname.Replace(" ", "."); + oldUser.LastName = "@" + uri.Authority; + oldUser.HomeURL = uri.AbsoluteUri; + oldUser.IsLocal = false; + } } else { - string homeURL; - string firstname = string.Empty; - string lastname = string.Empty; - - //creatorData = ; - - string[] parts = creatorData.Split(';'); - if(parts.Length > 1) - { - string[] nameparts = parts[1].Split(' '); - firstname = nameparts[0]; - for(int xi = 1; xi < nameparts.Length; ++xi) - { - if(xi != 1) - { - lastname += " "; - } - lastname += nameparts[xi]; - } - } - else - { - firstname = "Unknown"; - lastname = "UserUMMAU5"; - } - if (parts.Length >= 1) - { - homeURL = parts[0]; - if(Uri.IsWellFormedUriString(homeURL, UriKind.Absolute)) - { - AddUser(id, firstname, lastname, homeURL); - } - else - { - m_log.DebugFormat("[SCENE]: Unable to parse Uri {0} for CreatorID {1}", parts[0], creatorData); - - lock (m_UserCache) - { - if(!m_UserCache.ContainsKey(id)) - { - UserData newUser = new UserData(); - newUser.Id = id; - newUser.FirstName = firstname + "." + lastname.Replace(' ', '.'); - newUser.LastName = "@unknown"; - newUser.HomeURL = string.Empty; - newUser.HasGridUserTried = false; - newUser.IsUnknownUser = true; /* we mark those users as Unknown user so a re-retrieve may be activated */ - m_UserCache.Add(id, newUser); - } - } - } - } - else - { - lock(m_UserCache) - { - if(!m_UserCache.ContainsKey(id)) - { - UserData newUser = new UserData(); - newUser.Id = id; - newUser.FirstName = "Unknown"; - newUser.LastName = "UserUMMAU4"; - newUser.HomeURL = string.Empty; - newUser.IsUnknownUser = true; - newUser.HasGridUserTried = false; - m_UserCache.Add(id, newUser); - } - } - } + oldUser.FirstName = firstname.Replace(" ", ".") + "." + firstname.Replace(" ", "."); + oldUser.LastName = "UMMM1Unknown"; + oldUser.IsLocal = true; + oldUser.HomeURL = string.Empty; + oldUser.HasGridUserTried = true; + oldUser.IsUnknownUser = true; } + m_userCacheByID.Add(id, oldUser, int.MaxValue / 16); } public bool RemoveUser(UUID uuid) { - lock (m_UserCache) - { - return m_UserCache.Remove(uuid); - } + return m_userCacheByID.Remove(uuid); } #endregion public virtual bool IsLocalGridUser(UUID uuid) { - lock (m_Scenes) + if (m_Scenes.Count <= 0) + return true; + + if (m_userCacheByID.TryGetValue(uuid, out UserData u)) { - if (m_Scenes.Count == 0) - return true; - UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, uuid); - if (account == null || (account != null && !account.LocalToGrid)) - return false; + if (u.HasGridUserTried) + return u.IsLocal; } + if(m_userAccountService == null) + return true; + + UserAccount account = m_userAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, uuid); + if (account == null) + return false; + + if(u == null) + AddUser(account); + else + u.HasGridUserTried = true; return true; } #endregion IUserManagement - protected virtual void Init() + protected virtual void Init(IConfigSource config) { - AddUser(UUID.Zero, "Unknown", "User"); + m_ThisGatekeeperHost = Util.GetConfigVarFromSections(config, "GatekeeperURI", + new string[] { "Startup", "Hypergrid", "GridService" }, String.Empty); + m_ThisGatekeeperHost = Util.GetConfigVarFromSections(config, "Gatekeeper", + new string[] { "Startup", "Hypergrid", "GridService" }, m_ThisGatekeeperHost); + + string gatekeeperURIAlias = Util.GetConfigVarFromSections(config, "GatekeeperURIAlias", + new string[] { "Startup", "Hypergrid", "GridService" }, String.Empty); + + if (!string.IsNullOrWhiteSpace(m_ThisGatekeeperHost)) + { + try + { + Uri uri = new Uri(m_ThisGatekeeperHost, UriKind.Absolute); + m_ThisGatekeeperHost = uri.DnsSafeHost.ToLower(); + } + catch + { + m_log.Error("[UserManagementModule] Invalid grid gatekeeper"); + m_ThisGatekeeperHost = string.Empty; + } + } + + if (!string.IsNullOrWhiteSpace(gatekeeperURIAlias)) + { + string[] alias = gatekeeperURIAlias.Split(','); + for (int i = 0; i < alias.Length; ++i) + { + if (!string.IsNullOrWhiteSpace(alias[i])) + m_ThisGateKeeperAlias.Add(alias[i].Trim().ToLower()); + } + } + + AddUser(UUID.Zero, "Unknown", "User", false, int.MaxValue / 16); + AddUser(Constants.m_MrOpenSimID, "Mr", "Opensim", false, int.MaxValue / 16); RegisterConsoleCmds(); + + IConfig userManagementConfig = config.Configs["UserManagement"]; + if (userManagementConfig != null) + m_DisplayChangingHomeURI = userManagementConfig.GetBoolean("DisplayChangingHomeURI", false); + } protected virtual void RegisterConsoleCmds() @@ -975,9 +1019,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement protected virtual void HandleResetUserCache(string module, string[] cmd) { - lock(m_UserCache) + lock(m_userCacheByID) { - m_UserCache.Clear(); + m_userCacheByID.Clear(); } } @@ -1018,20 +1062,14 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement cdt.AddColumn("HomeURL", 40); cdt.AddColumn("Checked", 10); - Dictionary copyDict; - lock(m_UserCache) - { - copyDict = new Dictionary(m_UserCache); - } + ICollection copy = m_userCacheByID.Values; - foreach(KeyValuePair kvp in copyDict) + foreach(UserData u in copy) { - cdt.AddRow(kvp.Key, string.Format("{0} {1}", kvp.Value.FirstName, kvp.Value.LastName), kvp.Value.HomeURL, kvp.Value.HasGridUserTried ? "yes" : "no"); + cdt.AddRow(u.Id, string.Format("{0} {1}", u.FirstName, u.LastName), u.HomeURL, u.HasGridUserTried ? "yes" : "no"); } MainConsole.Instance.Output(cdt.ToString()); } - } - } diff --git a/OpenSim/Region/CoreModules/World/WorldMap/HGWorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/HGWorldMapModule.cs index 9336c8ae9c..13179048e4 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/HGWorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/HGWorldMapModule.cs @@ -37,8 +37,7 @@ using OpenSim.Framework; using OpenSim.Region.CoreModules.World.WorldMap; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; -using OpenSim.Services.Interfaces; -using GridRegion = OpenSim.Services.Interfaces.GridRegion; + namespace OpenSim.Region.CoreModules.Hypergrid { diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index 540e26edc0..b70219b9c5 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -1236,6 +1236,7 @@ namespace OpenSim.Region.Framework.Scenes } } + // to be removed if (client is IClientCore) { OnClientConnectCoreDelegate handlerClientConnect = OnClientConnect; diff --git a/OpenSim/Services/Interfaces/IUserManagement.cs b/OpenSim/Services/Interfaces/IUserManagement.cs index 39268c03fa..9af54e12e2 100644 --- a/OpenSim/Services/Interfaces/IUserManagement.cs +++ b/OpenSim/Services/Interfaces/IUserManagement.cs @@ -30,19 +30,26 @@ using System.Collections.Generic; using OpenMetaverse; -namespace OpenSim.Services.Interfaces +//namespace OpenSim.Services.Interfaces +namespace OpenSim.Framework { + + /// /// This maintains the relationship between a UUID and a user name. /// public interface IUserManagement { + UserData GetUserData(UUID id); string GetUserName(UUID uuid); string GetUserHomeURL(UUID uuid); + string GetUserHomeURL(UUID uuid, out bool failedWeb); string GetUserUUI(UUID uuid); bool GetUserUUI(UUID userID, out string uui); string GetUserServerURL(UUID uuid, string serverType); + string GetUserServerURL(UUID uuid, string serverType, out bool failedWeb); Dictionary GetUsersNames(string[] ids, UUID scopeID); + void UserWebFailed(UUID id); /// /// Get user ID by the given name. @@ -79,7 +86,7 @@ namespace OpenSim.Services.Interfaces /// /// /// - void AddUser(UUID uuid, string first, string last, bool isNPC = false); + void AddUser(UUID uuid, string first, string last, bool isNPC = false, int expire = 1800000); /// /// Add a user.