* Add preliminary code for resolving iar profile names

* Not yet active
0.6.5-rc1
Justin Clarke Casey 2009-04-28 17:47:09 +00:00
parent 1fdebf361f
commit 52d5628806
4 changed files with 152 additions and 18 deletions

View File

@ -0,0 +1,130 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System.Reflection;
using System.Text;
using log4net;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Communications.Cache;
namespace OpenSim.Framework.Communications
{
/// <summary>
/// Resolves OpenSim Profile Anchors (OSPA). An OSPA is a string used to provide information for
/// identifying user profiles or supplying a simple name if no profile is available.
/// </summary>
public class OspResolver
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public const string OSPA_PREFIX = "ospi:";
public const string OSPA_NAME_KEY = "n";
public const string OSPA_NAME_VALUE_SEPARATOR = " ";
public const string OSPA_TUPLE_SEPARATOR = "|";
public static readonly char[] OSPA_TUPLE_SEPARATOR_ARRAY = OSPA_TUPLE_SEPARATOR.ToCharArray();
public const string OSPA_KEY_VALUE_PAIR_SEPARATOR = "=";
/// <summary>
/// Resolve an osp string into the most suitable internal OpenSim identifier.
/// </summary>
///
/// In some cases this will be a UUID if a suitable profile exists on the system. In other cases, this may
/// just return the same identifier after creating a temporary profile.
///
/// <param name="ospa"></param>
/// <param name="commsManager"></param>
/// <returns>
/// A suitable internal OpenSim identifier. If the input string wasn't ospi data, then we simply
/// return that same string. If the input string was ospi data but no valid profile information has been found,
/// then returns null.
/// </returns>
public static string Resolve(string ospa, CommunicationsManager commsManager)
{
if (!ospa.StartsWith(OSPA_PREFIX))
return ospa;
string ospaMeat = ospa.Substring(OSPA_PREFIX.Length);
string[] ospaTuples = ospaMeat.Split(OSPA_TUPLE_SEPARATOR_ARRAY);
foreach (string tuple in ospaTuples)
{
int tupleSeparatorIndex = tuple.IndexOf(OSPA_TUPLE_SEPARATOR);
if (tupleSeparatorIndex < 0)
{
m_log.WarnFormat("[OSPA RESOLVER]: Ignoring non-tuple component {0} in OSPA {1}", tuple, ospa);
continue;
}
string key = tuple.Remove(tupleSeparatorIndex).Trim();
string value = tuple.Substring(tupleSeparatorIndex + 1).Trim();
if (OSPA_NAME_KEY == key)
return ResolveOspaName(value, commsManager);
}
return null;
}
/// <summary>
/// Resolve an OSPI name by querying existing persistent user profiles. If there is no persistent user profile
/// then a temporary user profile is inserted in the cache.
/// </summary>
/// <param name="name"></param>
/// <param name="commsManager"></param>
/// <returns>
/// An OpenSim internal identifier for the name given. Returns null if the name was not valid
/// </returns>
protected static string ResolveOspaName(string name, CommunicationsManager commsManager)
{
int nameSeparatorIndex = name.IndexOf(OSPA_NAME_VALUE_SEPARATOR);
if (nameSeparatorIndex < 0)
{
m_log.WarnFormat("[OSPA RESOLVER]: Ignoring unseparated name {0}", name);
return null;
}
string firstName = name.Remove(nameSeparatorIndex).TrimEnd();
string lastName = name.Substring(nameSeparatorIndex + 1).TrimStart();
CachedUserInfo userInfo = commsManager.UserProfileCacheService.GetUserDetails(firstName, lastName);
if (userInfo != null)
return userInfo.UserProfile.ID.ToString();
UserProfileData tempUserProfile = new UserProfileData();
tempUserProfile.FirstName = firstName;
tempUserProfile.SurName = lastName;
tempUserProfile.ID = new UUID(Utils.MD5(Encoding.Unicode.GetBytes(tempUserProfile.Name)), 0);
commsManager.UserService.AddTemporaryUserProfile(tempUserProfile);
return tempUserProfile.ID.ToString();
}
}
}

View File

