diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 328 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs | 17 |
2 files changed, 178 insertions, 167 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index b70e1c3..f37f94a 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 | |||
425 | InventoryItemBase item = new InventoryItemBase(itemId, senderId); | 425 | InventoryItemBase item = new InventoryItemBase(itemId, senderId); |
426 | item = InventoryService.GetItem(item); | 426 | item = InventoryService.GetItem(item); |
427 | 427 | ||
428 | if ((item != null) && (item.Owner == senderId)) | 428 | if (item == null) |
429 | { | 429 | { |
430 | IUserManagement uman = RequestModuleInterface<IUserManagement>(); | 430 | m_log.WarnFormat( |
431 | if (uman != null) | 431 | "[AGENT INVENTORY]: Failed to find item {0} sent by {1} to {2}", itemId, senderId, recipient); |
432 | uman.AddUser(item.CreatorIdAsUuid, item.CreatorData); | 432 | return null; |
433 | } | ||
433 | 434 | ||
434 | if (!Permissions.BypassPermissions()) | 435 | if (item.Owner != senderId) |
435 | { | 436 | { |
436 | if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) | 437 | m_log.WarnFormat( |
437 | return null; | 438 | "[AGENT INVENTORY]: Attempt to send item {0} {1} to {2} failed because sender {3} did not match item owner {4}", |
438 | } | 439 | item.Name, item.ID, recipient, senderId, item.Owner); |
440 | return null; | ||
441 | } | ||
442 | |||
443 | IUserManagement uman = RequestModuleInterface<IUserManagement>(); | ||
444 | if (uman != null) | ||
445 | uman.AddUser(item.CreatorIdAsUuid, item.CreatorData); | ||
446 | |||
447 | if (!Permissions.BypassPermissions()) | ||
448 | { | ||
449 | if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) | ||
450 | return null; | ||
451 | } | ||
439 | 452 | ||
440 | // Insert a copy of the item into the recipient | 453 | // Insert a copy of the item into the recipient |
441 | InventoryItemBase itemCopy = new InventoryItemBase(); | 454 | InventoryItemBase itemCopy = new InventoryItemBase(); |
442 | itemCopy.Owner = recipient; | 455 | itemCopy.Owner = recipient; |
443 | itemCopy.CreatorId = item.CreatorId; | 456 | itemCopy.CreatorId = item.CreatorId; |
444 | itemCopy.CreatorData = item.CreatorData; | 457 | itemCopy.CreatorData = item.CreatorData; |
445 | itemCopy.ID = UUID.Random(); | 458 | itemCopy.ID = UUID.Random(); |
446 | itemCopy.AssetID = item.AssetID; | 459 | itemCopy.AssetID = item.AssetID; |
447 | itemCopy.Description = item.Description; | 460 | itemCopy.Description = item.Description; |
448 | itemCopy.Name = item.Name; | 461 | itemCopy.Name = item.Name; |
449 | itemCopy.AssetType = item.AssetType; | 462 | itemCopy.AssetType = item.AssetType; |
450 | itemCopy.InvType = item.InvType; | 463 | itemCopy.InvType = item.InvType; |
451 | itemCopy.Folder = recipientFolderId; | 464 | itemCopy.Folder = recipientFolderId; |
452 | 465 | ||
453 | if (Permissions.PropagatePermissions() && recipient != senderId) | 466 | if (Permissions.PropagatePermissions() && recipient != senderId) |
467 | { | ||
468 | // Trying to do this right this time. This is evil. If | ||
469 | // you believe in Good, go elsewhere. Vampires and other | ||
470 | // evil creatores only beyond this point. You have been | ||
471 | // warned. | ||
472 | |||
473 | // We're going to mask a lot of things by the next perms | ||
474 | // Tweak the next perms to be nicer to our data | ||
475 | // | ||
476 | // In this mask, all the bits we do NOT want to mess | ||
477 | // with are set. These are: | ||
478 | // | ||
479 | // Transfer | ||
480 | // Copy | ||
481 | // Modufy | ||
482 | uint permsMask = ~ ((uint)PermissionMask.Copy | | ||
483 | (uint)PermissionMask.Transfer | | ||
484 | (uint)PermissionMask.Modify); | ||
485 | |||
486 | // Now, reduce the next perms to the mask bits | ||
487 | // relevant to the operation | ||
488 | uint nextPerms = permsMask | (item.NextPermissions & | ||
489 | ((uint)PermissionMask.Copy | | ||
490 | (uint)PermissionMask.Transfer | | ||
491 | (uint)PermissionMask.Modify)); | ||
492 | |||
493 | // nextPerms now has all bits set, except for the actual | ||
494 | // next permission bits. | ||
495 | |||
496 | // This checks for no mod, no copy, no trans. | ||
497 | // This indicates an error or messed up item. Do it like | ||
498 | // SL and assume trans | ||
499 | if (nextPerms == permsMask) | ||
500 | nextPerms |= (uint)PermissionMask.Transfer; | ||
501 | |||
502 | // Inventory owner perms are the logical AND of the | ||
503 | // folded perms and the root prim perms, however, if | ||
504 | // the root prim is mod, the inventory perms will be | ||
505 | // mod. This happens on "take" and is of little concern | ||
506 | // here, save for preventing escalation | ||
507 | |||
508 | // This hack ensures that items previously permalocked | ||
509 | // get unlocked when they're passed or rezzed | ||
510 | uint basePerms = item.BasePermissions | | ||
511 | (uint)PermissionMask.Move; | ||
512 | uint ownerPerms = item.CurrentPermissions; | ||
513 | |||
514 | // If this is an object, root prim perms may be more | ||
515 | // permissive than folded perms. Use folded perms as | ||
516 | // a mask | ||
517 | if (item.InvType == (int)InventoryType.Object) | ||
454 | { | 518 | { |
455 | // Trying to do this right this time. This is evil. If | 519 | // Create a safe mask for the current perms |
456 | // you believe in Good, go elsewhere. Vampires and other | 520 | uint foldedPerms = (item.CurrentPermissions & 7) << 13; |
457 | // evil creatores only beyond this point. You have been | 521 | foldedPerms |= permsMask; |
458 | // warned. | 522 | |
459 | 523 | bool isRootMod = (item.CurrentPermissions & | |
460 | // We're going to mask a lot of things by the next perms | 524 | (uint)PermissionMask.Modify) != 0 ? |
461 | // Tweak the next perms to be nicer to our data | 525 | true : false; |
462 | // | 526 | |
463 | // In this mask, all the bits we do NOT want to mess | 527 | // Mask the owner perms to the folded perms |
464 | // with are set. These are: | 528 | ownerPerms &= foldedPerms; |
465 | // | 529 | basePerms &= foldedPerms; |
466 | // Transfer | 530 | |
467 | // Copy | 531 | // If the root was mod, let the mask reflect that |
468 | // Modufy | 532 | // We also need to adjust the base here, because |
469 | uint permsMask = ~ ((uint)PermissionMask.Copy | | 533 | // we should be able to edit in-inventory perms |
470 | (uint)PermissionMask.Transfer | | 534 | // for the root prim, if it's mod. |
471 | (uint)PermissionMask.Modify); | 535 | if (isRootMod) |
472 | |||
473 | // Now, reduce the next perms to the mask bits | ||
474 | // relevant to the operation | ||
475 | uint nextPerms = permsMask | (item.NextPermissions & | ||
476 | ((uint)PermissionMask.Copy | | ||
477 | (uint)PermissionMask.Transfer | | ||
478 | (uint)PermissionMask.Modify)); | ||
479 | |||
480 | // nextPerms now has all bits set, except for the actual | ||
481 | // next permission bits. | ||
482 | |||
483 | // This checks for no mod, no copy, no trans. | ||
484 | // This indicates an error or messed up item. Do it like | ||
485 | // SL and assume trans | ||
486 | if (nextPerms == permsMask) | ||
487 | nextPerms |= (uint)PermissionMask.Transfer; | ||
488 | |||
489 | // Inventory owner perms are the logical AND of the | ||
490 | // folded perms and the root prim perms, however, if | ||
491 | // the root prim is mod, the inventory perms will be | ||
492 | // mod. This happens on "take" and is of little concern | ||
493 | // here, save for preventing escalation | ||
494 | |||
495 | // This hack ensures that items previously permalocked | ||
496 | // get unlocked when they're passed or rezzed | ||
497 | uint basePerms = item.BasePermissions | | ||
498 | (uint)PermissionMask.Move; | ||
499 | uint ownerPerms = item.CurrentPermissions; | ||
500 | |||
501 | // If this is an object, root prim perms may be more | ||
502 | // permissive than folded perms. Use folded perms as | ||
503 | // a mask | ||
504 | if (item.InvType == (int)InventoryType.Object) | ||
505 | { | 536 | { |
506 | // Create a safe mask for the current perms | 537 | ownerPerms |= (uint)PermissionMask.Modify; |
507 | uint foldedPerms = (item.CurrentPermissions & 7) << 13; | 538 | basePerms |= (uint)PermissionMask.Modify; |
508 | foldedPerms |= permsMask; | ||
509 | |||
510 | bool isRootMod = (item.CurrentPermissions & | ||
511 | (uint)PermissionMask.Modify) != 0 ? | ||
512 | true : false; | ||
513 | |||
514 | // Mask the owner perms to the folded perms | ||
515 | ownerPerms &= foldedPerms; | ||
516 | basePerms &= foldedPerms; | ||
517 | |||
518 | // If the root was mod, let the mask reflect that | ||
519 | // We also need to adjust the base here, because | ||
520 | // we should be able to edit in-inventory perms | ||
521 | // for the root prim, if it's mod. | ||
522 | if (isRootMod) | ||
523 | { | ||
524 | ownerPerms |= (uint)PermissionMask.Modify; | ||
525 | basePerms |= (uint)PermissionMask.Modify; | ||
526 | } | ||
527 | } | 539 | } |
540 | } | ||
528 | 541 | ||
529 | // These will be applied to the root prim at next rez. | 542 | // These will be applied to the root prim at next rez. |
530 | // The slam bit (bit 3) and folded permission (bits 0-2) | 543 | // The slam bit (bit 3) and folded permission (bits 0-2) |
531 | // are preserved due to the above mangling | 544 | // are preserved due to the above mangling |
532 | ownerPerms &= nextPerms; | 545 | ownerPerms &= nextPerms; |
533 | 546 | ||
534 | // Mask the base permissions. This is a conservative | 547 | // Mask the base permissions. This is a conservative |
535 | // approach altering only the three main perms | 548 | // approach altering only the three main perms |
536 | basePerms &= nextPerms; | 549 | basePerms &= nextPerms; |
537 | 550 | ||
538 | // Assign to the actual item. Make sure the slam bit is | 551 | // Assign to the actual item. Make sure the slam bit is |
539 | // set, if it wasn't set before. | 552 | // set, if it wasn't set before. |
540 | itemCopy.BasePermissions = basePerms; | 553 | itemCopy.BasePermissions = basePerms; |
541 | itemCopy.CurrentPermissions = ownerPerms; | 554 | itemCopy.CurrentPermissions = ownerPerms; |
542 | itemCopy.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm; | 555 | itemCopy.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm; |
543 | 556 | ||
544 | itemCopy.NextPermissions = item.NextPermissions; | 557 | itemCopy.NextPermissions = item.NextPermissions; |
545 | 558 | ||
546 | // This preserves "everyone can move" | 559 | // This preserves "everyone can move" |
547 | itemCopy.EveryOnePermissions = item.EveryOnePermissions & | 560 | itemCopy.EveryOnePermissions = item.EveryOnePermissions & |
548 | nextPerms; | 561 | nextPerms; |
549 | 562 | ||
550 | // Intentionally killing "share with group" here, as | 563 | // Intentionally killing "share with group" here, as |
551 | // the recipient will not have the group this is | 564 | // the recipient will not have the group this is |
552 | // set to | 565 | // set to |
553 | itemCopy.GroupPermissions = 0; | 566 | itemCopy.GroupPermissions = 0; |
554 | } | 567 | } |
555 | else | 568 | else |
569 | { | ||
570 | itemCopy.CurrentPermissions = item.CurrentPermissions; | ||
571 | itemCopy.NextPermissions = item.NextPermissions; | ||
572 | itemCopy.EveryOnePermissions = item.EveryOnePermissions & item.NextPermissions; | ||
573 | itemCopy.GroupPermissions = item.GroupPermissions & item.NextPermissions; | ||
574 | itemCopy.BasePermissions = item.BasePermissions; | ||
575 | } | ||
576 | |||
577 | if (itemCopy.Folder == UUID.Zero) | ||
578 | { | ||
579 | InventoryFolderBase folder = InventoryService.GetFolderForType(recipient, (AssetType)itemCopy.AssetType); | ||
580 | |||
581 | if (folder != null) | ||
556 | { | 582 | { |
557 | itemCopy.CurrentPermissions = item.CurrentPermissions; | 583 | itemCopy.Folder = folder.ID; |
558 | itemCopy.NextPermissions = item.NextPermissions; | ||
559 | itemCopy.EveryOnePermissions = item.EveryOnePermissions & item.NextPermissions; | ||
560 | itemCopy.GroupPermissions = item.GroupPermissions & item.NextPermissions; | ||
561 | itemCopy.BasePermissions = item.BasePermissions; | ||
562 | } | 584 | } |
563 | 585 | else | |
564 | if (itemCopy.Folder == UUID.Zero) | ||
565 | { | 586 | { |
566 | InventoryFolderBase folder = InventoryService.GetFolderForType(recipient, (AssetType)itemCopy.AssetType); | 587 | InventoryFolderBase root = InventoryService.GetRootFolder(recipient); |
567 | 588 | ||
568 | if (folder != null) | 589 | if (root != null) |
569 | { | 590 | itemCopy.Folder = root.ID; |
570 | itemCopy.Folder = folder.ID; | ||
571 | } | ||
572 | else | 591 | else |
573 | { | 592 | return null; // No destination |
574 | InventoryFolderBase root = InventoryService.GetRootFolder(recipient); | ||
575 | |||
576 | if (root != null) | ||
577 | itemCopy.Folder = root.ID; | ||
578 | else | ||
579 | return null; // No destination | ||
580 | } | ||
581 | } | 593 | } |
594 | } | ||
582 | 595 | ||
583 | itemCopy.GroupID = UUID.Zero; | 596 | itemCopy.GroupID = UUID.Zero; |
584 | itemCopy.GroupOwned = false; | 597 | itemCopy.GroupOwned = false; |
585 | itemCopy.Flags = item.Flags; | 598 | itemCopy.Flags = item.Flags; |
586 | itemCopy.SalePrice = item.SalePrice; | 599 | itemCopy.SalePrice = item.SalePrice; |
587 | itemCopy.SaleType = item.SaleType; | 600 | itemCopy.SaleType = item.SaleType; |
588 | 601 | ||
589 | if (AddInventoryItem(itemCopy)) | 602 | if (AddInventoryItem(itemCopy)) |
590 | { | 603 | { |
591 | IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>(); | 604 | IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>(); |
592 | if (invAccess != null) | 605 | if (invAccess != null) |
593 | invAccess.TransferInventoryAssets(itemCopy, senderId, recipient); | 606 | invAccess.TransferInventoryAssets(itemCopy, senderId, recipient); |
594 | } | 607 | } |
595 | 608 | ||
596 | if (!Permissions.BypassPermissions()) | 609 | if (!Permissions.BypassPermissions()) |
610 | { | ||
611 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) | ||
597 | { | 612 | { |
598 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) | 613 | List<UUID> items = new List<UUID>(); |
599 | { | 614 | items.Add(itemId); |
600 | List<UUID> items = new List<UUID>(); | 615 | InventoryService.DeleteItems(senderId, items); |
601 | items.Add(itemId); | ||
602 | InventoryService.DeleteItems(senderId, items); | ||
603 | } | ||
604 | } | 616 | } |
605 | |||
606 | return itemCopy; | ||
607 | } | ||
608 | else | ||
609 | { | ||
610 | m_log.WarnFormat("[AGENT INVENTORY]: Failed to find item {0} or item does not belong to giver ", itemId); | ||
611 | return null; | ||
612 | } | 617 | } |
613 | 618 | ||
619 | return itemCopy; | ||
614 | } | 620 | } |
615 | 621 | ||
616 | /// <summary> | 622 | /// <summary> |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs index 83f0686..10c275e 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 | |||
59 | // log4net.Config.XmlConfigurator.Configure(); | 59 | // log4net.Config.XmlConfigurator.Configure(); |
60 | 60 | ||
61 | Scene scene = SceneSetupHelpers.SetupScene(); | 61 | Scene scene = SceneSetupHelpers.SetupScene(); |
62 | UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene); | 62 | UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, 1001); |
63 | UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene); | 63 | UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, 1002); |
64 | InventoryItemBase item1 = UserInventoryHelpers.CreateInventoryItem(scene, "item1", user1.PrincipalID); | 64 | InventoryItemBase item1 = UserInventoryHelpers.CreateInventoryItem(scene, "item1", user1.PrincipalID); |
65 | 65 | ||
66 | scene.GiveInventoryItem(user2.PrincipalID, user1.PrincipalID, item1.ID); | 66 | scene.GiveInventoryItem(user2.PrincipalID, user1.PrincipalID, item1.ID); |
67 | 67 | ||
68 | InventoryItemBase retrievedItem1 | 68 | InventoryItemBase retrievedItem1 |
69 | = UserInventoryHelpers.GetInventoryItem(scene.InventoryService, user2.PrincipalID, "Objects/item1"); | 69 | = UserInventoryHelpers.GetInventoryItem(scene.InventoryService, user2.PrincipalID, "Notecards/item1"); |
70 | 70 | ||
71 | Assert.That(retrievedItem1, Is.Not.Null); | 71 | Assert.That(retrievedItem1, Is.Not.Null); |
72 | 72 | ||
73 | // Try giving back the freshly received item | 73 | // Try giving back the freshly received item |
74 | //scene.GiveInventoryItem(user1.PrincipalID, user2.PrincipalID, retrievedItem1.ID); | 74 | scene.GiveInventoryItem(user1.PrincipalID, user2.PrincipalID, retrievedItem1.ID); |
75 | |||
76 | List<InventoryItemBase> reretrievedItems | ||
77 | = UserInventoryHelpers.GetInventoryItems(scene.InventoryService, user1.PrincipalID, "Notecards/item1"); | ||
78 | |||
79 | Assert.That(reretrievedItems.Count, Is.EqualTo(2)); | ||
75 | } | 80 | } |
76 | 81 | ||
77 | [Test] | 82 | [Test] |
@@ -81,8 +86,8 @@ namespace OpenSim.Region.Framework.Tests | |||
81 | // log4net.Config.XmlConfigurator.Configure(); | 86 | // log4net.Config.XmlConfigurator.Configure(); |
82 | 87 | ||
83 | Scene scene = SceneSetupHelpers.SetupScene(); | 88 | Scene scene = SceneSetupHelpers.SetupScene(); |
84 | UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene); | 89 | UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, 1001); |
85 | UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene); | 90 | UserAccount user2 = UserAccountHelpers.CreateUserWithInventory(scene, 1002); |
86 | InventoryFolderBase folder1 | 91 | InventoryFolderBase folder1 |
87 | = UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, "folder1"); | 92 | = UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, "folder1"); |
88 | 93 | ||