From 9c71afe73e80209e0c5ab6d3911975cea1c326f1 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Mon, 22 Jul 2013 02:22:21 +0200 Subject: [PATCH] Handle PERM_EXPORT in LLPermissions. This moves all export test code to where it belongs: in LLPermissions. Added LLPermissions::allowExportBy, next to allowModifyBy, allowCopyBy and allowMoveBy. Then changed all code to use this call. Because LLPermissions is part of llinventory, I had to add a proxy for LFSimFeatureHandler. Added a new class LFSimFeatureHandlerInterface that can be used by LLPermissions to check simulator features by accessing the LFSimFeatureHandler singleton. Several parts of the code ignored the PERM_EXPORT but and still did demand that things are full perm next to being a creator. This has now changed the export rules are the same for everything as they were for mesh: you need to be the owner and the creator for every element that is exported (not just the root prim, of course). Export rules can now be easily made a function on simulator features. If different rules apply for different types (wearables, objects, mesh etc) then an extra variable indicating the type will have to be passed though. --- indra/llinventory/llpermissions.cpp | 15 +++++++++++++++ indra/llinventory/llpermissions.h | 23 +++++++++++++++++++++++ indra/newview/awavefront.cpp | 16 ++-------------- indra/newview/daeexport.cpp | 15 +-------------- indra/newview/lfsimfeaturehandler.h | 5 +++-- indra/newview/llagent.cpp | 6 ++++-- indra/newview/llpaneleditwearable.cpp | 6 +----- indra/newview/llpanelpermissions.cpp | 2 +- indra/newview/llselectmgr.cpp | 6 ++++++ indra/newview/llviewermenu.cpp | 10 +--------- indra/newview/llviewerobjectbackup.cpp | 13 +------------ 11 files changed, 58 insertions(+), 59 deletions(-) diff --git a/indra/llinventory/llpermissions.cpp b/indra/llinventory/llpermissions.cpp index f41fce8ed..9568cd001 100644 --- a/indra/llinventory/llpermissions.cpp +++ b/indra/llinventory/llpermissions.cpp @@ -34,6 +34,13 @@ #include "metapropertyt.h" #include "llsd.h" +///---------------------------------------------------------------------------- +/// Class LFSimFeatureHandlerInterface +///---------------------------------------------------------------------------- + +//static +LFSimFeatureHandlerInterface* LFSimFeatureHandlerInterface::sInstance; + ///---------------------------------------------------------------------------- /// Class LLPermissions ///---------------------------------------------------------------------------- @@ -475,6 +482,14 @@ BOOL LLPermissions::setNextOwnerBits(const LLUUID& agent, const LLUUID& group, B bool LLPermissions::allowOperationBy(PermissionBit op, const LLUUID& requester, const LLUUID& group) const { + // Singu extension: Make this function work for PERM_EXPORT operation (also on grids not supporting it). + if (op == PERM_EXPORT) + { + // Requester must always be the owner; on grids supporting PERM_EXPORT, that bit + // must be set in the mMaskEveryone mask, otherwise the requester must be the creator. + return (!mIsGroupOwned && (mOwner == requester) && + (mCreator == requester || (LFSimFeatureHandlerInterface::ifInstance()->simSupportsExport() && (mMaskEveryone & PERM_EXPORT)))); + } if(requester.isNull()) { // ...system making request diff --git a/indra/llinventory/llpermissions.h b/indra/llinventory/llpermissions.h index 7d3a68d35..5986e0dd9 100644 --- a/indra/llinventory/llpermissions.h +++ b/indra/llinventory/llpermissions.h @@ -40,6 +40,23 @@ extern void mask_to_string(U32 mask, char* str); extern std::string mask_to_string(U32 mask); template class LLMetaClassT; +// Interface of LFSimFeatureHandler. +class LFSimFeatureHandlerInterface +{ +private: + // LFSimFeatureHandler is a singleton. + static LFSimFeatureHandlerInterface* sInstance; + +protected: + LFSimFeatureHandlerInterface(void) { sInstance = this; } + virtual ~LFSimFeatureHandlerInterface() { } + +public: + virtual bool simSupportsExport() const = 0; + + static LFSimFeatureHandlerInterface* ifInstance(void) { return sInstance; } +}; + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLPermissions // @@ -274,6 +291,7 @@ public: inline bool allowModifyBy(const LLUUID &agent_id, const LLUUID& group) const; inline bool allowCopyBy(const LLUUID& agent_id, const LLUUID& group) const; inline bool allowMoveBy(const LLUUID &agent_id, const LLUUID &group) const; + inline bool allowExportBy(const LLUUID &agent_id) const; // Singu extension. // This somewhat specialized function is meant for testing if the // current owner is allowed to transfer to the specified agent id. @@ -373,6 +391,11 @@ bool LLPermissions::allowTransferTo(const LLUUID &agent_id) const } } +bool LLPermissions::allowExportBy(const LLUUID& agent) const +{ + return allowOperationBy(PERM_EXPORT, agent); +} + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLAggregatePermissions // diff --git a/indra/newview/awavefront.cpp b/indra/newview/awavefront.cpp index 3f4d2c994..816895e91 100644 --- a/indra/newview/awavefront.cpp +++ b/indra/newview/awavefront.cpp @@ -30,7 +30,6 @@ #include "llnotificationsutil.h" // newview includes -#include "lfsimfeaturehandler.h" #include "llavatarappearancedefines.h" #include "llface.h" #include "llvoavatar.h" @@ -220,17 +219,6 @@ void WavefrontSaver::Add(const LLViewerObject* some_vo) } namespace { - bool can_export_node(const LLSelectNode* node) - { - if (const LLPermissions* perms = node->mPermissions) - { - if (gAgentID == perms->getCreator() || (LFSimFeatureHandler::instance().simSupportsExport() && gAgentID == perms->getOwner() && perms->getMaskEveryone() & PERM_EXPORT)) - { - return true; - } - } - return false; - } class LFSaveSelectedObjects : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) @@ -245,7 +233,7 @@ namespace { total++; LLSelectNode* node = *iter; - if (!can_export_node(node)) continue; + if (!node->mPermissions->allowExportBy(gAgentID)) continue; included++; wfsaver->Add(node->getObject()); } @@ -328,7 +316,7 @@ void WavefrontSaver::Add(const LLVOAvatar* av_vo) //adds attachments, too! if (!c) continue; if (const LLSelectNode* n = LLSelectMgr::getInstance()->getSelection()->findNode(const_cast(c))) { - if (!can_export_node(n)) continue; + if (!n->mPermissions->allowExportBy(gAgentID)) continue; } else continue; const LLVolume* vol = c->getVolume(); diff --git a/indra/newview/daeexport.cpp b/indra/newview/daeexport.cpp index 586dc8cf5..145261d19 100644 --- a/indra/newview/daeexport.cpp +++ b/indra/newview/daeexport.cpp @@ -65,7 +65,6 @@ #include "boost/date_time/posix_time/posix_time.hpp" // newview includes -#include "lfsimfeaturehandler.h" #include "llface.h" #include "llvovolume.h" @@ -117,18 +116,6 @@ namespace DAEExportUtil } } - bool canExportNode(const LLSelectNode* node) - { - if (const LLPermissions* perms = node->mPermissions) - { - if (gAgentID == perms->getCreator() || (LFSimFeatureHandler::instance().simSupportsExport() && gAgentID == perms->getOwner() && perms->getMaskEveryone() & PERM_EXPORT)) - { - return true; - } - } - return false; - } - void saveSelectedObject() { static const std::string file_ext = ".dae"; @@ -144,7 +131,7 @@ namespace DAEExportUtil { total++; LLSelectNode* node = *iter; - if (!canExportNode(node) || !node->getObject()->getVolume()) continue; + if (!node->mPermissions->allowExportBy(gAgentID) || !node->getObject()->getVolume()) continue; included++; daesaver->Add(node->getObject(), node->mName); } diff --git a/indra/newview/lfsimfeaturehandler.h b/indra/newview/lfsimfeaturehandler.h index 070d6ba1e..062a55898 100644 --- a/indra/newview/lfsimfeaturehandler.h +++ b/indra/newview/lfsimfeaturehandler.h @@ -19,6 +19,7 @@ #define LFSIMFEATUREHANDLER_H #include "llsingleton.h" +#include "llpermissions.h" template class SignaledType @@ -45,7 +46,7 @@ private: Type mValue; }; -class LFSimFeatureHandler : public LLSingleton +class LFSimFeatureHandler : public LFSimFeatureHandlerInterface, public LLSingleton { protected: friend class LLSingleton; @@ -59,7 +60,7 @@ public: boost::signals2::connection setSupportsExportCallback(const boost::signals2::signal::slot_type& slot); // Accessors - bool simSupportsExport() const { return mSupportsExport; } + /*virtual*/ bool simSupportsExport() const { return mSupportsExport; } private: // SignaledTypes diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 50c8bc5cc..924164a26 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -3165,7 +3165,8 @@ BOOL LLAgent::allowOperation(PermissionBit op, U8 god_minimum) { // Check god level. - if (getGodLevel() >= god_minimum) return TRUE; + // Singu note: We should never get here for PERM_EXPORT really, but if we do - then Gods are not above the law. + if (getGodLevel() >= god_minimum && PERM_EXPORT != op) return TRUE; if (!perm.isOwned()) return FALSE; @@ -3187,7 +3188,8 @@ BOOL LLAgent::allowOperation(PermissionBit op, else { // Check for granted mod permissions. - if ((PERM_OWNER != op) && isGrantedProxy(perm)) + // Singu note: do not allow proxy powers for exporting. + if ((PERM_OWNER != op && PERM_EXPORT != op) && isGrantedProxy(perm)) { agent_proxy = owner_id; } diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index c2d3c549b..aef365e7b 100644 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -1422,11 +1422,7 @@ bool LLPanelEditWearable::updatePermissions() // Exporting (of slider values) is allowed when the wearable is full perm, and owned by and created by the user. // Of course, only modifiable is enough for the user to write down the values and enter them else where... but why make it easy for them to break the ToS. - if (is_complete && - gAgent.getID() == item->getPermissions().getOwner() && - gAgent.getID() == item->getPermissions().getCreator() && - (PERM_ITEM_UNRESTRICTED & - perm_mask) == PERM_ITEM_UNRESTRICTED) + if (is_complete && item->getPermissions().allowExportBy(gAgent.getID())) { can_export = true; } diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp index 9f3414448..fa7f0565c 100644 --- a/indra/newview/llpanelpermissions.cpp +++ b/indra/newview/llpanelpermissions.cpp @@ -1177,7 +1177,7 @@ void LLPanelPermissions::onCommitEveryoneCopy(LLUICtrl *ctrl, void *data) void LLPanelPermissions::onCommitExport(const LLSD& param) { - LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_EVERYONE, param, PERM_EXPORT); + LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_EVERYONE, param.asBoolean(), PERM_EXPORT); } // static diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 7bd68ad4a..7d84af13a 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -5926,6 +5926,12 @@ BOOL LLSelectNode::allowOperationOnNode(PermissionBit op, U64 group_proxy_power) } } + if (PERM_EXPORT == op) + { + // No proxy or god powers allowed. + return mPermissions->allowExportBy(gAgent.getID()); + } + // Calculate proxy_agent_id and group_id to use for permissions checks. // proxy_agent_id may be set to the object owner through group powers. // group_id can only be set to the object's group, if the agent is in that group. diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 21d4226a6..e384b8bdb 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -2895,15 +2895,7 @@ class LLObjectEnableExport : public view_listener_t const LLSD& userdata; virtual bool apply(LLSelectNode* node) { - // Note: the actual permission checking algorithm depends on the grid TOS and must be - // performed for each prim and texture. This is done later in llviewerobjectbackup.cpp. - // This means that even if the item is enabled in the menu, the export may fail should - // the permissions not be met for each exported asset. The permissions check below - // therefore only corresponds to the minimal permissions requirement common to all grids. - LLPermissions *item_permissions = node->mPermissions; - return (gAgent.getID() == item_permissions->getOwner() && - (gAgent.getID() == item_permissions->getCreator() || - (item_permissions->getMaskOwner() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED)); + return node->mPermissions->allowExportBy(gAgent.getID()); } }; ff * the_ff = new ff(userdata); diff --git a/indra/newview/llviewerobjectbackup.cpp b/indra/newview/llviewerobjectbackup.cpp index 09783ed21..932dde3a6 100644 --- a/indra/newview/llviewerobjectbackup.cpp +++ b/indra/newview/llviewerobjectbackup.cpp @@ -398,18 +398,7 @@ void LLObjectBackup::exportObject_continued(AIFilePicker* filepicker) bool LLObjectBackup::validatePerms(const LLPermissions *item_permissions) { - if (gHippoGridManager->getConnectedGrid()->isSecondLife()) - { - // In Second Life, you must be the creator to be permitted to export the asset. - return (gAgent.getID() == item_permissions->getOwner() && - gAgent.getID() == item_permissions->getCreator()); - } - else - { - // Out of Second Life, simply check that the asset is full perms. - return (gAgent.getID() == item_permissions->getOwner() && - (item_permissions->getMaskOwner() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED); - } + return item_permissions->allowExportBy(gAgent.getID()); } // So far, only Second Life forces TPVs to verify the creator for textures...