diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs index e7fb43a3a5..0d90a158c3 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs @@ -206,7 +206,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver else return null; } - + + public static List FindItemsByPath( + IInventoryService inventoryService, UUID userId, string path) + { + InventoryFolderBase rootFolder = inventoryService.GetRootFolder(userId); + + if (null == rootFolder) + return new List(); + + return FindItemsByPath(inventoryService, rootFolder, path); + } + /// /// Find items that match a given PATH_DELIMITOR delimited path starting from this folder. /// @@ -239,11 +250,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver if (components.Length == 1) { // m_log.DebugFormat( -// "FOUND SINGLE COMPONENT [{0}]. Looking for this in [{1}] {2}", +// "FOUND SINGLE COMPONENT [{0}]. Looking for this in [{1}] {2}", // components[0], startFolder.Name, startFolder.ID); List items = inventoryService.GetFolderItems(startFolder.Owner, startFolder.ID); - + // m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Found {0} items in FindItemByPath()", items.Count); foreach (InventoryItemBase item in items) @@ -257,7 +268,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver else { // m_log.DebugFormat("FOUND COMPONENTS [{0}] and [{1}]", components[0], components[1]); - + InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID); foreach (InventoryFolderBase folder in contents.Folders) diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index b70e1c3a56..f37f94ad32 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -425,192 +425,198 @@ namespace OpenSim.Region.Framework.Scenes InventoryItemBase item = new InventoryItemBase(itemId, senderId); item = InventoryService.GetItem(item); - if ((item != null) && (item.Owner == senderId)) + if (item == null) { - IUserManagement uman = RequestModuleInterface(); - if (uman != null) - uman.AddUser(item.CreatorIdAsUuid, item.CreatorData); - - if (!Permissions.BypassPermissions()) - { - if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) - return null; - } - - // Insert a copy of the item into the recipient - InventoryItemBase itemCopy = new InventoryItemBase(); - itemCopy.Owner = recipient; - itemCopy.CreatorId = item.CreatorId; - itemCopy.CreatorData = item.CreatorData; - itemCopy.ID = UUID.Random(); - itemCopy.AssetID = item.AssetID; - itemCopy.Description = item.Description; - itemCopy.Name = item.Name; - itemCopy.AssetType = item.AssetType; - itemCopy.InvType = item.InvType; - itemCopy.Folder = recipientFolderId; - - if (Permissions.PropagatePermissions() && recipient != senderId) - { - // Trying to do this right this time. This is evil. If - // you believe in Good, go elsewhere. Vampires and other - // evil creatores only beyond this point. You have been - // warned. - - // We're going to mask a lot of things by the next perms - // Tweak the next perms to be nicer to our data - // - // In this mask, all the bits we do NOT want to mess - // with are set. These are: - // - // Transfer - // Copy - // Modufy - uint permsMask = ~ ((uint)PermissionMask.Copy | - (uint)PermissionMask.Transfer | - (uint)PermissionMask.Modify); - - // Now, reduce the next perms to the mask bits - // relevant to the operation - uint nextPerms = permsMask | (item.NextPermissions & - ((uint)PermissionMask.Copy | - (uint)PermissionMask.Transfer | - (uint)PermissionMask.Modify)); - - // nextPerms now has all bits set, except for the actual - // next permission bits. - - // This checks for no mod, no copy, no trans. - // This indicates an error or messed up item. Do it like - // SL and assume trans - if (nextPerms == permsMask) - nextPerms |= (uint)PermissionMask.Transfer; - - // Inventory owner perms are the logical AND of the - // folded perms and the root prim perms, however, if - // the root prim is mod, the inventory perms will be - // mod. This happens on "take" and is of little concern - // here, save for preventing escalation - - // This hack ensures that items previously permalocked - // get unlocked when they're passed or rezzed - uint basePerms = item.BasePermissions | - (uint)PermissionMask.Move; - uint ownerPerms = item.CurrentPermissions; - - // If this is an object, root prim perms may be more - // permissive than folded perms. Use folded perms as - // a mask - if (item.InvType == (int)InventoryType.Object) - { - // Create a safe mask for the current perms - uint foldedPerms = (item.CurrentPermissions & 7) << 13; - foldedPerms |= permsMask; - - bool isRootMod = (item.CurrentPermissions & - (uint)PermissionMask.Modify) != 0 ? - true : false; - - // Mask the owner perms to the folded perms - ownerPerms &= foldedPerms; - basePerms &= foldedPerms; - - // If the root was mod, let the mask reflect that - // We also need to adjust the base here, because - // we should be able to edit in-inventory perms - // for the root prim, if it's mod. - if (isRootMod) - { - ownerPerms |= (uint)PermissionMask.Modify; - basePerms |= (uint)PermissionMask.Modify; - } - } - - // These will be applied to the root prim at next rez. - // The slam bit (bit 3) and folded permission (bits 0-2) - // are preserved due to the above mangling - ownerPerms &= nextPerms; - - // Mask the base permissions. This is a conservative - // approach altering only the three main perms - basePerms &= nextPerms; - - // Assign to the actual item. Make sure the slam bit is - // set, if it wasn't set before. - itemCopy.BasePermissions = basePerms; - itemCopy.CurrentPermissions = ownerPerms; - itemCopy.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm; - - itemCopy.NextPermissions = item.NextPermissions; - - // This preserves "everyone can move" - itemCopy.EveryOnePermissions = item.EveryOnePermissions & - nextPerms; - - // Intentionally killing "share with group" here, as - // the recipient will not have the group this is - // set to - itemCopy.GroupPermissions = 0; - } - else - { - itemCopy.CurrentPermissions = item.CurrentPermissions; - itemCopy.NextPermissions = item.NextPermissions; - itemCopy.EveryOnePermissions = item.EveryOnePermissions & item.NextPermissions; - itemCopy.GroupPermissions = item.GroupPermissions & item.NextPermissions; - itemCopy.BasePermissions = item.BasePermissions; - } - - if (itemCopy.Folder == UUID.Zero) - { - InventoryFolderBase folder = InventoryService.GetFolderForType(recipient, (AssetType)itemCopy.AssetType); - - if (folder != null) - { - itemCopy.Folder = folder.ID; - } - else - { - InventoryFolderBase root = InventoryService.GetRootFolder(recipient); - - if (root != null) - itemCopy.Folder = root.ID; - else - return null; // No destination - } - } - - itemCopy.GroupID = UUID.Zero; - itemCopy.GroupOwned = false; - itemCopy.Flags = item.Flags; - itemCopy.SalePrice = item.SalePrice; - itemCopy.SaleType = item.SaleType; - - if (AddInventoryItem(itemCopy)) - { - IInventoryAccessModule invAccess = RequestModuleInterface(); - if (invAccess != null) - invAccess.TransferInventoryAssets(itemCopy, senderId, recipient); - } - - if (!Permissions.BypassPermissions()) - { - if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) - { - List items = new List(); - items.Add(itemId); - InventoryService.DeleteItems(senderId, items); - } - } - - return itemCopy; - } - else - { - m_log.WarnFormat("[AGENT INVENTORY]: Failed to find item {0} or item does not belong to giver ", itemId); + m_log.WarnFormat( + "[AGENT INVENTORY]: Failed to find item {0} sent by {1} to {2}", itemId, senderId, recipient); return null; } + if (item.Owner != senderId) + { + m_log.WarnFormat( + "[AGENT INVENTORY]: Attempt to send item {0} {1} to {2} failed because sender {3} did not match item owner {4}", + item.Name, item.ID, recipient, senderId, item.Owner); + return null; + } + + IUserManagement uman = RequestModuleInterface(); + if (uman != null) + uman.AddUser(item.CreatorIdAsUuid, item.CreatorData); + + if (!Permissions.BypassPermissions()) + { + if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) + return null; + } + + // Insert a copy of the item into the recipient + InventoryItemBase itemCopy = new InventoryItemBase(); + itemCopy.Owner = recipient; + itemCopy.CreatorId = item.CreatorId; + itemCopy.CreatorData = item.CreatorData; + itemCopy.ID = UUID.Random(); + itemCopy.AssetID = item.AssetID; + itemCopy.Description = item.Description; + itemCopy.Name = item.Name; + itemCopy.AssetType = item.AssetType; + itemCopy.InvType = item.InvType; + itemCopy.Folder = recipientFolderId; + + if (Permissions.PropagatePermissions() && recipient != senderId) + { + // Trying to do this right this time. This is evil. If + // you believe in Good, go elsewhere. Vampires and other + // evil creatores only beyond this point. You have been + // warned. + + // We're going to mask a lot of things by the next perms + // Tweak the next perms to be nicer to our data + // + // In this mask, all the bits we do NOT want to mess + // with are set. These are: + // + // Transfer + // Copy + // Modufy + uint permsMask = ~ ((uint)PermissionMask.Copy | + (uint)PermissionMask.Transfer | + (uint)PermissionMask.Modify); + + // Now, reduce the next perms to the mask bits + // relevant to the operation + uint nextPerms = permsMask | (item.NextPermissions & + ((uint)PermissionMask.Copy | + (uint)PermissionMask.Transfer | + (uint)PermissionMask.Modify)); + + // nextPerms now has all bits set, except for the actual + // next permission bits. + + // This checks for no mod, no copy, no trans. + // This indicates an error or messed up item. Do it like + // SL and assume trans + if (nextPerms == permsMask) + nextPerms |= (uint)PermissionMask.Transfer; + + // Inventory owner perms are the logical AND of the + // folded perms and the root prim perms, however, if + // the root prim is mod, the inventory perms will be + // mod. This happens on "take" and is of little concern + // here, save for preventing escalation + + // This hack ensures that items previously permalocked + // get unlocked when they're passed or rezzed + uint basePerms = item.BasePermissions | + (uint)PermissionMask.Move; + uint ownerPerms = item.CurrentPermissions; + + // If this is an object, root prim perms may be more + // permissive than folded perms. Use folded perms as + // a mask + if (item.InvType == (int)InventoryType.Object) + { + // Create a safe mask for the current perms + uint foldedPerms = (item.CurrentPermissions & 7) << 13; + foldedPerms |= permsMask; + + bool isRootMod = (item.CurrentPermissions & + (uint)PermissionMask.Modify) != 0 ? + true : false; + + // Mask the owner perms to the folded perms + ownerPerms &= foldedPerms; + basePerms &= foldedPerms; + + // If the root was mod, let the mask reflect that + // We also need to adjust the base here, because + // we should be able to edit in-inventory perms + // for the root prim, if it's mod. + if (isRootMod) + { + ownerPerms |= (uint)PermissionMask.Modify; + basePerms |= (uint)PermissionMask.Modify; + } + } + + // These will be applied to the root prim at next rez. + // The slam bit (bit 3) and folded permission (bits 0-2) + // are preserved due to the above mangling + ownerPerms &= nextPerms; + + // Mask the base permissions. This is a conservative + // approach altering only the three main perms + basePerms &= nextPerms; + + // Assign to the actual item. Make sure the slam bit is + // set, if it wasn't set before. + itemCopy.BasePermissions = basePerms; + itemCopy.CurrentPermissions = ownerPerms; + itemCopy.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm; + + itemCopy.NextPermissions = item.NextPermissions; + + // This preserves "everyone can move" + itemCopy.EveryOnePermissions = item.EveryOnePermissions & + nextPerms; + + // Intentionally killing "share with group" here, as + // the recipient will not have the group this is + // set to + itemCopy.GroupPermissions = 0; + } + else + { + itemCopy.CurrentPermissions = item.CurrentPermissions; + itemCopy.NextPermissions = item.NextPermissions; + itemCopy.EveryOnePermissions = item.EveryOnePermissions & item.NextPermissions; + itemCopy.GroupPermissions = item.GroupPermissions & item.NextPermissions; + itemCopy.BasePermissions = item.BasePermissions; + } + + if (itemCopy.Folder == UUID.Zero) + { + InventoryFolderBase folder = InventoryService.GetFolderForType(recipient, (AssetType)itemCopy.AssetType); + + if (folder != null) + { + itemCopy.Folder = folder.ID; + } + else + { + InventoryFolderBase root = InventoryService.GetRootFolder(recipient); + + if (root != null) + itemCopy.Folder = root.ID; + else + return null; // No destination + } + } + + itemCopy.GroupID = UUID.Zero; + itemCopy.GroupOwned = false; + itemCopy.Flags = item.Flags; + itemCopy.SalePrice = item.SalePrice; + itemCopy.SaleType = item.SaleType; + + if (AddInventoryItem(itemCopy)) + { + IInventoryAccessModule invAccess = RequestModuleInterface(); + if (invAccess != null) + invAccess.TransferInventoryAssets(itemCopy, senderId, recipient); + } + + if (!Permissions.BypassPermissions()) + { + if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) + { + List items = new List(); + items.Add(itemId); + InventoryService.DeleteItems(senderId, items); + } + } + + return itemCopy; } /// diff --git a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs index 83f0686636..10c275e040 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs @@ -59,19 +59,24 @@ namespace OpenSim.Region.Framework.Tests // log4net.Config.XmlConfigurator.Configure(); Scene scene = SceneSetupHelpers.SetupScene(); - UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene); - UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene); + UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, 1001); + UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, 1002); InventoryItemBase item1 = UserInventoryHelpers.CreateInventoryItem(scene, "item1", user1.PrincipalID); scene.GiveInventoryItem(user2.PrincipalID, user1.PrincipalID, item1.ID); InventoryItemBase retrievedItem1 - = UserInventoryHelpers.GetInventoryItem(scene.InventoryService, user2.PrincipalID, "Objects/item1"); + = UserInventoryHelpers.GetInventoryItem(scene.InventoryService, user2.PrincipalID, "Notecards/item1"); Assert.That(retrievedItem1, Is.Not.Null); // Try giving back the freshly received item - //scene.GiveInventoryItem(user1.PrincipalID, user2.PrincipalID, retrievedItem1.ID); + scene.GiveInventoryItem(user1.PrincipalID, user2.PrincipalID, retrievedItem1.ID); + + List reretrievedItems + = UserInventoryHelpers.GetInventoryItems(scene.InventoryService, user1.PrincipalID, "Notecards/item1"); + + Assert.That(reretrievedItems.Count, Is.EqualTo(2)); } [Test] @@ -81,8 +86,8 @@ namespace OpenSim.Region.Framework.Tests // log4net.Config.XmlConfigurator.Configure(); Scene scene = SceneSetupHelpers.SetupScene(); - UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene); - UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene); + UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, 1001); + UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, 1002); InventoryFolderBase folder1 = UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, "folder1"); diff --git a/OpenSim/Services/InventoryService/InventoryService.cs b/OpenSim/Services/InventoryService/InventoryService.cs index e543337c71..73dd06ac3a 100644 --- a/OpenSim/Services/InventoryService/InventoryService.cs +++ b/OpenSim/Services/InventoryService/InventoryService.cs @@ -340,6 +340,9 @@ namespace OpenSim.Services.InventoryService List itemsList = new List(); itemsList.AddRange(m_Database.getInventoryInFolder(folderID)); + +// m_log.DebugFormat( +// "[INVENTORY SERVICE]: Found {0} items in folder {1} for {2}", itemsList.Count, folderID, userID); return itemsList; } @@ -385,8 +388,9 @@ namespace OpenSim.Services.InventoryService // See IInventoryServices public virtual bool AddItem(InventoryItemBase item) { - m_log.DebugFormat( - "[INVENTORY SERVICE]: Adding item {0} {1} to folder {2}", item.Name, item.ID, item.Folder); +// m_log.DebugFormat( +// "[INVENTORY SERVICE]: Adding item {0} {1} to folder {2} for {3}", +// item.Name, item.ID, item.Folder, item.Owner); m_Database.addInventoryItem(item); diff --git a/OpenSim/Tests/Common/Helpers/UserAccountHelpers.cs b/OpenSim/Tests/Common/Helpers/UserAccountHelpers.cs index 8cfad79f28..d924ecd5c8 100644 --- a/OpenSim/Tests/Common/Helpers/UserAccountHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/UserAccountHelpers.cs @@ -117,17 +117,20 @@ namespace OpenSim.Tests.Common // } public static UserAccount CreateUserWithInventory(Scene scene) + { + return CreateUserWithInventory(scene, 99); + } + + public static UserAccount CreateUserWithInventory(Scene scene, int uuidTail) { return CreateUserWithInventory( - scene, "Bill", "Bailey", UUID.Parse("00000000-0000-0000-0000-000000000099"), "troll"); + scene, "Bill", "Bailey", new UUID(string.Format("00000000-0000-0000-0000-{0:X12}", uuidTail)), "troll"); } public static UserAccount CreateUserWithInventory( Scene scene, string firstName, string lastName, UUID userId, string pw) { - UserAccount ua - = new UserAccount(userId) - { FirstName = firstName, LastName = lastName }; + UserAccount ua = new UserAccount(userId) { FirstName = firstName, LastName = lastName }; CreateUserWithInventory(scene, ua, pw); return ua; } diff --git a/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs b/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs index 93b655a42b..875bf4ac2c 100644 --- a/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs @@ -65,15 +65,18 @@ namespace OpenSim.Tests.Common /// public static InventoryItemBase CreateInventoryItem(Scene scene, string itemName, UUID itemId, UUID userId) { + AssetBase asset = AssetHelpers.CreateAsset(scene, userId); InventoryItemBase item = new InventoryItemBase(); item.Name = itemName; - item.AssetID = AssetHelpers.CreateAsset(scene, userId).FullID; + item.AssetID = asset.FullID; item.ID = itemId; + item.Owner = userId; + item.AssetType = asset.Type; + item.InvType = (int)InventoryType.Notecard; + + InventoryFolderBase folder = scene.InventoryService.GetFolderForType(userId, AssetType.Notecard); - // Really quite bad since the objs folder could be moved in the future and confuse the tests - InventoryFolderBase objsFolder = scene.InventoryService.GetFolderForType(userId, AssetType.Object); - - item.Folder = objsFolder.ID; + item.Folder = folder.ID; scene.AddInventoryItem(item); return item; @@ -165,5 +168,17 @@ namespace OpenSim.Tests.Common { return InventoryArchiveUtils.FindItemByPath(inventoryService, userId, path); } + + /// + /// Get the inventory items that match the path name. + /// + /// + /// + /// + /// An empty list if no matching items were found. + public static List GetInventoryItems(IInventoryService inventoryService, UUID userId, string path) + { + return InventoryArchiveUtils.FindItemsByPath(inventoryService, userId, path); + } } } \ No newline at end of file