@ -373,7 +373,6 @@ namespace OpenSim.Framework
return SHA1.ComputeHash(Encoding.Default.GetBytes(src));
}
public static int fast_distance2d(int x, int y)
{
x = Math.Abs(x);

View File

@ -57,7 +57,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
/// </value>
private Stream m_loadStream;
CommunicationsManager commsManager;
protected CommunicationsManager m_commsManager;
public InventoryArchiveReadRequest(
CachedUserInfo userInfo, string invPath, string loadPath, CommunicationsManager commsManager)
@ -75,7 +75,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
m_userInfo = userInfo;
m_invPath = invPath;
m_loadStream = loadStream;
this.commsManager = commsManager;
m_commsManager = commsManager;
}
/// <summary>
@ -101,7 +101,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
//
// FIXME: FetchInventory should probably be assumed to by async anyway, since even standalones might
// use a remote inventory service, though this is vanishingly rare at the moment.
if (null == commsManager.UserAdminService)
if (null == m_commsManager.UserAdminService)
{
m_log.ErrorFormat(
"[INVENTORY ARCHIVER]: Have not yet received inventory info for user {0} {1}",
@ -156,7 +156,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
// Don't use the item ID that's in the file
item.ID = UUID.Random();
item.CreatorId = m_userInfo.UserProfile.ID.ToString();
string ospResolvedId = OspResolver.Resolve(item.CreatorId, m_commsManager);
if (null != ospResolvedId)
item.CreatorId = ospResolvedId;
item.Owner = m_userInfo.UserProfile.ID;
// Reset folder ID to the one in which we want to load it
@ -352,7 +355,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
asset.Type = assetType;
asset.Data = data;
commsManager.AssetCache.AddAsset(asset);
m_commsManager.AssetCache.AddAsset(asset);
return true;
}

View File

@ -204,9 +204,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
string userFirstName = "Mr";
string userLastName = "Tiddles";
string folderName = "a";
string archiveFolderName
= string.Format("{0}{1}{2}", folderName, ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR, UUID.Random());
UUID userUuid = UUID.Parse("00000000-0000-0000-0000-000000000555");
string itemName = "b.lsl";
string archiveItemName
= string.Format("{0}{1}{2}", itemName, "_", UUID.Random());
@ -218,29 +216,33 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
item1.Name = itemName;
item1.AssetID = UUID.Random();
item1.GroupID = UUID.Random();
item1.CreatorId = userUuid.ToString();
//item1.CreatorId = "00000000-0000-0000-0000-000000000444";
item1.Owner = UUID.Parse(item1.CreatorId);
string item1FileName
= string.Format("{0}{1}/{2}", ArchiveConstants.INVENTORY_PATH, archiveFolderName, archiveItemName);
= string.Format("{0}{1}", ArchiveConstants.INVENTORY_PATH, archiveItemName);
tar.WriteFile(item1FileName, UserInventoryItemSerializer.Serialize(item1));
tar.Close();
MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
SerialiserModule serialiserModule = new SerialiserModule();
InventoryArchiverModule archiverModule = new InventoryArchiverModule();
// Annoyingly, we have to set up a scene even though inventory loading has nothing to do with a scene
Scene scene = SceneSetupHelpers.SetupScene();
SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
scene.CommsManager.UserAdminService.AddUser(userFirstName, userLastName, "meowfood", String.Empty, 1000, 1000);
scene.CommsManager.UserAdminService.AddUser(
userFirstName, userLastName, "meowfood", String.Empty, 1000, 1000, userUuid);
archiverModule.DearchiveInventory(userFirstName, userLastName, "/", archiveReadStream);
CachedUserInfo userInfo = scene.CommsManager.UserProfileCacheService.GetUserDetails(userFirstName, userLastName);
InventoryFolderImpl foundFolder = userInfo.RootFolder.FindFolderByPath(folderName);
Assert.That(foundFolder, Is.Not.Null, string.Format("Folder {0} not found on load", folderName));
CachedUserInfo userInfo
= scene.CommsManager.UserProfileCacheService.GetUserDetails(userFirstName, userLastName);
InventoryItemBase foundItem = userInfo.RootFolder.FindItemByPath(itemName);
InventoryItemBase foundItem = foundFolder.FindItemByPath(itemName);
Assert.That(foundItem, Is.Not.Null, string.Format("Item {0} not found on load", itemName));
// Currently, creator and ownership both revert to the loader
Assert.That(foundItem.CreatorId, Is.EqualTo(userUuid.ToString()));
Assert.That(foundItem.Owner, Is.EqualTo(userUuid));
Console.WriteLine("Finished TestLoadIarV0p1()");
}