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.
This commit is contained in:
Aleric Inglewood
2013-07-22 02:22:21 +02:00
parent 85ff52be30
commit 9c71afe73e
11 changed files with 58 additions and 59 deletions

View File

@@ -34,6 +34,13 @@
#include "metapropertyt.h" #include "metapropertyt.h"
#include "llsd.h" #include "llsd.h"
///----------------------------------------------------------------------------
/// Class LFSimFeatureHandlerInterface
///----------------------------------------------------------------------------
//static
LFSimFeatureHandlerInterface* LFSimFeatureHandlerInterface::sInstance;
///---------------------------------------------------------------------------- ///----------------------------------------------------------------------------
/// Class LLPermissions /// 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 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()) if(requester.isNull())
{ {
// ...system making request // ...system making request

View File

@@ -40,6 +40,23 @@ extern void mask_to_string(U32 mask, char* str);
extern std::string mask_to_string(U32 mask); extern std::string mask_to_string(U32 mask);
template<class T> class LLMetaClassT; template<class T> 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 // Class LLPermissions
// //
@@ -274,6 +291,7 @@ public:
inline bool allowModifyBy(const LLUUID &agent_id, const LLUUID& group) const; inline bool allowModifyBy(const LLUUID &agent_id, const LLUUID& group) const;
inline bool allowCopyBy(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 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 // This somewhat specialized function is meant for testing if the
// current owner is allowed to transfer to the specified agent id. // 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 // Class LLAggregatePermissions
// //

View File

@@ -30,7 +30,6 @@
#include "llnotificationsutil.h" #include "llnotificationsutil.h"
// newview includes // newview includes
#include "lfsimfeaturehandler.h"
#include "llavatarappearancedefines.h" #include "llavatarappearancedefines.h"
#include "llface.h" #include "llface.h"
#include "llvoavatar.h" #include "llvoavatar.h"
@@ -220,17 +219,6 @@ void WavefrontSaver::Add(const LLViewerObject* some_vo)
} }
namespace 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 class LFSaveSelectedObjects : public view_listener_t
{ {
bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata) bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
@@ -245,7 +233,7 @@ namespace
{ {
total++; total++;
LLSelectNode* node = *iter; LLSelectNode* node = *iter;
if (!can_export_node(node)) continue; if (!node->mPermissions->allowExportBy(gAgentID)) continue;
included++; included++;
wfsaver->Add(node->getObject()); wfsaver->Add(node->getObject());
} }
@@ -328,7 +316,7 @@ void WavefrontSaver::Add(const LLVOAvatar* av_vo) //adds attachments, too!
if (!c) continue; if (!c) continue;
if (const LLSelectNode* n = LLSelectMgr::getInstance()->getSelection()->findNode(const_cast<LLViewerObject*>(c))) if (const LLSelectNode* n = LLSelectMgr::getInstance()->getSelection()->findNode(const_cast<LLViewerObject*>(c)))
{ {
if (!can_export_node(n)) continue; if (!n->mPermissions->allowExportBy(gAgentID)) continue;
} }
else continue; else continue;
const LLVolume* vol = c->getVolume(); const LLVolume* vol = c->getVolume();

View File

@@ -65,7 +65,6 @@
#include "boost/date_time/posix_time/posix_time.hpp" #include "boost/date_time/posix_time/posix_time.hpp"
// newview includes // newview includes
#include "lfsimfeaturehandler.h"
#include "llface.h" #include "llface.h"
#include "llvovolume.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() void saveSelectedObject()
{ {
static const std::string file_ext = ".dae"; static const std::string file_ext = ".dae";
@@ -144,7 +131,7 @@ namespace DAEExportUtil
{ {
total++; total++;
LLSelectNode* node = *iter; LLSelectNode* node = *iter;
if (!canExportNode(node) || !node->getObject()->getVolume()) continue; if (!node->mPermissions->allowExportBy(gAgentID) || !node->getObject()->getVolume()) continue;
included++; included++;
daesaver->Add(node->getObject(), node->mName); daesaver->Add(node->getObject(), node->mName);
} }

View File

@@ -19,6 +19,7 @@
#define LFSIMFEATUREHANDLER_H #define LFSIMFEATUREHANDLER_H
#include "llsingleton.h" #include "llsingleton.h"
#include "llpermissions.h"
template<typename Type> template<typename Type>
class SignaledType class SignaledType
@@ -45,7 +46,7 @@ private:
Type mValue; Type mValue;
}; };
class LFSimFeatureHandler : public LLSingleton<LFSimFeatureHandler> class LFSimFeatureHandler : public LFSimFeatureHandlerInterface, public LLSingleton<LFSimFeatureHandler>
{ {
protected: protected:
friend class LLSingleton<LFSimFeatureHandler>; friend class LLSingleton<LFSimFeatureHandler>;
@@ -59,7 +60,7 @@ public:
boost::signals2::connection setSupportsExportCallback(const boost::signals2::signal<void()>::slot_type& slot); boost::signals2::connection setSupportsExportCallback(const boost::signals2::signal<void()>::slot_type& slot);
// Accessors // Accessors
bool simSupportsExport() const { return mSupportsExport; } /*virtual*/ bool simSupportsExport() const { return mSupportsExport; }
private: private:
// SignaledTypes // SignaledTypes

View File

@@ -3165,7 +3165,8 @@ BOOL LLAgent::allowOperation(PermissionBit op,
U8 god_minimum) U8 god_minimum)
{ {
// Check god level. // 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; if (!perm.isOwned()) return FALSE;
@@ -3187,7 +3188,8 @@ BOOL LLAgent::allowOperation(PermissionBit op,
else else
{ {
// Check for granted mod permissions. // 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; agent_proxy = owner_id;
} }

View File

@@ -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. // 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. // 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 && if (is_complete && item->getPermissions().allowExportBy(gAgent.getID()))
gAgent.getID() == item->getPermissions().getOwner() &&
gAgent.getID() == item->getPermissions().getCreator() &&
(PERM_ITEM_UNRESTRICTED &
perm_mask) == PERM_ITEM_UNRESTRICTED)
{ {
can_export = true; can_export = true;
} }

View File

@@ -1177,7 +1177,7 @@ void LLPanelPermissions::onCommitEveryoneCopy(LLUICtrl *ctrl, void *data)
void LLPanelPermissions::onCommitExport(const LLSD& param) void LLPanelPermissions::onCommitExport(const LLSD& param)
{ {
LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_EVERYONE, param, PERM_EXPORT); LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_EVERYONE, param.asBoolean(), PERM_EXPORT);
} }
// static // static

View File

@@ -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. // 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. // 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. // group_id can only be set to the object's group, if the agent is in that group.

View File

@@ -2895,15 +2895,7 @@ class LLObjectEnableExport : public view_listener_t
const LLSD& userdata; const LLSD& userdata;
virtual bool apply(LLSelectNode* node) virtual bool apply(LLSelectNode* node)
{ {
// Note: the actual permission checking algorithm depends on the grid TOS and must be return node->mPermissions->allowExportBy(gAgent.getID());
// 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));
} }
}; };
ff * the_ff = new ff(userdata); ff * the_ff = new ff(userdata);

View File

@@ -398,18 +398,7 @@ void LLObjectBackup::exportObject_continued(AIFilePicker* filepicker)
bool LLObjectBackup::validatePerms(const LLPermissions *item_permissions) bool LLObjectBackup::validatePerms(const LLPermissions *item_permissions)
{ {
if (gHippoGridManager->getConnectedGrid()->isSecondLife()) return item_permissions->allowExportBy(gAgent.getID());
{
// 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);
}
} }
// So far, only Second Life forces TPVs to verify the creator for textures... // So far, only Second Life forces TPVs to verify the creator for textures...